zoukankan      html  css  js  c++  java
  • 触发器五(建立INSTEAD OF触发器)(学习笔记)

    INSTEAD OF触发器

    对于简单视图,可以直接执行INSERT,UPDATE和DELETE操作
    但是对于复杂视图,不允许直接执行INSERT,UPDATE和DELETE操作。
    为了在具有以上情况的复杂视图上执行DML操作需要征用触发器来完成

    --创建复杂视图

    CREATE OR REPLACE VIEW v_emp20
     AS
    SELECT e.empno,e.ename,e.job,e.sal,d.deptno,d.dname,d.loc
    FROM emp e,dept d
    WHERE e.deptno=d.deptno;
    --查看视图
    SELECT * FROM user_views;

    INSTEAD OF触发器可以实现更新视图时多个数据表一起更新的问题

    instead-of触发器创建语法
    CREATE [OR REPLACE] TRIGGER 触发器名称
        INSTEAD OF [INSERT | UPDATE | UPDATE OF 列名称 [,列名称,...] | DELETE] ON 视图名称
        [FOR EACH ROW]
        [WHEN 触发条件]
        [DECLARE]
            [程序声明部分 ;]
        BEGIN
            程序代码部分 ;
        END [触发器名称] ;

    替代触发器创建时不需要使用BEFORE或者AFTER,而将其替换为INSTEAD OF,同时操作的对象也有表替换为视图

    示例一、创建一个insert替代触发器用于执行图添加操作

    create or replace trigger view_insert_tigger
      instead of insert on v_emp20  
      for each row
    declare
        v_empCount       NUMBER;
        v_deptCount      NUMBER;
    begin
        --判断要增加的员工是否存在
        SELECT COUNT(empno) INTO v_empCount FROM emp WHERE empno=:NEW.empno;
        
        --判断要部门是否存在
        SELECT COUNT(deptno) INTO v_deptCount FROM dept WHERE deptno=:new.deptno;
      --如果员工不存在
      IF v_empCount=0 THEN
          INSERT INTO emp(empno,ename,job,sal,deptno)
          VALUES(:new.empno,:new.ename,:new.job,:new.sal,:new.deptno);
        END IF;
        --如果部门不存在
        IF v_deptCount=0 THEN
          INSERT INTO dept(deptno,dname,loc)VALUES(:new.deptno,:new.dname,:new.loc);
        END IF;
    end view_insert_tigger;
    --添加数据
    INSERT INTO v_emp20(empno,ename,job,sal,deptno,dname,loc)
    VALUES(7777,'张三丰','CLERK',800,77,'活动部','深圳');

    示例二、创建一个update替代触发器用于执行视图更新操作

    create or replace trigger view_update_tigger
      INSTEAD OF update on v_emp20  
      for each row
    declare
      
    begin
      UPDATE emp SET ename=:new.ename,job=:new.job,sal=:new.sal WHERE empno=:NEW.empno;
      UPDATE dept SET dname=:new.dname,loc=:new.loc WHERE deptno=:new.deptno;
    end view_update_tigger;
    UPDATE v_emp20 SET ename='任我行',sal=2000,dname='魔教' WHERE empno=7777;
    COMMIT;
    --查询
    SELECT * FROM v_emp20;

    示例三、创建一个DELETE替代触发器用于执行视图的删除操作

    create or replace trigger view_delete_tigger
      instead of delete on v_emp20  
      for each row
    declare
      v_empCount          NUMBER;
    BEGIN
      --判断员工是否存在
     SELECT COUNT(empno) INTO v_empCount FROM emp WHERE empno=:old.empno;
    
      --如果员工存在
      IF v_empCount>0 THEN
          DELETE FROM emp WHERE empno=:old.empno;
        END IF;
    
      
    end view_delete_tigger;
    
    --执行删除
    DELETE FROM v_emp20 WHERE empno=7777;
    COMMIT;
    --查询
    SELECT * FROM v_emp20;
    SELECT * FROM emp;

    示例四、将以上三个合为一个

    create or replace trigger view20emp_trigger
      instead of INSERT OR UPDATE OR DELETE on v_emp20  
      for each row
    declare
      v_empCount            NUMBER;
      v_deptCount            NUMBER;
    BEGIN
      IF inserting THEN
          --判断要增加的员工是否存在
          SELECT COUNT(empno) INTO v_empCount FROM emp WHERE empno=:NEW.empno;
          --判断要增加的部门是否存在
          SELECT COUNT(deptno) INTO v_deptCount FROM dept WHERE deptno=:new.deptno;
          --员工不存在就增加
          IF v_empCount=0 THEN   
          INSERT INTO emp(empno,ename,job,sal,deptno)
          VALUES(:new.empno,:new.ename,:new.job,:new.sal,:new.deptno);
        END IF;
        --如果部门不存在
        IF v_deptCount=0 THEN
          INSERT INTO dept(deptno,dname,loc)VALUES(:new.deptno,:new.dname,:new.loc);
        END IF;
          
      ELSIF updating THEN
         UPDATE emp SET ename=:new.ename,job=:new.job,sal=:new.sal WHERE empno=:NEW.empno;
      UPDATE dept SET dname=:new.dname,loc=:new.loc WHERE deptno=:new.deptno;
      
      ELSIF deleting THEN
            --判断员工是否存在
     SELECT COUNT(empno) INTO v_empCount FROM emp WHERE empno=:old.empno;
      --如果员工存在
      IF v_empCount>0 THEN
          DELETE FROM emp WHERE empno=:old.empno;
        END IF;
      ELSE
        NULL;
      END IF;
      
    end view20emp_trigger;

    执行增加、修改、删除

    --添加数据
    INSERT INTO v_emp20(empno,ename,job,sal,deptno,dname,loc)
    VALUES(7777,'张三丰','CLERK',800,77,'活动部','深圳');
    --查询
    SELECT * FROM v_emp20;
    UPDATE v_emp20 SET ename='任我行',sal=2000,dname='魔教' WHERE empno=7777;
    COMMIT;
    --查询
    SELECT * FROM v_emp20;
    --执行删除
    DELETE FROM v_emp20 WHERE empno=7777;
    COMMIT;
    --查询
    SELECT * FROM v_emp20;
    SELECT * FROM emp;

    当视图中包含以下结构之一,就表示为不可更新的视图,都不允许直接执行DML操作

    1)具有集合操作符(UNION,UNION ALL,INTERSECT,MINUS);
    2)具有分组函数(MIN,MAX,SUM,AVG,COUNT等)统计函数;
    3)具有GROUP BY,CONNECT BY或START WITH等子句,HAVING 子句;
    4)具有DISTINCT关键字;
    5)具有连接查询(集合运算连接)

    6)CASE 或者DECODE 语句

  • 相关阅读:
    查看git submodule更改
    /var/lib/docker空间占用过大迁移
    docker -修改容器
    docker重命名镜像repository和tag
    方法的重写、重载。
    方法的声明与使用。
    二维数组。
    标准输入输出流概述和输出语句。
    冒泡排序法。
    IO流,对象操作流优化。
  • 原文地址:https://www.cnblogs.com/liunanjava/p/4219945.html
Copyright © 2011-2022 走看看