这是最好的时代,这是最坏的时代,这是智慧的时代,这是愚蠢的时代;这是信仰的时期,这是怀疑的时期;这是光明的季节,这是黑暗的季节;这是希望之春,这是失望之冬;人们面前有着各样事物,人们面前一无所有;人们正在直登天堂;人们正在直下地狱。 我也要与时俱进了,被itpub2.0牵着尾巴,拼命的奔跑,不停的灌水...

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

上一篇 / 下一篇  2008-01-30 00:37:30 / 个人分类:数据库专区

查看( 73 ) / 评论( 2 )
原来总是对触发器的几种写法和执行先后顺序感到困惑,找了个时间把Oracle的官方文档看了一下,然后做了几个例子,终于有点明白了。:
bVXPMf9@y0Types of Triggers
8AH'b;{ AA0触发器类型
6e)} OP"Yh3OT0Row Triggers and Statement Triggers
f{ z#i/w0[Z+N^0行级触发器和语句级触发器ITPUB个人空间0? j3dS_\C
BEFORE and AFTER Triggers
esV^ O0BEFORE和AFTER触发器
Cy P!H C/q0dN+gcL0INSTEAD OF Triggers
&hn)K!Q-j"i"o0INSTEAD OF触发器
a~}'R'n Q ex-I5?0Triggers on System Events and User EventsITPUB个人空间b.a{ f(mH6b!D#\
系统事件和用户事件触发器ITPUB个人空间})ix.{[;ah*}!b'|
--后面两种暂时不讨论
Bk \5S'KB0Trigger Type Combinations
o1A(OBx&p(O0组合触发器类型ITPUB个人空间k#i9aQ0W/N(I
Using the options listed previously, you can create four types of row and statement triggers:ITPUB个人空间9G/G1t^:]V
根据前面所列的选项,我们能够创建四种类型的行级和语句级触发器
o]!ku0Md0BEFORE statement trigger
+HD-YA(pAY*FN0BEFORE 语句级触发器ITPUB个人空间+| r4n)xCH
Before executing the triggering statement, the trigger action is run.
~n2y)fgaG0执行触发SQL语句之前,就会激活触发器动作。ITPUB个人空间B#s[M5yb ^
BEFORE row trigger
r!?V/d6yi g0BEFORE 行级触发器ITPUB个人空间-` N\+R:TAcC5YpG q
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.
q:x*bLZY0在修改由触发SQL语句影响的每一行记录之前或者在检查完整性约束之前,将会执行触发动作。ITPUB个人空间 Q2lhX V
AFTER row trigger
gs.xCHbe0AFTER 行级触发器ITPUB个人空间P9HWU"d`G#`3S
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.ITPUB个人空间+F&d ~n(r
在修改由触发SQL语句影响的每一行记录之后或者在满足完整性约束之后,将会执行触发动作。和BEFORE行级触发器不同,AFTER行级触发器将会锁定记录。
H`2PeT\+^0AFTER statement trigger
\'T8fYx Ce|+C0AFTER 语句级触发器
0P?@ Dn0After executing the triggering statement and applying any deferred integrity constraints, the trigger action is run.
)UmeW8d,fT,{t+]0在执行完毕触发SQL语句之后和确保不违反完整性约束的情况下,将会执行该触发动作。
Q^7` T$h u!B01. 创建一张数据表和一张记录触发动作的表,再创建一个序列用来记录各个触发器触发动作的先后顺序。ITPUB个人空间 ww _/?!upER3@
CREATE TABLE test
P I!K6{ B P~~^t0(ITPUB个人空间#OY^J(aOZ(Vv
  TestID    INTEGER NOT NULL,
,v;Ve'hM0  TestName  VARCHAR2(20) NOT NULL,ITPUB个人空间;A*M#~LU
  CreateDT  DATE,
uwMb+q)z0  UpdateDT  DATEITPUB个人空间'S1P#DpqecT
);
9gC_M#L"A F0ALTER TABLE test ADD CONSTRAINT TestPrimaryKey PRIMARY KEY (TestID);
b*}o6f'E9iD0CREATE TABLE TriggerLog
ji*y uLU#lM@0(ITPUB个人空间7Pi&} aL Zp
  SeqID        NUMBER(20,0),ITPUB个人空间j&a"^*Ok
  TriggerName  VARCHAR2(50),ITPUB个人空间+X1O+`_L"h:a-zrM
  TableName    VARCHAR2(30),ITPUB个人空间U'} |Tk.\
  FieldName    VARCHAR2(30),ITPUB个人空间YDg&dWX-i)A"iix
  FieldValue   VARCHAR2(30),
isj&i8Az} M!w?0[0  OperateOrder VARCHAR2(30),
r$d"|!`'sctH]h0  OperateType  VARCHAR2(30),ITPUB个人空间!oU(]'EY'r
  OperateDT    DATE
+[(T$C6j#G,nP0);
-d)f$BtQBf3?uE0-- Create sequenceITPUB个人空间7Y7?T\2N-?AI
CREATE SEQUENCE SeqTriggerLogITPUB个人空间_1k!wv$S{T8v
MINVALUE 1ITPUB个人空间U:E ^:D6X-T8q9\
MAXVALUE 100000ITPUB个人空间vF!Mr*s,O&v1N
START WITH 1ITPUB个人空间nY T3B*@+i"L
INCREMENT BY 1;ITPUB个人空间$v$`@6n,z
2. 创建4个触发器,分别为前置后置行级语句级的组合
R{|l S~_#? ZJ0CREATE OR REPLACE TRIGGER TrgBefInsStateOnTest
'cX7i%@a9ze)_0  BEFORE INSERT ON test  ITPUB个人空间6K+S7QC H;Yo LL:~5f
BEGIN
VP!rb$|/H0  INSERT INTO TriggerLog VALUES
[ nL!u5WA,_^0    (SeqTriggerLog.NextVal,'TrgBefInsStateOnTest','test','TestName',' ','BEFORE','INSERT',SYSDATE);
hsC.r L/\ mh @0END TrgBefInsStateOnTest;
_TS8c-K$Y0--在Before行级语句上可以对受影响的记录进行预处理
n.SM'u_ q ^~9c0CREATE OR REPLACE TRIGGER TrgBefInsRowOnTestITPUB个人空间-m$P-G8\"K)w
  BEFORE INSERT ON test  
#H2Crcv5U(P/s)E0  FOR EACH ROW BEGIN
nSb7G]-MD0    :new.CreateDT:=SYSDATE;
]7`2?(U%q0    INSERT INTO TriggerLog VALUESITPUB个人空间7sr)cRjS
      (SeqTriggerLog.NextVal,'TrgBefInsRowOnTest','test','TestName',:new.TestName,'BEFORE','INSERT',SYSDATE);
XJfI]1f#~"m1G;\0  END TrgBefInsRowOnTest;
Ep"XT/w H+D:I0--在After行级语句上可以进行相关完整性数据维护,当然对UPDATE更明显一些ITPUB个人空间Q+? ?/F3Ht z'y#Mc
CREATE OR REPLACE TRIGGER TrgAftInsRowOnTestITPUB个人空间$h K Y.Tfx:Ot
  AFTER INSERT ON test  
!_ Kvd+p(F0  FOR EACH ROW BEGINITPUB个人空间E.b(S%i,JP(E9l,~
    INSERT INTO TriggerLog VALUES
&|1EE;H8Rnv,I0      (SeqTriggerLog.NextVal,'TrgAftInsRowOnTest','test','TestName',:new.TestName,'AFTER','INSERT',SYSDATE);
.R+p)hg!a5@9aF0  END TrgAftInsRowOnTest;ITPUB个人空间 qs~$O|AG2Nb.t;W/W
CREATE OR REPLACE TRIGGER TrgAftInsStateOnTestITPUB个人空间 J*|Yf"U!yO8p9V
  AFTER INSERT ON test  
UD(w t/TO(y0BEGINITPUB个人空间g,vA(mp&oC
  INSERT INTO TriggerLog VALUES
1Y1p|1V+{B;zA0    (SeqTriggerLog.NextVal,'TrgAftInsStateOnTest','test','TestName',' ','AFTER','INSERT',SYSDATE);ITPUB个人空间3?,huo8S5^
END TrgAftInsStateOnTest;ITPUB个人空间 ^-l5_X.Cu.P4D
3. 首先一次性插入多条记录,然后分别单独插入两条记录,看看其运行的先后ITPUB个人空间bi+~"w%E?dN$bsa
INSERT INTO test(testid,testname) SELECT column_id,column_name FROM user_tab_columns WHERE table_name='TEST';  
f z1J9huV3Ei;a({V#I;K0COMMIT;
~c5m-g-})E!p6j4Ji9\0INSERT INTO test(testid,testname) VALUES(5,'AAA');
B4[ T^ xG Md~0INSERT INTO test(testid,testname) VALUES(6,'BBB');
]#N:`8Pr X+h6c0COMMIT;
'lo:X*Dm&v:U0SELECT * FROM test;ITPUB个人空间4Ww5aVp^\'r|
SELECT * FROM TriggerLog;ITPUB个人空间y&_!m@ P8K*?

$A*tC A9Jw'n&CV0最终执行触发器的先后顺序如下ITPUB个人空间M9H-Rnw8Nx{
1. 首先执行Before Insert State触发器,每条语句仅执行一次ITPUB个人空间lf1aiz
2. 其次执行Before Insert Row触发器,为SQL语句影响的记录数的多少ITPUB个人空间 s c E(K&S5M*B:hB
3. 再次执行After Insert Row触发器,为SQL语句影响的记录数的多少
-j7uS$j2Dn9y04. 最后执行After Insert State触发器,每条语句仅执行一次ITPUB个人空间7Dv!^DTz#qp,w

-B\*L4^%@#n;z%JP U8L0[本帖最后由 bq_wang 于 2008-1-30 00:34 编辑]

TAG:

wangfans的个人空间 wangfans 发布于2008-01-30 09:38:42
先顶一下,然后慢慢学习  
megan123发布于2008-01-30 16:05:19
先存下来
我来说两句

(可选)

日历

« 2008-10-13  
   1234
567891011
12131415161718
19202122232425
262728293031 

数据统计

  • 访问量: 25685
  • 日志数: 66
  • 建立时间: 2007-12-07
  • 更新时间: 2008-09-28

RSS订阅

Open Toolbar