触发器五(建立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 语句
触发器五(建立INSTEAD OF触发器)(学习笔记)的更多相关文章
- 实验楼课程管理程序-深入学习《C++ Primer第五版》实验报告&学习笔记1
本片博客为实验楼的训练营课程深入学习<C++ Primer第五版>的实验报告和学习笔记. 原课程地址为:https://www.shiyanlou.com/courses/405# 原文出 ...
- sql 入门经典(第五版) Ryan Stephens 学习笔记 第四部分:建立复杂的数据库查询/
第十三章: 在查询表里结合表 1.等值结合 : // 选择 tabla_a 和table_b 中id相等的行,输出 他们的id 和name select table_a.id , table_a.na ...
- 建立 Active Directory域 ----学习笔记
第五章 建立 Active Directory域 1.工作组和域的理解 a.工作组是一种平等身份环境,各个计算机之间各个为一个独立体,不方便管理和资源共享. b.域环境一般情况下满足两类需求, ...
- sql 入门经典(第五版) Ryan Stephens 学习笔记 第五部分: 性能调整
第十六章: 利用索引改善性能 1. create index 单字段索引: create index index_name on table_name (column_name);唯一索引: ...
- sql 入门经典(第五版) Ryan Stephens 学习笔记 (第六,七,八,九,十章,十一章,十二章)
第六章: 管理数据库事务 事务 是 由第五章 数据操作语言完成的 DML ,是对数据库锁做的一个操作或者修改. 所有事务都有开始和结束 事务可以被保存和撤销 如果事务在中途失败,事务中的任何部分都不 ...
- sql 入门经典(第五版) Ryan Stephens 学习笔记 (第一,二,三,,四,五章)
SQL - Structured Query Language (结构化查询语言) 1/ SQL 命令的类型 : 数据定义语言: DDL 数据操作语言: DML 数据查询语言: DQL 数据控制语言 ...
- OSPF建立邻居、邻接关系 学习笔记
Ospf中路由器之间存在两种连接关系:邻居关系和邻接关系.本博文将详细介绍这2种关系建立及工作原理. 如果两台路由器之间共享一条公共数据链路(两台路由器中间没有其它路由器,或者两台路由器之间存在虚连接 ...
- .NET 云原生架构师训练营(建立系统观)--学习笔记
目录 目标 ASP .NET Core 什么是系统 什么是系统思维 系统分解 什么是复杂系统 作业 目标 通过整体定义去认识系统 通过分解去简化对系统的认识 ASP .NET Core ASP .NE ...
- sql 入门经典(第五版) Ryan Stephens 学习笔记 后续——存储引擎
一.引擎基础 1 查看系统支持的存储引擎 show engines; 2 查看表使用的存储引擎两种方法: a.show table status from database_name where na ...
随机推荐
- tsinsen A1067. Fibonacci数列整除问题 dp
A1067. Fibonacci数列整除问题 时间限制:1.0s 内存限制:512.0MB 总提交次数:2796 AC次数:496 平均分:51.83 将本题分享到: 查看未格 ...
- C#高级编程9-第2章 核心C#
C#基础 使用C#命名编译器csc.exe,编译C#程序 变量 变量一般初始化后才能使用 类型判断弱类型var,根据初始值判断类型, 变量作用域,可以访问该代码的区域 类中定义的成员变量和属性,作用在 ...
- 原生+H5开发之:Android webview配置
在上一篇文章Android 原生开发.H5.React-Native开发特点,我们可以了解到三种Android开发方式的区别和优缺点.[Android开发:原生+H5]系列的文章,将主要讲解Andro ...
- Linux 内核编译步骤及配置详解
前言 Linux内核是操作系统的核心,也是操作系统最基本的部分. Linux内核的体积结构是单内核的.但是他充分采用了微内核的设计思想.使得虽然是单内核.但工作在模块化的方式下.并且这个模块可以 ...
- Spring <context:annotation-config/> 解说(转)
在基于主机方式配置Spring的配置文件中,你可能会见到<context:annotation-config/>这样一条配置,他的作用是式地向 Spring 容器注册 AutowiredA ...
- 关于maven依赖中的<scope>provided</scope>使用
今天开发web的时候,需要用到servlet-api,于是在pom.xml中添加依赖 <dependency> <groupId>javax.servlet</group ...
- C#程序集系列11,全局程序集缓存
全局程序集缓存(GAC:Global Assembly Cache)用来存放可能被多次使用的强名称程序集.当主程序需要加载程序集的时候,优先选择到全局程序集缓存中去找寻需要的程序集. 为什么需要全局程 ...
- C#程序集系列02,使用记事本查看可执行程序集的IL代码
继续上一篇"C#程序集系列01,用记事本编写C#,IL代码,用DOS命令编译程序集,运行程序",在F盘的as文件夹中已经有了若干程序集.本篇体验使用记事本查看可执行程序集的IL代码 ...
- 使用Dictionary泛型集合封装业务逻辑判断 z
C#2.0 提供了Dictionary 泛型类,它提供了从一组键到一组值的映射.字典中的每个添加项都由一个值及其相关联的键组成.通过键来检索值的速度是非常快的,接近于 O(1),这是因为 Dictio ...
- Web项目中获取SpringBean——在非Spring组件中获取SpringBean
最近在做项目的时候我发现一个问题:Spring的IOC容器不能在Web中被引用(或者说不能被任意地引用).我们在配置文件中让Spring自 动装配,但并没有留住ApplicationContext的实 ...