Mysql触发器的使用和创建

目录

触发器有什么用?

创建触发器

如何实现包含多条执行语句的触发器

如何查看已创建的触发器


触发器有什么用?

当一个数据库中某个关系表的数据被更新时,其他与之相关的表的数据可能也会需要更新。手动去修改那些需要更新的表的数据会比较枯燥而繁琐。而有了触发器,当一个表的数据被更新时,会启用对应的触发器来自动更新那些与之相关的表的数据,省时又省力。下面讨论如何创建触发器。

创建触发器

我们先来研究一下创建触发器的语法:

CREATE
[DEFINER={user | CURRENT_USER}]
TRIGGER trigger_name
trigger_time trigger_event
ON table_name FOR EACH ROW
trigger_body

对于上面这组语法,方括号里的内容[DEFINER={user | CURRENT_USER}] 的用法我们先不讨论。

trigger_name: 触发器的名字,自己取一个,但记住不可以取已经存在的触发器的名字,会报错。

trigger_time: 一般有两种选择,BEFORE或者AFTER,表示触发器在下一条提到的事件发生前或者发生后执行。

trigger_event: 一般有三种选择,INSERT、DELETE和UPDATE,表示的是触发该触发器的事件。

trigger_body: 触发器触发后执行的指令。

下面举个实际应用的例子:

假如有两张关系表,一张叫worker_info,用来存储公司员工的信息;一张叫worker_count用来存储公司的员工总数。然后要求写几个触发器,用来处理以下情况:在把公司新来的员工信息登记到worker_info后,worker_count的数据也要相应的更新。

做法很简单,首先创建个测试用的库:

CREATE DATABASE test;

然后,写两张用作测试的表,worker_info和worker_count:

CREATE TABLE worker_info(
w_no INT(5) NOT NULL AUTO_INCREMENT,
w_name VARCHAR(10) DEFAULT NULL,
PRIMARY KEY(w_no)
);

CREATE TABLE worker_count(
w_count INT(20) DEFAULT 0
);

INSERT INTO worker_count VALUE(0);

好,开始写触发器,一个在往worker_info添加数据时触发,另一个在从worker_info删除数据时触发:

CREATE TRIGGER trigger_worker_info_insert
AFTER INSERT
ON worker_info FOR EACH ROW
UPDATE worker_count SET w_count=w_count+1;

CREATE TRIGGER trigger_worker_info_delete
AFTER DELETE
ON worker_info FOR EACH ROW
UPDATE worker_count SET w_count=w_count-1;

测试一下,

INSERT INTO worker_info VALUE(NULL,'John'),(NULL,'Mark'),(NULL,'Alex');
SELECT * FROM worker_count;

成功,下面来测试下删除数据:

DELETE FROM worker_info WHERE w_name IN ('John','Alex');
SELECT * FROM worker_count;

这时候可能你就要想了,我们讨论的这个例子就只在trigger_body这部分用了一条执行语句啊,万一一条不够用,我们能不能多用几条?

当然可以,下面就来讨论包含多条执行语句的触发器如何实现。

如何实现包含多条执行语句的触发器

还是一样我们先来看看创建包含多条执行语句的触发器的语法:

CREATE
[DEFINER={user | CURRENT_USER}]
TRIGGER trigger_name
trigger_time trigger_event
ON table_name FOR EACH ROW
BEGIN
trigger_statments
END;

大多数地方都与前面提到过的语法一样。不同之处是,在执行多条语句时,我们需要BEGINEND来作为开始和结束的标志。

那么现在我们用这个触发器的性质来解决一下实际问题,

假如我在worker_count表和worker_info同时增加个字段,w_dept_no,表示员工所在的部门编号,0表示所有部门,1表示部门1,2表示部门2,那么现在如果要在worker_info中添加员工信息,这个触发器的创建比之前的触发器要复杂一点。有点挑战性,咱们开始写代码:

首先得清空两张表的数据,并且删除两个前面创建的触发器(不删除的话,会导致work_count表的数据不准确):

删除触发器的语法是:

DROP TRIGGER trigger_name;

于是我们执行以下代码:

DELETE FROM worker_info;
DELETE FROM worker_count;
DROP TRIGGER trigger_worker_info_insert;
DROP TRIGGER trigger_worker_info_delete;

然后添加字段w_dept_no,两张表都要添加:

ALTER TABLE worker_info ADD w_dept_no INT(10);
ALTER TABLE worker_count ADD w_dept_no INT(10);

下面开始写触发器:

DELIMITER $$
CREATE TRIGGER trigger_worker_info_insert
AFTER INSERT
ON worker_info FOR EACH ROW
BEGIN
UPDATE worker_count SET w_count=w_count+1 WHERE w_dept_no=0;
UPDATE worker_count SET w_count=w_count+1 WHERE w_dept_no=NEW.w_dept_no;
END$$
DELIMITER ;

DELIMITER $$
CREATE TRIGGER trigger_worker_info_delete
AFTER DELETE
ON worker_info FOR EACH ROW
BEGIN
UPDATE worker_count SET w_count=w_count-1 WHERE w_dept_no=0;
UPDATE worker_count SET w_count=w_count-1 WHERE w_dept_no=OLD.w_dept_no;
END$$
DELIMITER ;

创建完触发器后,初始化一下worker_count表:

INSERT INTO worker_count VALUE(0,0),(0,1),(0,2);

开始插入数据到worker_info:

INSERT INTO worker_info VALUES(NULL,'Jack',2),(NULL,'Bob',1),(NULL,'Carror',2),(NULL,'Dave',1),(NULL,'Brown',1),(NULL,'Alex',2);

很成功,再来试一下从worker_info删除数据:

DELETE FROM worker_info WHERE w_name='Carror';

下面来讨论一下,

大家可能想了解DELIMITER的作用,DELIMITER用于重新定义结束标识符。为什么要用这个东西呢?因为“;”是默认的语句结束标识符,一旦检测到这个标识符,程序就被认为结束了。在BEGIN和END语句块中,我们需要将语句的默认标识符设置成除了“;”之外的符号,这样就不至于只执行完第一句执行语句程序就终止。但是最后别忘了把默认标识符改回原来的“;”。

大家可能还注意到了,上面创建触发器的代码中NEWOLD这两个关键字。

NEW关键字在触发器执行INSERT事件的时候有效,表示当前正在插入的数据(如例子中正在插入worker_info表的新的w_dept_no数据);OLD则在触发器执行DELETE事件时有效,表示当前正在删除的数据(如例子中正在被从worker_info表删除的'carror'对应的w_dept_no数据)。

如何查看已创建的触发器

如果需要查看已经创建了哪些触发器,则可以使用语句:

SHOW TRIGGERS;

我电脑里执行的的结果是这样的...(这是已经把命令行设置成全屏显示了..)

如果要查看更加详细的触发器结构,可以用以下语句:

USE information_schema;
SELECT  * FROM triggers WHERE trigger_name=触发器名称;

拿前面最后一次创建的trigger_worker_info_insert来举例:

USE information_schema;
SELECT  * FROM triggers WHERE trigger_name='trigger_worker_count_insert';

执行结果:(也是命令行设置成全屏显示的情况下)

得去换个屏幕更大的笔记本了...

发布了38 篇原创文章 · 获赞 5 · 访问量 6587

猜你喜欢

转载自blog.csdn.net/shaotianyang12/article/details/85549188
今日推荐