Oracle触发器详细讲解(2)

create table emp_new
as
select * from emp;create table dept_new
as
select * from dept;CREATE OR REPLACE TRIGGER cascade_trigger
AFTER UPDATE OF deptno ON dept_new
FOR EACH ROW
BEGIN
  UPDATE emp_new SET deptno=:new.deptno WHERE deptno=:old.deptno;
END;update dept_new set deptno=15 where deptno=20;select * from dept_new;

select * from emp_new;

Oracle触发器详细讲解

这里参照完整新指具有主从关系的多个表,当更新主表主键时需要更新从表的相关数据。 3、替代触发器: 这里先讲另一个概念:带有with check option的视图: 如果视图的定义包括条件(如where子句)并且任何应用于该视图的INSERT或UPDATE语句都应包括该条件,则必须使用WITH CHECK OPTION定义该视图。 Example:

CREATE VIEW emp_view
(ename,empno)
AS SELECT ename,empno FROM emp
WHERE deptno=20
WITH CHECK OPTION;

这里有个条件部门号为20,则任何修改这个视图的语句都必须针对的是20号部门的员工。 继续替代触发器的概念:关键字insteadof,主要针对一些复杂的视图,因为级联表所产生的视图不可以使用update,insert,delete等关键字,没有before,after等关键字,并且不可以建立在with check option选项的视图上,比如新建一个emp表和dept表的级联视图,则不可以向其中添加数据,现在通过触发器解决: Example: 仍然新建2个表分别和emp表dept表的数据相同。

CREATE TABLE emp_new
AS
SELECT * FROM emp;
CREATE TABLE dept_new
AS
SELECT * FROM dept;CREATE VIEW emp_dept
AS
SELECT d.deptno,d.dname,e.empno,e.ename
FROM dept_new d,emp_new e
WHERE d.deptno=e.deptno;

这里scott用户需要先通过sysdba授权才能建立视图:

grant create view to scott;

CREATE OR REPLACE TRIGGER insteadof_trigger
INSTEAD OF INSERT ON emp_dept
FOR EACH ROW
DECLARE
    v_temp INT;
BEGIN
    SELECT COUNT(*) INTO v_temp FROM dept_new WHERE deptno=:new.deptno;
    IF v_temp=0 THEN
      INSERT INTO dept_new(deptno,dname) VALUES(:new.deptno,:new.dname);
    END IF;
    SELECT COUNT(*) INTO v_temp FROM emp_new WHERE empno=:new.empno;
    IF v_temp=0 THEN
      INSERT INTO emp_new(deptno,empno,ename) VALUES(:new.deptno,:new.empno,:new.ename);
    END IF;
END;

INSERT INTO emp_dept values(15,'HUMANRESOURCE',7999,'LEAF');select * from emp_new;

select * from dept_new;

Oracle触发器详细讲解

这里触发器中当对视图进行insert时,会对相应的emp_new 和dept_new进行修改,也就做到了对复杂视图的修改。 4、系统触发器: 顾名思义,由系统触发器所触发的事件,常用的系统事件startup,shutdown,db_roll_change,server error等。 Example:记录启动数据库时的事件以及时间。 此处因为是系统触发器,所以需要用sysdba的权限登陆。

CREATE TABLE event_table(event VARCHAR2(50),event_time DATE);CREATE OR REPLACE TRIGGER event_trigger
AFTER STARTUP ON DATABASE
BEGIN
  INSERT INTO event_table VALUES(ora_sysevent,sysdate);
END;

Oracle触发器详细讲解

select * from event_table;

三、触发器的综合实例 Example:做一个日志用来记录scott用户的一些操作: 首先在sysdba权限下建立日志表,序列,触发器:

CREATE TABLE object_log(
logid NUMBER CONSTRAINT pk_logid PRIMARY KEY,
operatedate DATE NOT NULL,
objecttype VARCHAR2(50) NOT NULL,
objectowner VARCHAR2(50) NOT NULL
);CREATE SEQUENCE obj_log_seq;CREATE OR REPLACE TRIGGER object_trigger
AFTER CREATE OR DROP OR ALTER ON DATABASE
BEGIN
  INSERT INTO object_log VALUES(obj_log_seq.nextval,sysdate,ora_dict_obj_type,ora_dict_obj_owner);
END;

在scott用户下随便创建个东西:

CREATE SEQUENCE my_seq;

回到sysdba权限下查看日志表中是否有对应的记录:

SELECT * FROM object_log;

发现有数据,说明一个日志表成功做好,监视一些用户操作的触发器就做好了。 至此,触发器全部说明完毕,不足之处还请评论说明,谢谢。   

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/b9e5d0ff0bb7d29a5a9638088d276819.html