关于数据库:MySQL – 如何为多行执行”每行”语句?

MySQL - how "for each row" statements get executed for multiple rows?

说明
我有一个更新前触发器来填充 updated_at 字段以记录更新时间。我使用了 for each row 语句并希望每一行都有不同的时间戳。但是如果我在一个语句中更新多行,所有行都会得到相同的时间戳。

示例
对于下表和触发器:

1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE `foo` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `bar` varchar(255) NOT NULL,
  `updated_at` bigint(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

delimiter $$
create trigger foo_before_update before update on `foo`
for each row begin
  set new.updated_at = UNIX_TIMESTAMP(now(6)) * 1000000;
end $$
delimiter ;

和现有数据:

1
2
3
4
5
6
7
+----+-----+------------+
| id | bar | updated_at |
+----+-----+------------+
|  1 | a   | 0          |
|  2 | b   | 0          |
|  3 | c   | 0          |
+----+-----+------------+

当我运行 UPDATE foo SET bar = 'd'; 时,我期望
有三个不同的时间戳,但我得到了:

1
2
3
4
5
6
7
+----+-----+------------------+
| id | bar | updated_at       |
+----+-----+------------------+
|  1 | d   | 1536903279930403 |
|  2 | d   | 1536903279930403 |
|  3 | d   | 1536903279930403 |
+----+-----+------------------+

我的问题
我正在使用 mysql 5.7 和文档:

The statement following FOR EACH ROW defines the trigger body; that
is, the statement to execute each time the trigger activates, which
occurs once for each row affected by the triggering event.

我想知道是什么导致时间戳相同:

  • 将mysql执行语句一次并应用于所有受影响的行作为优化?
  • 或者它一一执行这些行但仍然得到相同的时间?为什么?

如果您希望每行有不同的时间,则需要使用 SYSDATE()。来自 NOW() 的手册:

(Within a stored function or trigger, NOW() returns the time at which
the function or triggering statement began to execute.) This differs
from the behavior for SYSDATE(), which returns the exact time at which
it executes.