`

关于触发器在行级和语句级的执行顺序问题

 
阅读更多

原创于2008年01月30日,2009年10月18日迁移至此。


原来总是对触发器的几种写法和执行先后顺序感到困惑,找了个时间把Oracle的官方文档看了一下,然后做了几个例子,终于有点明白了。:
Types of Triggers
触发器类型
Row Triggers and Statement Triggers
行级触发器和语句级触发器
BEFORE and AFTER Triggers
BEFORE和AFTER触发器
INSTEAD OF Triggers
INSTEAD OF触发器
Triggers on System Events and User Events
系统事件和用户事件触发器
--后面两种暂时不讨论
Trigger Type Combinations
组合触发器类型
Using the options listed previously, you can create four types of row and statement triggers:
根据前面所列的选项,我们能够创建四种类型的行级和语句级触发器
BEFORE statement trigger
BEFORE 语句级触发器
Before executing the triggering statement, the trigger action is run.
执行触发SQL 语句之前,就会激活触发器动作。
BEFORE row trigger
BEFORE 行级触发器
Before modifying each row affected by the triggering statement and before checking appropriate integrity constraints, the trigger action is run, if the trigger restriction was not violated.
在修改由触发SQL语句影响的每一行记录之前或者在检查完整性约束之前,将会执行触发动作。
AFTER row trigger
AFTER 行级触发器
After modifying each row affected by the triggering statement and possibly applying appropriate integrity constraints, the trigger action is run for the current row provided the trigger restriction was not violated. Unlike BEFORE row triggers, AFTER row triggers lock rows.
在修改由触发SQL语句影响的每一行记录之后或者在满足完整性约束之后,将会执行触发动作。和BEFORE行级触发器不同,AFTER行级触发器将会锁定记录。
AFTER statement trigger
AFTER 语句级触发器
After executing the triggering statement and applying any deferred integrity constraints, the trigger action is run.
在执行完毕触发SQL语句之后和确保不违反完整性约束的情况下,将会执行该触发动作。
1. 创建一张数据表和一张记录触发动作的表,再创建一个序列用来记录各个触发器触发动作的先后顺序。
CREATE TABLE test
(
TestID INTEGER NOT NULL,
TestNameVARCHAR2(20) NOT NULL,
CreateDTDATE,
UpdateDTDATE
);
ALTER TABLE test ADD CONSTRAINT TestPrimaryKey PRIMARY KEY (TestID);
CREATE TABLE TriggerLog
(
SeqID NUMBER(20,0),
TriggerNameVARCHAR2(50),
TableName VARCHAR2(30),
FieldName VARCHAR2(30),
FieldValue VARCHAR2(30),
OperateOrder VARCHAR2(30),
OperateTypeVARCHAR2(30),
OperateDT DATE
);
-- Create sequence
CREATE SEQUENCE SeqTriggerLog
MINVALUE 1
MAXVALUE 100000
START WITH 1
INCREMENT BY 1;
2. 创建4个触发器,分别为前置后置行级语句级的组合
CREATE OR REPLACE TRIGGER TrgBefInsStateOnTest
BEFORE INSERT ON test
BEGIN
INSERT INTO TriggerLog VALUES
(SeqTriggerLog.NextVal,'TrgBefInsStateOnTest','test','TestName',' ','BEFORE','INSERT',SYSDATE);
END TrgBefInsStateOnTest;
--在Before行级语句上可以对受影响的记录进行预处理
CREATE OR REPLACE TRIGGER TrgBefInsRowOnTest
BEFORE INSERT ON test
FOR EACH ROW BEGIN
:new.CreateDT:=SYSDATE;
INSERT INTO TriggerLog VALUES
(SeqTriggerLog.NextVal,'TrgBefInsRowOnTest','test','TestName',:new.TestName,'BEFORE','INSERT',SYSDATE);
END TrgBefInsRowOnTest;
--在After行级语句上可以进行相关完整性数据维护,当然对UPDATE更明显一些
CREATE OR REPLACE TRIGGER TrgAftInsRowOnTest
AFTER INSERT ON test
FOR EACH ROW BEGIN
INSERT INTO TriggerLog VALUES
(SeqTriggerLog.NextVal,'TrgAftInsRowOnTest','test','TestName',:new.TestName,'AFTER','INSERT',SYSDATE);
END TrgAftInsRowOnTest;
CREATE OR REPLACE TRIGGER TrgAftInsStateOnTest
AFTER INSERT ON test
BEGIN
INSERT INTO TriggerLog VALUES
(SeqTriggerLog.NextVal,'TrgAftInsStateOnTest','test','TestName',' ','AFTER','INSERT',SYSDATE);
END TrgAftInsStateOnTest;
3. 首先一次性插入多条记录,然后分别单独插入两条记录,看看其运行的先后
INSERT INTO test(testid,testname) SELECT column_id,column_name FROM user_tab_columns WHERE table_name='TEST';
COMMIT;
INSERT INTO test(testid,testname) VALUES(5,'AAA');
INSERT INTO test(testid,testname) VALUES(6,'BBB');
COMMIT;
SELECT * FROM test;
SELECT * FROM TriggerLog;

最终执行触发器的先后顺序如下
1. 首先执行Before Insert State触发器,每条语句仅执行一次
2. 其次执行Before Insert Row触发器,为SQL语句影响的记录数的多少
3. 再次执行After Insert Row触发器,为SQL语句影响的记录数的多少
4. 最后执行After Insert State触发器,每条语句仅执行一次
ITPUB个人空间�T's6q @u-W2n#e ITPUB个人空间"Qn{-O�GW"`@ ITPUB个人空间)T8t G5t^C-F+] "X7N(N:/B%A%y8cs6517 (Gy%b6JK-v9B8_jJ6517

分享到:
评论

相关推荐

    行级触发器不能读.txt

    行级触发器不能读.txt

    Oracle触发器修改自身表

    1、行级触发器不支持 ...所以想要触发器对自身表数据做修该,则用行级触发器得到 :new 和 :old对象中的相关数据,然后将这样的数据保存到 package中,然后在语句级触发期中调用 package包中保存的数据,进行更新操作

    Oraclet中的触发器

    BEFORE 和AFTER指出触发器的触发时序分别为前触发和后触发方式,前触发是在执行触发事件之前触发当前所创建的触发器,后触发是在执行触发事件之后触发当前所创建的触发器。 INSTEAD OF 选项使ORACLE激活触发器,而...

    oracle 触发器

    在一个表上同时定义语句级触发器和行级触发器验证先触发那种触发器的验证sql代码

    数据中心行级和机柜级制冷架构有何优势

    房间级制冷系统无法满足新一代数据中心的冷却需求。最新一代的高负载密度和可变负载密度IT设备所产生的...本文将对比房间级、行级和机柜级制冷架构,并说明为何行级制冷架构将成为多数下一代数据中心的优选解决方案。

    实验六-触发器实验报告.doc

    行级触发器中引用表数据 在行级触发器中,使用伪记录来表示旧数据:old和新数据:new 引用示例::new.customer_name, :old.customer_name 3. 行级触发器中的谓词 在一个多条件触发的触发器中,使用谓词可以区分当前...

    详解oracle中通过触发器记录每个语句影响总行数

    详解oracle中通过触发器记录每个语句影响总行数 需求产生:  业务系统中,有一步“抽数”流程,就是把一些数据从...触发器分为“语句级触发器”和“行级触发器”。语句级是每一个语句执行前后触发一次操作,如果我在

    Oracle触发器用法实例详解

    这里面需要说明一下,触发器可以分为语句级触发器和行级触发器。详细的介绍可以参考网上的资料,简单的说就是语句级的触发器可以在某些语句执行前或执行后被触发。而行级触发器则是在定义的了触发的表中的行数据改变...

    实验4答案-触发器.sql

    为LoanT表创建一个INSERT语句级触发器,当有新的贷款记录插入时,需要及时更新LoanNum表中该法人的贷款次数。 2、创建一个AFTER行级触发器,当对LoanT表的贷款金额(Lamount)进行修改时,若金额减少了10%,则将...

    oracle触发器详解

    oracle触发器详解,对初步学习数据库的人有很大的帮助

    oracle触发器使用,很详细

    触发器使用教程和命名规范 1 1,触发器简介 1 2,触发器示例 2 3,触发器语法和功能 3 ...7,例四:语句级触发器之一 8 8,例五:语句级触发器之二 9 9,例六:用包封装触发器代码 10 10,触发器命名规范 11

    关于采用Oralce行级安全策略解决应用系统数据权限的论述

    我们在开发应用系统时,经常遇到这样的问题:用户只被允许访问某张表的一部分数据,而且无论使用哪个界面,都只能访问这一部分数据。比如,用户A只能访问装货港是上海的委托。通常我们会在SQL语句中加入条件来过滤...

    第9章_触发器.ppt

    1、了解触发器的类型及各种触发器的功能。 2、掌握各类触发器的创建方法及执行流程。 3、熟悉触发器谓词的使用。 4、重点掌握行级触发器的创建和标识符的使用 方法。

    实验二十五触发器

    网络数据库的触发器章节。又不太懂的同学可以下载下来研究下。

    trigger触发器trigger触发器trigger触发器

    --行级触发器 create or replace trigger insert_person after insert on person for each row begin insert into person2 values(:new.id,:new.name,:new.password); end; create or replace trigger update_...

    触发器的建立使用

    发器是一种特殊的存储过程,它在执行语言事件执行时自动生效。

    为何行级制冷架构将成为下一代数据中心的优选方案

    房间级制冷系统无法满足新一代数据中心的冷却需求。最新一代的高负载密度和可变负载密度IT设备所产生的...本文将对比房间级、行级和机柜级制冷架构,并说明为何行级制冷架构将成为多数下一代数据中心的优选解决方案。

    数据库-触发器

    简要介绍触发器,触发器的种类,定义,使用方法。

    MySQL中的行级锁、表级锁、页级锁

    在计算机科学中,锁是在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制中保证对互斥要求的满足。 在DBMS中,可以按照锁的粒度把数据库锁分为行级锁(INNODB引擎)、表级锁(MYISAM引擎)和页级锁(BDB...

    oracle 触发器方式实现行ID自增加

    oracle 触发器方式实现行ID自增加介绍的很详细! 大家好好学习啊

Global site tag (gtag.js) - Google Analytics