MySQL:INSERT 错误“不能为 NULL”——DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP

use*_*083 5 mysql sql activerecord datetime

其实类似的问题还有很多,我也解决不了这个问题。我正在使用 codeigniter 框架。当我insert通过传递 php 对象来调用 ActiveRecord 的方法时,它会按其值或 null 发送所有属性。它会导致cannot be null.错误。

表结构:

CREATE TABLE `scheduledTasks` (
  `id` int(11) NOT NULL,
  `type` varchar(255) COLLATE utf8_bin NOT NULL,
  `createTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `executionTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `ownerUserId` int(11) DEFAULT NULL,
  `subjectUserId` text COLLATE utf8_bin,
  `detail` text COLLATE utf8_bin,
  `isExecuted` int(1) DEFAULT '0'
);
ALTER TABLE `scheduledTasks`
  ADD PRIMARY KEY (`id`);
ALTER TABLE `scheduledTasks`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
Run Code Online (Sandbox Code Playgroud)

我尝试过的查询:

INSERT INTO `scheduledTasks` (`id`, `type`, `createTime`, `executionTime`, `ownerUserId`, `detail`, `isExecuted`)
VALUES (NULL, 'QuoteRequest', NULL, NULL, '926', NULL, NULL)
Run Code Online (Sandbox Code Playgroud)

MySQL版本:

+-------------------------+
| VERSION()               |
+-------------------------+
| 5.7.17-0ubuntu0.16.04.1 |
+-------------------------+
Run Code Online (Sandbox Code Playgroud)

我有

explicit_defaults_for_timestamp | OFF
Run Code Online (Sandbox Code Playgroud)

sql模式是

+-------------------------------------------------------------------------------------------------------------------------------------------+
| @@SESSION.sql_mode                                                                                                                        |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+-------------------------------------------------------------------------------------------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

Ant*_*dge 4

讨论

\n\n

MySQL 5.7 手册指出...

\n\n
\n

此外,您可以通过为任何TIMESTAMP列分配NULL值来将其初始化或更新为当前日期和时间,除非已使用 NULL 属性定义该列以允许 NULL 值。

\n
\n\n

该手册没有说您可以对DATETIME字段执行此操作。最好的办法是在INSERT查询中不为createTimeexecutionTime字段提供任何值。那应该给你DEFAULT_TIMESTAMP. 如果失败了,好吧,我尝试过。

\n\n
INSERT INTO `scheduledTasks` (`id`, `type`, `createTime`, `executionTime`, `ownerUserId`, `detail`, `isExecuted`)\nVALUES (NULL, \'QuoteRequest\', , , \'926\', NULL, NULL)\n
Run Code Online (Sandbox Code Playgroud)\n\n

另外,请记住MySQL 默认值,即使您的DATETIME列确实显式DEFAULT子句。

\n\n
\n

NOT NULL对于没有显式 \n子句的列的数据输入DEFAULT,如果INSERT或REPLACE语句不包含\n 的值,或者UPDATE语句将该列设置为NULL,则MySQL根据\n中的SQL模式处理\n该列当时的效果:

\n\n

如果启用严格SQL模式,事务表会出错,语句会回滚。对于非事务性表,会发生错误,但如果多行语句的第二行或后续行发生这种情况,则前面的行将被插入。

\n\n

如果未启用严格模式,MySQL 会将列设置为列数据类型的隐式默认值。

\n
\n\n

最后, MySQL手册中关于严格模式:

\n\n
\n

对于STRICT_TRANS_TABLES,MySQL 会将无效值转换为该列最接近的有效值,并插入调整后的值。如果缺少值,MySQL 会插入列数据类型的隐式默认值。无论哪种情况,MySQL 都会生成警告而不是错误,并继续处理该语句。隐式默认值在第 12.7 节 \xe2\x80\x9c 数据类型默认值\xe2\x80\x9d 中描述。

\n
\n\n

结论

\n\n

总之,如果您处于严格模式(即您所在的模式STRICT_TRANS_TABLES)并将DATETIME列设置为NOT NULL DEFAULT CURRENT_TIMESTAMP,然后您NULL在 期间提供值INSERT,然后您会收到“ cannot be NULL ”错误,...下次不要这样做向字段提供值DATETIME

\n\n

如果您的框架无法设置为在 期间省略值INSERT,并且更改 SQL 模式不起作用,那么更改要使用的表 (gasp)可能是您在严格模式下TIMESTAMP使用并出现的唯一选项。NULLDEFAULT TIMESTAMP

\n