公布MySQL 5.0 新特征教程 触发器:第一讲
如果你在一个遵循GPL的自由(开源)项目中使用MySQL,那么你可以遵循GPL协议使用MySQL。然而,如果你的项目不是在GPL协议下的话,你必须为使用MySQL来支付许可费用,或者你可能因为这个因素而将你的项目改为遵循GPL。MySQLAB;翻译:陈朋奕ConventionsandStyles商定和编程作风
每次我想要演示实践代码时,我会对mysql客户真个屏幕就呈现的代码举行调剂,将字体改成Courier,使他们看起来与一般文本纷歧样(让人人区分程序代码和注释)。在这里举个例子:
mysql>DROPFUNCTIONf;
QueryOK,0rowsaffected(0.00sec)
假如实例对照年夜,则必要在某些行和段落间加正文,同时我会用将"<--"标记放在页面的右侧以暗示夸大。比方:
mysql>CREATEPROCEDUREp()
->BEGIN
->/*Thisproceduredoesnothing*/<--
->END;//
QueryOK,0rowsaffected(0.00sec)
偶然候我会将例子中的"mysql>"和"->"这些体系显现往失落,你能够间接将代码复制到mysql客户端程序中(假如你如今所读的不是电子版的,能够在mysql.com网站下载相干剧本)
以是的例子都已在Suse9.2linux、Mysql5.0.3大众版上测试经由过程。在您浏览本书的时分,Mysql已有更高的版本,同时能撑持更多OS了,包含Windows,Sparc,HP-UX。因而这里的例子将能一般的运转在您的电脑上。但假如运转仍旧呈现妨碍,能够征询你熟悉的资深Mysql用户,如许就可以失掉对照好的撑持和匡助。
WhyTriggers为何要用触发器
我们在MySQL5.0中包括对触发器的撑持是因为以下缘故原由:
MySQL初期版本的用户临时有必要触发器的请求。
我们已经允诺撑持一切ANSI尺度的特征。
您可使用它来反省或防备坏的数据进进数据库。
您能够改动大概作废INSERT,UPDATE和DELETE语句。
您能够在一个会话中监督数据改动的举措。
在这里我假定人人都读过"MySQL新特征"丛书的第一集--"MySQL存储历程",那末人人都应当晓得MySQL至此存储历程和函数,那是很主要的常识,由于在触发器中你可使用在函数中利用的语句。出格举个例子:
复合语句(BEGIN/END)是正当的.
流把持(Flow-of-control)语句(IF,CASE,WHILE,LOOP,WHILE,REPEAT,LEAVE,ITERATE)也是正当的.
变量声明(DECLARE)和指派(SET)是正当的.
同意前提声明.
非常处置声明也是同意的.
可是在这里要记着函数有受限前提:不克不及在函数中会见表.因而在函数中利用以下语句长短法的。
ALTERCACHEINDEXCALLCOMMITCREATEDELETE
DROPFLUSHPRIVILEGESGRANTINSERTKILL
LOCKOPTIMIZEREPAIRREPLACEREVOKE
ROLLBACKSAVEPOINTSELECTFROMtable
SETsystemvariableSETTRANSACTION
SHOWSTARTTRANSACTIONTRUNCATEUPDATE
在触发器中也有完整一样的限定.
触发器绝对而言对照新,因而会有(bugs)缺点.以是我在这里给人人告诫,就像我在存储历程书中所说那样.不要在含有主要数据的数据库中利用这个触发器,假如必要的话在一些以测试为目标的数据库上利用,同时在你对表创立触发器时确认这些数据库是默许的。
Syntax语法
1.Syntax:Name语法:定名划定规矩
CREATETRIGGER<触发器称号><--
{BEFORE|AFTER}
{INSERT|UPDATE|DELETE}
ON<表称号>
FOREACHROW
<触发器SQL语句>
触发器必需着名字,最多64个字符,大概前面会附有分开符.它和MySQL中其他工具的定名体例基础相象.
这里我有个习气:就是用表的名字+_+触发器范例的缩写.因而假如是表t26,触发器是在事务UPDATE(参考上面的点(2)和(3))之前(BEFORE)的,那末它的名字就是t26_bu。
2.Syntax:Time语法:触发工夫
CREATETRIGGER<触发器称号>
{BEFORE|AFTER}<--
{INSERT|UPDATE|DELETE}
ON<表称号>
FOREACHROW
<触发的SQL语句>
触发器有实行的工夫设置:能够设置为事务产生前或后。
3.Syntax:Event语法:事务
CREATETRIGGER<触发器称号>
{BEFORE|AFTER}
{INSERT|UPDATE|DELETE}<--
ON<表称号>
FOREACHROW
<触发的SQL语句>
一样也能设定触发的事务:它们能够在实行insert、update或delete的过程当中触发。
4.Syntax:Table语法:表
CREATETRIGGER<触发器称号>
{BEFORE|AFTER}
{INSERT|UPDATE|DELETE}
ON<表称号><--
FOREACHROW
<触发的SQL语句>
触发器是属于某一个表的:当在这个表上实行拔出、更新或删除操纵的时分就招致触发器的激活.
我们不克不及给统一张表的统一个事务布置两个触发器。
5.Syntax:Granularity语法:(:(步长)触发距离
CREATETRIGGER<触发器称号>
{BEFORE|AFTER}
{INSERT|UPDATE|DELETE}
ON<表称号>
FOREACHROW<--
<触发的SQL语句>
触发器的实行距离:FOREACHROW子句关照触发器每隔一行实行一次举措,而不是对全部表实行一次。
6.Syntax:Statement语法:语句
CREATETRIGGER<触发器称号>
{BEFORE|AFTER}
{INSERT|UPDATE|DELETE}
ON<表称号>
FOREACHROW
<触发的SQL语句><--
触发器包括所要触发的SQL语句:这里的语句能够是任何正当的语句,包含复合语句,可是这里的语句受的限定和函数的一样。
Privileges权限
你必需具有相称年夜的权限才干创立触发器(CREATETRIGGER)。假如你已是Root用户,那末就充足了。这跟SQL的尺度有所分歧,我也但愿能尽快改成尺度的。
因而鄙人一个版本的MySQL中,你完整有大概看到有一种叫做CREATETRIGGER的新权限。然后经由过程如许的办法付与:
GRANTCREATETRIGGERON<表称号>TO<用户或用户列表>;
也能够经由过程如许发出权限:
REVOKECREATETRIGGERON<表称号>FROM<用户或用户列表>;
ReferringtoOLDandNEWcolumns关于旧的和新创立的列的标识
在触发器的SQL语句中,你能够联系关系表中的恣意列。但你不克不及仅利用列的称号往标识,那会使体系搅浑,由于那边大概会有列的新名(这大概恰是你要修正的,你的举措大概恰是要修正列名),另有列的旧名存在。因而你必需用如许的语法来标识:
"NEW.column_name"大概"OLD.column_name".如许在手艺上处置(NEW|OLD.column_name)新和旧的列名属于创立了过渡变量("transitionvariables")。
关于INSERT语句,只要NEW是正当的;关于DELETE语句,只要OLD才正当;而UPDATE语句能够在和NEW和OLD同时利用。上面是一个UPDATE中同时利用NEW和OLD的例子。
CREATETRIGGERt21_au
BEFOREUPDATEONt22
FOREACHROW
BEGIN
SET@old=OLD.s1;
SET@new=NEW.s1;
END;//
如今假如t21表中的s1列的值是55,那末实行了"UPDATEt21SETs1=s1+1"以后@old的值会酿成55,而@new的值将会酿成56。
ExampleofCREATEandINSERTCREATE和INSERT的例子
CREATEtablewithtrigger创立有触发器的表
这里一切的例程中我都假定人人的分开符已设置成//(DELIMITER//)。
CREATETABLEt22(s1INTEGER)//
CREATETRIGGERt22_bi
BEFOREINSERTONt22
FOREACHROW
BEGIN
SET@x=Triggerwasactivated!;
SETNEW.s1=55;
END;//
在最入手下手我创立了一个名字为t22的表,然后在表t22上创立了一个触发器t22_bi,当我们要向表中的行拔出时,触发器就会被激活,实行将s1列的值改成55的举措。
INSERTontablewithatrigger利用触发器实行拔出举措
mysql>INSERTINTOt22VALUES(1)//
让我们看假如向表t2中拔出一行数据触发器对应的表会怎样?
这里的拔出的举措是很罕见的,我们不必要触发器的权限来实行它。乃至不必要晓得是不是有触发器联系关系。
mysql>SELECT@x,t22.*FROMt22//
+------------------------+------+
|@x|s1|
+------------------------+------+
|Triggerwasactivated!|55|
+------------------------+------+
1rowinset(0.00sec)
人人能够看到INSERT举措以后的了局,和我们预期的一样,x标志被修改了,同时这里拔出的数据不是我们入手下手输出的拔出数据,而是触发器本人的数据。
Exampleofa"check"constraint
"check"完全性束缚例子
Whatsa"check"constraint甚么是"check"束缚
在尺度的SQL言语中,我们能够在(CREATETABLE)创立表的过程当中利用"CHECK(condition)",
比方:
CREATETABLEt25
(s1INT,s2CHAR(5),PRIMARYKEY(s1),
CHECK(LEFT(s2,1)=A))
ENGINE=INNODB;
这里CHECK的意义是"当s2列的最右边的字符不是A时,insert和update语句城市不法",MySQL的视图不撑持CHECK,我团体是很但愿它能撑持的。但假如你很必要在表中利用如许的功效,我倡议人人利用触发器来完成。
CREATETABLEt25
(s1INT,s2CHAR(5),
PRIMARYKEY(s1))
ENGINE=INNODB//
CREATETRIGGERt25_bi
BEFOREINSERTONt25
FOREACHROW
IFLEFT(NEW.s2,1)ATHENSETNEW.s1=0;ENDIF;//
CREATETRIGGERt25_bu
BEFOREUPDATEONt25
FOREACHROW
IFLEFT(NEW.s2,1)ATHENSETNEW.s1=0;ENDIF;//
我只必要利用BEFOREINSERT和BEFOREUPDATE语句就好了,删除触发器不会对表有影响,同时AFTER的触发器也不克不及修正NEW的历程变量(transitionvariables)。为了激活触发器,我实行了向表中的行拔出s1=0的数据,以后只需实行切合LEFT(s2,1)A前提的举措城市失利:
INSERTINTOt25VALUES(0,a)/*primingthepump*///
INSERTINTOt25VALUES(5,b)/*getserror23000*///
DontBelieveTheOldMySQLManual
该丢弃旧的MySQL的手册了
我在这里告诫人人不要信任已往的MySQL手册中所说的了。我们已往失落了关于触发器的毛病的语句,可是仍然有良多旧版本的手册在网上,举个例子,这是一个德国的Url上的:
http://dev.mysql.com/doc/mysql/de/ANSI_diff_Triggers.html.
这个手册上说触发器就是存储历程,忘记吧,你也已瞥见了,触发器就是触发器,而存储历程仍是存储历程。
手册上还说触发器能够从其他表下去删除,大概是当你删除一个事件的时分引发,不管他说的是甚么意义,忘记吧,MySQL不会往完成这些的。
最初关于说利用触发器会对查询速率发生影响的说法也是错的,触发器不会对查询发生任何影响。
Bugs
(欠好的器材就不翻译了)
OnDecember142004,Ididan"AdvancedSearch"inhttp://bugs.mysql.comfortriggeror
triggers,Ifoundthattherewere17activebugsasofthatdate.Ofcoursetheymightdisappear
beforeyoureadthis,butjustincasetheyhavent,Illmentiontheimportantones.Iftheyrestill
there,youllhavetoworkaroundthemwhenyouretryingtriggers.
Bug#5859DROPTABLEdoesnotdroptriggers.
(删除表的时分没有主动删除触发器)
Whenyoudropatable,droppingthetablestriggersshouldbeautomatic.
Bug#5892Triggershavethewrongnamespace.
(触发器的定名空间有错,你必需在后面加上表的名字才干删除触发器,上面是例子)
Youhavetosay"DROPTRIGGER<tablename>.<triggername>".
Thecorrectwayis"DROPTRIGGER<triggername>".
Bug#5894Triggerswithalteredtablescausecorruptdatabases.
(触发器对表的改动大概会形成数据库数据被损坏)
Donotalteratablethathasatriggeronit,untilyouknowthisisfixed.
Conclusion最初
到了书的最初,我以为不必要给人人温习大概是重温一下了,由于信任人人能够很轻松的记着下面所说的。
对免费版的用户也具有充足的支持服务。在dev.mysql.com上,一个大型的MySQL学习教程强大社区用户和开发者可以讨论所有关于MySQL的事情。这个站点拥有博客、指南、视频、技术交流会、白皮书和论坛等方式的交流。 发几份SQL课件,以飨阅者 varchar(max)\\\\nvarchar(max)类型的引入大大的提高了编程的效率,可以使用字符串函数对CLOB类型进行操作,这是一个亮点。 其实可以做一下类比,Oracle等数据库产品老早就支持了java编程,而且提供了java池参数作为用户配置接口。但是现在有哪些系统大批使用了java存储过程?!连Oracle自己的应用都不用为什么?! 很多书籍啊,不过个人认为看书太慢,还不如自己学。多做实际的东西,就会遇到很多问题,网上搜下解决问题。不断重复这个过程,在配合sql的F1功能。 连做梦都在想页面结构是怎么样的,绝非虚言 多走走一此相关论坛,多看一些实例开发,多交流0经验,没什么的,我也是刚学没多久!加油 分区表效率问题肯定是大家关心的问题。在我的试验中,如果按照分区字段进行的查询(过滤)效率会高于未分区表的相同语句。但是如果按照非分区字段进行查询,效率会低于未分区表的相同语句。 连做梦都在想页面结构是怎么样的,绝非虚言
页:
[1]