MySQL After Update Trigger 顯然沒有執行
我在 MySQL 表上有以下更新後觸發器:
CREATE DEFINER = 'root'@'localhost' TRIGGER phpbb_rathermenacing.phpbb_bbdkp_memberlist_AUPD AFTER UPDATE ON phpbb_rathermenacing.phpbb_bbdkp_memberlist FOR EACH ROW BEGIN IF NEW.member_confirmed = 1 AND NEW.member_rank_id <> OLD.member_rank_id AND ((select min(m.member_rank_id) from phpbb_bbdkp_memberlist m WHERE m.phpbb_user_id = NEW.phpbb_user_id AND m.member_guild_id = NEW.member_guild_id AND m.member_id != NEW.member_id) >= new.member_rank_id OR (select count(m.member_rank_id) from phpbb_bbdkp_memberlist m WHERE m.phpbb_user_id = NEW.phpbb_user_id AND m.member_guild_id = NEW.member_guild_id AND m.member_id != NEW.member_id) = 0) THEN BEGIN IF (SELECT count(*) FROM phpbb_user_group ug WHERE ug.group_id = (SELECT mr.phpbb_group_id FROM phpbb_bbdkp_member_ranks mr WHERE mr.guild_id = OLD.member_guild_id AND mr.rank_id = OLD.member_rank_id) AND ug.group_leader = 0 ) > 0 THEN UPDATE phpbb_user_group ug SET ug.group_id = (SELECT mr.phpbb_group_id FROM phpbb_bbdkp_member_ranks mr WHERE mr.guild_id = NEW.member_guild_id AND mr.rank_id = NEW.member_rank_id), ug.user_pending = 0 WHERE ug.user_id = NEW.phpbb_user_id AND ug.group_id = (SELECT mr.phpbb_group_id FROM phpbb_bbdkp_member_ranks mr WHERE mr.guild_id = OLD.member_guild_id AND mr.rank_id = OLD.member_rank_id); ELSE IF(SELECT count(*) FROM phpbb_user_group ug WHERE ug.group_id = (SELECT mr.phpbb_group_id FROM phpbb_bbdkp_member_ranks mr WHERE mr.guild_id = NEW.member_guild_id AND mr.rank_id = NEW.member_rank_id)) = 0 THEN INSERT INTO phpbb_user_group (group_id, user_id, group_leader, user_pending) VALUES ((SELECT mr.phpbb_group_id FROM phpbb_bbdkp_member_ranks mr WHERE mr.guild_id = NEW.member_guild_id AND mr.rank_id = NEW.member_rank_id), m.phpbb_user_id, 0, 0); END IF; END IF; END; END IF; END
基本上,觸發器正在檢查與使用者關聯的一種類型的組是否已更改,如果已更改,它會進行更改以設置另一種類型的組的引用。
我遇到的問題是,雖然觸發器保存得很好,但當我嘗試進行更新時似乎什麼也沒發生。我可以更改成員列表行的 rank_id,但它只是更新該行。我什至嘗試使用 dbForge Studio 進行調試,雖然它會在我用來實際進行更新的 UPDATE 查詢上停止,但進入 UPDATE 方法似乎並沒有觸發觸發器。
什麼可能導致調試斷點永遠不會被擊中,並且觸發器沒有明顯的行為被看到?
我最初的猜測將基於觸發器的流程。為什麼 ?
根據書
第 11 章第 251 頁第 3 段說如下:
BEFORE
和AFTER
触發器之間最顯著的區別是,AFTER
您無法修改將要插入或更新相關表的值——DML 已執行,嘗試更改 DML 的內容為時已晚正在做。從這個陳述中,我的理解是:由於 DML 被執行並且 DML 仍然在未來不完美時態中被提及(我不是英語老師),所以新的價值觀真的無法閱讀,
SELECT
因為觸發器未完成。在你的情況下,你正在做一個
AFTER UPDATE
onphpbb_rathermenacing.phpbb_bbdkp_memberlist
。觸發器完成 99.99999999% 後,您將嘗試在 IF 語句的第三個子句中執行以下操作:((select min(m.member_rank_id) from phpbb_bbdkp_memberlist m WHERE m.phpbb_user_id = NEW.phpbb_user_id AND m.member_guild_id = NEW.member_guild_id AND m.member_id != NEW.member_id) >= new.member_rank_id OR (select count(m.member_rank_id) from phpbb_bbdkp_memberlist m WHERE m.phpbb_user_id = NEW.phpbb_user_id AND m.member_guild_id = NEW.member_guild_id AND m.member_id != NEW.member_id) = 0)
您正在詢問
phpbb_bbdkp_memberlist
尚未更改的表的計數和狀態。無論儲存引擎如何,我都非常確定您永遠不會得到響應,因為觸發器必須完成,儲存引擎才能考慮將更改發佈到磁碟。我有兩篇舊文章討論了為什麼觸發器不適用於商業智能:
Aug 11, 2011
:策略 RE 數據庫觸發器在精心設計的應用程序中?Aug 15, 2011
: MySQL 中觸發器與儲存過程的性能建議
- 使其觸發儲存過程
- 移除
AFTER UPDATE
觸發器UPDATE
在應用程序中執行儲存過程。
在這種情況下,事實證明問題是對症狀的誤診。調試器只是因為一些未知的原因而無法執行,並且觸發器沒有做任何事情,因為它正在正確執行其程式碼。INSERT 語句之前的條件缺少檢查以確保它只查看目前使用者的記錄,因此它始終認為組中有人並且從未插入,儘管使用者尚未在組中。