日期:2011-05-02 15:44:00 来源:本站整理
MySQL5触发器教程[MySQL防范]
本文“MySQL5触发器教程[MySQL防范]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
约定和编程气势
每次我想要演示实际代码时,我会对MySQL客户端的屏幕就呈现的代码举行调整,将字体改成Courier,使他们看起来与普通文本不一样(让大家辨别程序代码和正文).在这里举个例子:
mysql> DROP FUNCTION f; Query OK, 0 rows affected (0.00 sec)假照实例对比大,则需求在某些行和段落间加注释,同时我会用将"<--"标记放在页面的右边以表示夸大.比方:
mysql> CREATE PROCEDURE p () -> BEGIN -> /* This procedure does nothing */ <-- -> END;// Query OK, 0 rows affected (0.00 sec)有时刻我会将例子中的"mysql>"和"->"这些系统显示去掉,你可以直接将代码复制到mysql客户端程序中(假如你目前所读的不是电子版的,可以在mysql.com网站下载相关脚本) 所以的例子都已经在Suse 9.2 Linux、Mysql 5.0.3大众版上测试通过.在您阅读本书的时刻,Mysql已经有更高的版本,同时能支持更多OS了,包含Windows,Sparc,HP-UX.因此这里的例子将能正常的运行在您的电脑上.但假如运行仍旧呈现弊端,可以咨询你熟习的资深Mysql用户,这样就可以得到对比好的支持和帮忙.
为什么要用触发器
我们在MySQL 5.0中包含对触发器的支持是由于以下缘由:
MySQL早期版本的用户长期有需求触发器的要求. 我们曾经答应支持全部ANSI尺度的特点. 您可以利用它来查抄或预防坏的数据进入数据库. 您可以改变大概撤消INSERT, UPDATE以及DELETE语句. 您可以在一个会话中监督数据改变的行动.在这里我假定大家都读过"MySQL新特点"丛书的第一集--"MySQL存储历程",那么大家都应当知道MySQL至此存储历程和函数,那是很重要的知识,因为在触发器中你可以利用在函数中利用的语句.分外举个例子:
复合语句(BEGIN / END)是合理的. 流掌握(Flow-of-control)语句(IF, CASE, WHILE, LOOP, WHILE, REPEAT, LEAVE,ITERATE)也是合理的. 变量声明(DECLARE)以及指派(SET)是合理的. 答应条件声明. 非常处理声明也是答应的. 但是在这里要记着函数有受限条件:不能在函数中拜候表. 因此在函数中利用以下语句是不法的. ALTER 'CACHE INDEX' CALL COMMIT CREATE DELETE DROP 'FLUSH PRIVILEGES' GRANT INSERT KILL LOCK OPTIMIZE REPAIR REPLACE REVOKE ROLLBACK SAVEPOINT 'SELECT FROM table' 'SET system variable' 'SET TRANSACTION' SHOW 'START TRANSACTION' TRUNCATE UPDATE 在触发器中也有完好一样的限制.触发器相对而言对比新,因此会有(bugs)缺陷.所以我在这里给大家告诫,就像我在存储历程书中所说那样.不要在含有重要数据的数据库中利用这个触发器,假如需求的话在一些以测试为目的的数据库上利用,同时在你对表成立触发器时确认这些数据库是默许的.
语法
1. 语法:命名法则 CREATE TRIGGER <触发器名称> <-- { BEFORE | AFTER } { INSERT | UPDATE | DELETE } ON <表名称> FOR EACH ROW <触发器SQL语句>触发器必须闻名字,最多64个字符,大概背面会附有脱离符.它和MySQL中其他对象的命名方法基本相象.
这里我有个习惯:就是用表的名字+'_'+触发器范例的缩写.因此假如是表t26,触发器是在事件UPDATE(参考下面的点(2)和(3))之前(BEFORE)的,那么它的名字就是t26_bu.
2. 语法:触发时间 CREATE TRIGGER <触发器名称> { BEFORE | AFTER } <-- { INSERT | UPDATE | DELETE } ON <表名称> FOR EACH ROW <触发的SQL语句> 触发器有履行的时间设置:可以设置为事件发生前或后. 3. 语法:事件 CREATE TRIGGER <触发器名称> { BEFORE | AFTER } { INSERT | UPDATE | DELETE } <-- ON <表名称> FOR EACH ROW <触发的SQL语句> 一样也能设定触发的事件:它们可以在履行insert、update或delete的历程中触发. 4. 语法:表 CREATE TRIGGER <触发器名称> { BEFORE | AFTER } { INSERT | UPDATE | DELETE } ON <表名称> <-- FOR EACH ROW <触发的SQL语句> 触发器是属于某一个表的:当在这个表上履行插入、 更新或删除操作的时刻就招致触发器的激活. 我们不能给同一张表的同一个事件安置两个触发器. 5. 语法:( 步长)触发隔断 CREATE TRIGGER <触发器名称> { BEFORE | AFTER } { INSERT | UPDATE | DELETE } ON <表名称> FOR EACH ROW <-- <触发的SQL语句> 触发器的履行隔断:FOR EACH ROW子句告诉触发器 每隔一行履行一次行动,而不是对整个表履行一次. 6. 语法:语句 CREATE TRIGGER <触发器名称> { BEFORE | AFTER } { INSERT | UPDATE | DELETE } ON <表名称> FOR EACH ROW <触发的SQL语句> <-- 触发器包含所要触发的SQL语句:这里的语句可以是任何合理的语句, 包含复合语句,但是这里的语句受的限制和函数的一样. Privileges权限 你必须拥有相当大的权限才能成立触发器(CREATE TRIGGER). 假如你已经是Root用户,那么就充足了.这跟SQL的尺度有所差别. 因此在下一个版本的MySQL中, 你完好有大概看到有一种叫做CREATE TRIGGER的新权限. 然后通过这样的办法赋予: GRANT CREATE TRIGGER ON <表名称> TO <用户或用户列表>; 也可以通过这样收回权限: REVOKE CREATE TRIGGER ON <表名称> FROM <用户或用户列表>;关于旧的和新成立的列的标识
在触发器的SQL语句中,你可以关联表中的肆意列.但你不能仅利用列的名称去标识,那会使系统混合,因为那边大概会有列的新名(这大概恰是你要改正的,你的行动大概恰是要改正列名),还有列的旧名存在.因此你必须用这样的语法来标识: "NEW . column_name"大概"OLD . column_name".这样在技术上处理(NEW | OLD . column_name)新和旧的列名属于成立了过渡变量("transition variables").
关于INSERT语句,只有NEW是合理的;关于DELETE语句,只有OLD才合理;而UPDATE语句可以在和NEW以及OLD同时利用.下面是一个UPDATE中同时利用NEW和OLD的例子.
CREATE TRIGGER t21_au BEFORE UPDATE ON t22 FOR EACH ROW BEGIN SET @old = OLD . s1; SET @new = NEW.s1; END;// 目前假如t21表中的s1列的值是55,那么履行了 "UPDATE t21 SET s1 = s1 + 1"之后@old的值会变成55, 而@new的值将会变成56.
Example of CREATE and INSERT CREATE和INSERT的例子 成立有触发器的表 这里全部的例程中我都假定大家的脱离符已经设置成//(DELIMITER //). CREATE TABLE t22 (s1 INTEGER)// CREATE TRIGGER t22_bi BEFORE INSERT ON t22 FOR EACH ROW BEGIN SET @x = 'Trigger was activated!'; SET NEW.s1 = 55; END;//在最开始我成立了一个名字为t22的表,然后在表t22上成立了一个触发器t22_bi,当我们要向表中的行插入时,触发器就会被激活,履行将s1列的值改成55的行动.
利用触发器履行插入行动
mysql> INSERT INTO t22 VALUES (1)//
让我们看假如向表t2中插入一行数据触发器对应的表会怎么样? 这里的插入的行动是很常见的,我们不需求触发器的权限来履行它.乃至不需求知道能否有触发器关联.
mysql> SELECT @x, t22.* FROM t22// +------------------------+------+ | @x | s1 | +------------------------+------+ | Trigger was activated! | 55 | +------------------------+------+ 1 row in set (0.00 sec)大家可以看到INSERT行动之后的后果,和我们预期的一样,x标志被窜改了,同时这里插入的数据不是我们开始输入的插入数据,而是触发器自己的数据.
"check"完好性约束例子 什么是"check"约束 在尺度的SQL语言中,我们可以在(CREATE TABLE)成立表的历程中利用"CHECK (condition)", 比方: CREATE TABLE t25 (s1 INT, s2 CHAR(5), PRIMARY KEY (s1), CHECK (LEFT(s2,1)='A')) ENGINE=INNODB;这里CHECK的意思是"当s2列的最左边的字符不是'A'时,insert和update语句城市不法",MySQL的视图不支持CHECK,我个人是很但愿它能支持的.但假如你很需求在表中利用这样的功效,我倡议大家利用触发器来实现.
CREATE TABLE t25 (s1 INT, s2 CHAR(5), PRIMARY KEY (s1)) ENGINE=INNODB// CREATE TRIGGER t25_bi BEFORE INSERT ON t25 FOR EACH ROW IF LEFT(NEW.s2,1)<>'A' THEN SET NEW.s1=0; END IF;// CREATE TRIGGER t25_bu BEFORE UPDATE ON t25 FOR EACH ROW IF LEFT(NEW.s2,1)<>'A' THEN SET NEW.s1=0; END IF;//我只需求利用BEFORE INSERT和BEFORE UPDATE语句就行了,删除了触发器不会对表有影响,同时AFTER的触发器也不能改正NEW的历程变量(transition variables).为了激活触发器,我履行了向表中的行插入s1=0的数据,之后只要履行符合LEFT(s2,1) <> 'A'条件的行动城市失利:
INSERT INTO t25 VALUES (0,'a') /* priming the pump */ // INSERT INTO t25 VALUES (5,'b') /* gets error '23000' */ // Don't Believe The Old MySQL Manual该丢弃旧的MySQL的手册了
我在这里告诫大家不要相信过去的MySQL手册中所说的了.我们已经去掉了关于触发器的错误的语句,但是仍旧有很多旧版本的手册在网上,举个例子,这是一个德国的Url上的: http://dev.mysql.com/doc/mysql/de/ANSI_diff_Triggers.HTML. 这个手册上说触发器就是存储历程,忘掉吧,你也已经瞥见了,触发器就是触发器,而存储历程还是存储历程. 手册上还说触发器可以从其他表上来删除,大概是当你删除一个事件的时刻激起,无论他说的是什么意思,忘掉吧,MySQL不会去实现这些的. 最后关于说利用触发器会对查询速度产生影响的说法也是错的,触发器不会对查询产生任何影响. 以上是“MySQL5触发器教程[MySQL防范]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |
评论内容只代表网友观点,与本站立场无关!
评论摘要(共 0 条,得分 0 分,平均 0 分)
查看完整评论