在 SQL Server(以及大多数数据库)中,存储过程(Stored Procedure)和函数(Function)都是用来封装 SQL 逻辑的对象,但它们在用途、特性和限制上有明显的区别。

区别总结

1. 返回值

  • 存储过程:可以返回 0 个或多个结果集,可以通过 OUTPUT 参数返回值,也可以用 RETURN 返回一个整数。
  • 函数:必须 返回一个值(标量值、表值或标量表函数),不能返回多个结果集。

2. 调用方式

  • 存储过程:使用 EXECEXECUTE 调用。 EXEC usp_GetUsers @Status = 'Active';
  • 函数:可以在 SQL 语句里直接调用,如 SELECTWHEREJOIN 等。 SELECT dbo.fn_GetUserName(1);

3. 是否可以在 SQL 语句中使用

  • 存储过程:不能在 SELECTWHERE 中使用。
  • 函数:可以在 SQL 语句中使用,像内置函数(LEN(), GETDATE())一样。

4. 事务控制

  • 存储过程:可以在其中 使用事务控制语句BEGIN TRAN, COMMIT, ROLLBACK)。
  • 函数:不允许显式事务控制。

5. 是否允许副作用(修改数据)

  • 存储过程:可以执行 INSERTUPDATEDELETEMERGE 等 DML 操作。
  • 函数:标量函数中通常 不允许修改数据库数据,表值函数返回的只是查询结果集。

6. 错误处理

  • 存储过程:支持 TRY...CATCH 错误处理。
  • 函数:不支持 TRY...CATCH,错误处理能力有限。

7. 编译与性能

  • 存储过程:通常会被编译并缓存执行计划,适合复杂的业务逻辑和批量处理。
  • 函数:适合封装计算逻辑或可复用的查询片段,但过度使用标量函数可能导致性能下降。

对比表

特性存储过程(Stored Procedure)函数(Function)
返回值可无返回值,可返回多个结果集必须返回值(标量/表)
调用方式EXECSELECT dbo.fn()
SQL语句中使用❌ 不可直接用✅ 可在 SELECT、WHERE、JOIN 中使用
修改数据✅ 允许❌ 一般不允许
事务控制✅ 支持❌ 不支持
错误处理✅ TRY…CATCH❌ 不支持
适用场景复杂逻辑、批量处理封装计算逻辑、复用查询

一句话总结

  • 存储过程 更像是 任务执行器(可操作数据、事务处理),
  • 函数 更像是 工具函数(返回计算或查询结果,可嵌入 SQL 使用)。