Oracle 建立 Trigger 觸發器

基礎 Insert Trigger 示範

    
CREATE OR REPLACE TRIGGER trigger_name
    BEFORE INSERT
    ON table_name
    FOR EACH ROW
DECLARE
BEGIN
    -- do something 
END ;
    

其中 FOR EACH ROW 是指每一行都會觸發一次 trigger,如果沒有加上 FOR EACH ROW 就會是一個指令觸發一次 trigger ,不過就無法取得變更資料。

BEFORE 可以替換為 AFTER 或 INSTEAD OF

基礎 Update Trigger 示範

    
CREATE OR REPLACE TRIGGER trigger_name
    BEFORE UPDATE
    OF column_name
    ON table_name
    FOR EACH ROW
DECLARE
BEGIN
    -- do something
END ;
    

Update 和上面 Insert 相比多了可以使用 OF 來指定哪個欄位更新要觸發

取得變更資料

如果有使用 FOR EACH ROW 關鍵字讓每一行都會觸發一次 trigger,則可以使用 :NEW.Column_Name 和 :OLD.Column_Name 取得每次變更的資料,不過 :NEW 和 :OLD 並不是資料表,只是假的變數,並不能和 SQL Server 一樣有 inserted 或是 deleted 的表可以存取。
    
CREATE OR REPLACE TRIGGER trigger_name
    BEFORE INSERT OR DELETE OR UPDATE
    ON table_name
    FOR EACH ROW
DECLARE
BEGIN
    
    IF INSERTING THEN -- 新增
        -- 只能使用 :NEW.Column_Name

    ELSIF UPDATING THEN -- 更新
        -- 可以使用 :NEW.Column_Name 和 :OLD.Column_Name

    ELSIF DELETING THEN -- 刪除
        -- 只能使用 :OLD.Column_Name

    END IF;
END ;
    

變數

變數需要先使用 DECLARE 宣告變數,使用 := 賦值,需要注意的是 Oracle 內字串串接的方式是使用 ||
    
CREATE OR REPLACE TRIGGER trigger_name
    BEFORE INSERT OR DELETE OR UPDATE
    ON table_name
    FOR EACH ROW
DECLARE
    V_TYPE VARCHAR2(6);
    V_ID   NUMBER;
BEGIN

    IF INSERTING THEN -- 新增
        V_TYPE := 'insert';
        V_ID := :NEW.id;
    ELSIF UPDATING THEN -- 更新
        V_TYPE := 'update';
        V_ID := :NEW.id;
    ELSIF DELETING THEN -- 刪除
        V_TYPE := 'delete';
        V_ID := :OLD.id;
    END IF;

    INSERT INTO my_table (id, type)
    VALUES (V_ID, V_TYPE);

END ;
    

刪除 trigger

    
drop trigger trigger_name;
    



參考資料:
Oracle.docs - CREATE TRIGGER
Oracle.docs - 9 Using Triggers

留言