本文基於多篇博文整理而來,目的是較全面的學會使用DB2觸發器,后期再整理復雜的使用場景,看完本文應該能夠自己創建一個基本的觸發器。
1.什么是觸發器
當一個指定的 SQL 操作(如 DELETE,INSERT,或者是 UPDATE 操作)作用於某張表時,
一個定義了一組操作的觸發器就可以被激活。
觸發器並不像參照完整性約束和檢查約束那樣,我們甚至可以使用對其他表來進行更新。
觸發器是一種過程,與表關系密切,用於保護表中的數據。
當一個表被修改(insert、update或delete)時,觸發器自動執行。
觸發器可以實現多個表之間數據的一致性和完整性。
觸發器分為:DML觸發器、替代觸發器、系統觸發器。
DML觸發器:可以在DML語句進行觸發,可以在DML操作前或操作后進行觸發,並且可以對每個行或語句操作上進行觸發。
替代觸發器:進行視圖操作的一種處理方法。
系統觸發器:可以在數據庫系統的事件中進行觸發,如系統的啟動與關閉等。
2.DML觸發器工作原理
觸發器是利用了表數據發生變化時,自動生成的兩個虛擬表,一個是inserted,一個是deleted,
這兩個虛擬表從其他地方是檢索不到的,只有觸發器能讀到。
當數據發生變化時,如果是新插入數據,則該數據會在inserted里面暫時保存。
而刪除一條數據時,則會在deleted里面暫時保存。
更新則等於先刪除再插入,也就是deleted里面存更新前,inserted里面存更新后。
這些數據會在觸發器執行完成后消失。
3、DML觸發器類型
1)BEFORE 觸發器:在對表插入或更新之前執行該觸發器,允許使用CALL 和 SIGNAL SQL 語句;
2)BEFORE DELETE 觸發器:在刪除操作之前執行該觸發器;
3)AFTER 觸發器:在更新、插入或刪除操作之后執行。該觸發器用於更新反映表間關系和一致性的其他表中的數據,還用於確保數據完整性。AFTER 觸發器通常用於在特定情況下向用戶生成報警;
4)INSTEAD OF 觸發器:該觸發器支持對不支持插入、更新和刪除操作的視圖執行這些操作;
4、基本語法
CREATE TRIGGER 1) trigger_name
2) [BEFORE/AFTER] 3)[INSERT/DELETE/UPDATE] ON 4) [table_name]
5) [FOR EACH ROW]
屬性解析:
1)觸發器名稱
2)觸發器條件達成前還是達成后調用觸發器
3)觸發器被觸發的條件(當table_name表執行insert/delete/update這三種操作哪一種時候被觸發)
4)當table_name表被操作時候調用觸發器
5)聲明該觸發器是一個行級觸發器(如果未指明則被默認為語句級觸發器)
觸發器中使用NEW和OLD來獲取某列的新舊屬性
insert中只能用NEW,DELETE中只能用OLD,update中既可以用NEW,也可以用OLD
5. before舉例--- before代表觸發器里面的命令在DML修改數據之前執行
1)在emp表上面創建觸發器,當輸入的工資小於100時,自動將工資修改為100
create or replace trigger tri_emp_sal_check
before INSERT OR UPDATE ON emp
for each row
BEGIN
IF :new.sal <100 THEN
:new.sal :=100;
END IF;
END;
執行DML語句
update emp set sal =90 where empno =3030;
commit;
發現工號3030員工的工資成功修改為100。
需要修改NEW值的時候就使用BEFORE,其余場景一律使用after
舉個需要修改:NEW值的情況:某個字段數據庫中是NUMBER型的,比如年齡,而送過來的數據是帶字符的,比如“17歲”,
直接寫入就報錯了,此時用觸發器把數據進行規范化處理后再寫入數據庫,就可以用before類型的數據庫。
2)在sales表執行insert之前觸發
CREATE TRIGGER sales_bi_trg #觸發器聲明
BEFORE INSERT ON sales #觸發器被觸發條件
FOR EACH ROW #聲明為一個行級觸發器
BEGIN
DECLARE row_count INTEGER; #聲明row_count變量
SELECT COUNT(*) INTO row_count FROM customer_sales_totals WHERE customer_id=NEW.customer_id;
IF row_count > 0 THEN
UPDATE customer_sales_totals
SET sale_value=sale_value+NEW.sale_value
WHERE customer_id=NEW.customer_id;
ELSE
INSERT INTO customer_sales_totals
(customer_id,sale_value)
VALUES(NEW.customer_id,NEW.sale_value);
END IF;
END
語句分析:在sales表執行insert操作之前,查看customer_sales_totals表中是否有將要插入的客戶記錄,
有的話更新customer_sales_totals表,沒有則在customer_sales_totals表中插入客戶交易信息。
6.mysql觸發器
在一個表上最多建立6個觸發器,即
1)before insert型,
2)before update型,
3)before delete型,
4)after insert型,
5)after update型,
6)after delete型。
觸發器的一個限制是不能同時在一個表上建立2個相同類型的觸發器。
這個限制的一個來源是觸發器程序體的“begin和end之間允許運行多個語句”(摘自mysql使用手冊)
7.刪除觸發器
db2 drop trigger <trigger_name>
----------------------------------------------------------------------------------------------------------------------------------------------------------------
使用命令行方式:
su - db2inst1
db2 connect to 數據庫名
db2 “觸發器SQL語句”