'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不更改表结构的情况下获得?

Answers:


302

您可以在数据源配置中直接使用此JDBC URL:

jdbc:mysql://您的服务器:3306 /您的数据库?zeroDateTimeBehavior = convertToNull


2
好奇。阅读其他答案,answers,没有零月。这到底是什么意思?
Thufir

2
您是否知道是否有等效的MariaDB附加到我的jdbc URL?jdbc:mariadb:// localhost:3306 / dev?zeroDateTimeBehavior = convertToNull似乎对我不起作用。
jeffkempf

对我来说应该是CONVERT_TO_NULL
routeburn

16

“日期”“ 0000-00-00”是否为有效的“日期”与问题无关,“仅更改数据库”很少是可行的解决方案。

事实:

  • MySQL允许使用零值的日期。
  • 此“功能”在其他语言中享有广泛的使用。

因此,如果我“只是更改数据库”,数千行PHP代码将中断。

Java程序员需要接受MySQL的零日期,并且当其他语言都依赖此“功能”时他们需要将零日期放回数据库中。

连接到MySQL的程序员需要处理null和0000-00-00以及有效日期。将0000-00-00更改为null并不是一个可行的选择,因为那样您将无法再确定该日期是否应为用于回写到数据库的0000-00-00。

对于0000-00-00,我建议将日期值检查为字符串,然后将其更改为(“ y”,1)或(“ yyyy-MM-dd”,0001-01-01)或任何无效的值MySQL日期(小于1000年,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 2016年

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

我努力解决了这个问题,并实现了@Kushan在上面接受的答案中提供的URL串联解决方案。它在我的本地MySql实例中工作。但是,当我将Play / Scala应用程序部署到Heroku时,它将不再起作用。Heroku还将几个args串联到它们提供给用户的DB URL上,并且由于Heroku使用“?”串联,因此此解决方案也是如此。在自己设置参数之前,将无法正常工作。但是,我发现了另一种似乎同样有效的解决方案。

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年,但比有用的恕我直言更容易造成混淆。


2
是的,年份为0000。实际上,它的年份为0,而我们的年份为-1,年份为-1000。从来没有见过这个公历或这个Anno Domini,更特别的是,公历没有零年,但是iso有,iso用bij电脑看到了0年
botenvouwer

@sirwilliam感谢您提供有趣的资格。看来OP希望0年被视为NULL或不存在的东西。
彼得·劳瑞

1
在MySQL 0000-00-00 00:00:00等于0。在旧代码中,可能会有一些查询依赖于此。
JuhaPalomäki2015年


0

我知道这将是一个较晚的答案,但这是最正确的答案。

在MySQL数据库中,将timestamp默认值更改为CURRENT_TIMESTAMP。如果您有带有假值的旧记录,则必须手动对其进行修复。


这也无济于事。
Sunil Sharma

0

如果不需要,您可以从mysql表的列中删除“ not null”属性。当您删除“ not null”属性时,无需进行“ 0000-00-00 00:00:00”转换,问题就解决了。

至少对我有用。


-2

我相信这对谁将获得下面的全部帮助是完全有用的。

答案:jdbc:mysql:// localhost:3306 / database_name?zeroDateTimeBehavior = convertToNull“

或者如果您正在使用mysql

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.