【database】oracle触发器基础
一、oracle触发器基本语法
CREATE [OR REPLACE] TRIGGER trigger_name
{BEFORE | AFTER }
{INSERT | DELETE | UPDATE [OF column [, column …]]}
[OR {INSERT | DELETE | UPDATE [OF column [, column …]]}...]
ON [schema.]table_name | [schema.]view_name
[REFERENCING {OLD [AS] old | NEW [AS] new| PARENT as parent}]
[FOR EACH ROW ]
[WHEN condition]
PL/SQL_BLOCK | CALL procedure_name;
BEFORE: 在执行触发事件前执行触发器内容;
AFTER:在执行触发事件后执行触发器内容;
(貌似还存在第3中:instead of,主要用于视图。待学习....)
FOR EACH ROW: 行级触发器,对应的还有语句级触发器。
行级触发器,只要数据行符合触发条件,就执行1次触发器;
语句级触发器,整个语句操作作为触发事件,符合触发条件,则只执行1次触发器;(这个理解还不深刻)
NEW/OLD:只存在与FOR EACH ROW中。且update:NEW、OLD,insert:NEW,delete:OLD;
二、基础demo
说明:当更新子表CHILD的时候,把其对应父表的姓名拼接”123”。
create or replace trigger TEST_TRIGGER
before update ON "CHILD" for each row
declare
old_age number;
new_age number;
v_id number;
p_id number;
--PRAGMA AUTONOMOUS_TRANSACTION; -- 自治事务,独立于触发sql的事务
begin
old_age := :old.child_age;
new_age := :new.child_age;
v_id := :new.child_id;
p_id := :new.parent_id;
dbms_output.put_line('After: old='||old_age||',new='||new_age);
if 3>2 then
-- UPDATE CHILD set child_name = child_name||'123' where CHILD_ID = 5;
UPDATE parent set parent_name = parent_name||'' where PARENT_ID = p_id;
--:new.child_name := :old.child_name || '123';
dbms_output.put_line('if scope!');
end if;end TEST_TRIGGER;
奇葩问题: 如果trigger中存在if语法,
注意demo最后 end if;end TEST_TRIGGER; 如果不这么写(分成2行),此trigger在navicat中编译是通不过的。但在pl/sql中是正确的。
三、trigger的事务、自治事务
如果trigger不用自治事务,那么触发器的事务和触发触发器事件的事务是同一个。
我在测试的时候遇到的问题:1、目的:在更新child_age后,通过触发器更新其名字child_name。2、因为我要的确实更新后,才更新chile_name,所以我用的BEFORE。
如果不用自治事务,那么表示触发器和触发事件是处于同一事务(即便是after,触发事件的事务也是没提交的。),oracle是不允许对同一行记录再次进行DML的。
但是如果使用自治事务,这明显有个问题是,如果触发事件的语句被回滚,那么触发器是确定被触发、且被提交的。所以,此处不能用自治事务(我还真没想到什么场景要用到自治事务)
如何实现?
这时就要用到BEFORE/AFTER的区别了,通过前面知道了默认触发器和触发事件是在同一事务。那么可以通过BEFORE达到目的,直接在BEFORE中修改:new对应的字段值。如demo中的:
:new.child_name := :old.child_name || '123'; 这样,其实就会更新行所对应的字段值。
四、备注
在网上查了下对触发器的看法,发现大部分的观念都不推荐触发器。观点总结:1、触发器性能不好;2、触发器太隐蔽,容易被忽略;3、移植性低,难以维护。
对于性能,不清楚程度到底怎么样。
移植性,我接触的项目都不考虑。
隐蔽性,这很关键,如果项目管理不好。可能都不知道有这个触发器的存在。
综上,我只能了解到反正大家都不怎么推荐…
这说下为什么我要用的情况:有张表table_a,存在一个状态位a.status=[1,2,3,4,5,6…];当状态位为[4,5,6]时要给客户发送短信提醒。
存在的做法:1、在所有代码中,更改status的地方判断,直接调用发送短信(或者把短信放到短信池,定时发送。这有很大却别)。 2、定时器,检测状态位,然后发送。 3、触发器。
方式1: 我觉得很蠢,你要找到现在有的所有地方。如果后面新增一个地方修改status,别人不一定知道要发短信。(而且还不止这么简单,万一这update被回滚,你直接调短信发送不雪崩?如果是放到短信池还好,都回滚了。)
方式2: 有一个问题是,你要知道这行数据是不是状态改变过,且是没发送过短信的(麻烦,我没细想这)
方式3: 触发器,检测行的status,然后符合的insert一条短信到短信池,然后在定时检测短信池发送短信。
附录
[oracle官方文档 12c]CREATE TRIGGER Statement
【database】oracle触发器基础的更多相关文章
- ORACLE 触发器 基础
--触发器--语法 CREATE OR REPLACE TRIGGER TRIGGER_NAME AFTER|BEFORE|INSTEAD OF [INSERT][OR UPDATE [OF COLU ...
- Oracle数据库基础入门《二》Oracle内存结构
Oracle数据库基础入门<二>Oracle内存结构 Oracle 的内存由系统全局区(System Global Area,简称 SGA)和程序全局区(Program Global Ar ...
- oracle触发器加条件判断
oracle触发器加条件判断,如果某个字段,isnode=0,那么不执行下面的方法,数据如下: create or replace trigger tr_basestation_insert_emp ...
- Oracle 触发器在日志管理开发中的应用
摘要: 本文讨论了利用数据库中的触发器对日志管理进行设计与实现的方法, 是对原来在客户端软件中编写日志管理方法的一种改进, 并给出了 Oracle9i 中的实例演示.关键词: Oracle; 触发器; ...
- oracle触发器应用
首先给大家推荐两篇我看后的博文,我已经内容转载过来: 1.对触发器的讲解 本篇主要内容如下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触发器 8.1.3 系统触发器 8.2 创建 ...
- SQL server与Oracle触发器的创建与使用
SQL Server 1创建触发器 GO BEGIN IF (object_id('WMY', 'tr') is not null) DROP trigger WMY END; GO CREATE T ...
- Oracle数据库基础入门《一》Oracle服务器的构成
Oracle数据库基础入门<一>Oracle服务器的构成 Oracle 服务器是一个具有高性能和高可靠性面向对象关系型数据库管理系统,也是一 个高效的 SQL 语句执行环境. Oracle ...
- Oracle 触发器(二)
Oracle触发器详解 触发器是许多关系数据库系统都提供的一项技术.在oracle系统里,触发器类似过程和函数,都有声明,执行和异常处理过程的PL/SQL块. 8.1 触发器类型 触发器在数据库里 ...
- Oracle 备份与恢复基础
Oracle 备份与恢复基础 :三思笔记 备份与恢复 A whole database backup is either a consistent backup or an inconsistent ...
随机推荐
- RocketMQ重试机制和消息幂等
一.重试机制 由于MQ经常处于复杂的分布式系统中,考虑网络波动,服务宕机,程序异常因素,很有可能出现消息发送或者消费失败的问题.因此,消息的重试就是所有MQ中间件必须考虑到的一个关键点.如果没有消息重 ...
- c++ 初始化列表和构造函数初始化区别
先上代码 #include <iostream> class MyContruct { public: MyContruct() { std::cout << "My ...
- Yandex Big Data Essentials Week1 Unix Command Line Interface File Content exploration
cat displays the contents of a file at the command line copies or apppend text file into a document ...
- 仅仅知道如何终止XHR请求,或许对你来说是不够的!
TLDR: 当我们需要的时候,我们可以通过AbortController接口来终止一个或者多个请求. 前言 到目前为止,我们有两个常用的基本的手段去发送请求进而局部刷新页面内容,其一是XMR(XMLH ...
- python-nmap 使用
安装 [root@localhost ~]# yum -y install nmap [root@localhost ~]# pip install python-nmap 使用 import nma ...
- rm -f 后如何恢复
前言 每当我们在生产环境服务器上执行rm命令时,总是提心吊胆的,因为一不小心执行了误删,然后就要准备跑路了,毕竟人不是机器,更何况机器也有bug,呵呵. 那么如果真的删除了不该删除的文件,比如数据库. ...
- 高级安全Windows防火墙概述以及最佳实践
本文简单介绍Windows防火墙的概念,给出使用场景并列出了常见的防火墙操作. 简介 在Windows NT6.0之后微软推出了高级安全Windows防火墙(简称WFAS),高级安全Windows防火 ...
- h5笔记1
1.HTML中不支持 空格.回车.制表符,它们都会被解析成一个空白字符 2.适用于大多数 HTML 元素的属性: class 为html元素定义一个或多个类名(classname)(类名从样式文件引入 ...
- vue 使用v-for进行循环
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 使用HSSFWorkbook导出、操作excel
原文地址:https://www.jianshu.com/p/dd1e4f28757b 在实际开发中我们经常需要导入数据,统计数据,并且将统计好的数据导出excel,今天分享一个导出学生信息的方法. ...