"for each row"如何在mysql中的触发器中工作?

ome*_*ega 8 mysql

在mysql触发器中,当我在表上执行"更新后" A然后使用"for each row"时,它会在A每次更新行时为每行运行触发器的主体A,还是说要应用触发每一行,A然后如果一行更新,它只会运行该更新行的正文代码?

谢谢

Rav*_*ddy 8

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)


And*_*y W 7

从字面上看 - mysql 将为受 SQL 语句影响的每一行运行您的触发器代码。

而不是针对表 A 中的每一行本身。


Bil*_*man 5

这只是 MySQL 的一个语法怪癖,而且几乎没有任何意义。MySQL 触发器需要语法FOR EACH ROW。如果没有它,您将收到语法错误。它们的工作方式与标准 SQL(例如 SQLite)触发器完全相同,不带FOR EACH ROW.

https://dev.mysql.com/doc/refman/8.0/en/create-trigger.html