CodeGym /课程 /SQL SELF /函数和过程的区别

函数和过程的区别

SQL SELF
第 51 级 , 课程 4
可用

在很多编程语言里,函数和过程几乎没啥区别。但在SQL里就不一样了。 在PostgreSQL里,函数和过程不仅仅是两种写代码的方式。这是两种完全不同的思维方式

SQL里的函数不能改数据库里的数据。它只能处理传进来的数据,然后基于这些数据返回结果。函数就是为了在SELECT查询里用的。

SQL里的过程就是用来改数据库的。所以它可以操作事务(和函数不一样),还能往库里写点啥。但过程不能在SELECT查询里用。

下面是它们的简要对比:

特点 函数 (FUNCTION) 过程 (PROCEDURE)
返回数据 ✅ 是的 (RETURNS ...) ❌ 不会(只能做点事)
怎么调用 SELECT, PERFORM CALL
能在查询里用吗 ✅ 可以 ❌ 不行
能在 DO 里用吗 ✅ 可以 ❌ 不行
支持 COMMIT, ROLLBACK ❌ 不支持 ✅ 支持
PostgreSQL里啥时候有的 一开始就有 11版本开始

SQL里的区别

在普通SQL里,函数就像表达式:它计算并返回一个值。 过程就是指令:它做点啥,但不会参与表达式。

SQL里的函数

SELECT calculate_discount(200);
  • 可以用在 WHEREORDER BYINSERTUPDATE 等等。
  • 必须是纯函数:不能改数据库状态(如果IMMUTABLE/STABLE)。

SQL里的过程

CALL process_order(123);
  • 不会返回结果。
  • 可以做 COMMITROLLBACK、调用 RAISE、写循环啥的。

PL/pgSQL里的区别

PostgreSQL里的函数可以理解为一组计算。 它们非常灵活:可以传参数、用条件语句、循环、游标、子查询、返回行、标量、表。

PL/pgSQL里的函数

CREATE FUNCTION square(x INT) RETURNS INT AS $$
BEGIN
    RETURN x * x;
END;
$$ LANGUAGE plpgsql;

特点:

  • 必须有 RETURNS
  • 可以用 DECLAREBEGINENDLOOPIFCASE
  • 不能执行 COMMIT/ROLLBACK
  • 可以在 SELECTUPDATECHECKWHERERETURNING 里调用

调用:

SELECT square(5);  -- 会返回25

PL/pgSQL里的过程

过程就是控制操作的机制。 它们特别适合:

  • 执行多步逻辑
  • 批量更新和插入大量数据;
  • 事务控制COMMITROLLBACKSAVEPOINT
CREATE PROCEDURE log_event(msg TEXT) AS $$
BEGIN
    INSERT INTO logs(message) VALUES (msg);
    COMMIT;
END;
$$ LANGUAGE plpgsql;

特点:

  • 没有 RETURNS
  • 只能通过 CALL 调用
  • 允许用 COMMITROLLBACKSAVEPOINT
  • 适合批处理、迁移、ETL

调用:

CALL log_event('处理完成');

为啥要分函数和过程

因为它们在SQL里目标不一样

函数 过程
“算点东西然后返回” “做点事但不返回结果”
SQL里调用 当命令调用
不能控制事务 能控制事务
用在 SELECTJOINWHERE 用在 CALL、脚本里

过程的核心优势 — COMMIT

过程可以自己管理事务。 也就是说,在过程里你可以直接:

BEGIN;
-- 逻辑
SAVEPOINT point1;
-- 尝试更新
ROLLBACK TO point1;
COMMIT;

函数里禁止用 COMMITROLLBACK。 如果你试了,会报错:ERROR: invalid transaction termination in function

这就意味着,函数必须是确定且安全的,而过程可以“脏活累活”——清理、记录日志、插入数据啥的。

对比表

特点 FUNCTION PROCEDURE
返回值 RETURNS
能用在 SELECT
调用方式 SELECTPERFORMDO 只能 CALL
能用在触发器里 ❌(只能函数)
内部事务(COMMIT ❌ 禁止 ✅ 允许
OUT参数用法 通过 RETURNS TABLERECORD 直接用 OUT 参数
适合做计算 🚫 不推荐
适合ETL、数据导入 🚫 有限制 ✅ 完美
能用游标 ✅ 可以 ✅ 可以

啥时候用啥?

用函数,如果你:

  • 想要返回值;
  • SELECT 里调用、过滤数据;
  • 只是简单计算、校验或者SQL的封装。

用过程,如果你:

  • 要做复杂操作;
  • 需要事务控制;
  • 处理批量、迁移、归档、日志啥的。
1
调查/小测验
控制结构第 51 级,课程 4
不可用
控制结构
控制结构
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION