选择何时使用每个选项

已完成

SQL Server 可编程性对象提供了在数据库中封装和重用逻辑的不同方法。 每个对象类型(视图存储过程函数触发器)都提供不同的用途,并提供独特的功能。

比较选项

下表总结了每种对象类型的关键功能和限制:

能力 Views 存储过程 Functions Triggers
接受参数 是的 是的
修改数据 受限制 是的 是的
返回结果集 是的 是的 是 (TVFs)
用于 SELECT/JOIN 是的 是的
事务控制 是的 是的
自动执行 是的
执行计划缓存 是的 多种多样 是的

仅当更改影响单个基表时,视图才能修改数据。 内联表值函数受益于计划缓存,因为优化器将它们直接扩展到查询计划中。 多语句表值函数 (TVF) 和标量函数被视为“黑匣子”,优化器看不到它们的内部,通常会导致行数估计不准确,进而生成不佳的计划。

根据要求进行选择

正确的可编程性对象取决于您需要完成的工作。 使用此决策框架指导你的选择:

在需要时选择视图:

  • 简化对复杂联接或常用筛选数据的访问
  • 通过控制列和行可见性提供安全层
  • 创建可能更改的基础表的稳定接口
  • 在不接受参数或修改值的情况下呈现数据

在需要时选择存储过程:

  • 使用多个语句执行复杂的业务逻辑
  • 在单个事务中跨多个表修改数据
  • 接受输入参数并返回输出参数或结果集
  • 实现错误处理和事务控制

在需要以下情况下选择函数:

  • 执行可重用计算,以返回在查询中使用的值
  • 返回参数化结果集(表值函数)
  • SELECTWHEREJOIN子句中直接嵌入逻辑
  • 确保索引的确定性结果(针对特定函数类型)

需要时选择触发器:

  • 自动响应数据修改事件
  • 强制实施超出约束的复杂业务规则
  • 维护数据更改的审核日志
  • 自动跨表同步相关数据

应用决策情景

请考虑以下常见方案和针对每个方案的建议方法:

Scenario 推荐对象 为什么
简化多个报表使用的 5 表联接 视图 封装复杂性;不需要任何参数
处理订单:验证库存、插入订单、更新库存 存储过程 在一次事务中进行的多次修改
根据重量和目标计算发货成本 标量函数 查询中的可重用计算
返回日期范围内客户的所有订单 Table-valued 函数 参数化的结果集可用 JOIN
记录Salary列的所有更改 Trigger 自动化且透明的审计日志
在没有 SSN 的情况下提供对员工数据的只读访问权限 视图 安全层用于隐藏敏感列

避免常见错误

选择可编程性对象时,请观察以下陷阱:

  • 在大型表的子句中使用 WHERE 标量函数 - 该函数针对每一行执行,从而降低性能。 请考虑使用内联表值函数或重新编写逻辑。

  • 为存储过程更好地处理的逻辑创建触发器 — 触发器隐式执行且难以调试。 仅在自动执行至关重要时使用它们。

  • 构建嵌套其他视图的复杂视图 - 深度嵌套视图难以优化和维护。 使视图定义保持专注和浅表。

  • 当函数可以更好地集成时选择存储过程 — 如果需要 SELECT 语句中的结果,函数提供的语法比 EXEC 的临时表更简洁。

通过了解每个可编程性对象的优缺点和权衡,可以为数据库设计和实现任务选择适当的工具。