如何使用 DML 触发器

在 SQL Server 中构建与优化触发器

Florin Angelescu

Instructor

为何使用 DML 触发器?

  • 在数据操作时触发动作
  • 阻止数据操作
  • 跟踪数据或对象变更
  • 用户审计与数据库安全
在 SQL Server 中构建与优化触发器

AFTER 与 INSTEAD OF 的选择

CREATE TRIGGER MyFirstAfterTrigger
ON Table1
-- Triggered after 
-- the firing event (UPDATE)
AFTER UPDATE
AS
{trigger_actions_section};
CREATE TRIGGER MyFirstInsteadOfTrigger
ON Table2
-- Triggered instead of 
-- the firing event (UPDATE)
INSTEAD OF UPDATE
AS
{trigger_actions_section};
在 SQL Server 中构建与优化触发器

AFTER 与 INSTEAD OF 的选择

AFTER 触发器

初始事件触发触发器

初始事件执行

执行触发器操作

AFTER 触发器的工作方式

INSTEAD OF 触发器

初始事件触发触发器

初始事件不再执行

执行触发器操作

INSTEAD OF 触发器的工作方式

在 SQL Server 中构建与优化触发器

AFTER 触发器示例

  • 向销售表插入数据
  • 启动数据清洗过程
  • 生成过程结果的表格报告
  • 通知数据库管理员
CREATE TRIGGER SalesNewInfoTrigger
ON Sales
AFTER INSERT
AS

EXEC sp_cleansing @Table = 'Sales';
EXEC sp_generateSalesReport;
EXEC sp_sendnotification;
在 SQL Server 中构建与优化触发器

INSTEAD OF 触发器示例

| Brand | Model    | Power | Stock |
|-------|----------|-------|-------|
| Ecco  | Standard | 30W   | 30    |
| Miry  | Buma     | 45W   | 0     |
| Lume  | Ultra    | 50W   | 0     |
  • 部分型号的功率发生变化
CREATE TRIGGER BulbsStockTrigger
ON Bulbs
INSTEAD OF INSERT
AS
在 SQL Server 中构建与优化触发器

INSTEAD OF 触发器示例

| Brand | Model    | Power | Stock |
|-------|----------|-------|-------|
| Ecco  | Standard | 30W   | 30    |
| Miry  | Buma     | 50W   | 100   |
| Lume  | Ultra    | 52W   | 100   |
  • 部分型号的功率发生变化
  • 仅更新无库存的产品
CREATE TRIGGER BulbsStockTrigger
ON Bulbs
INSTEAD OF INSERT
AS

IF EXISTS (SELECT * FROM Bulbs AS b INNER JOIN inserted AS i ON b.Brand = i.Brand AND b.Model = i.Model WHERE b.Stock = 0) BEGIN UPDATE b SET b.Power = i.Power, b.Stock = i.Stock FROM Bulbs AS b INNER JOIN inserted AS i ON b.Brand = i.Brand AND b.Model = i.Model WHERE b.Stock = 0 END
在 SQL Server 中构建与优化触发器

INSTEAD OF 触发器示例

| Brand | Model    | Power | Stock |
|-------|----------|-------|-------|
| Ecco  | Standard | 30W   | 30    |
| Miry  | Buma     | 50W   | 100   |
| Lume  | Ultra    | 52W   | 100   |
| Ecco  | Standard | 35W   | 100   |
  • 部分型号的功率发生变化
  • 仅更新无库存的产品
  • 对有库存的产品新增行
-- 为节省空间,前半部分已截断
IF EXISTS (SELECT * FROM Bulbs AS b
INNER JOIN inserted AS i
           ON b.Brand = i.Brand
          AND b.Model = i.Model
WHERE b.Stock = 0)
BEGIN
    UPDATE b
    SET b.Power = i.Power,
        b.Stock = i.Stock
    FROM Bulbs AS b
    INNER JOIN inserted AS i
                ON b.Brand = i.Brand
                  AND b.Model = i.Model
    WHERE b.Stock = 0
END
ELSE
    INSERT INTO Bulbs
    SELECT * FROM inserted;
在 SQL Server 中构建与优化触发器

练习题

在 SQL Server 中构建与优化触发器

Preparing Video For Download...