触发器(Trigger)是一种特殊的数据库对象,它与表相关联,并在表上的特定操作(如插入、更新、删除)发生时自动触发执行。触发器通常用于实现数据完整性约束、日志记录、审计跟踪等功能。
触发器的主要特点包括:
-
触发时机:触发器可以在数据操作之前(Before Trigger)或之后(After Trigger)执行。
-
事件类型:触发器可以与表的插入(INSERT)、更新(UPDATE)或删除(DELETE)操作相关联。
-
执行逻辑:触发器可以执行一系列的SQL语句,包括查询、修改数据等。
触发器的优点包括:
-
数据完整性:触发器可以在数据操作之前或之后执行验证和修正操作,确保数据的完整性。
-
自动化处理:触发器可以自动执行,无需手动干预,提高了数据处理的一致性和效率。
-
日志记录和审计:触发器可以用于记录数据变化和审计跟踪,方便后续分析和追踪数据的变更历史。
总之,存储过程和触发器是数据库中常用的对象,用于实现特定的业务逻辑和数据操作。存储过程通常用于执行复杂的数据操作和业务处理,而触发器则用于实现数据完整性约束和自动化处理。它们在数据库设计和应用开发中都扮演着重要的角色。
在 SQL Server 中,触发器可以在以下几个时机被触发:
1. 在插入数据之前触发(BEFORE INSERT):在将数据插入到表中之前触发触发器。可以在触发器中对将要插入的数据进行修改或验证。
- 示例:在插入新员工数据之前,触发器可以自动为新员工生成一个唯一的员工编号。 - 触发器代码示例: ```sql CREATE TRIGGER trgBeforeInsertEmployee ON Employee BEFORE INSERT AS BEGIN SET NEW.EmployeeID = (SELECT MAX(EmployeeID) + 1 FROM Employee) END ```
2. 在插入数据之后触发(AFTER INSERT):在将数据插入到表中之后触发触发器。可以在触发器中执行与插入数据相关的其他操作。
- 示例:在插入新订单数据之后,触发器可以自动更新客户的最近订单日期。 - 触发器代码示例: ```sql CREATE TRIGGER trgAfterInsertOrder ON Orders AFTER INSERT AS BEGIN UPDATE Customers SET LastOrderDate = GETDATE() WHERE CustomerID IN (SELECT CustomerID FROM inserted) END ```
3. 在更新数据之前触发(BEFORE UPDATE):在更新表中的数据之前触发触发器。可以在触发器中对将要更新的数据进行修改或验证。
- 示例:在更新产品价格之前,触发器可以验证价格是否在有效范围内。 - 触发器代码示例: ```sql CREATE TRIGGER trgBeforeUpdateProduct ON Products BEFORE UPDATE AS BEGIN IF UPDATE(UnitPrice) -- 只在更新 UnitPrice 字段时触发 BEGIN IF NOT EXISTS (SELECT * FROM inserted WHERE UnitPrice BETWEEN 0 AND 100) BEGIN RAISERROR('Invalid price range', 16, 1) ROLLBACK END END END ```
4. 在更新数据之后触发(AFTER UPDATE):在更新表中的数据之后触发触发器。可以在触发器中执行与更新数据相关的其他操作。
- 示例:在更新订单状态之后,触发器可以记录状态变更的日志。 - 触发器代码示例: ```sql CREATE TRIGGER trgAfterUpdateOrder ON Orders AFTER UPDATE AS BEGIN INSERT INTO OrderLog (OrderID, OldStatus, NewStatus, ChangeDate) SELECT o.OrderID, d.Status, i.Status, GETDATE() FROM inserted i INNER JOIN deleted d ON i.OrderID = d.OrderID END ```
5. 在删除数据之前触发(BEFORE DELETE):在从表中删除数据之前触发触发器。可以在触发器中对将要删除的数据进行修改或验证。
- 示例:在删除客户数据之前,触发器可以检查是否有关联的订单存在。 - 触发器代码示例: ```sql CREATE TRIGGER trgBeforeDeleteCustomer ON Customers BEFORE DELETE AS BEGIN IF EXISTS (SELECT * FROM Orders WHERE CustomerID IN (SELECT CustomerID FROM deleted)) BEGIN RAISERROR('Cannot delete customer with associated orders', 16, 1) ROLLBACK END END ```
6. 在删除数据之后触发(AFTER DELETE):在从表中删除数据之后触发触发器。可以在触发器中执行与删除数据相关的其他操作。
- 示例:在删除产品数据之后,触发器可以更新相关订单中的产品信息。 - 触发器代码示例: ```sql CREATE TRIGGER trgAfterDeleteProduct ON Products AFTER DELETE AS BEGIN UPDATE Orders SET ProductID = NULL WHERE ProductID IN (SELECT ProductID FROM deleted) END ```