在日常项目开发中,经常需要对关键业务表的变更进行记录,例如学员训练状态的变化、订单流程的推进、员工信息的修改等。为了自动化这些记录,可以借助 SQL Server 的触发器机制,让数据库在发生 INSERT 或 UPDATE 时自动生成一条审计日志,无需业务端额外编码。
下面使用 Sy_PracticalTraining 作为示例,通过两个触发器将新增和更新操作写入到 Sy_PracticalTraining_Temps 记录表中。
插入触发器:记录新增数据
当有新的训练记录写入 Sy_PracticalTraining 时,触发器会捕获这条数据,把其中的 ID 和当前状态写入到日志表里。插入时没有“旧状态”,因此 OldStatus 写为 NULL。
CREATE TRIGGER trgAfterInsertEmployee
ON Sy_PracticalTraining
AFTER INSERT
AS
BEGIN
DECLARE @TrainingId INT, @NewStatus INT;
SELECT @TrainingId = ID,
@NewStatus = Status
FROM inserted;
INSERT INTO Sy_PracticalTraining_Temps (TrainingId, OldStatus, NewStatus, UpdateDate)
VALUES (@TrainingId, NULL, @NewStatus, GETDATE());
END;
inserted 表是 SQL Server 触发器中的虚拟表,用来存储本次新增的数据。
更新触发器:记录状态变化
当训练记录被更新时,往往更需要关注“更新前是什么状态、更新后又变成什么状态”。触发器通过 deleted(旧数据)和 inserted(新数据)两个虚拟表来获取这两个值。
CREATE TRIGGER trgAfterUpdateEmployee
ON Sy_PracticalTraining
AFTER UPDATE
AS
BEGIN
DECLARE @OldStatus INT, @NewStatus INT, @TrainingID INT;
SELECT @TrainingId = inserted.ID,
@OldStatus = deleted.Status,
@NewStatus = inserted.Status
FROM deleted
JOIN inserted ON deleted.ID = inserted.ID;
INSERT INTO Sy_PracticalTraining_Temps (TrainingId, OldStatus, NewStatus, UpdateDate)
VALUES (@TrainingId, @OldStatus, @NewStatus, GETDATE());
END;
这段代码会在每一次状态发生改变时,自动生成一条历史记录,便于后期查询操作轨迹。
删除触发器(可选)
如果后续不用这些触发器,直接删除即可。
DROP TRIGGER trgAfterInsertEmployee;
DROP TRIGGER trgAfterUpdateEmployee;
小结
利用 SQL Server 触发器,可以让数据变更记录变得自动化、透明化,不需要在业务代码中重复编写。inserted 与 deleted 两张虚拟表是实现审计功能的关键,通过它们就能精准获取变化前后的数据状态。
如果你的系统涉及流程节点、审批状态、培训记录等场景,这样的触发器结构非常适合作为历史追踪机制。接下来还能扩展内容,例如记录操作用户、记录修改字段、甚至加入 JSON 格式的变更详情,让审计表更强大。