MySql觸發器對同表更新
阿新 • • 發佈:2019-01-08
觸發器初始結構:
DELIMITER $$
CREATE
TRIGGER `資料庫名`.`觸發器名` BEFORE/AFTER INSERT/UPDATE/DELETE
ON `資料庫名`.`表名`
FOR EACH ROW BEGIN
-- 邏輯、條件語句
END$$
DELIMITER ;
目的:當一張表中的某個欄位值更新為特定值時,觸發更新本條資料的另一欄位值
(示例:根據prj_base_info表中的project_status的值判斷是否是600時,觸發更新同表的complete_time欄位的時間為系統當前時間)
1、開始寫出的觸發器如下所示
DROP TRIGGER IF EXISTS update_complete_time; DELIMITER $ CREATE TRIGGER update_complete_time AFTER UPDATE ON prj_base_info FOR EACH ROW BEGIN IF (new.project_status=600) THEN UPDATE prj_base_info SET complete_time =DATE_FORMAT(NOW(), '%Y-%m-%d') WHERE prj_base_info.id = new.id; END IF; END $
執行結果沒有問題,建立觸發器成功,但是執行update語句進行測試如下報錯,提示:無法更新儲存函式/觸發器中的表'prj_base_info',因為它已經被呼叫此儲存函式/觸發器的語句使用。
1 queries executed, 0 success, 1 errors, 0 warnings 查詢:update prj_base_info set type=2,project_status=600 where id='1537842899333' 錯誤程式碼: 1442 Can't update table 'prj_base_info' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
通過查閱資料瞭解,同表的更新不能在觸發器裡使用 update,而是直接使用set
修改為:
DROP TRIGGER IF EXISTS update_complete_time;
DELIMITER $
CREATE TRIGGER update_complete_time AFTER UPDATE
ON prj_base_info FOR EACH ROW
BEGIN
IF (new.project_status=600)
THEN
SET new.complete_time =DATE_FORMAT(NOW(), '%Y-%m-%d')
;
END IF;
END $
結果發現還報錯。。。
錯誤程式碼: 1362
Updating of NEW row is not allowed in after trigger
把AFTER修改為BEFORE即可:
DROP TRIGGER IF EXISTS update_complete_time;
DELIMITER $
CREATE TRIGGER update_complete_time BEFORE UPDATE
ON prj_base_info FOR EACH ROW
BEGIN
IF (new.project_status=600)
THEN
SET new.complete_time =DATE_FORMAT(NOW(), '%Y-%m-%d')
;
END IF;
END $
BEFORE與AFTER區別:
BEFORE:(insert、update)可以對new進行修改,AFTER不能對new進行修改,兩者都不能修改old資料。
對於INSERT語句, 只有NEW是合法的;
對於DELETE語句,只有OLD才合法;
對於UPDATE語句,NEW、OLD可以同時使用。
總結:BEFORE 或 AFTER 關鍵字決定何時執行觸發器動作,決定是在關聯行的插入、修改或刪除之前或者之後執行觸發器動作。