触发器五(建立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 语句

时间: 2024-10-25 15:10:15

触发器五(建立INSTEAD OF触发器)(学习笔记)的相关文章

第十五天和十六天学习笔记

第十五天学习笔记: 主要学习了HTML5: 1 <!DOCTYPE html> <!--文档类型声明--> 2 <html> 3 <head> 4 <title>学习HTML5</title> 5 <meta charset = "UTF-8"> 6 </head> 7 <body> 8 <p>学习html5</p> 9 </body> 10

Oracle 中的PL/SQL、存储过程、触发器、函数、包(学习笔记)

   一.PL/SQL是什么? PL/SQL(procedural language/SQL)是oracle在sql上的扩展,pl/sql不仅允许嵌入sql语言,而且可以定义常量和变量,允许使用条件语句和循环语句,允许使用例外处理各种错误,这使得它的功能十分强大.但是移植性不好. 1. 实例1 只包括执行部分的PL/SQL块 set serveroutput on; begin dbms_output.put_line('asdasdasdas'); end; / set serverout 选

sql 入门经典(第五版) Ryan Stephens 学习笔记  第四部分:建立复杂的数据库查询

第十四章: 使用子查询定义未确定的数据 1. 子查询与select 结合使用 select colum from table where column where  columnb=(select colum_name from ...); 2.   子查询与inset结合使用 insert table1 select column1 from table2 where cloumn2>(select ......); 将表二中满足条件的某几项 插入到表1 中,注: 插入的项数 = table1

sql 入门经典(第五版) Ryan Stephens 学习笔记 (第六,七,八,九,十章)

第六章: 管理数据库事务 事务 是 由第五章 数据操作语言完成的  DML ,是对数据库锁做的一个操作或者修改. 所有事务都有开始和结束 事务可以被保存和撤销 如果事务在中途失败,事务中的任何部分都不会被记录到数据库 控制事务: commit , rollback ,savepoint; 6.1 commit 在操作之前 需要 设置: set autocommit = 0 ;  // 否则所有的操作都是 自动提交的 commit: 用于把事务所做的修改保存到数据库,它把上一个commit 或 r

关于Redis五种类型对象的学习笔记

我们在使用Redis的时候,直接接触到的是字符串对象(String),列表对象(List),哈希对象(Hash),集合对象(Set),有序集合对象(SortedSet)这五种类型的对象,基本的命令如:String(get set) List(lpush rpush lpop rpop lrange) Hash(hget hset hlen hgetall) Set(sadd smembers smov) SortedSet(Zadd Zrange)等. 我们首先看一下redis对象的数据结构:

OSPF建立邻居、邻接关系 学习笔记

Ospf中路由器之间存在两种连接关系:邻居关系和邻接关系.本博文将详细介绍这2种关系建立及工作原理. 如果两台路由器之间共享一条公共数据链路(两台路由器中间没有其它路由器,或者两台路由器之间存在虚连接),并且成功协商了hello包中所指定的参数,那么它们就成为邻居.如果两个邻居之间需要同步LSDB,那么它们之间需要建立邻接关系.如果两个路由器之间建立了邻接关系,那么它们的LSDB一定是同步的.LSA只在存在邻接关系的路由器之间传递. 那么邻居关系和邻接关系怎么建立呢?邻居关系通过hello报文来

sql 入门经典(第五版) Ryan Stephens 学习笔记 第五部分: 性能调整

第十六章: 利用索引改善性能 1. create index 单字段索引:  create index index_name on table_name (column_name);唯一索引:     create unique index index_name on table_name (column_name); 组合索引: 一个表中有两个或者多个字段的索引 create index index_name on table_name (column1,column2); 2.何时考虑设置索

sql 入门经典(第五版) Ryan Stephens 学习笔记 (第一章)

SQL - Structured  Query Language (结构化查询语言) 1/ SQL 命令的类型 : 数据定义语言: DDL 数据操作语言: DML 数据查询语言: DQL 数据控制语言: DCL 数据管理命令 事物控制命令 2/ 数据库 - 表 主键: 确保所有元素的标识都是唯一的 不同的表的映射: 公用某个字段(通常是主键)

sql 入门经典(第五版) Ryan Stephens 学习笔记 后续——存储引擎

一.引擎基础 1 查看系统支持的存储引擎 show engines; 2 查看表使用的存储引擎两种方法: a.show table status from database_name where name='table_name'; b.show create table table_name; 查看使用的默认引擎: show variables like 'default_storage_engine';  //MySQL5.5以后默认使用InnoDB存储引擎, 如果显示的格式不好看,可以用\