1. 前置知识:什么是SQL Server触发器
在进行SQL Server数据库操作时,触发器是处理数据前后逻辑的一种重要手段。触发器会在指定的数据操作时点,“触发”一些指定的操作,比如更新另外的表、写入日志等。
使用触发器,可以在数据操作的前后添加一些附加逻辑处理,从而实现数据的自动处理以及保障数据库数据的完整性和稳定性。
2. SQL Server触发器的类型
2.1 DML触发器
DML(Data Manipulation Language,数据操作语言)触发器会在插入、更新、删除等数据操作前后发生。
创建一个DML触发器,需要选择一个表并指定该触发器要处理的操作类型。
比如,下面的DML触发器会在在每次插入Users表时,将计数器表Counters中对应的字段自动递增1:
CREATE TRIGGER CountersUserInsert
ON Users
AFTER INSERT
AS BEGIN
UPDATE Counters SET UsersCount = UsersCount + 1
END
2.2 DDL触发器
DDL(Data Definition Language,数据定义语言)触发器会在创建表、视图、存储过程等数据库对象前后发生。
DDL触发器与DML触发器的创建方式类似,但需要在创建时指定触发器类型为DDL:
CREATE TRIGGER LogDDLActivity
ON DATABASE
FOR CREATE_TABLE, DROP_TABLE, ALTER_TABLE
AS
BEGIN
INSERT INTO DDLActivityLog (EventDate, EventType, ObjectName, TSQLCommand)
SELECT GETDATE(), EVENTDATA().value('(/EVENT_INSTANCE/EventType)[1]', 'nvarchar(100)'),
EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]', 'nvarchar(100)'),
EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'nvarchar(max)');
END
3. SQL Server触发器的精彩之处
3.1 数据自动处理与完整性保护
触发器可以自动处理数据,保障数据库数据的完整性和稳定性。
比如,下面的DML触发器会在插入订单表时自动计算出订单总金额并更新到订单总金额表中:
CREATE TRIGGER OrdersTotalAmount
ON Orders
AFTER INSERT
AS BEGIN
DECLARE @OrderId INT, @UserId INT, @OrderDate DATETIME, @TotalAmount DECIMAL(10,2)
SELECT @OrderId = inserted.OrderId, @UserId = inserted.UserId, @OrderDate = inserted.OrderDate FROM inserted
SELECT @TotalAmount = SUM(UnitPrice * Quantity)
FROM OrderDetails
WHERE OrderId = @OrderId
INSERT INTO OrdersTotalAmount (OrderId, UserId, OrderDate, TotalAmount)
VALUES (@OrderId, @UserId, @OrderDate, @TotalAmount)
END
另一个例子:在插入用户申请表时,在申请的基础上自动添加一些其他的申请信息。
CREATE TRIGGER ApplyInfoAdded
ON UserApplies
AFTER INSERT
AS BEGIN
DECLARE @ApplyId INT, @FirstName VARCHAR(50), @LastName VARCHAR(50), @Email VARCHAR(100)
SELECT @ApplyId = inserted.ApplyId, @FirstName = inserted.FirstName, @LastName = inserted.LastName, @Email = inserted.Email
FROM inserted
INSERT INTO OtherApplyInfo (ApplyId, FirstName, LastName, Email, ApplyDate, Position, AppliedDepartment, CurrentCompany)
VALUES (@ApplyId, @FirstName, @LastName, @Email, GETDATE(), '', '', '');
END
3.2 业务逻辑处理与扩展功能
触发器可以添加业务逻辑功能和扩展功能,从而增强数据库的应用场景和功能。
一个例子:在插入用户表时,自动发送一封欢迎邮件。
CREATE TRIGGER SendWelcomeEmail
ON Users
AFTER INSERT
AS BEGIN
DECLARE @UserId INT, @Email VARCHAR(100), @FullName VARCHAR(100), @Message NVARCHAR(1000)
SELECT @UserId = inserted.UserId, @Email = inserted.Email, @FullName = inserted.FirstName + ' ' + inserted.LastName
FROM inserted
SET @Message = 'Hello ' + @FullName + ' , welcome to our website!'
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'MyEmailProfile',
@recipients = @Email,
@subject = 'Welcome to our website!',
@body = @Message;
END
另一个例子:在插入订单表时自动计算订单等级并更新到客户表中。
CREATE TRIGGER UpdateCustomerOrderLevel
ON Orders
AFTER INSERT
AS BEGIN
DECLARE @OrderId INT, @TotalAmount DECIMAL(10,2), @CustomerId INT, @OrderLevel INT
SELECT @OrderId = inserted.OrderId, @CustomerId = inserted.CustomerId, @TotalAmount = SUM(UnitPrice * Quantity)
FROM inserted
INNER JOIN OrderDetails ON inserted.OrderId = OrderDetails.OrderId
IF @TotalAmount > 10000
SET @OrderLevel = 1
ELSE IF @TotalAmount > 5000
SET @OrderLevel = 2
ELSE IF @TotalAmount > 1000
SET @OrderLevel = 3
ELSE
SET @OrderLevel = 4
UPDATE Customers
SET LastOrderDate = GETDATE(), OrderLevel = @OrderLevel
WHERE CustomerId = @CustomerId
END
4. 总结
SQL Server触发器可以在数据操作前后触发一些指定的操作,从而方便用户完成一些自动化或复杂逻辑处理。
使用SQL Server触发器可以保障数据库数据的完整性和稳定性,同时也可以添加业务逻辑功能和扩展功能,从而增强数据库的应用场景和功能。