“create_date”时间戳字段的默认值无效
Posted
技术标签:
【中文标题】“create_date”时间戳字段的默认值无效【英文标题】:Invalid default value for 'create_date' timestamp field 【发布时间】:2012-02-29 19:29:06 【问题描述】:我有以下 sql create 语句
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'
这里有什么错误?
【问题讨论】:
我看不出您的查询有什么问题,它适用于刚刚测试的 5.1.50 社区。span> 我这边的查询也没问题。 不确定,但给该字段取一个不同的名称并尝试? 我在 ubuntu 10.04 中使用 mysql 5.1.56 社区。并且不工作 无零日期需要一个日期。使用“1970-01-01 00:00:01”。 [取自这里][1] [1]:dba.stackexchange.com/questions/6171/… 【参考方案1】:这是因为服务器 SQL 模式 - NO_ZERO_DATE。
来自参考:NO_ZERO_DATE
- 在严格模式下,不允许 '0000-00-00'
作为有效日期。您仍然可以使用 IGNORE 选项插入零日期。当不在严格模式下时,日期会被接受,但会生成警告。
【讨论】:
如何给忽略选项? 您不能忽略此选项。这是服务器选项。如果您有权访问 my.ini(mysql 配置文件),则从 sql-mode 选项中删除 NO_ZERO_DATE 并重新启动服务器。 要检查这个选项 - 运行 SHOW VARIABLES LIKE 'sql_mode' 我使用 mysql 工作台生成了脚本。在脚本中,sql_mode 设置为传统的。如果我删除传统,脚本可以工作。 在 MySQL Workbench 首选项中,转到选项卡“型号:MySQL”。将 'SQL_MODE to be used in generated scripts' 设置为 "STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" 这样就解决了问题。【参考方案2】:如果您从 MySQL 工作台生成脚本。
下面一行生成
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
从 SQL_MODE 中删除 TRADITIONAL,然后脚本应该可以正常工作
否则,您可以将 SQL_MODE 设置为 Allow Invalid Dates
SET SQL_MODE='ALLOW_INVALID_DATES';
【讨论】:
节省了我一些时间来搜索它为什么不起作用:) 啊,谢谢。 SET SQL_MODE='ALLOW_INVALID_DATES';是一个救生员。当我尝试将 wordpress 站点迁移到另一台服务器(都是本地服务器)时遇到了这个问题,并且由于此错误,它不允许我导入数据库数据,即使表中没有出现此错误的行。 工作就像一个魅力!谢谢。 SET SQL_MODE='ALLOW_INVALID_DATES';在执行查询之前做了诀窍 为了让它在 MySQL 8 中工作,我必须添加全局:SET GLOBAL SQL_MODE ='ALLOW_INVALID_DATES';
【参考方案3】:
TIMESTAMP 的范围为 '1970-01-01 00:00:01' UTC 到 '2038-01-19 03:14:07' UTC(请参阅 doc)。默认值必须在该范围内。
其他奇怪的相关行为:
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)
旁注,如果要插入 NULLS:
CREATE TABLE tbl4 (
ts TIMESTAMP NULL DEFAULT NULL);
【讨论】:
这发生在我身上。这是怎么回事? ts2 甚至不是“NOT NULL”...! 可能是因为“如果您没有为表中的第一个 TIMESTAMP 列设置值,MariaDB 会在对行执行 UPDATE 或 INSERT 查询时自动为其分配当前日期和时间(s ) 有问题。” – MariaDB Docs 我喜欢使用column_name TIMESTAMP DEFAULT NOW()
。可能并不适合所有情况,但我想我会分享,因为我也在处理这个问题。
column_name TIMESTAMP DEFAULT '1970-01-01 00:00:01' 对我有用。谢谢!
谢谢!当像这样添加带有 liquibase 的列时,这对我有用。 <column defaultValueDate="1970-01-01 00:00:01" name="at" type="timestamp"> <constraints nullable="false"/> </column>
【参考方案4】:
在 ubuntu 桌面 16.04 中,我这样做了:
在您选择的编辑器中打开文件:/etc/mysql/mysql.conf.d/mysqld.cnf
。
寻找:sql_mode
,它会在[mysqld]
下面的某个地方。
并将sql_mode
设置为以下内容:
NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
保存并重启mysql服务:
sudo service mysql restart
【讨论】:
它确实有帮助,只是我在 ubuntu16.04 上的 mySQL 实例没有sql_mode
。我必须通过删除“NO_ZERO_DATE”在文件中为其添加一个条目。所以,这就是它现在的样子:#添加以下行以摆脱 no_zero_date 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
你是对的。我之前添加了禁用严格模式。当我为这个特定问题编辑它时,sql_mode
条目已经存在。
这是一个错误吗? CURRENT_TIMESTAMP 永远不应该返回“0000-00-00 00:00:00”,还是我错了?为什么我必须更改 mysqld 设置?
@letsjump 因为有人错误地配置了你的 mysql 服务器。我用我导入的数据库遇到了这个问题。列中时间戳的默认值不是有效的时间戳值。真正的解决方法是将默认时间戳更新为有效的时间,例如 1970 - 可用的最早日期。临时解决方法是禁用对数据库的检查。【参考方案5】:
只需在数据库 SQL 文件的顶部定义以下行。
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
它对我有用。
【讨论】:
【参考方案6】:使用 OS X,从 Homebrew 安装 mysql,系统变量基于其编译的默认值。 解决方案是从系统变量“sql_mode”中删除“NO_ZERO_DATE”。
请记住范围涉及。
如果你只想影响你的会话,请使用"@@session"
,例如:
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"
,例如:
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".
在这种情况下,它只影响更改后连接的客户端(不影响当前所有客户端),一旦服务器退出将不起作用。
【讨论】:
【参考方案7】:为避免此问题,您需要从 mysql 模式配置中删除 NO_ZERO_DATE
。
-
转到“phpmyadmin”。
加载 phpmyadmin 后,单击“变量”选项卡。
搜索“sql 模式”。
单击“编辑”选项并从配置中删除
NO_ZERO_DATE
(及其结尾的逗号)。
这是 wamp 或 xamp 本地环境中非常常见的问题。
【讨论】:
当我重新启动 Mamp 时,它们会重新出现【参考方案8】:我在 MySQL 5.7 中遇到了类似的问题,代码如下:
`update_date` TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
我改用这个来修复:
`update_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
【讨论】:
我认为这实际上是最好的选择,因为当默认为当前确实有意义时,它对出生时间戳没有意义 - 仅作为示例。 你会失去精度(毫秒)【参考方案9】:我可以通过从 Homebrew 安装 MySQL 在 OS X 上解决这个问题
brew install mysql
通过将以下内容添加到 /usr/local/etc/my.cnf
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
brew tap homebrew/services
brew services restart mysql
【讨论】:
【参考方案10】:禁用严格的 SQL 模式
Create disable_strict_mode.cnf file at /etc/mysql/conf.d/
在文件中,输入这两行:
[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:
sudo service mysql restart
【讨论】:
【参考方案11】:默认值应从 1000 年开始。
例如,
ALTER TABLE mytable last_active DATETIME DEFAULT '1000-01-01 00:00:00'
希望这对某人有所帮助。
【讨论】:
【参考方案12】:改变这个:
`create_date` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
`update_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
致以下:
`create_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
`update_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ,
【讨论】:
点评来源: 您好,请不要只用源代码回答。尝试对您的解决方案如何工作提供一个很好的描述。请参阅:How do I write a good answer?。谢谢 如果这是一个 WordPress 站点,请不要更新核心 WordPress 表。许多插件需要一个 zeores 值,因此 WordPress 无法更改此默认值,因为遗留原因会破坏插件。 Wordpress thread 和 Wordpress support。在不熟悉依赖默认值的代码的情况下更改数据库结构可能会导致麻烦的错误。虽然这在许多情况下可能是一种解决方案,但它可能会破坏其他情况。不是通用的解决方案。【参考方案13】:您可能想检查 MySql 实例上的时区设置:
mysql> show variables like 'time_zone';
+---------------+--------+
| Variable_name | Value |
+---------------+--------+
| time_zone | SYSTEM |
+---------------+--------+
在我的例子中,我意识到底层系统的时区设置为 BST 而不是 UTC,因此在创建表中,默认值 '1970-01-01 00:00:01' 被强制退回 1 小时,导致时间戳值无效。
对我来说,我实际上希望将机器的时区设置为 UTC,这让我很满意。当我运行 Centos/7 时,我只是这样做了
# timedatectl set-timezone UTC
然后重新启动一切。
【讨论】:
【参考方案14】:如果你没有服务器的管理权限,你可以设置当前会话的sql模式:
SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
【讨论】:
【参考方案15】:你可以改变这个:
`create_date` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
这样的:
`create_date` TIMESTAMP NOT NULL DEFAULT '2018-04-01 12:00:00',
【讨论】:
【参考方案16】:我很奇怪看到这么多答案,但没有人指出主要原因:不正确的“零”日期格式。简而言之,只需使用 '0000-01-01 00:00:00' 而不是 '0000-00-00 00:00:00'。显然,month 00 和 day 00 都不是有效值。
我同意***用户的观点,即错误是由 MySQL 设置 NO_ZERO_DATE 引起的。这个设置是在新的 MySQL 服务器版本中引入的,默认启用,这让许多开发人员感到惊讶。但请注意,这个设置的主要目的不是让开发者的生活更加艰难,而只是迫使他们修复过时的表结构,避免将来使用这种不正确的数据结构格式。
因此,如果您要创建新表并希望指定“零”日期,请使用“0000-01-01 00:00:00”。
如果您已经创建了表并出现此错误(例如,在插入新记录时忽略了默认值),只需像这样更新您的表:
ALTER TABLE `erp`.`je_menus`
MODIFY COLUMN `create_date` datetime(0) NOT NULL DEFAULT '0000-01-01 00:00:00' AFTER `notes`;
删除提及的服务器设置只是暂时的解决方案,并不是良好做法的示例。
【讨论】:
【参考方案17】:我尝试将列类型设置为“时间戳”,它对我有用。
【讨论】:
【参考方案18】:你可以改变这个:
create_date
datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
这样的:
create_date
varchar(80) NOT NULL DEFAULT '0000-00-00 00:00:00',
【讨论】:
以上是关于“create_date”时间戳字段的默认值无效的主要内容,如果未能解决你的问题,请参考以下文章
为啥 laravel 迁移的时间戳('my_col_name')返回语法错误或访问冲突:1067 'my_col_name' 的默认值无效