触发器是一种 特殊的存储过程,不同的是存储过程要用CALL来调用,而触发器不需要使用CALL也不需要手工启动,只要当一个预定义的事件发生时,就会被MYSQL自动调用。它在插入,删除或修改特定表中的数据时触发执行,它比数据库本身的标准功能有更精细和更复杂的数据控制能力。它是一种与表操作有关的数据库对象,当触发器所在表上出现指定事件时,将调用该对象,即表的操作事件触发表上的触发器的执行。
创建触发器:
创建触发器语法如下:
CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EACH ROW tigger_stmt
其中:
trigger_name:标识触发器名称,由用户自定义
trigger_time :标识触发时机,取值为BEFORE或AFTER,以指明触发程序是在激活它的语句之前或之后触发
trigger_event:标识触发事件,取值为INSERT,UPDATE或DELETE
tbl_name:标识建立触发器的表名,即在哪张表上建立触发器
trigger_stmt:触发器程序体,可以是一句sql语句,或者用BEGIN和END包含的多条语句。触发程序是与表有关的命名数据库对象,当表上出现特定事件时,将激活该对象。触发程序与命名为tbl_name的表相关。tbl_name必须引用永久性表。
由此可见,我们可以建立6种触发器,即BEFORE INSERT,BEFORE UPDATE,BDFORE DELETE,AFTER INSERT,AFTER UPDATE,AFTER DELETE。另外,我们不能在同一张表上建立2个相同类型的触发器,因此在一个表上最多建立6个触发器。
接下来我们详细了解下trigger_event:
mysql除了对INSERT,UPDATE,DELETE基本操作进行定义外,还定义了LOAD DATA和REPLACE语句,这两种语句也能引起上述6种类型的触发器的触发。
LOAD DATA语句用于将一个文件装入到一个数据表中,相当于一系列的INSERT操作。
REPLACE语句一般来说和INSERT语句很像,只是在表中有primary key或unique索引时,如果插入的数据和原来primary key和unique索引一致时,会先删除原来的数据,然后增加一条新数据,也就是说,一条REPLACE语句有时等价于一条INSERT语句,有时候等价于一条DELETE语句加上一条INSERT语句。
trigger_event指明了激活触发程序的语句的类型,可以是下述值之一:
INSERT:将新行插入表时激活触发器程序,例如通过INSERT,LOAD DATA,和REPLACE语句。
UPDATE:更改某一行时激活触发程序,例如通过UPDATE语句。
DELETE:从表中删除某一行时激活触发程序,例如,通过DELETE和REPLACE语句。这里我们要注意trigger_event与以表操作方式激活触发器程序的sql语句并不很类似,这点很重要。例如,关于INSERT的BEFORE触发程序不仅能被INSERT程序激活,也能被LOAD DATA语句激活。
删除触发器:
DROP TRIGGER [schema_name.]trigger_name
如上是舍弃触发器程序,方案名称(schema_name)是可选的,如果省略了方案,将从当前方案中舍弃触发程序。舍弃触发器程序语句需要super权限。
上述我们提到了BEGIN...END语句,我们来说说他们的用法:
在mysql中,BEGIN...END语句的语法为:
BEGIN
[statement_list]
END
其中,statement_list代表一个或多个语句的列表,列表内的每条语句都必须用;来结尾,而在mysql中分号是语句结束的标识符,遇到分号表示该段语句一结束,mysql可以开始执行了,因此,解释器遇到statement_list中的分号后就开始执行,然后会报出错误,因为没有找到和BEGIN拼配的END.这时就会用到DELIMITER(定界符,分隔符的意思)命令,它是一条命令,不需要语句结束标识,语法为:
DELIMITER new_delemiter
其中new_delemiter为一个或多个长度的符号,默认的是分号,我们可以修改为其他符号$:DELIMITER $.在这之后的语句以分号结束,解释器不会有什么反应,只有遇到了$才认为是语句结束。注意,使用完之后,我们还得把它给改回来。
我们来看看一个具体的使用BEGIN...END的实例:
接下来我们看一个创建触发器的实例:
我们假设系统中有两个表:
班级表:class(班级号 classID,班内学生数stuCount)
学生表:student(学号 stuID,所属班级号 calssID)
我们要创建触发器来使班级表中的班内学生数随着学生的添加自动更新,代码如下:
DELIMITER $
create trigger tri_stuInsert after insert
on student for each row
begin
declare c int;
set c =(select stuCount from class where classID=new.classID);
update class set stuCount =c+1 where classID =new.classID);
end$
DELIMITER ;
我们来说说上面的变量。在mysql中,使用DECLARE来定义一局部变量,该变量只能在BEGIN...END复合语句中使用,并且应该定义在复合语句的开头,也就是其他语句之前,语法是:declare var_name[...]type[DEFAULT value].其中,var_name为变量名称,同sql语句一样,变量名不区分大小写,type为mysql支持的任何数据类型,可以同时定义多个同类型的变量,用逗号隔开,变量初始值为NULL,如果需要可以使用DEFAULT子句提供默认值,值可以是一个表达式。对变量赋值采用set语句,语法为:set val_name=expr[]...
我们在上述示例中还用到了NEW关键字,下面我们就来说说NEW和OLD关键字:
在mysql中用他们来表示触发器的所在表中,触发了触发器的那一行数据。
在INSERT触发器中,NEW用来表示将要(BEFORE)或已经(AFTER)插入的新数据
在UPDATE型触发器中,OLD用来表示将要或已经被修改的数据,NEW用来表示将要或已经修改为的新数据
在DELETE型触发器中,OLD用来表示将要或已经被删除的原数据
使用方法是:new.columnName(columnName是相应的某一列名)
另外,old是只读的,而new则可以在触发器中使用set赋值,这样不会再次触发触发器,造成循环调用(例如每插入一个学生前都在其学号前加“2016”)。
查看触发器:
查看触发器是指数据库中已存在的触发器的定义,状态,语法等信息。我们可以使用SHOW TRIGGERS 和在TRIGGERS表中查看触发器信息。
(1)SHOW TRIGGERS
(2)在information_schema数据库的TRIGGERS表中查看触发器信息:
select * from 'information_schema'.'TRIGGERS' where 'TEIGGER_NAME'='ins_sum'
以上就是自己目前所交接触发器的基本操作,随着以后深入的了解,还会进一步学习触发器。