触发器(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
```
需要注意的是,触发器可以在每个操作(插入、更新、删除)的不同阶段触发,即在执行操作之前或之后触发。这样可以在触发器中执行不同类型的操作,根据需要进行数据的修改、验证或其他处理。