MySQL触发器 - 更新后删除

时间:2011-08-25 11:47:38

标签: mysql sql triggers sql-update sql-delete

对于一个项目中的测试用例,如果其中一个字段符合其中一个条件,我必须删除记录。 最简单似乎是简单的触发器:

delimiter $$
drop trigger w_leb_go $$

create trigger w_leb_go after update on test
for each row
begin
set @stat=NEW.res;
set @id=NEW.id;
IF @stat=3 THEN
  delete from test where id=@id;
END IF;
end$$

delimiter ;

但我怀疑有错误:

  

更新测试集res = 3,其中id = 1;
       ERROR 1442(HY000):无法更新存储函数/触发器中的表'test',因为它已被调用此存储函数/触发器的语句使用。

只有访问数据库才能完成其他工作?我的意思是我不应该更改测试的应用程序。

3 个答案:

答案 0 :(得分:1)

您可能需要做的是使用触发器的“BEFORE INSERT”来检查添加的记录是否无效。

此SO问题提供了有关如何对无效记录进行详细说明的详细信息:Prevent Insert

替代方法是修改程序以将记录插入到另一个表中,该表具有清除所需表的触发器。

答案 1 :(得分:0)

在触发器内部,您无法更改触发器所属的表格 你也不能间接地改变那张桌子。

然而,您可以做一些其他事情。如果你没有删除一行,但是添加了一个字段deleted,那么你可以标记为已删除,如此。

delimiter $$
drop trigger w_leb_go $$

CREATE TRIGGER w_leb_go BEFORE UPDATE ON test FOR EACH ROW
BEGIN
  IF NEW.res=3 THEN
    SET NEW.deleted = 1;
  END IF;
END$$

delimiter ;

请注意,如果要更改行中的任何内容,则触发器必须为before

或者,您可以向某些临时表添加删除提醒,并在更新语句后测试该表。

CREATE TRIGGER au_test_each AFTER UPDATE ON test FOR EACH ROW
BEGIN
  IF NEW.res=3 THEN
    INSERT INTO deletion_list_for_table_test (test_id) VALUE (NEW.id);
  END IF;
END$$

现在您需要将更新语句更改为:

START TRANSACTION;
UPDATE test SET whatever to whichever;
DELETE test FROM test
INNER JOIN deletion_list_for_table_test dt ON (test.id = dt.test_id);
DELETE FROM deletion_list_for_table_test WHERE test_id > 0 /*i.e. everything*/
COMMIT;

当然,如果您标记您的行,您可以将删除代码简化为:

START TRANSACTION;
UPDATE test SET whatever to whichever;
DELETE FROM test WHERE deleted = 1;
COMMIT;

答案 2 :(得分:0)

我的几分钱: - 添加'已删除'列被视为表结构中的更改。 因此,除非是新开发,否则不推荐使用。

如果是遗留应用程序,最好是 - 将删除提醒添加到某个临时表并在更新语句后测试该表。