在实际开发中,我们经常会遇到这样的情况:有 2 个或者多个相互关联的表,如商品信息和库存信息分别存放在 2 个不同的数据表中,我们在添加一条新商品记录的时候,为了保证数据的完整性,必须同时在库存表中添加一条库存记录。
这样一来,我们就必须把这两个关联的操作步骤写到程序里面mysql触发器,而且要用事务包裹起来,确保这两个操作成为一个原子操作,要么全部执行,要么全部不执行。要是遇到特殊情况,可能还需要对数据进行手动维护,这样就很容易忘记其中的一步,导致数据缺失。
这个时候,可以使用触发器。可以创建一个触发器,让商品信息数据的插入操作自动触发库存数据的插入操作。 这样一来,就不用担心因为忘记添加库存数据而导致的数据缺失了。
文章目录
1. 触发器概述 2. 触发器的创建 2.1 创建触发器语法
CREATE TRIGGER 触发器名称
{BEFORE|AFTER} {INSERT|UPDATE|DELETE} ON 表名
FOR EACH ROW
触发器执行的语句块;
说明:
触发器执行的语句块:可以是单条SQL语句,也可以是由BEGIN…END结构组成的复合语句块。
2.2 代码举例
举例1:
1、创建数据表:
CREATE TABLE test_trigger (
id INT PRIMARY KEY AUTO_INCREMENT,
t_note VARCHAR(30)
);
CREATE TABLE test_trigger_log (
id INT PRIMARY KEY AUTO_INCREMENT,
t_log VARCHAR(30)
);
2、创建触发器:创建名称为before_insert的触发器,向test_trigger数据表插入数据之前,向test_trigger_log数据表中插入before_insert的日志信息。
DELIMITER
CREATE TRIGGER before_insert
BEFORE INSERT ON test_trigger
FOR EACH ROW
BEGIN
INSERT INTO test_trigger_log (t_log)
VALUES('before_insert');
END
DELIMITER ;
3、向test_trigger数据表中插入数据
INSERT INTO test_trigger (t_note) VALUES ('测试 BEFORE INSERT 触发器');
4、查看 test_trigger 表中的数据
mysql> SELECT * FROM test_trigger_log;
+
| id | t_log |
+
| 1 | before_insert |
+
1 row in set (0.00 sec)
举例2:
1、创建名称为after_insert的触发器,向test_trigger数据表插入数据之后,向test_trigger_log数据表中插入after_insert的日志信息。
DELIMITER $
CREATE TRIGGER after_insert
AFTER INSERT ON test_trigger
FOR EACH ROW
BEGIN
INSERT INTO test_trigger_log (t_log)
VALUES('after_insert');
END $
DELIMITER ;
2、向test_trigger数据表中插入数据。
INSERT INTO test_trigger (t_note) VALUES ('测试 AFTER INSERT 触发器');
3、查看test_trigger_log数据表中的数据
mysql> SELECT * FROM test_trigger_log;
+
| id | t_log |
+
| 1 | before_insert |
| 2 | before_insert |
| 3 | after_insert |
+
3 rows in set (0.00 sec)
举例3: 定义触发器“salary_check_trigger”,基于员工表“employees”的INSERT事件,在INSERT之前检查将要添加的新员工薪资是否大于他领导的薪资,如果大于领导薪资,则报sqlstate_value为’HY000’的错误,从而使得添加失败。
DELIMITER
CREATE TRIGGER salary_check_trigger
BEFORE INSERT ON employees FOR EACH ROW
BEGIN
DECLARE mgrsalary DOUBLE;
SELECT salary INTO mgrsalary FROM employees WHERE employee_id = NEW.manager_id;
IF NEW.salary > mgrsalary THEN
SIGNAL SQLSTATE 'HY000' SET MESSAGE_TEXT = '薪资高于领导薪资错误';
END IF;
END
DELIMITER ;
上面触发器声明过程中的NEW关键字代表INSERT添加语句的新记录。
INSERT INTO employees(employee_id,last_name,email,hire_date,job_id,salary,manager_id)
VALUES(300,'Tom','tom@126.com',CURDATE(),'AD_VP',8000,103);
INSERT INTO employees(employee_id,last_name,email,hire_date,job_id,salary,manager_id)
VALUES(301,'Jerry','Jerry@126.com',CURDATE(),'AD_VP',10000,103);

3. 查看、删除触发器 3.1 查看触发器
方式1:查看当前数据库的所有触发器的定义
G 类似于结尾的分号 ”;“,此命令建议在命令行下执行
SHOW TRIGGERS\G

SHOW TRIGGERS;

方式2:查看当前数据库中某个触发器的定义
SHOW CREATE TRIGGER 触发器名

方式3:从系统库information_schema的TRIGGERS表中查询“salary_check_trigger”触发器的信息。
SELECT * FROM information_schema.TRIGGERS;
3.2 删除触发器
触发器也是数据库对象,删除触发器也用DROP语句,语法格式如下:
DROP TRIGGER IF EXISTS 触发器名称;
4. 触发器的优缺点 4.1 优点
1、触发器可以确保数据的完整性。


1)重新计算进货单明细表中的数量合计和金额合计;
2)用第一步中计算出来的值更新进货单头表中的合计数量与合计金额。
2、触发器可以帮助记录操作日志。
3、触发器还可以用在操作数据前,对数据进行合法性检查。
4.2 缺点
1、触发器最大的一个问题就是可读性差。
mysql> update demo.membermaster set memberdeposit=20 where memberid = 2;
ERROR 1054 (42S22): Unknown column 'aa' in 'field list'
2、相关数据的变更,可能会导致触发器出错。
4.3 注意点
(编辑:武汉站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|