触发器五(建立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 ...
随机推荐
- 浅析OpenGL光照
浅析OpenGL光照 之前从来都没有涉及光照的内容,心想只要能通过常规的方法渲染出几何体甚至是模型就可以了,然而没有光照的日子注定是苦涩的,因为仅凭几何体和模型的颜色无法达到真是渲染的效果,在实际中有 ...
- C语言每日小练(四)——勇者斗恶龙
勇者斗恶龙 你的王国里有一条n个头的恶龙,你希望雇佣一些骑士把它杀死(砍掉全部的头). 村里有m个骑士能够雇佣.一个能力值为x的骑士能够砍掉恶龙一个致敬不超过x的头,且须要支付x个金币. 怎样雇佣骑士 ...
- C# 去掉webapi返回json所带的转义字符
反序列换报错: {"Error converting value \"{\"Result\":true,\"Code\":\"\& ...
- 我对NHibernate的感受(4):令人欣喜的Interceptor机制
之前谈了NHibernate的几个方面,似乎抱怨的居多,不过这次我想谈一下我对Interceptor的感受,则基本上都是好话了.这并不一定是说Interceptor设计的又多么好(事实上它使用起来还是 ...
- MVC客户端使用 Mustache.js把json数据填充到模版中
使用Mustache的好处是:可以把一些反复用到的html部分定义成Mustache模版,以便多次使用.使用Mustache的大致步骤是: →从后台拿到json数据 →获取前台页面预先定义好Musta ...
- linux列出一个目录及其子目录下面的某种类型的文件
linux列出一个目录及其子目录下面的某种类型的文件 作者:smarteng ⁄ 时间:2009年07月09日 ⁄ 分类: Linux命令 ⁄ 评论:0 怎么样把,一个目录及其所有的子目录下面的某种类 ...
- Android中关于项目中对Thread的管理(不是线程池)
背景 项目中对于一些并不复杂的耗时操作,比如计算,不频繁操作数据库等,因为没必要使用线程池,所以之前项目会直接使用new Thread的方式,时间一长,回头再看,原来new Thread之处已经很多了 ...
- Struts2 S标签 数目字格式化成金额输出(保留两位小数)
JSP: <s:property value="%{formatDouble(price)}" /> Action:添加 //格式化数字显示 public String ...
- 开启otl的64位长整数支持
要开启OTL的64位长整数支持,必须先定义宏 #define OTL_BIGINT __int64 // VC++, Borland C++ 或者 #define OTL_BIGINT long lo ...
- Qt Quick 和qml介绍
很多人不了解Qt Quick和Qml,还有很多人对其存在偏见.这篇文章就是来向这些有困惑的人介绍一下其是什么,有什么特点. 首先,这两个是一个东西吗? 答案:是的.但是,具体来说,Qt Quick是框 ...