CREATE [OR REPLACE] TRIGGER trigger_name AFTER | BEFORE | INSTEAD OF [INSERT] [[OR] UPDATE [OF column_list]] [[OR] DELETE] ON table_or_view_name [REFERENCING {OLD [AS] old / NEW [AS] new}] [FOR EACH ROW] [WHEN ( condition ) ] pl/sql_block;
:new --為一個引用最新的列值;
:old --為一個引用以前的列值;
這兩個變量只有在使用了關鍵字
"FOR
EACH ROW"時才存在.
且update語句兩個都有,而insert只有:new ,delect 只有:old;
CREATE OR REPLACE TRIGGER trig_sal AFTER UPDATE OF empsal ON salary_records --在更新 emp_sal 列之後激活觸發器 …
… FOR EACH ROW WHEN (NEW.empsal>OLD.empsal) --只有在WHEN子句中的條件得到滿足時,才激活trig_sal 觸發器 DECLARE Sal_diff NUMBER; …
… BEGIN sal_diff:=:NEW.empsal-:OLD.empsal; --如果WHEN子句中的條件得到滿足,將執行BEGIN 塊中的代碼 DBMS_OUTPUT.PUT_LINE(‘工資差額:’sal_diff); END;
CREATE OR REPLACE TRIGGER aiu_itemfile AFTER INSERT ON itemfile FOR EACH ROW BEGIN IF (:NEW.qty_hand = 0) THEN DBMS_OUTPUT.PUT_LINE('警告:已插入記錄,但數量為零'); ELSE DBMS_OUTPUT.PUT_LINE(‘已插入記錄'); END IF; END;
查看表的觸發器
select * from all_triggers where table_name =upper('tbname')
CREATE OR REPLACE TRIGGER TR_SEC_EMP BEFOR INSERT OR UPDATE OR DELETE ON EMP2 BEGIN IF TO_CHAR(SYSDATE,'DY', 'nls_date_language=AMERICAN') IN ('SAT', 'SUN') THEN RAISE_APPLICATION_ERROR(-20002,’禁止修改數據!’); END IF; END;
工資一般來說都是往上調整,寫個觸發器禁止降低工資?
create or replace trigger guo_trigger----創建觸發器 before update on emp2 ----指明觸發器時機 for each row ----行觸發器標識 when (new.sal<old.sal ) ----觸發條件 begin raise_application_error(-20500,'不能給員工減少工資'); end;
DDL 觸發器 在模式中執行 DDL 語句時執行 數據庫級觸發器 在發生打開、關閉、登錄和退出數據庫等系統事件時執行 DML 觸發器 在對表或視圖執行DML語句時執行 語句級觸發器 無論受影響的行數是多少,都只執行一次 行級觸發器 對DML語句修改的每個行執行一次 INSTEAD OF 觸發器 用於用戶不能直接使用 DML 語句修改的視圖
語句級(STATEMENT)觸發器:是指當某觸發事件發生時,該觸發器只執行一次;行級(ROW)觸發器:是指當某觸發事件發生時,對受到該操作影響的每一行數據,觸發器都單獨執行一次。
觸發器不接受參數。 l 一個表上最多可有12個觸發器,但同一時間、同一事件、同一類型的觸發器只能有一個。並各觸發器之間不能有矛盾。 l 在一個表上的觸發器越多,對在該表上的DML操作的性能影響就越大。 l 觸發器最大為32KB。若確實需要,可以先建立過程,然後在觸發器中用CALL語句進行調用。 l 在觸發器的執行部分只能用DML語句(SELECT、INSERT、UPDATE、DELETE),不能使用DDL語句(CREATE、ALTER、DROP)。 l 觸發器中不能包含事務控制語句(COMMIT,ROLLBACK,SAVEPOINT)。因為觸發器是觸發語句的一部分,觸發語句被提交、回退時,觸發器也被提交、回退了。 l 在觸發器主體中調用的任何過程、函數,都不能使用事務控制語句。 l 在觸發器主體中不能申明任何Long和blob變量。新值new和舊值old也不能向表中的任何long和blob列。l 不同類型的觸發器(如DML觸發器、INSTEAD OF觸發器、系統觸發器)的語法格式和作用有較大區別。
CREATE TABLE TEST_TRG (ID NUMBER, NAME VARCHAR2(20)); CREATE SEQUENCE SEQ_TEST;
CREATE OR REPLACE TRIGGER BI_TEST_TRG BEFORE INSERT OR UPDATE OF ID ON TEST_TRG FOR EACH ROW BEGIN --函數UPDATING, DELETING判斷觸發器是由哪個操作觸發的 IF INSERTING THEN SELECT SEQ_TEST.NEXTVAL INTO :NEW.ID FROM DUAL; ELSE RAISE_APPLICATION_ERROR(-20020, '不允許更新ID值!'); END IF; END;
修改數據前備份員工工資
CREATE OR REPLACE TIGGER TR_SAL_BACK AFFTER UPDATE OF SAL ON EMP2 FOR EACH ROW DECLARE V_TEM INT ; BEGIN SELECT COUNT(*) INTO V_TEMP FROM NEW_BACK WHERE ENAME =:OLD.ENAME; IF V_TEMP =0 THEN INSERT INTO NEW_BACK VALUES (:OLD.ENAME,:OLD.SAL, :NEW.SAL,SYSDATE); ELSE UPDATE NEW_BACK VALUES SET OLDSAL=:OLDSAL, NEWSAL=:NEW.SAL,TIME=SYSDATE WHERE NAME=:OLD.ENAME; END IF; END;
建立一個觸發器, 當職工表 emp 表被刪除一條記錄時,把被刪除記錄寫到職工表刪除日志表中去。
CREATE TABLE emp_his AS SELECT * FROM EMP WHERE 1=2; CREATE OR REPLACE TRIGGER tr_del_emp BEFORE DELETE --指定觸發時機為刪除操作前觸發 ON scott.emp FOR EACH ROW --說明創建的是行級觸發器 BEGIN --將修改前數據插入到日志記錄表 del_emp ,以供監督使用。 INSERT INTO emp_his(deptno , empno, ename , job ,mgr , sal , comm , hiredate ) VALUES( :old.deptno, :old.empno, :old.ename , :old.job,:old.mgr, :old.sal, :old.comm, :old.hiredate ); END; DELETE emp WHERE empno=7788; DROP TABLE emp_his; DROP TRIGGER del_emp;
CREATE OR REPLACE TRIGGER trgdemo AFTER INSERT OR UPDATE OR DELETE ON order_master BEGIN IF UPDATING THEN DBMS_OUTPUT.PUT_LINE('已更新 ORDER_MASTER 中的數據'); ELSIF DELETING THEN DBMS_OUTPUT.PUT_LINE('已刪除 ORDER_MASTER 中的數據'); ELSIF INSERTING THEN DBMS_OUTPUT.PUT_LINE('已在 ORDER_MASTER 中插入數據'); END IF; END;
CREATE OR REPLACE TRIGGER upd_ord_view INSTEAD OF UPDATE ON ord_view FOR EACH ROW BEGIN UPDATE order_master SET vencode=:NEW.vencode WHERE orderno = :NEW.orderno; DBMS_OUTPUT.PUT_LINE('已激活觸發器'); END;
CREATE TABLE dropped_obj
( obj_name VARCHAR2(30), obj_type VARCHAR2(20), drop_date DATE
);
CREATE OR REPLACE TRIGGER log_drop_obj AFTER DROP ON SCHEMA BEGIN INSERT INTO dropped_obj VALUES( ORA_DICT_OBJ_NAME, ORA_DICT_OBJ_TYPE, SYSDATE); END;
ALTER TRIGGER aiu_itemfile DISABLE;
ALTER TRIGGER aiu_itemfile ENABLE;
刪除觸發器
DROP TRIGGER aiu_itemfile;
SELECT TRIGGER_NAME FROM USER_TRIGGERS WHERE TABLE_NAME='EMP';
SELECT TRIGGER_TYPE, TRIGGERING_EVENT, WHEN_CLAUSE FROM USER_TRIGGERS WHERE TRIGGER_NAME = 'BIU_EMP_DEPTNO';