如果日期>日期时间字段溢出' 9999-12-31 23:59:59.4'

时间:2016-07-24 15:35:35

标签: mysql datetime

我的桌子admin_tool_functionality

CREATE TABLE admin_tool_functionality (

    id BIGINT NOT NULL AUTO_INCREMENT,

    admin_tool_functionality_type_id BIGINT NOT NULL,

    CONSTRAINT fk__admin_tool_functionality__admin_tool_functionality_type
        FOREIGN KEY (admin_tool_functionality_type_id)
        REFERENCES admin_tool_functionality_type(id),

    PRIMARY KEY (id, admin_tool_functionality_type_id),

    price FLOAT NOT NULL,

    valid_from_day DATETIME NOT NULL, 

    valid_until_day DATETIME NOT NULL,

    CHECK(valid_from_day < valid_until_day)

);

此插入工作正常:

INSERT INTO admin_tool_functionality 
    (admin_tool_functionality_type_id, price, valid_from_day, valid_until_day)
VALUES
    (1, 13.37, '2016-01-01', '9999-12-31 23:59:59.4');

但是任何比'9999-12-31 23:59:59.4'更大的值都失败了:

INSERT INTO admin_tool_functionality 
    (admin_tool_functionality_type_id, price, valid_from_day, valid_until_day)
VALUES
    (1, 13.37, '2016-01-01', '9999-12-31 23:59:59.5');

给我:

Caused by: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Datetime function: datetime field overflow
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3964)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3902)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2526)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2673)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2545)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2503)
    at com.mysql.jdbc.StatementImpl.executeInternal(StatementImpl.java:839)
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:739)

尽管documentation

  

DATETIME值的范围是'1000-01-01 00:00:00.000000''9999-12-31 23:59:59.999999'

为什么我收到此错误?

2 个答案:

答案 0 :(得分:3)

请参阅MySQL的fractional seconds文档,并注意@Pieter关于MySQL版本的评论。

在MySQL 5.6.4之前,微秒被丢弃并且没有存储,但可以按照文档在以下情况下使用:

  

在文本值等上下文中,以及在某些时间函数的参数或返回值中,允许使用尾部小数部分。

在MySQL 5.6.4之上或之后,扩展了小数秒支持。

除非您为DATETIME列定义小数秒( fsp ),否则它将默认为0,即无微秒。

根据文档中的评论:

  

将带有小数秒部分的TIME,DATE或TIMESTAMP值插入到相同类型但具有较少小数位的列中会导致舍入

基于上述评论和失败的INSERT的假设和理论是.4甚至.499999(MySQL 5.6.4或更新支持的最多6个小数位)将围绕向下< / em>,而.5或更高版本将围绕向上

由于微秒被认为是小数,这将使秒成为整数或数字的整个部分。如果将59.5向上舍入,则会导致您的日期部分必须更改(向前移动1天),因为时间部分范围为00:00:0023:59:59。在调整日期和时间的函数之外,此行为可能被视为意外。

答案 1 :(得分:2)

自MySQL 5.6.4以来,TIMEDATETIMETIMESTAMP已添加了小数秒支持。在该版本之前,您不能将小数秒添加到时间戳(请参阅documentation)。

您是否有机会使用5.6.4之前的MySQL版本?