在mysql触发器中,当我在表上执行"更新后" A然后使用"for each row"时,它会在A每次更新行时为每行运行触发器的主体A,还是说要应用触发每一行,A然后如果一行更新,它只会运行该更新行的正文代码?
谢谢
FOR EACH ROW意味着每个匹配的行的那得到任何更新或删除.
除非查询中有where条件,否则触发器主体不会遍历整个表数据.
下面演示了一个工作示例:
创建样本表:
drop table if exists tbl_so_q23374151;
create table tbl_so_q23374151 ( i int, v varchar(10) );
-- set test data
insert into tbl_so_q23374151
values (1,'one'),(2,'two' ),(3,'three'),(10,'ten'),(11,'eleven');
-- see current data in table**:
select * from tbl_so_q23374151;
+------+--------+
| i | v |
+------+--------+
| 1 | one |
| 2 | two |
| 3 | three |
| 10 | ten |
| 11 | eleven |
+------+--------+
5 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
用于记录触发器主体中循环计数的样本表:
-- let us record, loop count of trigger, in a table
drop table if exists tbl_so_q23374151_rows_affected;
create table tbl_so_q23374151_rows_affected( i int );
select count(*) as rows_affected from tbl_so_q23374151_rows_affected;
+---------------+
| rows_affected |
+---------------+
| 0 |
+---------------+
Run Code Online (Sandbox Code Playgroud)
定义删除触发器:
drop trigger if exists trig_bef_del_on_tbl_so_q23374151;
delimiter //
create trigger trig_bef_del_on_tbl_so_q23374151 before delete on tbl_so_q23374151
for each row begin
set @cnt = if(@cnt is null, 1, (@cnt+1));
/* for cross checking save loop count */
insert into tbl_so_q23374151_rows_affected values ( @cnt );
end;
//
delimiter ;
Run Code Online (Sandbox Code Playgroud)
现在,测试删除操作:
delete from tbl_so_q23374151 where i like '%1%';
-- now let us see what the loop count was
select @cnt as 'cnt';
+------+
| cnt |
+------+
| 3 |
+------+
Run Code Online (Sandbox Code Playgroud)
现在,检查主表上的触发效果:
-- now let us see the table data
select * from tbl_so_q23374151;
+------+-------+
| i | v |
+------+-------+
| 2 | two |
| 3 | three |
+------+-------+
2 rows in set (0.00 sec)
select count(*) as rows_affected from tbl_so_q23374151_rows_affected;
+---------------+
| rows_affected |
+---------------+
| 3 |
+---------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
这只是 MySQL 的一个语法怪癖,而且几乎没有任何意义。MySQL 触发器需要语法FOR EACH ROW。如果没有它,您将收到语法错误。它们的工作方式与标准 SQL(例如 SQLite)触发器完全相同,不带FOR EACH ROW.
https://dev.mysql.com/doc/refman/8.0/en/create-trigger.html