SQL觸發(fā)器trigger, since 2021-12-20

(2021.12.23 Thur)
觸發(fā)器有時(shí)也稱作事件-條件-動(dòng)作規(guī)則(event-condition-action rule),或ECA。觸發(fā)器有如下特點(diǎn)

  1. 僅當(dāng)數(shù)據(jù)庫程序員生命的事件發(fā)生時(shí),觸發(fā)器被激活。允許的事件種類是對某個(gè)特定關(guān)系的INSERT, UPDATEDELETE。很多SQL系統(tǒng)中允許的另一種事件是事務(wù)的結(jié)束。
  2. 當(dāng)觸發(fā)器被事件激活時(shí),trigger測試觸發(fā)的條件(condition)。如果條件不成立,則響應(yīng)該事件的觸發(fā)器不做任何事。
  3. 如果trigger聲明的條件滿足,則與該觸發(fā)器相連的動(dòng)作(action)有DBMS執(zhí)行。動(dòng)作可以是以某種方式修改事件的結(jié)果,甚至可以是撤銷事件所在的事務(wù)。事實(shí)上,動(dòng)作可以使任何數(shù)據(jù)庫操作的序列,包括與觸發(fā)事件毫無關(guān)聯(lián)的操作。

觸發(fā)器的特征

  • 條件檢察和動(dòng)作可以在觸發(fā)事件執(zhí)行之前的數(shù)據(jù)庫的狀態(tài)(state of the database)(即當(dāng)前所有關(guān)系的實(shí)例)上或在出發(fā)動(dòng)作被執(zhí)行后的狀態(tài)上執(zhí)行。BEFORE/AFTER
  • 條件和動(dòng)作可以引用元組的舊值和/或觸發(fā)動(dòng)作被執(zhí)行后的狀態(tài)上執(zhí)行。NEW/OLD
  • 更新事件可以被局限到某個(gè)特定的屬性或某一些屬性
  • 可選擇動(dòng)作執(zhí)行的方式:
    a) 一次只對一個(gè)更新元組(row-level trigger,行級觸發(fā)器) 或
    b) 一次針對在數(shù)據(jù)庫操作中被改變的所有元組(statement-level trigger,語句級觸發(fā)器,記住一個(gè)SQL更新語句可以影響許多元組)。

觸發(fā)器的格式

CREATE TRIGGER <trigger_name>
<timing> <action> [OF <field1>] ON <table1>
[REFERENCING
OLD ROW AS <name_old>
NEW ROW AS <name_new>
]
FOR EACH <method>
BEGIN
<sql_scripts>
END

記得在MySQL中還要在該格式的前后加上DELIMITER\\DELIMITER;。

  • <trigger_name>: 觸發(fā)器的命名
  • <timing>: 時(shí)機(jī),只有兩個(gè)選項(xiàng)BEFOREAFTER,代表著觸發(fā)動(dòng)作之前的前/后對特定表格做修改
  • <action>: 觸發(fā)的條件動(dòng)作,即當(dāng)某個(gè)動(dòng)作發(fā)生時(shí),觸發(fā)后面的操作。有三個(gè)動(dòng)作,INSERT,UPDATEDELETE
  • <field1>: 可選。代表著條件動(dòng)作中需要修改的列
  • <table1>: 觸發(fā)條件動(dòng)作的表格
  • <name_old/name_new>: 可選。該REFERENCING子句允許觸發(fā)器的動(dòng)作和動(dòng)作引用正被修改的元組,在更新的情況下,蓋子局允許給改變之前和之后的元組命名。如果不使用該子句,則只需要用NEWOLD代表修改前后的元組即可。
  • <method>: 有ROWSTATEMENT兩種可選,告訴觸發(fā)器支隊(duì)每個(gè)修改的執(zhí)行一次,還是對由SQL語句做的所有修改執(zhí)行一次的子句。默認(rèn)是FOR EACH STATEMENT
  • <sql_scripts>: 被觸發(fā)器觸發(fā)的動(dòng)作

例1,該案例中每次對MovieExec表中的netWorth字段做按行的UPDATE之后,并且修改前的數(shù)據(jù)大于修改后的數(shù)據(jù)的情況下,設(shè)定MoveExec中的netWorth保留為原數(shù)據(jù)。

DELIMITER &&
CREATE TRIGGER NetWorthTrigger
AFTER UPDATE OF netWorth ON MovieExec
REFERENCING
          OLD ROW AS OldTuple
          NEW ROW AS NewTuple
FOR EACH ROW
WHEN (OldTuple.netWorth > NewTuple.netWorth)
           UPDATE MovieExec
           SET netWorth = OldTuple.netWorth
           WHERE cert# = NewTuple.cert#;
DELIMITER;

new/old

(2021.12.24 Fri)
每行數(shù)據(jù)在操作前后都有一個(gè)狀態(tài),trigger將沒有操作之前的狀態(tài)保存到old中,將操作之后的保存到new關(guān)鍵字中。調(diào)用格式是

new/old.<field_name>

  • INSERT關(guān)鍵字:只有new沒有old
  • UPDATE關(guān)鍵字:有new也有old,old表示更新前的數(shù)據(jù),new表示更新后的數(shù)據(jù)
  • DELETE關(guān)鍵字:只有old沒有newold表示被刪除前的數(shù)據(jù)

這里的new/old代表的是觸發(fā)條件的數(shù)據(jù)。比如,對關(guān)系A的修改加入或刪除會觸發(fā)關(guān)系B變化,這里的A可以被new/old指代。在觸發(fā)的動(dòng)作里,可通過new/old.<field_name>引用觸發(fā)條件關(guān)系的數(shù)據(jù)。

行級、語句級觸發(fā)器

一旦有合適類型的語句被執(zhí)行,語句級觸發(fā)器就被執(zhí)行,而不問它實(shí)際上會影響多少個(gè)元組。例如,如果用SQL更新語句更新整個(gè)表,語句級的修改觸發(fā)器將只被執(zhí)行一次,而元組級觸發(fā)器將對要修改的元組一次一個(gè)的執(zhí)行。

下面這個(gè)例子,在更新MovieExec的元組過程中,平均凈資產(chǎn)可以暫時(shí)的低于500000,當(dāng)所有變更結(jié)束時(shí),其凈資產(chǎn)值將超過500000。約束要做的是,若語句執(zhí)行結(jié)束后,凈資產(chǎn)值仍然低于500000,則整個(gè)一組更新操作被拒絕。

CREATE TRIGGER AvgNetWorthTrigger
AFTER UPDATE OF netWorth ON MovieExec
REFERENCING 
         OLD TABLE AS OldStuff
         NEW TABLE AS NewStuff
FOR EACH STATEMENT
WHEN (500000 > (SELECT AVG(netWorth) FROM MovieExec))
BEGIN
         DELETE FROM MovieExec
         WHERE (name, address, cert#, netWorth) IN NewStuff;
         INSERT INTO MovieExec
                 (SELECT * FROM OldStuff);
END;

命令

查看觸發(fā)器

SHOW TRIGGERS;
SHOW TRIGGERS/G;

查看觸發(fā)器的創(chuàng)建語句

SHOW CREATE TRIGGER <trigger_name>;
SHOW CREATE TRIGGER <trigger_name>/G;

刪除觸發(fā)器

DROP TRIGGER <trigger_name>;

限制

  • 觸發(fā)器不能使用CALL 語句來將數(shù)據(jù)返回給客戶端或使用動(dòng)態(tài)SQL的存儲過程。但允許存儲過程通過OUT或INOUT 參數(shù)將數(shù)據(jù)返回到觸發(fā)器
  • 觸發(fā)不能使用事務(wù)相關(guān)的語句,如 START TRANSACTION,COMMIT或ROLLBACK。因?yàn)橛|發(fā)器對update,delete,insert等事件做了處理,并且是按照before,SQL語句,after的順序來執(zhí)行的,一旦某一步出錯(cuò),就會回滾數(shù)據(jù)。如果在觸發(fā)器中使用事務(wù),就會產(chǎn)生矛盾。

Reference

1 Jeffery U.等著,岳麗華等譯,數(shù)據(jù)庫系統(tǒng)基礎(chǔ)教程,機(jī)械工業(yè)出版社

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容