'0000-00-00 00:00:00' ไม่สามารถแสดงเป็นข้อผิดพลาด java.sql.Timestamp


141

ฉันมีตารางฐานข้อมูลที่มีวันที่

 (`date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'). 

ฉันใช้ MySQL จากโปรแกรมบางครั้งข้อมูลถูกส่งโดยไม่มีวันที่ไปยังฐานข้อมูล ดังนั้นค่าวันที่จะถูกกำหนดโดยอัตโนมัติ0000-00-00 00:00:00 เมื่อข้อมูลตารางถูกเรียกพร้อมกับคอลัมน์วันที่ซึ่งทำให้เกิดข้อผิดพลาด

...'0000-00-00 00:00:00' can not be represented as java.sql.Timestamp.......

ฉันพยายามส่งผ่านค่า Null ไปยังวันที่เมื่อแทรกข้อมูล แต่ได้รับมอบหมายให้เป็นเวลาปัจจุบัน

มีวิธีใดบ้างที่ฉันจะได้รับResultSetโดยไม่ต้องเปลี่ยนโครงสร้างตาราง?

คำตอบ:


302

คุณสามารถใช้ JDBC URL นี้โดยตรงในการกำหนดค่าแหล่งข้อมูลของคุณ:

JDBC: MySQL: // yourserver: 3306 / yourdatabase zeroDateTimeBehavior = convertToNull


2
อยากรู้อยากเห็น อ่านคำตอบอื่น ๆ ใช่ไม่มีเดือนเป็นศูนย์ สิ่งนี้หมายความว่าอะไรจริงๆ?
Thufir

2
คุณรู้หรือไม่ว่ามี MariaDB เทียบเท่ากับผนวกกับ jdbc URL ของฉันหรือไม่ jdbc: mariadb: // localhost: 3306 / dev? zeroDateTimeBehavior = convertToNull ดูเหมือนจะไม่ทำงานสำหรับฉัน
jeffkempf

ต้องเป็น CONVERT_TO_NULL สำหรับฉัน
เส้นทางประจำ

16

ไม่ว่า "วันที่" '0000-00-00 "เป็น" วันที่ที่ถูกต้อง "นั้นไม่เกี่ยวข้องกับคำถามหรือไม่" เพียงแค่เปลี่ยนฐานข้อมูล "เป็นวิธีแก้ปัญหาที่ใช้งานได้จริง

ข้อเท็จจริง:

  • MySQL อนุญาตให้มีวันที่ที่มีค่าเป็นศูนย์
  • "ฟีเจอร์" นี้ใช้กับภาษาอื่นอย่างแพร่หลาย

ดังนั้นถ้าฉัน "เพียงแค่เปลี่ยนฐานข้อมูล" โค้ด PHP หลายพันบรรทัดจะแตก

โปรแกรมเมอร์ Java จำเป็นต้องยอมรับ MySQL zero-date และพวกเขาจำเป็นต้องใส่ zero date กลับเข้าไปในฐานข้อมูลเมื่อภาษาอื่น ๆ พึ่งพา "ฟีเจอร์" นี้

โปรแกรมเมอร์ที่เชื่อมต่อกับ MySQL จำเป็นต้องจัดการ null และ 0000-00-00 เช่นเดียวกับวันที่ที่ถูกต้อง การเปลี่ยน 0000-00-00 เป็น null ไม่ใช่ตัวเลือกที่ใช้งานได้เพราะคุณไม่สามารถระบุได้ว่าวันที่คาดว่าจะเป็น 0000-00-00 สำหรับการเขียนกลับไปที่ฐานข้อมูล

สำหรับ 0000-00-00 ฉันขอแนะนำให้ตรวจสอบค่าวันที่เป็นสตริงจากนั้นเปลี่ยนเป็น ("y", 1) หรือ ("yyyy-MM-dd", 0001-01-01) หรือเปลี่ยนเป็นค่าไม่ถูกต้อง MySQL วันที่ (น้อยกว่า 1,000 ปี, iirc) MySQL มี "ฟีเจอร์" อื่น: วันที่ต่ำจะถูกแปลงเป็น 0000-00-00 โดยอัตโนมัติ

ฉันรู้ว่าคำแนะนำของฉันคือกระบอง แต่นั่นก็คือการจัดการวันที่ของ MySQL และสองกระบองไม่ได้ทำให้ถูกต้อง ข้อเท็จจริงของเรื่องที่เป็นโปรแกรมเมอร์จำนวนมากจะมีการจัดการ MySQL ศูนย์วันตลอดไป


9

ผนวกคำสั่งต่อไปนี้ไปยังโปรโตคอล JDBC-mysql:

?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8

ตัวอย่างเช่น:

jdbc:mysql://localhost/infra?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8

5
ระวังด้วยวิธีนี้ มันใช้งานได้อย่างมีเสน่ห์ แต่เอาเซิร์ฟเวอร์การผลิตมาใช้กับเรา สิ่งที่เราได้เรียนรู้คือคุณจะต้องอ้างอิงสตริงในขณะที่ & ถูกตีความว่าเป็นอักขระพิเศษในบริบทบางอย่างที่ทำให้บรรทัดมีความหมายที่แตกต่างกันโดยสิ้นเชิง ...
Techmag

6

แทนที่จะใช้วันที่ปลอมเช่น0000-00-00 00:00:00หรือ0001-01-01 00:00:00(ควรยอมรับหลังเพราะเป็นวันที่ที่ถูกต้อง) เปลี่ยนสคีมาฐานข้อมูลของคุณเพื่ออนุญาตNULLค่าต่างๆ

ALTER TABLE table_name MODIFY COLUMN date TIMESTAMP NULL

3

ในฐานะที่เป็นการตอบสนองอย่างกว้างขวางเมื่อคุณไม่สามารถทำการเปลี่ยนแปลงในคอลัมน์วันที่ของคุณหรือเพื่อปรับปรุงค่าหรือในขณะที่การแก้ไขเหล่านี้เกิดขึ้นคุณสามารถทำการเลือกโดยใช้เคส / เมื่อ

SELECT CASE ModificationDate WHEN '0000-00-00 00:00:00' THEN '1970-01-01 01:00:00' ELSE ModificationDate END AS ModificationDate FROM Project WHERE projectId=1;

1

ฉันต่อสู้กับปัญหานี้และนำโซลูชันการต่อเชื่อม URL ไปใช้โดย @Kushan ในคำตอบที่ยอมรับด้านบน มันทำงานในอินสแตนซ์ MySql ในพื้นที่ของฉัน แต่เมื่อฉันปรับใช้แอพ Play / Scala ของฉันกับ Heroku มันจะไม่ทำงานอีกต่อไป Heroku เชื่อมต่อหลาย ๆ args กับ DB URL ที่พวกเขาให้ผู้ใช้และวิธีการแก้ปัญหานี้เพราะ Heroku ใช้ concatenation ของ "?" ก่อนที่ชุดของตัวเองจะไม่ทำงาน อย่างไรก็ตามฉันพบวิธีแก้ไขปัญหาที่แตกต่างกันซึ่งดูเหมือนว่าจะทำงานได้ดีอย่างเท่าเทียมกัน

SET sql_mode = 'NO_ZERO_DATE';

ฉันใส่ไว้ในคำอธิบายตารางของฉันและจะแก้ไขปัญหาของ '0000-00-00 00:00:00' ไม่สามารถแสดงเป็น java.sql.Timestamp


1

คุณสามารถลองแบบนี้

ArrayList<String> dtlst = new ArrayList<String>();
String qry1 = "select dt_tracker from gs";

Statement prepst = conn.createStatement();
ResultSet rst = prepst.executeQuery(qry1);
while(rst.next())
{
    String dt = "";
    try
    {
        dt = rst.getDate("dt_tracker")+" "+rst.getTime("dt_tracker");
    }
    catch(Exception e)
    {
        dt = "0000-00-00 00:00:00";
    }

    dtlst.add(dt);
}

0

ไม่มีปี 0000 และไม่มีเดือน 00 หรือวัน 00 ฉันขอแนะนำให้คุณลอง

0001-01-01 00:00:00

แม้ว่าจะมีการกำหนดปี 0 ในมาตรฐานบางอย่าง แต่ก็มีแนวโน้มที่จะสับสนมากกว่า IMHO ที่เป็นประโยชน์


2
ใช่มีปี 0000 infact ของปี 0 และเรามีปี -1 และปี -1000 ไม่เคยเห็นปฏิทิน Gregorianนี้หรือAnno Dominiนี้และอีกต่อไปโดยเฉพาะปฏิทิน Gregorian ไม่มีศูนย์ปี แต่ iso มีและ iso ถูกใช้คอมพิวเตอร์ bij ดู0 ปี
botenvouwer

@sirwilliam ขอบคุณสำหรับคุณสมบัติที่น่าสนใจ ดูเหมือนว่า OP ต้องการให้ปี 0 ถือว่าเป็น NULL หรือบางอย่างที่ไม่มีอยู่
Peter Lawrey

1
ใน MySQL 0000-00-00 00:00:00 มีค่าเท่ากับ 0 ในรหัสดั้งเดิมอาจมีข้อสงสัยบางข้อที่ต้องใช้สิ่งนี้
Juha Palomäki


0

ฉันรู้ว่านี่จะเป็นคำตอบที่ล่าช้า แต่นี่เป็นคำตอบที่ถูกต้องที่สุด

ในฐานข้อมูล MySQL, เปลี่ยนค่าเริ่มต้นเข้าสู่timestamp CURRENT_TIMESTAMPหากคุณมีระเบียนเก่าที่มีค่าปลอมคุณจะต้องแก้ไขด้วยตนเอง


สิ่งนี้จะไม่ช่วยด้วย
Sunil Sharma

0

คุณสามารถลบคุณสมบัติ "ไม่เป็นโมฆะ" จากคอลัมน์ของคุณในตาราง mysql หากไม่จำเป็น เมื่อคุณลบคุณสมบัติ "ไม่เป็นโมฆะ" ไม่จำเป็นต้องมีการแปลง "0000-00-00 00:00:00" และปัญหาจะหายไป

อย่างน้อยก็ทำงานให้ฉัน


-2

ฉันเชื่อว่านี่คือความช่วยเหลืออย่างเต็มรูปแบบสำหรับผู้ที่ได้รับสิ่งนี้ด้านล่างยกเว้นเพื่อปั๊มข้อมูลผ่านข้อผิดพลาด logstash: logstash.inputs.jdbc - ข้อยกเว้นเมื่อดำเนินการแบบสอบถาม JDBC {: exception => #}

คำตอบ: JDBC: MySQL: // localhost: 3306 / database_name zeroDateTimeBehavior = convertToNull"

หรือถ้าคุณทำงานกับ mysql

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.