CREATE [OR REPLACE] TRIGGER trigger_name
{BEFORE | AFTER }
{INSERT | DELETE | UPDATE [OF column [, column …]]}
[OR {INSERT | DELETE | UPDATE [OF column [, column …]]}...]
ON [schema.]table_name | [schema.]view_name
[REFERENCING {OLD [AS] old | NEW [AS] new| PARENT as parent}]
[FOR EACH ROW ]
[WHEN condition]
PL/SQL_BLOCK | CALL procedure_name;
例1: 建立一个触发器, 当职工表 emp 表被删除一条记录时,把被删除记录写到职工表删除日志表中去。
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;
例2:限制对Departments表修改(包括INSERT,DELETE,UPDATE)的时间范围,即不允许在非工作时间修改departments表。
BEFORE INSERT OR DELETE OR UPDATE
ON departments
BEGIN
IF (TO_CHAR(sysdate, ' DAY ' ) IN ( ' 星期六 ' , ' 星期日 ' )) OR (TO_CHAR(sysdate, ' HH24:MI ' ) NOT BETWEEN ' 08:30 ' AND ' 18:00 ' ) THEN
RAISE_APPLICATION_ERROR( - 20001 , ' 不是上班时间,不能修改departments表 ' );
END IF ;
END ;
例2:限制对Departments表修改(包括INSERT,DELETE,UPDATE)的时间范围,即不允许在非工作时间修改departments表。
BEFORE INSERT OR DELETE OR UPDATE
ON departments
BEGIN
IF (TO_CHAR(sysdate, ' DAY ' ) IN ( ' 星期六 ' , ' 星期日 ' )) OR (TO_CHAR(sysdate, ' HH24:MI ' ) NOT BETWEEN ' 08:30 ' AND ' 18:00 ' ) THEN
RAISE_APPLICATION_ERROR( - 20001 , ' 不是上班时间,不能修改departments表 ' );
END IF ;
END ;
例4:利用行触发器实现级联更新。在修改了主表regions中的region_id之后(AFTER),级联的、自动的更新子表countries表中原来在该地区的国家的region_id。
AFTER update OF region_id
ON regions
FOR EACH ROW
BEGIN
DBMS_OUTPUT.PUT_LINE( ' 旧的region_id值是 ' || :old.region_id
|| ' 、新的region_id值是 ' || :new.region_id);
UPDATE countries SET region_id = :new.region_id
WHERE region_id = :old.region_id;
END ;
例5:在触发器中调用过程。
( p_emp_id job_history.employee_id % type
, p_start_date job_history.start_date % type
, p_end_date job_history.end_date % type
, p_job_id job_history.job_id % type
, p_department_id job_history.department_id % type
)
IS
BEGIN
INSERT INTO job_history (employee_id, start_date, end_date,
job_id, department_id)
VALUES (p_emp_id, p_start_date, p_end_date, p_job_id, p_department_id);
END add_job_history;
-- 创建触发器调用存储过程...
CREATE OR REPLACE TRIGGER update_job_history
AFTER UPDATE OF job_id, department_id ON employees
FOR EACH ROW
BEGIN
add_job_history(:old.employee_id, :old.hire_date, sysdate,
:old.job_id, :old.department_id);
END ;