编程数据库开发人员 / 数据库架构师

如何在SQL中正确创建和使用子程序(过程/函数),以实现可重用的业务逻辑,以及在参数和返回值管理方面有哪些注意事项?

用 Hintsage AI 助手通过面试

答案。

SQL中的子程序有两种类型:

  • 过程(存储过程): 执行操作(插入、更新、删除),可以返回OUT参数或结果集(通过SELECT)。通过CALL/EXEC调用,并不总是在select层中使用。
  • 函数(用户定义函数,UDF): 返回值(标量或表),可以直接用于SELECT、WHERE、ORDER BY等结构中。

重要:

  • 过程不能在普通SELECT中使用,仅通过EXEC/CALL调用。
  • 函数只能返回一个值(标量)或一个表(表函数),并且可以在任何表达式中使用。
  • 始终记录参数:IN(输入)、OUT(返回结果)、INOUT(双向)。

标量函数示例(PostgreSQL):

CREATE FUNCTION get_tax(amount NUMERIC, rate NUMERIC DEFAULT 0.13) RETURNS NUMERIC AS $$ BEGIN RETURN amount * rate; END; $$ LANGUAGE plpgsql; -- 使用: SELECT *, get_tax(price) AS tax FROM product;

存储过程示例(SQL Server):

CREATE PROCEDURE add_employee(@name NVARCHAR(100), @salary INT, @emp_id INT OUTPUT) AS BEGIN INSERT INTO employees (name, salary) VALUES (@name, @salary); SET @emp_id = SCOPE_IDENTITY(); END; DECLARE @id INT; EXEC add_employee 'John', 100000, @id OUTPUT;

隐含问题。

可以直接在SELECT中使用存储过程吗?

人们常回答"可以",但这是错误的。

答案:

  • 不可以:标准过程只能单独调用(EXEC/CALL),而函数可以在SELECT中使用。

因为不了解主题的细节而导致的实际错误示例。


故事

项目: 初始账务系统,实现报告。 错误: 为计算总和编写了过程而不是函数 — SELECT无法工作,必须重写所有用户报告的逻辑。


故事

项目: 具有外部参数的ERP系统。 错误: 对过程未设置OUT关键字,导致客户端无法获取添加记录的ID,集成"崩溃"。


故事

项目: 根据不同规则计算税收的金融服务。 错误: 在大规模查询中使用标量函数而未进行性能测试 — 查询因逐行调用而减慢处理速度(未优化计划)。