When calling one procedure from another: ERROR: procedure parameter "..." is an output parameter but corresponding argument is not writable

When calling one procedure from another: ERROR: procedure parameter "..." is an output parameter but corresponding argument is not writable

我有以下带有 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

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

原因是outer_proc中的v_msgcharacter varying类型,而inner_proc的参数pmsg是[=15=类型].

因此,当您使用 v_msg 调用 inner_proc 时,PostgreSQL 会执行 类型转换 。在 character varyingtext 的情况下,这只是一个“类型强制转换”,因为这些类型的内部表示是相同的,但它也可以像 integer 那样是一个真正的转换 → bigint.

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

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