关于mysql:’create_date’时间戳字段的默认值无效

Invalid default value for 'create_date' timestamp field

我有以下SQL create语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> CREATE  TABLE IF NOT EXISTS `erp`.`je_menus` (
    ->   `id` INT(11) NOT NULL AUTO_INCREMENT ,
    ->   `name` VARCHAR(100) NOT NULL ,
    ->   `description` VARCHAR(255) NOT NULL ,
    ->   `live_start_date` DATETIME NULL DEFAULT NULL ,
    ->   `live_end_date` DATETIME NULL DEFAULT NULL ,
    ->   `notes` VARCHAR(255) NULL ,
    ->   `create_date` TIMESTAMP NOT NULL DEFAULT  '0000-00-00 00:00:00',
    ->   `created_by` INT(11) NOT NULL ,
    ->   `update_date` TIMESTAMP NOT NULL DEFAULT  CURRENT_TIMESTAMP  ,
    ->   `updated_by` INT(11) NOT NULL ,
    ->   `status` VARCHAR(45) NOT NULL ,
    ->   PRIMARY KEY (`id`) )
    -> ENGINE = InnoDB;

出现以下错误

ERROR 1067 (42000): Invalid default value for 'create_date'

这里的错误是什么?


这是因为服务器SQL模式-没有零日期。

从参考文献中:NO_ZERO_DATE—在严格模式下,不允许'0000-00-00'作为有效日期。您仍然可以使用忽略选项插入零日期。如果不是严格模式,则接受日期,但会生成警告。


如果从MySQL工作台生成脚本。

生成以下行

1
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';

从SQL_模式中删除传统模式,然后脚本应该可以正常工作。

否则,您可以将SQL_模式设置为允许无效日期。

1
SET SQL_MODE='ALLOW_INVALID_DATES';


时间戳的范围是"1970-01-01 00:00:01"UTC到"2038-01-19 03:14:07"UTC(请参阅文档)。默认值必须在该范围内。

其他奇怪的、相关的、行为:

1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE tbl1 (
    ts TIMESTAMP);  
Query OK, 0 rows affected (0.01 sec)

CREATE TABLE tbl2 (
    ts TIMESTAMP,
    ts2 TIMESTAMP);
ERROR 1067 (42000): Invalid default value for 'ts2'

CREATE TABLE tbl3 (
    ts TIMESTAMP,
    ts2 TIMESTAMP DEFAULT '1970-01-01 00:00:01');
Query OK, 0 rows affected (0.01 sec)

侧注,如果要插入空值:

1
2


在Ubuntu桌面16.04中,我这样做了:

  • 打开文件:/etc/mysql/mysql.conf.d/mysqld.cnf在您选择的编辑器中。

  • 寻找:sql_mode,它将在[mysqld]下面的某个地方。

  • sql_mode设置为:

    埃多克斯1〔6〕

  • 保存并重新启动MySQL服务,方法是:

    江户十一〔七〕号


  • 我可以在OS X上通过从自制安装mysql来解决这个问题。

    1
    brew install mysql

    在/usr/local/etc/my.cnf中添加以下内容

    1
    sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

    重启mysql

    1
    2
    brew tap homebrew/services
    brew services restart mysql


    使用OS X,从Homebrew安装MySQL,系统变量基于其默认编译。解决方案是从系统变量"SQL模式"中删除"无零日期"。

    请记住范围涉及。

    如果您只想在您的会话中产生影响,请使用"@@session",例如:

    1
    SET @@session.sql_mode ="ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION".

    在这种情况下,一旦会话结束或更改会话,它将不会受到影响。它对其他会话没有影响。

    如果您想影响所有客户,请使用"@@global",例如:

    1
    SET @@global.sql_mode ="ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION".

    在这种情况下,它只影响更改后连接的客户机(不影响当前所有客户机),一旦服务器退出,它将不工作。


    为了避免这个问题,您需要从mysql模式配置中删除NO_ZERO_DATE

  • 转到"phpmyadmin"。
  • 加载phpmyadmin后,单击"变量"选项卡。
  • 搜索"SQL模式"。
  • 单击编辑选项并从配置中删除NO_ZERO_DATE(及其尾随逗号)。
  • 这是本地环境中使用WAMP或XAMP时非常常见的问题。


    我对MySQL5.7也有类似的问题,代码如下:

    埃多克斯1〔10〕

    我改为使用这个:

    江户十一〔11〕。


    只需在数据库SQL文件的顶部定义以下行。

    1
    2
    SET SQL_MODE ="NO_AUTO_VALUE_ON_ZERO";
    SET time_zone ="+00:00";

    它对我有效。


    禁用严格的SQL模式

    1
    Create disable_strict_mode.cnf file at /etc/mysql/conf.d/

    在文件中,输入以下两行:

    1
    2
    [mysqld]
    sql_mode=IGNORE_SPACE,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

    最后,使用以下命令重新启动mysql:

    1
    sudo service mysql restart


    您可能需要检查mysql实例上的时区设置:

    1
    2
    3
    4
    5
    6
    mysql> show variables like 'time_zone';
    +---------------+--------+
    | Variable_name | Value  |
    +---------------+--------+
    | time_zone     | SYSTEM |
    +---------------+--------+

    在我的例子中,我意识到底层系统的时区设置为BST而不是UTC,因此在创建表中,"1970-01-01 00:00:01"的默认值被强制后退1小时,导致时间戳值无效。

    对我来说,我实际上想把机器的时区设置为UTC,这就解决了我的问题。当我运行CentOS/7时,我只是

    1
    # timedatectl set-timezone UTC

    重新启动一切。


    默认值应该从1000年开始。

    例如,

    1
    ALTER TABLE mytable last_active DATETIME DEFAULT '1000-01-01 00:00:00'

    希望这能帮助别人。


    你可以改变这个:

    1
    `create_date` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',

    像这样的事情:

    1
    `create_date` TIMESTAMP NOT NULL DEFAULT '2018-04-01 12:00:00',