MySQL、phpMyAdmin:TIMESTAMP 始终执行 NOW 函数

Posted

技术标签:

【中文标题】MySQL、phpMyAdmin:TIMESTAMP 始终执行 NOW 函数【英文标题】:MySQL, phpMyAdmin: TIMESTAMP Always Executes NOW Function 【发布时间】:2011-09-28 10:18:08 【问题描述】:

我的 TIMESTAMPS 发生了一些非常烦人的事情......

我的表中有一个“createdat”、“deletedat”和“updatedat”列...我已将 deleteat 和更新设置为 NULL 和 DEFAULT NULL ...但是,当添加新记录时, NOW() 函数总是为 deleteat 和 updatedat 执行,而不是仅仅将其保留为 NULL。

所以我最终得到:00:00:00 ...

为什么不只是默认为 NULL?

这是我的表:

插入时(注意选择了 NOW 功能):

执行以下SQL:

INSERT INTO `MYTABLE_DEV`.`messages` (`id`, `fromUserId`, `toUserId`, `subject`, `body`, `createdat`, `updatedat`, `deletedat`) VALUES (NULL, '1', '3', 'Message', 'This is another message.', CURRENT_TIMESTAMP, NOW(), NOW());

【问题讨论】:

发布您的 DDL 可能会有所帮助。 是否有触发器进行该修改? 没有什么特别的事情发生......我没有做任何事情来触发这种行为。 当您执行该查询时,phpMyAdmin 会显示什么作为提交的 SQL? 【参考方案1】:

您正在执行 NOW() 而不是设置 null。使用这个查询:

INSERT INTO `MYTABLE_DEV`.`messages` (`id`, `fromUserId`, `toUserId`, `subject`, `body`) VALUES (NULL, '1', '3', 'Message', 'This is another message.');

或所有字段...

INSERT INTO `MYTABLE_DEV`.`messages` (`id`, `fromUserId`, `toUserId`, `subject`, `body`, `createdat`, `updatedat`, `deletedat`) VALUES (NULL, '1', '3', 'Message', 'This is another message.', CURRENT_TIMESTAMP, NULL, NULL);

【讨论】:

查询只是自动运行的......不是我自己构建的。【参考方案2】:

这是预期的行为。

与其他数据库不同,在 mysql 中,TIMESTAMP总是在行更新时使用now() 更新。这是 TIMESTAMP 数据类型的特意设计的特性。

编辑:请注意,我在这里谈论的是TIMESTAMP不是 TIMESTAMP DEFAULT NULL 或任何其他变体。

您想要的是 DATETIME 数据类型 - 它们的行为与普通列一样。

这里有一些测试 SQL 来显示它的行为:

create table timestamp_datatype (id int, dt datetime, ts timestamp);
-- test 1: leaving ts to default - you get now()
insert into timestamp_datatype (id, dt) values (1, '2011-01-01 01:01:01'); 
-- test 2: trying to give ts a value - this works
insert into timestamp_datatype (id, dt, ts) values (2, '2011-01-01 01:01:01', '2011-01-01 01:01:01');
-- test 3: specifying null for ts - this doesn't work - you get now()
insert into timestamp_datatype (id, dt, ts) values (3, '2011-01-01 01:01:01', null);
-- test 4: updating the row - ts is updated too
insert into timestamp_datatype (id, dt, ts) values (4, '2011-01-01 01:01:01', '2011-01-01 01:01:01');
update timestamp_datatype set dt = now() where id = 4; -- ts is updated to now()
select * from timestamp_datatype;
+------+---------------------+---------------------+
| id   | dt                  | ts                  |
+------+---------------------+---------------------+
|    1 | 2011-01-01 01:01:01 | 2011-07-05 09:50:24 |
|    2 | 2011-01-01 01:01:01 | 2011-01-01 01:01:01 |
|    3 | 2011-01-01 01:01:01 | 2011-07-05 09:50:24 |
|    4 | 2011-07-05 09:50:24 | 2011-07-05 09:50:24 |
+------+---------------------+---------------------+

【讨论】:

TIMESTAMP始终更新。尝试使用例如VARCHAR 列和定义为NULL DEFAULT NULLTIMESTAMP 列创建一个表。插入一行,仅指定 VARCHAR 字段。 TIMESTAMP 字段将保持为 NULL。更新插入的行,再次仅指定 VARCHAR 字段。同样,TIMESTAMP 将保持为NULL。刚刚用 MySQL 5.1 测试过。 要记住的一点是CREATE TABLE 中的ts TIMESTAMP 表示ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP。如果要使用 NULL 值,则必须指定:ts TIMESTAMP NULL 我会提到,虽然上面的一些陈述是错误的,但 DATETIME 工作得很好,并且做了它应该做的事情。我会接受“新闻快讯”,尽管看起来很讨厌。 说了这么多,TIMESTAMP 列类型并不是最合乎逻辑的,但MySQL reference 试图解释默认值和自动更新的行为方式。 是的,TIMESTAMP 一直在更新。 TIMESTAMP NULL DEFAULT NULL 不是 TIMESTAMP!正如我所说的TIMESTAMP(即没有任何额外修改)总是根据我的帖子更新【参考方案3】:

让它在这里(3.5.2 中即将发布的小补丁完全解决了这个问题): the bug report

【讨论】:

【参考方案4】:

这可能是 phpMyAdmin 中的错误/功能。看看this bug report,尤其是在 2010-06-13 11:06:47 UTC 添加的评论。有趣的部分:

但是,您可以质疑选择框中 NOW() 的默认值 在执行 INSERT/UPDATE 时,当时间戳字段的默认值 设置为 NULL。这可能不是您在设置 默认为 NULL。

如果这是真的,我想这就是 phpMyAdmin 的工作方式。我自己不使用 phpMyAdmin,所以我没有个人经验。

【讨论】:

以上是关于MySQL、phpMyAdmin:TIMESTAMP 始终执行 NOW 函数的主要内容,如果未能解决你的问题,请参考以下文章

怎么用phpmyadmin连接远程MYSQL数据库?

phpmyadmin 不会验证 mysql 帐户 - 无法登录 phpmyadmin

Mysql phpmyadmin docker镜像安装

phpMyAdmin 抛出 #2002 无法登录 mysql 服务器 phpmyadmin

利用phpmyadmin修改mysql的root密码及如何进入修改密码后的phpmyadmin

MySQL 数据库服务器对比phpmyadmin