【问题标题】:ERROR 1067 (42000): Invalid default value for 'created_at'错误 1067 (42000):“created_at”的默认值无效
【发布时间】:2016-08-21 07:09:28
【问题描述】:

当我尝试更改表格时,它显示错误:

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

我用谷歌搜索了这个错误,但我发现的只是他们试图改变时间戳,所以它发生了。但是在这里我试图添加一个新列,我收到了这个错误:

mysql> ALTER TABLE investments ADD bank TEXT;
ERROR 1067 (42000): Invalid default value for 'created_at'

我表格的最后两列是created_atupdated_at

这是我的表结构:

【问题讨论】:

  • 这些列的默认值是什么?你能分享一下表结构吗?
  • @Priyanshu 我已经更新了我的表格结构
  • 为最后两列设置默认值 current_timestamp。
  • 解决此类问题的分步说明:stackoverflow.com/a/69733605/2677449

标签: mysql


【解决方案1】:

我在 Server version: 8.0.27-0ubuntu0.20.04.1 (Ubuntu) 遇到了类似的挑战,并使用以下技巧解决了

  1. 连接MySQL服务器mysql -u root -p
  2. 使用“查询”显示 sql_mode 变量:show variables like 'sql_mode';
  3. exit复制字符串后输出
  4. 编辑sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf的配置文件
  5. 如果您的配置文件丢失 sql_mode =sql_mode = ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION 从您的字符串中省略 NO_ZERO_IN_DATE、NO_ZERO_DATE。
  6. 运行 Sudo service mysql restart 应用更改。

【讨论】:

    【解决方案2】:

    对于那些在使用 Navicat 传输或导入数据时收到此错误的人,在我的例子中是从 MariaDB 到旧版本的 MySQL..

    尝试在日期转移下启用“Use DDL from SHOW CREATE TABLE” > 高级标签

    navicat data transfer advanced tab settings

    【讨论】:

      【解决方案3】:

      这个问题太宽泛,无法回答。关于这些问题有很多问题,当不同的基于 MySQL 的引擎的不兼容是臭名昭著的时候更是如此。 对我来说,最好的选择是在使用选项 --opt (mysqldump --opt) 进行备份时了解变量的状态,如果它没有像往常一样将其应用于我们的备份,或者因为原始备份我没有,或者因为发生在我们身上的备份不正确。

      如果备份不包含创建它的设置,我们将不得不开始调查,但基本上我们可以这样做。

      将设置添加到备份的标题

      echo '
      /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
      /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
      /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
      /*!50503 SET NAMES utf8mb4 */;
      /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
      /*!40103 SET TIME_ZONE='+00:00' */;
      /*!50606 SET @OLD_INNODB_STATS_AUTO_RECALC=@@INNODB_STATS_AUTO_RECALC */;
      /*!50606 SET GLOBAL INNODB_STATS_AUTO_RECALC=OFF */;
      /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
      /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
      /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
      /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;' | cat - mybackup.sql > temp && mv temp  mybackup.sql 
      

      添加恢复设置结束

      /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
      /*!50606 SET GLOBAL INNODB_STATS_AUTO_RECALC=@OLD_INNODB_STATS_AUTO_RECALC */;
      
      /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
      /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
      /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
      /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
      /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
      /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
      /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;' >> mybackup.sql 
      

      如果您没有这些设置,您可以在原始服务器上使用 --opt 选项进行 mysqldump 备份,以获取它们。

      如果你没有,你可以一点一点地进行,设置必要的设置,无论是在开始还是在出口。

      【讨论】:

        【解决方案4】:

        最简单的方法是将current timestamp 添加到default value

        通过 sql 添加这个 = "... DEFAULT CURRENT_TIMESTAMP;"

        【讨论】:

          【解决方案5】:

          尝试运行以下命令:

          ALTER TABLE `investments` 
          MODIFY created_at TIMESTAMP 
          DEFAULT CURRENT_TIMESTAMP 
          NOT NULL;
          

          ALTER TABLE `investments` 
          MODIFY updated_at TIMESTAMP 
          DEFAULT CURRENT_TIMESTAMP 
          NOT NULL;
          

          您收到此错误的原因是您没有为created_atupdated_at 字段设置默认值。 MySQL 不接受您的命令,因为这些列的值不能为空。

          【讨论】:

            【解决方案6】:

            就我而言,我有一个要导入的文件。
            所以我只是在文件开头添加了SET sql_mode = '';,它就可以工作了!

            【讨论】:

              【解决方案7】:

              简单地说,在你运行任何语句之前,把它放在第一行:

              SET sql_mode = '';
              

              请注意:此语句应仅用于开发,不得用于生产。

              【讨论】:

              • 感谢您的提示。但仅删除日期限制NO_ZERO_IN_DATE,NO_ZERO_DATE 仅允许我们维护其他安全功能:SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
              • 为澄清起见,此语句应仅在开发中使用,而不应在生产中使用。
              【解决方案8】:

              对于Mysql5.7,登录mysql命令行并运行命令,

              mysql> show variables like 'sql_mode' ;
              

              在sql_mode中会显示NO_ZERO_IN_DATE,NO_ZERO_DATE。

              尝试在你的mysql conf文件中的[mysqld]下面添加一行以删除这两个选项,我的(Ubuntu 16上的mysql 5.7)是/etc/mysql/mysql.conf.d/mysqld.cnf

              现在重启mysql。有效!

              【讨论】:

                【解决方案9】:
                1. 首先,检查现有模式是否在终端中使用以下命令:

                  $ mysql -u root -p -e "SHOW VARIABLES LIKE 'sql_mode';"

                  mysql> show variables like 'sql_mode';

                  你会看到如下输出

                2. 通过 my.cnf 禁用模式: 在这种情况下,您需要移除 NO_ZERO_IN_DATE、NO_ZERO_DATE 模式

                  打开my.cnf文件(一般可以在/etc/my.cnf或/etc/mysql/my.cnf找到my.cnf文件)

                  更新 my.cnf 中 [mysqld] 标题下的模式

                  sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

                  这里我省略了 NO_ZERO_IN_DATE、NO_ZERO_DATE 模式

                3. 重启mysql服务器

                  $ /etc/init.d/mysql restart

                【讨论】:

                  【解决方案10】:

                  对于Mysql8.0.18:

                  CURRENT_TIMESTAMP([fsp])
                  

                  删除“([fsp])”,解决了我的问题。

                  【讨论】:

                    【解决方案11】:

                    问题是由于sql_modes。 请通过命令检查您当前的 sql_modes:

                    show variables like 'sql_mode' ; 
                    

                    并删除 sql_mode "NO_ZERO_IN_DATE,NO_ZERO_DATE" 以使其工作。 这是mysql新版本默认的sql_mode。

                    您可以通过命令将sql_mode全局设置为root:

                    set global sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
                    

                    【讨论】:

                    • 我知道这一点,但在我的服务器 sql_mode 显示空白,仍然无法正常工作,我正在使用 [服务器版本:5.5.53-0ubuntu0.12.04.1 - (Ubuntu)]。不升级服务器版本,任何人都可以有任何解决方案?
                    • 你用全局命令检查了吗?同一会话的 sql_mode 中没有任何内容吗?
                    • 我检查了 show variables like 'sql_mode' ;并且输出是 Variable_name|Value = sql_mode|
                    • 这对这个答案很有用stackoverflow.com/questions/2317650/…
                    • 5.7 对我不起作用。不确定我是否必须在全球范围内这样做。
                    【解决方案12】:

                    只需按此行转换即可:

                    对于新表:

                    CREATE TABLE t1 (
                      ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
                    );
                    

                    对于现有表:

                    Alter ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
                    

                    来源:

                    https://dev.mysql.com/doc/refman/5.5/en/timestamp-initialization.html

                    【讨论】:

                      【解决方案13】:

                      正如@Bernd Bufen 的回答中提到的那样。这是 MariaDB 5.5 的问题,我简单地将 MariaDB 5.5 升级到 MariaDB 10.1 并解决了问题。

                      在 CentOS 7 上将 MariaDB 5.5 升级到 MariaDB 10.1 的步骤(64 位)

                      1. 将以下行添加到 MariaDB 存储库。

                        nano /etc/yum.repos.d/mariadb.repo 并粘贴以下行。

                      [mariadb]
                      名称 = MariaDB
                      baseurl = http://yum.mariadb.org/10.1/centos7-amd64
                      gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
                      gpgcheck=1

                      1. 停止 MariaDB(如果已在运行) service mariadb stop
                      2. 执行更新

                        yum update

                      3. 启动 MariaDB 并执行升级

                        service mariadb start

                        mysql_upgrade

                      一切都完成了。

                      检查 MariaDB 版本:mysql -V


                      注意:请始终在执行升级之前备份数据库。如果升级失败或出现问题,数据可能会丢失。

                      【讨论】:

                        【解决方案14】:

                        运行此查询:

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

                        对我有用

                        【讨论】:

                        • 顺便说一下不需要 SET time_zone = "+00:00";
                        【解决方案15】:

                        我在尝试安装第三方数据库时遇到了同样的错误。 我尝试了未成功提出的解决方案,即
                        SET sql_mode = '';

                        然后我尝试了下面的命令,它允许安装数据库
                        SET GLOBAL sql_mode = '';

                        【讨论】:

                        • SET sql_mode = ''; 现已弃用,SET GLOBAL sql_mode = '' 可以
                        【解决方案16】:

                        我有类似的问题。以下解决了它:

                        变化:

                        recollect_date TIMESTAMP DEFAULT 'CURRENT_TIMESTAMP',

                        到:

                        recollect_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

                        即只需删除 CURRENT_TIMESTAMP 周围的引号即可。

                        希望这对某人有所帮助。

                        【讨论】:

                          【解决方案17】:

                          你可以这样做:

                           CREATE TABLE `ttt` (
                            `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
                            `t1` TIMESTAMP  NULL DEFAULT '0000-00-00 00:00:00',
                            `t2` TIMESTAMP  NULL DEFAULT '0000-00-00 00:00:00',
                            `t3` TIMESTAMP  NULL DEFAULT '0000-00-00 00:00:00',
                            `t4` TIMESTAMP  NULL DEFAULT 0,
                            PRIMARY KEY (`id`)
                          ) ENGINE=INNODB DEFAULT CHARSET=utf8;
                          
                          • 由于 TIMESTAMP 值存储为 Epoch Seconds,因此保留时间戳值 '1970-01-01 00:00:00' (UTC),因为秒 #0 用于表示 '0000-00-00 00: 00:00'。
                          • 在 MariaDB 5.5 及之前版本中,每个表只能有一个将 CURRENT_TIMESTAMP 定义为其默认值的 TIMESTAMP 列。自 MariaDB 10.0 起,此限制不再适用。

                          见:https://mariadb.com/kb/en/mariadb/timestamp/

                          样本

                          MariaDB []> insert into ttt (id) VALUES (1),(2),(3);
                          Query OK, 3 rows affected (0.01 sec)
                          Records: 3  Duplicates: 0  Warnings: 0
                          
                          MariaDB []> select * from ttt;
                          +----+---------------------+---------------------+---------------------+---------------------+
                          | id | t1                  | t2                  | t3                  | t4                  |
                          +----+---------------------+---------------------+---------------------+---------------------+
                          |  1 | 0000-00-00 00:00:00 | 2000-01-01 12:01:02 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
                          |  2 | 0000-00-00 00:00:00 | 2000-01-01 12:01:02 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
                          |  3 | 0000-00-00 00:00:00 | 2000-01-01 12:01:02 | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |
                          +----+---------------------+---------------------+---------------------+---------------------+
                          3 rows in set (0.00 sec)
                          
                          MariaDB []>
                          

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 2018-07-06
                            • 1970-01-01
                            • 1970-01-01
                            • 2018-02-06
                            • 1970-01-01
                            • 2021-04-15
                            • 1970-01-01
                            • 2020-12-01
                            相关资源
                            最近更新 更多