原文链接:http://www.jb51.cc/article/p-skrqcnwv-tu.html
-----------------------------------------------------------
Oracle触发器格式:
- CREATE[ORREPLACE]TRIGGERtrigger_name
- BEFORE|AFTERINSERT|UPDATE|DELETEONtable_name
- [FOREACHROW]
- DECLAREarg_nametype[CONSTANT][NOTNULL][:=value]
- BEGIN
- pl/sql语句
- END
MysqL触发器格式:
CREATETRIGGERtrigger_name
BEGIN
DECLAREarg_name1[,arg_name2,...]type[DEFAULTvalue]
sql语句
创建测试表(建表语句适用于Oracle、MysqL):
- CREATETABLEtest(
- idint,
- namevarchar(10),
- agebirthdaydate,0);background-color:inherit;">descriptionvarchar(50),153);font-size:14px;border:none;">PRIMARYKEY(id)
- );
- TABLEtest_log(
- dealtimedealtypeKEY(`id`)
- );
Oracle触发器和MysqL触发器的区别如下:
1,创建语句格式不同
Oracle:create or replace(Oracle客户端需要手动提交,MysqL客户端设置的自动提交)
sql>CREATEORREPLACETRIGGERtrigger_test_insert
2BEFOREINSERTONtest
3FOREACHROW
4BEGIN
5insertintotest_logvalues(1,sysdate,'insert');
6END;
7/
Triggercreated
sql>insertintotest(id,name)values(1,'name');
1rowinserted
sql>commit;
Commitcomplete
sql>select*fromtest_log;
IDDEALTIMEDEALTYPE
------------------------------------------------------------
12014/7/161insert
MysqL:不包含or replace
MysqL>delimiter$
CREATETRIGGERtrigger_test_insert
BEFOREINSERTONtest
FOREACHROW
insertintotest_logvalues(1,now(),'insert');
END$
delimiter;
QueryOK,0rowsaffected
MysqL>insertintotest(id,1rowaffected
MysqL>select*fromtest_log;
+----+------------+----------+
|id|dealtime|dealtype|
|1|2014-07-16|insert|
1rowinset
2,变量的声明位置、声明格式均不相同
Oracle:声明位置在触发时的执行语句块外部
通过%type的方式将变量与表特定字段类型相关联的好处是:在某些情况下,修改该字段类型时不需要修改触发器(如:字段类型由varchar(10)修改为varchar(20)时,不需要修改触发器)
sql>CREATETRIGGERtrigger_test_insert
4DECLAREid1intdefault1;
5id2int:=1;
6id3test_log.id%type:=1;
7BEGIN
8insertintotest_logvalues(id1+id2+id3,0);background-color:inherit;">9END;
10/
Triggercreated
1rowinserted
sql>commit;
Commitcomplete
sql>select*fromtest_log;
IDDEALTIMEDEALTYPE
------------------------------------------------------------
32014/7/161insert
MysqL:声明位置在触发时的执行语句块内部
DECLAREid1intDEFAULT1;
DECLAREid2intDEFAULT1;
insertintotest_logvalues(id1+id2,0rowsaffected
MysqL>select*fromtest_log;
+----+------------+----------+
|id|dealtime|dealtype|
|2|2014-07-16|insert|
3,注释符不同
Oracle:使用/* */作为注释符,或者两个连续的-作为注释符(PL/sql块中至少包含一条可执行语句)
CREATEORREPLACETRIGGERtrigger_test_insert
BEFOREINSERTONtest
FOREACHROW
BEGIN
--justatest
/*justatest*/
null;
END;
/
MysqL:使用/* */作为注释符,或者两个连续的-后加一个空格作为注释符
delimiter$
TRIGGERtrigger_test_insert
ONtest
FOREACHROW
BEGIN
--两个‘-’后面必须带空格
END$
delimiter;
4,赋值语法不同
Oracle:可以通过select into语句赋值,还可以通过:=进行赋值
4DECLAREidint;
5BEGIN
6selectmax(tl.id)intoidfromtest_logtl;
7ifidisnullthen
8id:=1;
9else
10id:=id+1;
11endif;
12insertintotest_logvalues(id,0);background-color:inherit;">13END;
14/
MysqL:可以通过select into语句赋值,还可以通过set语句进行赋值
DECLAREidint;
selectmax(tl.id)intoidfromtest_logtl;
ifidisnullthen
setid=1;
else
setid=id+1;
endif;
insertintotest_logvalues(id,0);background-color:inherit;">END$
delimiter;
5,对于行级更新触发器
Oracle:原有行用:old表示,新行用:new表示
sql>CREATEORREPLACETRIGGERtrigger_test_update
2BEFOREUPDATEONtest
5:new.description:='changename['||
6:old.name||']->['||
7:new.name||']';
8END;
9/
sql>updatetestsetname='bbb'whereid=1;
1rowupdated
sql>selectid,name,descriptionfromtest;
IDNAMEDESCRIPTION
-----------------------------------------------------------------------
1bbbchangename[aaa]->[bbb]
MysqL:原有行用old表示,新行用new表示
CREATETRIGGERtrigger_test_update
BEFOREUPDATEONtest
setnew.description=concat('changename[',
old.name,']->[',new.name,']');
MysqL>updatetestsetname='bbb'whereid=1;
Rowsmatched:1Changed:1Warnings:0
MysqL>selectid,descriptionfromtest;
+----+------+-------------------------+
|id|name|description|
|1|bbb|changename[aaa]->[bbb]|
6,其它一些语法、函数上的区别
Oracle:使用if...elsif...else
MysqL:使用if...elseif...else
Oracle:sysdate指代系统时间
MysqL:sysdate()指代系统时间