2011-08-25 232 views
2

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

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 [email protected]; 
END IF; 
end$$ 

delimiter ; 

但正如我怀疑遇到错误:

update test set res=3 where id=1;
ERROR 1442 (HY000): Can't update table 'test' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

否则怎么能够只通过访问数据库来完成?我的意思是我不应该改变测试的应用程序。

回答

1

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

这SO问题提供了关于如何dipose无效记录的一些细节:Prevent Insert

备用是修改您的程序中插入记录具有触发吹扫所需的表的另一个表。

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$$ 

现在你需要改变你的update语句:

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; 
0

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

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