编程后端开发者

在 SQL 中存储过程和触发器之间有什么区别?何时最好使用这两种实体,开发人员在混合使用它们时常犯哪些错误?

用 Hintsage AI 助手通过面试

答案。

存储过程(stored procedures) — 可编程的代码块,被明确调用并可以接受参数,执行复杂的业务逻辑,处理事务,返回数据集或输出参数。

触发器(triggers) — 特殊对象,在数据变更事件(INSERT、UPDATE、DELETE)时“自动”触发,确保在对表执行特定操作时透明地执行定义的逻辑。

何时使用存储过程

  • 需要处理大量数据时。
  • 需要明确的事务控制。
  • 需要返回结果或多个数据集。

何时使用触发器

  • 需要确保在任何数据更改时进行隐式检查或更新(例如,审计)。
  • 需要实现贯穿的完整性检查。

代码示例

存储过程:

CREATE PROCEDURE UpdateProductPrice @ProductID int, @NewPrice money AS BEGIN UPDATE Products SET Price = @NewPrice WHERE ProductID = @ProductID; END

触发器:

CREATE TRIGGER trg_ProductsPriceChange ON Products AFTER UPDATE AS BEGIN INSERT INTO PriceAuditLog(ProductID, OldPrice, NewPrice, ChangeDate) SELECT i.ProductID, d.Price, i.Price, GETDATE() FROM inserted i JOIN deleted d ON i.ProductID = d.ProductID WHERE i.Price <> d.Price END

有陷阱的问题。

问:是否可以在 SQL Server 中通过标准手段确定同一表上多个 AFTER 触发器的执行顺序?

**答:**不,可以确认的是,SQL 标准不保证同一方向的 AFTER 触发器在同一表上的触发顺序。如果顺序重要,应该将它们合并为一个。

由于对主题细节的不了解而导致的真实错误示例。


故事

在 CRM 解决方案中,为了支持变更历史功能,使用了触发器。由于大量更新导致的高负载,日志记录延迟并阻塞了“实时”操作,导致服务短时间不可用。


故事

开发人员在触发器中而不是在存储过程中创建了数据检查逻辑,期望用户能立即看到变化。忘记了触发器是“透明”的,导致业务逻辑变得不清晰(“魔法”),难以调试。


故事

重要:触发器常常在存储过程内部被调用,或者存储过程内部调用触发器,这可能导致递归和超出嵌套限制 — 例如,自动插入会通过相关程序重新触发触发器。