Files
LabelChange-server/MySQL_Trigger_Implementation.md
2026-06-01 16:30:29 +08:00

171 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MySQL触发器实现方案
## 1. 触发器创建语句
### 1.1 基本触发器
```sql
DELIMITER $$
CREATE TRIGGER update_label_replace_timestamp
BEFORE UPDATE ON label_replace_requests
FOR EACH ROW
BEGIN
SET NEW.UpdatedAt = UTC_TIMESTAMP();
END$$
DELIMITER ;
```
### 1.2 包含条件判断的触发器(可选)
```sql
DELIMITER $$
CREATE TRIGGER update_label_replace_timestamp
BEFORE UPDATE ON label_replace_requests
FOR EACH ROW
BEGIN
-- 仅当记录确实被修改时才更新时间戳
IF NOT (NEW.BillOfLadingNumber <=> OLD.BillOfLadingNumber AND
NEW.MasterPackageNumber <=> OLD.MasterPackageNumber AND
NEW.ReferenceNumber <=> OLD.ReferenceNumber AND
NEW.NeutralWaybillNumber <=> OLD.NeutralWaybillNumber AND
NEW.FinalMileTrackingNumber <=> OLD.FinalMileTrackingNumber AND
NEW.Label <=> OLD.Label AND
NEW.ReplaceStatus <=> OLD.ReplaceStatus AND
NEW.CustomerId <=> OLD.CustomerId) THEN
SET NEW.UpdatedAt = UTC_TIMESTAMP();
END IF;
END$$
DELIMITER ;
```
## 2. 实现步骤
### 2.1 登录MySQL数据库
使用MySQL客户端工具如MySQL Workbench、Navicat或命令行登录到数据库服务器。
### 2.2 选择数据库
```sql
USE your_database_name;
```
### 2.3 执行触发器创建语句
复制上述触发器创建语句并执行。
### 2.4 验证触发器是否创建成功
```sql
SHOW TRIGGERS LIKE 'update_label_replace_timestamp';
```
## 3. 触发器说明
### 3.1 触发时机
- `BEFORE UPDATE`:在更新操作执行前触发
- `FOR EACH ROW`:对每一行更新都会触发
### 3.2 时间戳设置
- 使用 `UTC_TIMESTAMP()` 函数获取当前UTC时间与代码中使用的 `DateTime.UtcNow` 保持一致
- 确保时间戳格式与数据库表结构匹配
### 3.3 条件判断(可选)
- 使用 `<=>` 操作符进行NULL安全的比较
- 仅当记录确实被修改时才更新时间戳,避免不必要的时间戳更新
## 4. 测试验证
### 4.1 功能测试
1. **创建测试记录**
```sql
INSERT INTO label_replace_requests (NeutralWaybillNumber, ReplaceStatus)
VALUES ('TEST123456', 'Y');
```
2. **查询初始时间戳**
```sql
SELECT UpdatedAt FROM label_replace_requests WHERE NeutralWaybillNumber = 'TEST123456';
```
3. **更新记录**
```sql
UPDATE label_replace_requests SET FinalMileTrackingNumber = 'FM123456'
WHERE NeutralWaybillNumber = 'TEST123456';
```
4. **验证时间戳是否更新**
```sql
SELECT UpdatedAt FROM label_replace_requests WHERE NeutralWaybillNumber = 'TEST123456';
```
### 4.2 性能测试
1. **批量更新测试**
```sql
-- 创建测试数据
INSERT INTO label_replace_requests (NeutralWaybillNumber, ReplaceStatus)
VALUES
('TEST001', 'Y'),
('TEST002', 'Y'),
('TEST003', 'Y'),
('TEST004', 'Y'),
('TEST005', 'Y');
-- 批量更新
UPDATE label_replace_requests SET FinalMileTrackingNumber = 'FM999'
WHERE NeutralWaybillNumber LIKE 'TEST%';
```
2. **测量执行时间**
- 使用MySQL的 `BENCHMARK` 函数或应用程序中的计时功能
## 5. 注意事项
### 5.1 权限要求
- 需要 `CREATE TRIGGER` 权限
- 需要对 `label_replace_requests` 表有 `TRIGGER` 权限
### 5.2 性能影响
- 触发器会在每次更新操作时执行,可能影响高频更新场景的性能
- 建议在生产环境中进行性能测试
### 5.3 维护性
- 触发器逻辑存储在数据库中,与应用代码分离,可能增加维护难度
- 建议在代码中添加注释,说明触发器的存在和功能
### 5.4 兼容性
- 确保MySQL版本支持触发器MySQL 5.0及以上版本支持)
- 不同MySQL版本的触发器语法可能略有差异
## 6. 触发器管理
### 6.1 修改触发器
```sql
-- 先删除旧触发器
DROP TRIGGER IF EXISTS update_label_replace_timestamp;
-- 再创建新触发器
DELIMITER $$
CREATE TRIGGER update_label_replace_timestamp
BEFORE UPDATE ON label_replace_requests
FOR EACH ROW
BEGIN
SET NEW.UpdatedAt = UTC_TIMESTAMP();
END$$
DELIMITER ;
```
### 6.2 删除触发器
```sql
DROP TRIGGER IF EXISTS update_label_replace_timestamp;
```
## 7. 总结
通过创建MySQL触发器可以在数据库层面自动更新 `UpdatedAt` 字段,确保无论通过什么方式更新数据,都会自动记录更新时间。这种方法的优点是实现简单,无需修改应用代码,缺点是可能影响性能,且增加了数据库的复杂性。
在实际应用中,应根据系统的具体情况(如更新频率、性能要求等)选择合适的方案。