【问题标题】:mysql delete triggersmysql删除触发器
【发布时间】:2012-06-29 11:59:25
【问题描述】:

我想我读到删除触发器不知道删除了哪些数据并循环应用触发器的整个表。这是真的吗?

这是否意味着在删除数据之前,删除前循环整个表,删除发生后删除后循环整个表?

有没有办法只遍历已删除的记录?那么如果删除了 10 条记录会循环遍历它们吗?

DELIMITER $$
DROP TRIGGER  `before_delete_jecki_triggername`$$
CREATE TRIGGER before_delete_triggername
BEFORE DELETE ON table
FOR EACH ROW 
BEGIN
    /*do stuff*/
END$$
DELIMITER ;

谢谢,

垫子

【问题讨论】:

  • 你在哪里读到的? AFAIK,{BEFORE | AFTER} DELETE 触发器仅在分别要/已被删除的记录上调用。您可以使用OLD 表别名来访问相关记录中的数据。
  • SO 上的其他人 - 我正在尝试查找线程。有人知道吗?

标签: mysql triggers


【解决方案1】:

我认为这是由于与 FOR EACH ROW 声明混淆所致。
它仅适用于“在调用触发器之前发出的语句的匹配记录。

如果一个表中存在N的记录数并且匹配where id=x的记录,
假设x 导致的结果少于N 记录,例如N-5,则
FOR EACH ROW 仅导致N-5 次循环。

更新
由于FOR EACH ROW 语句影响的行上运行的示例测试如下所示。

mysql> -- create a test table
mysql> drop table if exists tbl; create table tbl ( i int, v varchar(10) );
Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.06 sec)

mysql> -- set test data
mysql> insert into tbl values(1,'one'),(2,'two' ),(3,'three'),(10,'ten'),(11,'eleven');
Query OK, 5 rows affected (0.02 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> select * from tbl;
+------+--------+
| i    | v      |
+------+--------+
|    1 | one    |
|    2 | two    |
|    3 | three  |
|   10 | ten    |
|   11 | eleven |
+------+--------+
5 rows in set (0.02 sec)

mysql> select count(*) row_count from tbl;
+-----------+
| row_count |
+-----------+
|         5 |
+-----------+
1 row in set (0.00 sec)

mysql>
mysql> -- record loop count of trigger in a table
mysql> drop table if exists rows_affected; create table rows_affected( i int );
Query OK, 0 rows affected (0.02 sec)

Query OK, 0 rows affected (0.05 sec)

mysql> select count(*) 'rows_affected' from rows_affected;
+---------------+
| rows_affected |
+---------------+
|             0 |
+---------------+
1 row in set (0.00 sec)

mysql>
mysql> set @cnt=0;
Query OK, 0 rows affected (0.00 sec)

mysql>
mysql> -- drop trigger if exists trig_bef_del_on_tbl;
mysql> delimiter //
mysql> create trigger trig_bef_del_on_tbl before delete on tbl
    ->   for each row begin
    ->     set @cnt = if(@cnt is null, 1, (@cnt+1));
    ->
    ->     /* for cross checking save loop count */
    ->     insert into rows_affected values ( @cnt );
    ->   end;
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql>
mysql> delimiter ;
mysql>
mysql> -- now let us test the delete operation
mysql> delete from tbl where i like '%1%';
Query OK, 3 rows affected (0.02 sec)

mysql>
mysql> -- now let us see what the loop count was
mysql> select @cnt as 'cnt';
+------+
| cnt  |
+------+
| 3    |
+------+
1 row in set (0.00 sec)

mysql>
mysql> -- now let us see the table data
mysql> select * from tbl;
+------+-------+
| i    | v     |
+------+-------+
|    2 | two   |
|    3 | three |
+------+-------+
2 rows in set (0.00 sec)

mysql> select count(*) row_count from tbl;
+-----------+
| row_count |
+-----------+
|         2 |
+-----------+
1 row in set (0.00 sec)

mysql> select count(*) 'rows_affected' from rows_affected;
+---------------+
| rows_affected |
+---------------+
|             3 |
+---------------+
1 row in set (0.00 sec)

mysql>

【讨论】:

  • 哦,这更有意义。我一直不太明白 for 每一行循环的内容。
  • 那么删除前触发器是循环遍历表中的所有行还是针对每个删除的记录运行?还是对即将删除的每一行运行一次?
  • @MatKay 我在更新的答案中包含了一个经过测试的示例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-02
  • 2018-10-09
  • 1970-01-01
  • 1970-01-01
  • 2010-12-29
相关资源
最近更新 更多