Instead Of 触发器

对于简单视图,可以直接执行 insert、update 和 delete 操作。但是对于复杂视图,不允许直接执行 insert、update 和 delete 操作。当视图符合以下任何一种情况时,都不允许直接执行 dml 操作。具体情况如下。

    A 、具有集合操作符(union、union all、intersect、minus)。
    B、具有分组函数(min()、max()、sun()、avg()、count() 等)。
    C、具有 group by、connect by 或 start with 等子句。
    D、具有 distinct 关键字。
    E、具有连接查询。

为了在具有以上情况的复杂视图上执行 dml 操作,必须要基于视图建立 instead of 触发器。在建立了 instead of 触发器之后,就可以基于复杂视图执行 insert、update 和 delete 语句。但建立 instead of 触发器有以下注意事项。

    A、instead of 选项只适用于视图。
    B、当基于视图建立触发器时,不能指定 before 和 after 选项。
    C、在建立视图时不能指定 with check option 选项。
    D、在建立 instead of 触发器时,必须指定 for each row 选项。


下面是一个简单的使用 instead of 触发器的列子:
1、建立复杂视图 dept_emp
视图是逻辑表,本身没有任何数据。视图只是对应于一条 select 语句,当查询视图时,其数据实际是从视图基表上取得。
create or replace view dept_emp as select a.deptno, a.dname, b.empno, b.ename from dept a, emp b where a.deptno = b.deptno;
当执行以上语句建立了复杂视图 dept_emp 之后,直接查询视图 dept_emp 会显示部门及其雇员信息

Instead Of 触发器_第1张图片

但不允许执行dml操作
Instead Of 触发器_第2张图片

2、建立 instead of 触发器
为了在复杂视图上执行 dml 操作,必须要基于复杂视图来建立 instead of 触发器。下面以在复杂视图 dept_emp 上执行 insert 操作为例,说明建立 instead of 触发器的方法。

create or replace trigger tr_instead_of_dept_emp instead of insert on dept_emp for each row
declare
  v_temp int;
begin
  select count(*) into v_temp from dept where deptno = :new.deptno;
  if v_temp = 0 then
    insert into dept(deptno, dname) values(:new.deptno, :new.dname);
  end if;
  select count(*) into v_temp from emp where empno = :new.empno;
  if v_temp = 0 then
    insert into emp(empno, ename, deptno) values(:new.empno, :new.ename, :new.deptno);
  end if;
end;
/

当建立了 instead of 触发器 tr_instead_of_dept_emp 之后,就可以在复杂视图 dept_emp 上执行 insert 操作。


执行了上面的 insert 语句之后,就分别为 dept 和 emp 表插入一条数据,可查询视图 dept_emp查看结果。
Instead Of 触发器_第3张图片

你可能感兴趣的:(Oracle,Oracle,instead,of,触发器)