1. 程式人生 > >java.sql.SQLException: Cannot convert value '0000-00-00 00:00:00' from column 7 to TIMESTAMP

java.sql.SQLException: Cannot convert value '0000-00-00 00:00:00' from column 7 to TIMESTAMP

在Mysql資料庫中使用DATETIME型別來儲存時間,使用JDBC中讀取這個欄位的時候,應該使用 ResultSet.getTimestamp(),這樣會得到一個java.sql.Timestamp型別的資料。在這裡既不能使用 ResultSet.getDate(),也不能使用ResultSet.getTime(),因為前者不包括time資料,後者不包括date資料。

但是在使用ResultSet.getTimestamp()時也不是完全安全的,例如,當資料庫中的TIMESTAMP型別的欄位值為 '0000-00-00 00:00:00'時,使用此方法進行讀取,會丟擲異常:Cannot convert value '0000-00-00 00:00:00' from column 1 to TIMESTAMP,這是因為JDBC不能將'0000-00-00 00:00:00'轉化為一個為一個java.sql.Timestamp,在Java中,想建立一個java.util.Date,使其值為 '0000-00-00'也是不可能的,最古老的日期應該是'0001-01-01 00:00:00'。

那麼在程式中該怎麼辦捏? 解決方案在這裡:

Datetimes with all-zero components (0000-00-00 ...) — These values can not be represented reliably in Java. Connector/J 3.0.x always converted them to NULL when being read from a ResultSet.

Connector/J 3.1 throws an exception by default when these values are encountered as this is the most correct behavior according to the JDBC and SQL standards. This behavior can be modified using the zeroDateTimeBehavior configuration property. The allowable values are:

exception (the default), which throws an SQLException with an SQLState of S1009.
convertToNull, which returns NULL instead of the date.
round, which rounds the date to the nearest closest value which is 0001-01-01.
Starting with Connector/J 3.1.7, ResultSet.getString() can be decoupled from this behavior via noDatetimeStringSync=true (the default value is false) so that you can retrieve the unaltered all-zero value as a String. It should be noted that this also precludes using any time zone conversions, therefore the driver will not allow you to enable noDatetimeStringSync and useTimezone at the same time.

所以,在JDBC URL中加入zeroDateTimeBehavior資訊,既可以解決:
String url = "jdbc:mysql://10.149.51.80:3306/test?relaxAutoCommit=true&zeroDateTimeBehavior=convertToNull";