You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何调用PostgreSQL存储过程时OUT参数不可留空?

PL/pgSQL OUT参数的CALL调用规则解析

首先看定义的存储过程及调用示例:

CREATE OR REPLACE PROCEDURE test1(OUT i int)
LANGUAGE plpgsql AS
$$
  BEGIN
    i:=10;
END;
$$;

CALL test1(1); -- 可正常执行,返回10,传入的数值1被忽略
CALL test1(); -- 执行失败,报错:procedure test1() does not exist Hint: No procedure matches the given name and argument types. You might need to add explicit type casts. Position: 6

核心问题解析:

1. 为什么OUT参数的传入初始值会被忽略?

OUT参数的设计定位就是仅用于输出结果,它的生命周期是:存储过程启动时,会自动将OUT参数初始化为对应数据类型的默认值(比如int类型默认是NULL),之后过程体内的赋值操作会覆盖这个初始值。哪怕你调用时传入了字面量或者变量的初始值,都会被这个初始化步骤覆盖,所以传入的值自然不会生效。

2. 为什么OUT/INOUT参数在CALL时必须对应变量(或至少占参数位置)?

  • 存储过程签名的严格匹配:PostgreSQL会根据参数的数量、类型和模式(IN/OUT/INOUT)来匹配存储过程签名。test1(OUT i int)的签名要求有一个int类型的参数位置,哪怕是OUT模式,你也必须在调用时为这个位置提供一个值(变量或字面量),否则数据库会认为你要调用的是无参数的test1(),而这个签名的存储过程不存在,因此报错。
  • 输出结果需要可写入载体:规范要求传变量的原因是,OUT参数最终要把计算结果返回给调用者,字面量是不可修改的常量,无法承载输出结果。虽然传字面量能绕过语法检查,但没有实际意义——你没法从字面量里拿到输出值。而变量是可写入的,调用者可以通过变量获取存储过程输出的结果,比如正确的用法应该是:
DECLARE res int;
CALL test1(res);
SELECT res; -- 得到输出结果10

内容的提问来源于stack exchange,提问作者Akthar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 00:57:10