【问题标题】:When calling one procedure from another: ERROR: procedure parameter "..." is an output parameter but corresponding argument is not writable从另一个过程调用一个过程时:错误:过程参数“...”是一个输出参数,但对应的参数不可写
【发布时间】:2021-02-03 15:41:10
【问题描述】:

我有以下带有 INOUT 参数的 Postgres 存储过程。

PROCEDURE inner_proc(IN pid INT, INOUT pmsg TEXT);

我可以从匿名块中成功调用此过程。

do
$$
declare
v_id int := 4;
v_msg text;
begin
call inner_proc(pid => v_id, pmsg => v_msg);
raise notice '%', v_msg;                                                   
end;
$$
language plpgsql;

匿名块打印'Success' 符合预期。 但是当我在另一个过程中调用这个过程时,它失败了。

PROCEDURE outer_proc()
as
$$
declare
   v_id int := 4;
   v_msg character varying(1000);
begin
call inner_proc(pid => v_id, pmsg => v_msg);
raise notice '%', v_msg;
end;
$$
language plpgsql;

当我调用上述程序outer_proc 时,我收到以下错误。

call outer_proc();
ERROR:  procedure parameter "pmsg" is an output parameter but corresponding argument is not writable

有人可以帮忙解决这个问题吗?

【问题讨论】:

  • @LaurenzAlbe 我发现问题是因为inner_proc 的INOUT 参数是TEXT 数据类型,而我从outer_proc 传递了一个CHARACTER VARYING 参数。感谢您调查它。
  • 为什么不让“inner_proc”成为一个返回状态的函数呢?
  • @a_horse_with_no_name,这只是我根据我正在工作的实际程序创建的示例程序。我不应该将其更改为函数,因为它会影响许多其他应用程序。

标签: postgresql postgresql-11


【解决方案1】:

原因是outer_proc中的v_msgcharacter varying类型,但是inner_proc的参数pmsgtext类型。

所以当你用v_msg 调用inner_proc 时,PostgreSQL 执行类型转换。在character varyingtext的情况下,这只是一种“类型强制”,因为这些类型的内部表示是相同的,但也可以是像integerbigint这样的真正转换。

现在这适用于IN 方向,但现在inner_proc 的参数不再是一个普通变量,而是一个包含参数的表达式,就像你传递了v_msg || 'tail' 一样。当然不可能将输出值分配给这样的表达式,因此会出错。

有人会很想争辩说结果可以简单地转换回character varying,但是a)没有人为这种特殊情况实施额外的处理,并且b)不能保证总是有相反的转换方向。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    • 2015-08-24
    • 2015-01-25
    • 1970-01-01
    • 2016-01-01
    相关资源
    最近更新 更多