当前位置: 首页 > 编程日记 > 正文

Oracle学习笔记十三 触发器

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

简介

触发器是当特定事件出现时自动执行的存储过程,特定事件可以是执行更新的DML语句和DDL语句,触发器不能被显式调用。

触发器的功能:

1.自动生成数据

2.自定义复杂的安全权限

3.提供审计和日志记录

4.启用复杂的业务逻辑

创建触发器的语法

复制代码

CREATE [OR REPLACE] TRIGGER trigger_name
AFTER | BEFORE | INSTEAD OF
[INSERT] [[OR] UPDATE [OF column_list]] 
[[OR] DELETE]
ON table_or_view_name
[REFERENCING {OLD [AS] old / NEW [AS] new}]
[FOR EACH ROW]
[WHEN ( condition ) ]
pl/sql_block;

复制代码

:new --为一个引用最新的列值;
:old --为一个引用以前的列值; 这两个变量只有在使用了关键字 "FOR EACH ROW"时才存在.

且update语句两个都有,而insert只有:new ,delect 只有:old;

触发器由三部分组成:

触发器语句(事件)

定义激活触发器的 DML 事件和 DDL 事件

触发器限制

执行触发器的条件,该条件必须为真才能激活触发器

触发器操作(主体)

包含一些 SQL 语句和代码,它们在发出了触发器语句且触发限制的值为真时运行

触发器语句

CREATE OR REPLACE TRIGGER trig_salAFTER UPDATE OF empsal ON salary_records  --在更新 emp_sal 列之后激活触发器

触发器限制

FOR EACH ROWWHEN (NEW.empsal>OLD.empsal)    --只有在WHEN子句中的条件得到满足时,才激活trig_sal 触发器DECLARESal_diff NUMBER;…    

触发器操作

BEGINsal_diff:=:NEW.empsal-:OLD.empsal;    --如果WHEN子句中的条件得到满足,将执行BEGIN 块中的代码
      DBMS_OUTPUT.PUT_LINE(‘工资差额:’sal_diff);END;

BEFORE 触发器的工作原理

081741_a81j_2263361.png  081741_zNy9_2263361.png

创建触发器

复制代码

CREATE OR REPLACE TRIGGER aiu_itemfile
AFTER INSERT
ON itemfile
FOR EACH ROW
BEGINIF (:NEW.qty_hand = 0) THENDBMS_OUTPUT.PUT_LINE('警告:已插入记录,但数量为零');ELSEDBMS_OUTPUT.PUT_LINE(‘已插入记录');END IF;
END;

复制代码

查看表的触发器

select * from all_triggers where table_name =upper('tbname')

复制代码

CREATE OR REPLACE TRIGGER TR_SEC_EMP
BEFOR INSERT  OR UPDATE OR DELETE ON EMP2
BEGIN IF TO_CHAR(SYSDATE,'DY', 'nls_date_language=AMERICAN') IN ('SAT', 'SUN') THEN 
RAISE_APPLICATION_ERROR(-20002,’禁止修改数据!’);
END IF;
END;

复制代码

工资一般来说都是往上调整,写个触发器禁止降低工资?

复制代码

create or replace trigger guo_trigger----创建触发器 
before update on emp2 ----指明触发器时机 
for each row ----行触发器标识 
when (new.sal<old.sal ) ----触发条件 
begin 
raise_application_error(-20500,'不能给员工减少工资'); 
end;

复制代码

触发器类型

触发器的类型有:

081741_OKbA_2263361.png

DDL 触发器

在模式中执行 DDL 语句时执行

数据库级触发器

在发生打开、关闭、登录和退出数据库等系统事件时执行

DML 触发器

在对表或视图执行DML语句时执行

语句级触发器

无论受影响的行数是多少,都只执行一次

行级触发器

对DML语句修改的每个行执行一次

INSTEAD OF 触发器

用于用户不能直接使用 DML 语句修改的视图

综述:

触发器组成:

l         触发事件:引起触发器被触发的事件。 例如:DML语句(INSERT, UPDATE, DELETE语句对表或视图执行数据处理操作)、DDL语句(如CREATE、ALTER、DROP语句在数据库中创建、修改、删除模式对象)、数据库系统事件(如系统启动或退出、异常错误)、用户事件(如登录或退出数据库)。

l         触发时间:即该TRIGGER 是在触发事件发生之前(BEFORE)还是之后(AFTER)触发,也就是触发事件和该TRIGGER 的操作顺序。

l         触发操作:即该TRIGGER 被触发之后的目的和意图,正是触发器本身要做的事情。 例如:PL/SQL 块。

l         触发对象:包括表、视图、模式、数据库。只有在这些对象上发生了符合触发条件的触发事件,才会执行触发操作。

l         触发条件:由WHEN子句指定一个逻辑表达式。只有当该表达式的值为TRUE时,遇到触发事件才会自动执行触发器,使其执行触发操作。

l         触发频率:说明触发器内定义的动作被执行的次数。即语句级(STATEMENT)触发器和行级(ROW)触发器。

语句级(STATEMENT)触发器:是指当某触发事件发生时,该触发器只执行一次;行级(ROW)触发器:是指当某触发事件发生时,对受到该操作影响的每一行数据,触发器都单独执行一次。

触发器不接受参数。

l         一个表上最多可有12个触发器,但同一时间、同一事件、同一类型的触发器只能有一个。并各触发器之间不能有矛盾。

l         在一个表上的触发器越多,对在该表上的DML操作的性能影响就越大。

l        触发器最大为32KB。若确实需要,可以先建立过程,然后在触发器中用CALL语句进行调用。

l         在触发器的执行部分只能用DML语句(SELECT、INSERT、UPDATE、DELETE),不能使用DDL语句(CREATE、ALTER、DROP)。

l         触发器中不能包含事务控制语句(COMMIT,ROLLBACK,SAVEPOINT)。因为触发器是触发语句的一部分,触发语句被提交、回退时,触发器也被提交、回退了。

l         在触发器主体中调用的任何过程、函数,都不能使用事务控制语句。

l         在触发器主体中不能申明任何Long和blob变量。新值new和旧值old也不能向表中的任何long和blob列。

l         不同类型的触发器(如DML触发器、INSTEAD OF触发器、系统触发器)的语法格式和作用有较大区别。

行级触发器

复制代码

CREATE TABLE TEST_TRG(ID NUMBER, NAME VARCHAR2(20));
CREATE SEQUENCE SEQ_TEST;CREATE OR REPLACE TRIGGER BI_TEST_TRGBEFORE INSERT OR UPDATE OF IDON TEST_TRGFOR EACH ROW
BEGIN
--函数UPDATING, DELETING判断触发器是由哪个操作触发的 IF INSERTING THEN SELECT SEQ_TEST.NEXTVAL INTO :NEW.ID FROM DUAL;ELSERAISE_APPLICATION_ERROR(-20020, '不允许更新ID值!');END IF;
END;

复制代码

修改数据前备份员工工资

复制代码

CREATE OR REPLACE TIGGER TR_SAL_BACK AFFTER UPDATE OF SAL ON EMP2 FOR EACH ROW 
DECLARE V_TEM INT ;
BEGIN 
  SELECT COUNT(*) INTO V_TEMP FROM NEW_BACK WHERE ENAME =:OLD.ENAME;IF V_TEMP =0 THEN 
    INSERT INTO NEW_BACK VALUES (:OLD.ENAME,:OLD.SAL, :NEW.SAL,SYSDATE);ELSE 
    UPDATE NEW_BACK VALUES  SET OLDSAL=:OLDSAL, NEWSAL=:NEW.SAL,TIME=SYSDATE WHERE NAME=:OLD.ENAME;END IF; 
END;

复制代码

建立一个触发器, 当职工表 emp 表被删除一条记录时,把被删除记录写到职工表删除日志表中去。

复制代码

CREATE TABLE emp_his AS SELECT * FROM EMP WHERE 1=2; CREATE OR REPLACE TRIGGER tr_del_emp BEFORE 
DELETE --指定触发时机为删除操作前触发ON scott.emp FOR EACH ROW   --说明创建的是行级触发器 
BEGIN--将修改前数据插入到日志记录表 del_emp ,以供监督使用。INSERT INTO emp_his(deptno , empno, ename , job ,mgr , sal , comm , hiredate )VALUES( :old.deptno, :old.empno, :old.ename , :old.job,:old.mgr, :old.sal, :old.comm, :old.hiredate );
END;DELETE emp WHERE empno=7788;
DROP TABLE emp_his;
DROP TRIGGER del_emp;

复制代码

语句级触发器

复制代码

CREATE OR REPLACE TRIGGER trgdemoAFTER INSERT OR UPDATE OR DELETEON order_master
BEGINIF UPDATING THENDBMS_OUTPUT.PUT_LINE('已更新 ORDER_MASTER 中的数据');ELSIF DELETING THENDBMS_OUTPUT.PUT_LINE('已删除 ORDER_MASTER 中的数据');ELSIF INSERTING THENDBMS_OUTPUT.PUT_LINE('已在 ORDER_MASTER 中插入数据');END IF;
END;

复制代码

行级与语句区别

行触发器和语句触发器的区别表现在:行触发器要求当一个DML语句操走影响数据库中的多行数据时,对于其中的每个数据行,只要它们符合触发约束条件,均激活一次触发器;而语句触发器将整个语句操作作为触发事件,当它符合约束条件时,激活一次触发器。当省略FOR EACH ROW 选项时,BEFORE 和AFTER 触发器为语句触发器,而INSTEAD OF 触发器则只能为行触发器。

INSTEAD OF 触发器

复制代码

CREATE OR REPLACE TRIGGER upd_ord_viewINSTEAD OF UPDATE ON ord_viewFOR EACH ROW
BEGINUPDATE order_masterSET vencode=:NEW.vencode WHERE orderno = :NEW.orderno;DBMS_OUTPUT.PUT_LINE('已激活触发器');
END;

复制代码

模式触发器

复制代码

CREATE TABLE dropped_obj 
(obj_name VARCHAR2(30),obj_type VARCHAR2(20),drop_date DATE
);CREATE OR REPLACE TRIGGER log_drop_objAFTER DROP ON SCHEMA
BEGININSERT INTO dropped_obj
  VALUES( ORA_DICT_OBJ_NAME, ORA_DICT_OBJ_TYPE, SYSDATE);
END;

复制代码

启用、禁用和删除触发器

启用和禁用触发器

ALTER TRIGGER aiu_itemfile DISABLE;
ALTER TRIGGER aiu_itemfile ENABLE;

删除触发器

DROP TRIGGER aiu_itemfile;

查看有关触发器的信息

USER_TRIGGERS 数据字典视图包含有关触发器的信息

复制代码

SELECT TRIGGER_NAME FROM USER_TRIGGERS
WHERE TABLE_NAME='EMP';SELECT TRIGGER_TYPE, TRIGGERING_EVENT, WHEN_CLAUSE
FROM USER_TRIGGERS
WHERE TRIGGER_NAME = 'BIU_EMP_DEPTNO';

复制代码

转载于:https://my.oschina.net/u/2263361/blog/680779

相关文章:

使用Notepad++比较文件的差异

有时候需要比较两个文件的差异部分&#xff0c;如果不在git里可以使用Notepad的插件。 在Notepad中安装Compare插件 打开NotePad&#xff0c;点击工具栏上的插件--Plugin Manager--Show Plugin Manager&#xff0c;选中Compare 然后安装。 比如下看两个线程堆栈的差异&#xf…

【MATLAB】将向量表示的多项式用字符串输出的通用函数示例

%创建一个名为pprintf的M文件 function s pprintf(p) %UNTITLED7 此处显示有关此函数的摘要 % 此处显示详细说明 if nargin>1error(Too much input arguments); end while(p(1)0)p1[]; end llength(p); if l0s0; elseif l1snum2str(p(1)); elseif l2s strcat(num2str(p(…

30秒或更短的时间内弄懂的有用CSS代码片段

今天无意间看到这个&#xff0c;真的很牛逼&#xff0c;记录下中文网&#xff1a; caibaojian.com/30-seconds-…转载于:https://juejin.im/post/5bf278a85188255e9b61a226

【MATLAB】数据分析之多项式及其函数

1、多项式的表达式和创建 MATLAB中使用一维向量来表示多项式。将多项式按照降幂次序存放在向量中。 多项式就可以用向量 [2 3 5 0 1]来表示。 2、多项式求根 >> p[1 2 1]p 1 2 1>> r roots(p)r -1-13、由根创建多项式 >> r [2;3]r 23>>…

SpringBoot自定义异常源码分析

SpringBoot自定义异常源码分析 在类上加ControllerAdvice注解&#xff0c;在方法上加ExceptionHandler注解&#xff0c;就可以在方法里处理相应的异常。 1.自定义异常处理类AdditionalExceptionHandler 挂RestControllerAdvice注解&#xff1a; ------------------ 2.自定义…

Android 应用性能优化-StrictMode(严格模式)

为什么80%的码农都做不了架构师&#xff1f;>>> UI线程如果被阻塞5秒的话&#xff0c;那么应用程序此时就会弹出ANR的对话框&#xff0c;ANR对应用程序来说是一个很严重的问题。 如何防止应用程序出现ANR&#xff0c;怎么分析查看导致ANR问题的原因&#xff1f; 我…

跨进程通信,到底用长连接还是短连接

一个完整的软件系统大多数情况下是由多个进程共同协作进行的&#xff0c;哪怕它们在同一台服务器上。所以&#xff0c;进程之间如何进行高效的通信至关重要。 单个应用程序单个数据库这套基础开发套餐我相信每个人都经历过&#xff0c;甚至在初期它们还有可能部署在同一台服务器…

Java的List和Json转换以及StringRedisTemplate往redis存泛型对象

List转Json List<User> user new ArrayList(); String str JSON.toJSONString(user); Json 转List方法一 List<User> user JSON.parseArray(json,User.class); 如果是泛型方法需要使用TypeReference Json 转List 方法二 String json "[{}]"; Li…

【MATLAB】符号数学计算(一):符号对象的创建

一、符号对象的创建命令 1、函数命令sym( ) variablesym(A,flag)Ssym(A,flag) 如果A是(不带单引号)是一个数字、数值矩阵或者数值表达式&#xff0c;则输出结果是将数值对象转换成的符号对象。 如果A(带单引号)是一个字符串&#xff0c;输出结果则是将字符串转换成的符号对象…

分布式session一致性问题

传统的网站结构&#xff08;并发量不大&#xff0c;没有session的不一致的问题。传统的网站结构图&#xff1a; **结论&#xff1a;**从图中可以看出在传统的网站结构中&#xff0c;所有的客户端都连接一个服务器&#xff0c;每个客户端发送过来的请求都被该服务器处理&#…

切换阿里云maven源解决maven中央仓库下载太慢卡顿的问题

maven默认官方的中央仓库有时候很慢下载jar甚至会卡住&#xff0c;那么你可以切换到阿里云的maven源 在本地的maven文件夹新建settings.xml <?xml version"1.0" encoding"UTF-8"?> <settings xmlns"http://maven.apache.org/SETTINGS/1.…

【MATLAB】符号数学计算(二):符号运算中的运算符和函数

一般的这里就不再列举 1、算术运算符号 运算符号“ ”、“ . ”分别实现矩阵的共轭转置和非共轭转置。 >> syms a b c d; >> Asym([a,b;c,d])A [ a, b] [ c, d]>> R1AR1 [ conj(a), conj(c)] [ conj(b), conj(d)]>> R2A.R2 [ a, c] [ b, d] 2、关…

2015级C++第14周实践项目 模板

【项目1-排序函数模板】 已知 void Sort(int a[],int size); void Sort(double a[],int size); 是一个函数模板的两个实例&#xff0c;其功能是将数组a中的前size个元素按从小到大顺序排列。试设计这个函数模板。 【项目2-两个成员的类模板】 设有如下的类声明&#…

11月18日珠三角城市人口迁徙可视化(和弦图)

2019独角兽企业重金招聘Python工程师标准>>> 一、导入数据&#xff0c;初始图 > library(circlize) > data<-read.table("C:/Users/cuiy/Desktop/PersonalData/qianxi.csv",sep",",headerT) > head(data)from to value 1 中山 珠…

【MATLAB】符号数学计算(三):符号的精度计算

符号计算的一个非常显著的特点是&#xff0c;由于计算中不会出现舍入误差&#xff0c;从而可以得到任意精度的数值解。 &#xff08;要计算精确&#xff0c;就要牺牲计算时间和储存空间&#xff09; 符号工具箱中有三种不同类型的算术运算&#xff1a; 数值类型&#xff1a;…

SQLite第三方框架FMDB的使用,以及使用FMDatabaseQueue保证线程安全

2019独角兽企业重金招聘Python工程师标准>>> &#xff08;1&#xff09;下载地址&#xff1a;https://github.com/ccgus/fmdb &#xff08;2&#xff09;注意点 ——语句可以带分号“&#xff1b;”&#xff0c;也可以省略分号。 ——同样需要添加“libsqlite3.dyli…

Linus采访对Linux对git和对代码品味的理解

【Linus对办公环境的要求】 Linus大师说他11岁就开始编程,他说他是一个喜欢安静和不合群的人。 图中是他和他的弟弟,看来少儿编程还是很重要的,大师21岁写出linux0.0.1最初的内核。 图中是他的家,也是Linux的总部,非常简单的办公环境,只有显示器,大师喜欢安静,所以不想…

04 集成学习 - Boosting - AdaBoost算法构建

03 集成学习 - Boosting - AdaBoost算法原理 十、AdaBoost算法构建 上一章最后说明了每个基模型的权值α是如何求得的&#xff0c;于是我就可以对模型进行更新操作了。 构建过程一 1、假设数据集&#xff1a; T{(X1,Y1),(X2,Y2),...(Xn,Yn)} 2、初始化训练数据权重分布&#xf…

Redis源码分析 List实现

在版本3.2之前&#xff0c;Redis中的列表是 ziplist 和 linkedlist 实现的&#xff0c;在3.2之后&#xff0c;由quicklist实现。 双向链表linkedlist在表的两端进行push和pop操作非常方便&#xff0c;但是地址不连续&#xff0c;而且需要保持额外的指针。 ziplist是连续内存&am…

Linux cut命令

用途 文本文件按列提取。 特点 过于简单&#xff0c;只能处理固定格式的分隔符&#xff0c;分隔符不能使用正则表达式。 用法 命令基本格式 -b、-c、-f分别表示字节、字符、字段&#xff08;即byte、character、field&#xff09;&#xff1b;list表示-b、-c、-f操作范围&#…

【MATLAB】符号数学计算(四):符号表达式操作

一、符号表达式合并 Rcollect(S)&#xff1a;将表达式S中相同次幂的项合并。S可以是一个表达式&#xff0c;也可以是一个符号矩阵。Rcollect(S,v)&#xff1a;将表达式中S中v的相同次幂进行合并。如果v没有指定&#xff0c;则默认将含有x的相同次幂的项进行合并。 >> sy…

Alpha冲刺——day1

Alpha冲刺——day1 作业链接 Alpha冲刺随笔集 github地址 站立式会议 会议安排&#xff1a;alpha冲刺的第一天&#xff0c;我们站立式会议讨论了我们接下来的安排&#xff0c;做出大致的规划&#xff0c;并针对之前的原型设计&#xff0c;讨论了界面设计的大概 项目进展项目进展…

一步一步学习VirtualBox安装CentOS7和CentOS8

个人学习研究Linux推荐安装VirtualBoxCentOS。 CentOS7和CentOS8的安装实际上是非常相似的&#xff0c;改变的地方不多&#xff0c;从CentOS7开始和CentOS6相比改变是非常大的。 VirtualBox本身是免费的&#xff0c;足够正常学习应用了&#xff0c;安装CentOS是因为企业线上大…

建模原语:四象图

原文地址&#xff1a;http://www.douban.com/note/164191021/ “模型、状态和行为特征、场景”和“四象图”&#xff0c;建模观的命名与立象。 建模原语:四象图 作者&#xff1a;achieveideagmail.com 命名&#xff1a;模型、结构特征、行为特征、场景&#xff08;及其规约&…

【MATLAB】符号数学计算(五):符号函数的替换

一、subs替换函数 Rsubs(S)&#xff1a;用工作区中的变量值替换符号表达式中的某一特定符号。Rsubs(S,New)&#xff1a;用新符号变量New来替换符号表达式S中的默认变量。Rsubs(S,Old,New) >> syms x y >> fsym(x^2x*yy^2)f x^2 x*y y^2>> x2; >> su…

Ubuntu阿里云搭建Mono.net环境

查看磁盘信息 我们买的系统默认情况下只是安装了系统&#xff0c;而数据盘需要自己挂载&#xff0c;例如我这里的系统占用20多G&#xff0c;还有40多G的数据盘默认是没有挂载的&#xff0c;首先我们运行df -h查看&#xff1a; rootAY1212241134392134698:~# df -hFilesystem Si…

MongoDB分布式原理以及read-preference和readConcern解决读写一致性问题

MongoDB词汇表&#xff1a; https://docs.mongodb.com/manual/reference/glossary/#term-replica-set MongoDB分布式原理 primary In a replica set, the primary is the member that receives all write operations. See Primary. 在副本集中&#xff0c;主库是接收所有写…

Lua(Codea) 中 table.insert 越界错误原因分析

2019独角兽企业重金招聘Python工程师标准>>> Lua(Codea) 中 table.insert(touches, touch.id, touch) 越界错误原因分析 背景介绍 在 Codea 上运行其他人以前写的代码时, 发现某段处理 touch 事件的代码总是报错, 开始报浮点数没有整型的表示, 修改代码增加类型转换…

【MATLAB】符号数学计算(六):符号函数的操作

一、复合函数的操作 compose(f,g)&#xff1a;返回复合函数f(g(y))&#xff0c;此处ff(x)&#xff0c;gg(y)&#xff1b;compose(f,g,x,z)&#xff1a;返回自变量是z的复合函数f(g(z)) >> syms x y >> fsym(xx^-1); >> gsym(sin(x)); >> h(1y^2); >…

java中如何应对读改写场景

前言 volatile可以确保数据及时刷新到主存&#xff0c;但是对于读改写场景还是无能为力 举个例子 public class ConcurrentHashMapExample {public static void main(String[] args) throws InterruptedException {Map<String, Long> ordersMap new ConcurrentHashMap&l…