文件首頁
MySQL 9.0 參考手冊
相關文件 下載本手冊
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
Man Pages (TGZ) - 258.2Kb
Man Pages (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 參考手冊  /  ...  /  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.4.1 節「觸發程序語法和範例」

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

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.9 節「儲存程序的限制」

在觸發程序主體中,您可以使用別名 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.7 節「儲存物件存取控制」中所述。另請參閱該節以取得有關觸發程序安全性的其他資訊。

如果省略 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 來鎖定具有觸發程序的表格,則觸發程序內使用的表格也會被鎖定,如鎖定表格和觸發程序中所述。

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