2011-08-25 233 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

我的幾美分: - 添加「已刪除」列被視爲表結構中的更改。 因此,除非是新開發,否則不推薦。

如果它是遺留應用程序,最好 - 向某個臨時表添加刪除提醒,並在更新語句後測試該表。