# 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` 字段，确保无论通过什么方式更新数据，都会自动记录更新时间。这种方法的优点是实现简单，无需修改应用代码，缺点是可能影响性能，且增加了数据库的复杂性。

在实际应用中，应根据系统的具体情况（如更新频率、性能要求等）选择合适的方案。