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';