mysql--17000触发器

来源:互联网 发布:网络诽谤案例分析 编辑:程序博客网 时间:2024/05/18 03:55

定义
高级功能
举例

概述
对指定表进行指定操作时,在的同事
表的操作事件触发表上的触发器的执行。
缺点
把业务交给了数据库处理

定义

CREATE
TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
trigger_body

参数
trigger_name: 触发器的名称,
不能与已经存在的触发器重复;
trigger_time: 触发时机
可选值: { BEFORE | AFTER },表示在事件之前或之后触发;
trigger_event: 触发事件
可选值: { INSERT |UPDATE | DELETE },触发该触发器的具体事件;
tbl_name: 监听的表
trigger_body: 需要执行的sql

另外有一个限制是不能同时在一个表上建立2个相同类型的触发器,因此在一个表上最多建立6个触发器。

MySQL 除了对 INSERT、UPDATE、DELETE 基本操作进行定义外,还定义了 LOAD DATA 和 REPLACE 语句,这两种语句也能引起

上述6中类型的触发器的触发。
LOAD DATA 语句用于将一个文件装入到一个数据表中,相当与一系列的 INSERT 操作。
REPLACE 语句一般来说和 INSERT 语句很像,只是在表中有 primary key 或 unique 索引时,如果插入的数据和原来 primary

key 或 unique 索引一致时,会先删除原来的数据,然后增加一条新数据,也就是说,一条 REPLACE 语句有时候等价于一条

INSERT 语句,有时候等价于一条 DELETE 语句加上一条 INSERT 语句。
因此:
INSERT 型触发器:插入某一行时激活触发器,可能通过 INSERT、LOAD DATA、REPLACE 语句触发;
UPDATE 型触发器:更改某一行时激活触发器,可能通过 UPDATE 语句触发;
DELETE 型触发器:删除某一行时激活触发器,可能通过 DELETE、REPLACE 语句触发。

高级功能

当前数据
NEW在触发器为INSERT事件类型时有效,表示当前正在插入的数据;
OLD在触发器类型为DELETE事件类型时有效,表示当前正在删除的数据。

多个语句
1.在trigger_body中可以执行多条SQL语句,需要使用BEGIN和END作为开始和结束的标志;
2.在MySQL中,分号”;”标志着SQL语句的结束,但是在触发器要执行的SQL语句中使用到了”;”作为要执行SQL语句的结束标记,
所以你需要重新定义结束标识符。例如:语句起始 DELIMITER $$ ,语句结束 DELIMITER ;

【变量详解】

MySQL 中使用 DECLARE 来定义一局部变量,该变量只能在 BEGIN … END 复合语句中使用,并且应该定义在复合语句的开头,

即其它语句之前,语法如下:
DECLARE var_name[,…] type [DEFAULT value]

其中:
var_name 为变量名称,同 SQL 语句一样,变量名不区分大小写;
type 为 MySQL 支持的任何数据类型;
可以同时定义多个同类型的变量,用逗号隔开;
变量初始值为 NULL,如果需要,可以使用 DEFAULT 子句提供默认值,值可以被指定为一个表达式。

对变量赋值采用 SET 语句,语法为:
SET var_name = expr [,var_name = expr] …

查看触发器

可以通过执行SHOW TRIGGERS命令查看触发器,但是因为不能查询指定的触发器,所以每次都返回所有的触发器的信息,使用不方便。但是可以使用查询系统表information_schema.triggers的方式指定查询条件,查看指定的触发器信息。如:
mysql> USE information_schema;
Database changed
mysql> SELECT * FROM triggers WHERE trigger_name=’trigger_student_count_insert’;
删除触发器

DROP TRIGGER trigger_name;

举例

作用1:
增删学生信息表的时候同时修改学生统计表的数据

数据
CREATE TABLE student_info (
stu_no INT(11) NOT NULL AUTO_INCREMENT,
stu_name VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (stu_no)
);
CREATE TABLE student_count (
student_count INT(11) DEFAULT 0
);
INSERT INTO student_count VALUES(0);

触发器:
CREATE TRIGGER trigger_student_count_insert
AFTER INSERT
ON student_info FOR EACH ROW
UPDATE student_count SET student_count=student_count+1;

CREATE TRIGGER trigger_student_count_delete
AFTER DELETE
ON student_info FOR EACH ROW
UPDATE student_count SET student_count=student_count-1;

插入数据
INSERT INTO student_info VALUES(NULL,’张明’),(NULL,’李明’),(NULL,’王明’);
DELETE FROM student_info WHERE stu_name IN(‘张明’,’李明’);

功能2:
作用:
在INSERT时首先增加学生总人数,然后判断新增的学生是几年级的,再增加对应年级的学生总数:
定义触发器:
DELIMITER

CREATETRIGGERtriggerstudentcountinsertAFTERINSERTONstudentinfoFOREACHROWBEGINUPDATEstudentcountSETstudentcount=studentcount+1WHEREstudentclass=0;UPDATEstudentcountSETstudentcount=studentcount+1WHEREstudentclass=NEW.studentclass;END

DELIMITER ;

问题

触发器的使用限制
官网“触发器语法和示例” http://dev.mysql.com/doc/refman/5.6/en/trigger-syntax.html
<1> 触发器只能创建在永久表上,不能对临时表创建触发器;
<2> 触发器不能使用CALL语句调用具有返回值或使用了动态SQL的存储过程(存储过程可以使用OUT或INOUT参数返回给触发器返回值)。
<3> 触发器中不能使用开启或结束事务的语句段,比如,开始事务(START TRANSACTION)、提交事务(COMMIT)或是回滚事务(ROLLBACK),但是回滚到一个保存点(SAVEPOINT是允许的,因为回滚到保存点不会结束事务);
<4> 外键不会激活触发器;
<5> 当使用基于行的复制时,从表上的触发器不会因操作主表中的数据而激活。当使用基于语句的复制时,从表上的触发器会被激活。参考 Section 17.4.1.34,“Replication and Triggers”;
<6> 触发器中不允许返回值,因此触发器中不能有返回语句,如果要立即停止一个触发器,应该使用LEAVE语句;

触发器中的异常机制
MySQL的触发器是按照BEFORE触发器、行操作、AFTER触发器的顺序执行的,其中任何一步发生错误都不会继续执行剩下的操作。如果是对事务表进行的操作,那么会整个作为一个事务被回滚,但是如果是对非事务表进行的操作,那么已经更新的记录将无法回滚,这也是设计触发器的时候需要注意的问题。

【触发器的执行顺序】

我们建立的数据库一般都是 InnoDB 数据库,其上建立的表是事务性表,也就是事务安全的。这时,若SQL语句或触发器执行失

败,MySQL 会回滚事务,有:
①如果 BEFORE 触发器执行失败,SQL 无法正确执行
②SQL 执行失败时,AFTER 型触发器不会触发
③AFTER 类型的触发器执行失败,SQL 会回滚

性能
http://blog.csdn.net/tao546377318/article/details/53841992