PHP数据操作之MySQL触发器(触发器实战指南)
发布时间: 2024-07-22 21:35:11 阅读量: 37 订阅数: 38
![PHP数据操作之MySQL触发器(触发器实战指南)](https://worktile.com/kb/wp-content/uploads/2022/09/43845.jpg)
# 1. MySQL触发器简介和原理
### 1.1 触发器概述
MySQL触发器是一种数据库对象,当特定事件发生在表中时,它会自动执行预定义的SQL语句或存储过程。触发器可以用于多种目的,例如:
- 数据验证和完整性约束
- 数据审计和跟踪
- 业务逻辑实现
### 1.2 触发器工作原理
触发器与表相关联,并在表中发生特定事件时触发。这些事件包括:
- INSERT:当新行插入表中时
- UPDATE:当表中的现有行更新时
- DELETE:当表中的行被删除时
触发器可以定义为在事件发生之前(BEFORE触发器)或之后(AFTER触发器)执行。触发器中的SQL语句或存储过程可以访问触发事件的详细信息,例如新插入的行或更新的行。
# 2. MySQL触发器实战应用
### 2.1 创建和使用触发器
触发器是一种存储在数据库中的特殊存储过程,当表中的数据发生特定事件(如插入、更新或删除)时自动执行。触发器可以用来在数据操作发生时执行额外的操作,例如验证数据、执行业务逻辑或记录数据更改。
#### 2.1.1 BEFORE触发器
BEFORE触发器在数据操作发生之前执行。它可以用来验证数据、修改数据或阻止数据操作。
```sql
CREATE TRIGGER before_insert_customer
BEFORE INSERT ON customer
FOR EACH ROW
BEGIN
-- 验证客户姓名是否为空
IF NEW.name IS NULL THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '客户姓名不能为空';
END IF;
-- 修改客户注册时间为当前时间
SET NEW.register_time = NOW();
END;
```
**逻辑分析:**
* 该触发器在`customer`表中插入数据之前执行。
* 它首先检查`name`字段是否为空,如果为空则抛出错误。
* 然后,它将`register_time`字段设置为当前时间。
#### 2.1.2 AFTER触发器
AFTER触发器在数据操作发生之后执行。它可以用来记录数据更改、执行业务逻辑或发送通知。
```sql
CREATE TRIGGER after_update_order
AFTER UPDATE ON orders
FOR EACH ROW
BEGIN
-- 记录订单更新日志
INSERT INTO order_log (order_id, old_status, new_status)
VALUES (OLD.order_id, OLD.status, NEW.status);
-- 如果订单状态变为已发货,则发送邮件通知客户
IF NEW.status = 'shipped' THEN
SEND EMAIL TO customer@example.com
SUBJECT = '订单已发货'
BODY = '您的订单已发货,预计将于 [预计送达时间] 送达。';
END IF;
END;
```
**逻辑分析:**
* 该触发器在`orders`表中更新数据之后执行。
* 它首先记录订单更新日志。
* 然后,它检查订单状态是否变为已发货,如果是,则发送邮件通知客户。
### 2.2 触发器中的数据操作
触发器可以执行各种数据操作,包括插入、更新、删除和选择。
#### 2.2.1 插入和更新操作
触发器可以使用`INSERT`和`UPDATE`语句插入或更新表中的数据。
```sql
CREATE TRIGGER after_insert_product
AFTER INSERT ON product
FOR EACH ROW
BEGIN
-- 插入一条库存记录
INSERT INTO inventory (product_id, quantity)
VALUES (NEW.product_id, NEW.quantity);
END;
```
**逻辑分析:**
* 该触发器在`product`表中插入数据之后执行。
* 它插入一条库存记录,其中`product_id`和`quantity`字段与插入的产品相同。
#### 2.2.2 删除操作
触发器可以使用`DELETE`语句删除表中的数据。
```sql
CREATE TRIGGER before_delete_order
BEFORE DELETE ON orders
FOR EACH ROW
BEGIN
-- 检查订单是否已发货
IF OLD.status = 'shipped' THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '已发货订单不能删除';
END IF;
END;
```
**逻辑分析:**
* 该触发器在`orders`表中删除数据之前执行。
* 它检查订单是否已发货,如果是,则抛出错误。
### 2.3 触发器中的控制流语句
触发器可以使用控制流语句来控制执行流,包括`IF`条件语句和`CASE`语句。
#### 2.3.1 IF条件语句
`IF`条件语句用于根据条件执行不同的操作。
```sql
CREATE TRIGGER after_update_employee
AFTER UPDATE ON employee
FOR EACH ROW
BEGIN
-- 如果员工部门发生变化,则更新部门平均工资
IF OLD.department_id <> NEW.department_id THEN
UPDATE department
SET avg_salary = (
SELECT AVG(salary)
FROM employee
WHERE department_id = NEW.department_id
)
WHERE department_id = NEW.department_id;
END IF;
END;
```
**逻辑分析:**
* 该触发器在`employee`表中更新数据之后执行。
* 它检查员工部门是否发生变化,如果是,则更新部门平均工资。
#### 2.3.2 CASE语句
`CASE`语句用于根据不同的条件执行不同的操作。
```sql
CREATE TRIGGER after_insert_order
AFTER INSERT ON orders
FOR EACH ROW
BEGIN
-- 根据订单类型执行不同的操作
```
0
0