触发器五(建立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 ...
随机推荐
- PAT甲级1123. Is It a Complete AVL Tree
PAT甲级1123. Is It a Complete AVL Tree 题意: 在AVL树中,任何节点的两个子树的高度最多有一个;如果在任何时候它们不同于一个,则重新平衡来恢复此属性.图1-4说明了 ...
- 成为一名JAVA高级工程师你需要学什么【转】
宏观上: 1.技术广度方面至少要精通多门开源技术吧,研究过struts\spring等的源码. 2.项目经验方面从头到尾跟过几个大项目,头是指需求阶段,包括需求调研.尾是指上线交付之后,包括维护阶段. ...
- bootstrap字体图标不正常显示的原因
本地引入bootstrap.css文件,使用https://v3.bootcss.com/components/站点 字体图标 时不能正常显示,换成 bootstrap 官网的 cdn 链接却能正常显 ...
- 重温PHP之冒泡排序
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法. 它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如从大到小.首字母从A到Z)错误就把他们交换过来.走 ...
- PowerDesigner设置唯一约束/唯一索引/唯一键
注意:还需要设置unique约束,也是在这个界面. 参考: https://blog.csdn.net/cnham/article/details/6676650 https://blog.csdn. ...
- GoodSync 同步 对比 备份
单向/双向皆可,针对任何一侧的文件进行处理,两侧文件都进行更新 文件同步 的操作过程是:确保两处或多处包含完全一致.及时更新 的各种文件.当对某一处进行文件添加.更改或删除,则同步操作将对对应的 另一 ...
- C#中结构(struct)的部分初始化和完全初始化
假设有这样一个值类型struct. public struct Size { public int Length; public int Width; public int Area() { retu ...
- python接口自动化4-绕过验证码登录(cookie)
前言 有些登录的接口会有验证码:短信验证码,图形验证码等,这种登录的话验证码参数可以从后台获取的(或者查数据库最直接). 获取不到也没关系,可以通过添加cookie的方式绕过验证码. 一.抓登录coo ...
- zookeeper 伪分布式安装
1 下载zookeeper安装包 下载地址 http://apache.fayea.com/zookeeper/ 我下载的是zookeeper-3.4.6.tar.gz 2 解压缩 将zookeepe ...
- key-value 多线程server的Linux C++实现
项目需求 整体思路 网络通信 字符解析 数据存储与查询 1 存储管理 2 数据查询 多线程 待改进未实现的想法 GitHub源代码 项目需求 设计一个基于Socket或基于HTTP的server,服务 ...