文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 參考手冊  /  ...  /  CREATE TRIGGER 陳述式

15.1.22 CREATE TRIGGER 陳述式

CREATE
    [DEFINER = user]
    TRIGGER [IF NOT EXISTS] trigger_name
    trigger_time trigger_event
    ON tbl_name FOR EACH ROW
    [trigger_order]
    trigger_body

trigger_time: { BEFORE | AFTER }

trigger_event: { INSERT | UPDATE | DELETE }

trigger_order: { FOLLOWS | PRECEDES } other_trigger_name

此陳述式會建立新的觸發程序。觸發程序是與資料表相關聯的具名資料庫物件,當資料表發生特定事件時會啟動。觸發程序會與名為 tbl_name 的資料表相關聯,該資料表必須參照永久資料表。您無法將觸發程序與 TEMPORARY 資料表或檢視表相關聯。

觸發程序名稱存在於結構描述命名空間中,這表示所有觸發程序在結構描述內都必須具有唯一名稱。不同結構描述中的觸發程序可以具有相同的名稱。

如果相同結構描述中存在具有相同名稱且位於相同資料表上的觸發程序,則 IF NOT EXISTS 可防止發生錯誤。

本節說明 CREATE TRIGGER 的語法。如需更多討論,請參閱第 27.3.1 節「觸發程序語法和範例」

CREATE TRIGGER 需要與觸發程序相關聯的表格具有 TRIGGER 權限。如果存在 DEFINER 子句,則所需的權限取決於 user 值,如第 27.6 節「儲存物件存取控制」中所述。如果啟用二進位記錄,CREATE TRIGGER 可能需要 SUPER 權限,如第 27.7 節「儲存程式二進位記錄」中所述。

DEFINER 子句決定在檢查觸發程序啟用時間的存取權限時要使用的安全內容,如本節稍後所述。

trigger_time 是觸發程序動作時間。它可以是 BEFOREAFTER,表示觸發程序在每個要修改的列之前或之後啟用。

基本欄位值檢查會在觸發程序啟用之前進行,因此您不能使用 BEFORE 觸發程序將不適合欄位類型的值轉換為有效值。

trigger_event 表示啟動觸發程序的操作種類。允許使用以下 trigger_event 值:

  • INSERT:當新列插入表格時,觸發程序會啟用(例如,透過 INSERTLOAD DATAREPLACE 陳述式)。

  • UPDATE:當列被修改時,觸發程序會啟用(例如,透過 UPDATE 陳述式)。

  • DELETE:當列從表格中刪除時,觸發程序會啟用(例如,透過 DELETEREPLACE 陳述式)。對表格執行的 DROP TABLETRUNCATE TABLE 陳述式不會啟用此觸發程序,因為它們不使用 DELETE。刪除分割區也不會啟用 DELETE 觸發程序。

trigger_event 並不代表啟動觸發程序的 SQL 陳述式的字面類型,而是代表表格操作的類型。例如,INSERT 觸發程序不僅會在 INSERT 陳述式時啟用,也會在 LOAD DATA 陳述式時啟用,因為這兩個陳述式都會將列插入表格中。

一個可能令人困惑的例子是 INSERT INTO ... ON DUPLICATE KEY UPDATE ... 語法:對於每一列,都會先啟用 BEFORE INSERT 觸發程序,然後啟用 AFTER INSERT 觸發程序,或者同時啟用 BEFORE UPDATEAFTER UPDATE 觸發程序,具體取決於該列是否存在重複的索引鍵。

注意

串聯外鍵動作不會啟用觸發程序。

可以為給定表格定義多個具有相同觸發事件和動作時間的觸發程序。例如,您可以為一個表格設定兩個 BEFORE UPDATE 觸發程序。依預設,具有相同觸發事件和動作時間的觸發程序會按照建立順序啟用。若要影響觸發程序順序,請指定 trigger_order 子句,指示 FOLLOWSPRECEDES,以及也具有相同觸發事件和動作時間的現有觸發程序的名稱。使用 FOLLOWS 時,新的觸發程序會在現有觸發程序之後啟用。使用 PRECEDES 時,新的觸發程序會在現有觸發程序之前啟用。

trigger_body 是觸發程序啟用時要執行的陳述式。若要執行多個陳述式,請使用 BEGIN ... END 複合陳述式結構。這也可讓您使用儲存常式內允許的相同陳述式。請參閱第 15.6.1 節「BEGIN ... END 複合陳述式」。某些陳述式不允許在觸發程序中使用;請參閱第 27.8 節「儲存程式的限制」

在觸發程序主體內,您可以使用別名 OLDNEW 來參照主表格(與觸發程序相關聯的表格)中的欄位。OLD.col_name 指的是更新或刪除之前現有列的欄位。NEW.col_name 指的是要插入的新列的欄位,或是更新之後的現有列的欄位。

觸發程序無法使用 NEW.col_name,也無法使用 OLD.col_name 來參照產生的欄位。如需產生欄位的相關資訊,請參閱第 15.1.20.8 節「CREATE TABLE 和產生欄位」

MySQL 會儲存建立觸發程序時生效的 sql_mode 系統變數設定,並始終強制使用此設定執行觸發程序主體,無論觸發程序開始執行時的目前伺服器 SQL 模式為何

DEFINER 子句指定在檢查觸發程序啟用時間的存取權限時要使用的 MySQL 帳戶。如果存在 DEFINER 子句,則 user 值應為指定為 'user_name'@'host_name'CURRENT_USERCURRENT_USER() 的 MySQL 帳戶。允許的 user 值取決於您擁有的權限,如第 27.6 節「儲存物件存取控制」中所述。另請參閱該節以取得有關觸發程序安全性的其他資訊。

如果省略 DEFINER 子句,則預設的定義者是執行 CREATE TRIGGER 陳述式的使用者。這與明確指定 DEFINER = CURRENT_USER 相同。

MySQL 會在檢查觸發程序權限時考慮 DEFINER 使用者,如下所示:

  • CREATE TRIGGER 時間,發出陳述式的使用者必須具有 TRIGGER 權限。

  • 在觸發程序啟用時間,會根據 DEFINER 使用者檢查權限。此使用者必須具有以下權限:

    • 主表格的 TRIGGER 權限。

    • 如果在觸發程序主體中使用 OLD.col_nameNEW.col_name 參照表格欄位,則主表格的 SELECT 權限。

    • 如果表格欄位是觸發程序主體中 SET NEW.col_name = value 指派的目標,則主表格的 UPDATE 權限。

    • 觸發程序執行的陳述式通常需要的任何其他權限。

在觸發程序主體內,CURRENT_USER 函數會傳回在觸發程序啟用時間檢查權限時使用的帳戶。這是 DEFINER 使用者,而不是導致觸發程序啟用的動作的使用者。如需觸發程序內的使用者稽核相關資訊,請參閱第 8.2.23 節「基於 SQL 的帳戶活動稽核」

如果您使用 LOCK TABLES 來鎖定具有觸發程序的表格,則觸發程序中使用的表格也會被鎖定,如LOCK TABLES 和觸發程序中所述。

如需有關觸發程序使用的其他討論,請參閱第 27.3.1 節「觸發程序語法和範例」