SQL Server触发器实战展示了如何在同一张表中实现数据的自动联动与更新,通过监控表内的数据变更操作,触发器能自动执行相关逻辑,确保数据的一致性与完整性,有效解决业务中复杂的实时数据依赖问题。
在 SQL Server 的数据库开发中,触发器是一种非常强大且复杂的机制,它允许我们在数据发生变更(如 INSERT、UPDATE 或 DELETE)之前或之后,自动执行一段 T-SQL 代码。
很多时候,我们并不需要去修改其他表,而是需要在同一个表中根据变更的数据进行自动更新,当插入一条新订单时,自动更新库存;或者在更新员工薪资时,同时更新历史薪资记录,这种操作被称为“自引用”或“表内联动”。
本文将深入探讨如何在 SQL Server 中编写触发器来改变同一个表,并分析其中的关键技巧与潜在陷阱。

场景需求
假设我们有一个 Orders(订单表),其中包含 OrderStatus(订单状态)和 OrderDate(下单时间)字段,我们的业务需求是:
- 当插入一条新订单时,自动设置
OrderDate为当前时间。 - 当订单状态从“待支付”变为“已支付”时,自动触发更新,将状态改为“发货中”,并记录更新时间。
这不需要去操作其他表,而是纯粹地在同一个表内进行逻辑判断和数据回写。
基础语法与实现
对于同一个表的修改,最常用的是使用 AFTER 触发器。AFTER 触发器会在数据变更操作(INSERT/UPDATE/DELETE)成功执行,并完成所有约束检查之后运行。
注意: 在 AFTER 触发器中,你可以直接通过 INSERTED 和 DELETED 逻辑表来访问变更的数据。
代码示例
下面是一个具体的 SQL Server 脚本示例,演示如何在同一个表中实现状态联动:
-- 1. 创建测试表
CREATE TABLE Orders (
OrderID INT IDENTITY(1,1) PRIMARY KEY,
ProductName NVARCHAR(50),
OrderStatus NVARCHAR(20), -- '待支付', '已支付', '发货中', '已完成'
OrderDate DATETIME,
LastModified DATETIME
);
-- 2. 创建触发器
-- 当对 Orders 表进行 INSERT 或 UPDATE 操作时触发
CREATE TRIGGER tr_Orders_StatusUpdate
ON Orders
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
-- 使用事务确保逻辑的原子性(防止并发问题)
BEGIN TRY
BEGIN TRANSACTION;
-- 情况1:如果是 INSERT 操作,设置默认时间
IF EXISTS (SELECT 1 FROM inserted)
BEGIN
UPDATE o
SET o.OrderDate = GETDATE()
FROM Orders o
INNER JOIN inserted i ON o.OrderID = i.OrderID
WHERE o.OrderDate IS NULL;
END
-- 情况2:如果是 UPDATE 操作,检查状态变化
-- 我们需要比较 inserted 表(新数据)和 deleted 表(旧数据)
UPDATE o
SET
o.OrderStatus = i.OrderStatus,
o.LastModified = GETDATE()
FROM Orders
文章版权声明:除非注明,否则均为XMSDN - MSDN原版系统镜像 | 纯净ISO系统下载原创文章,转载或复制请以超链接形式并注明出处。

