从另一个过程调用一个过程时:错误:过程参数“...”是一个输出参数,但相应的参数不可写

问题描述

我有以下带有 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,v_msg;
end;
$$
language plpgsql;

当我调用上述过程 outer_proc 时,出现以下错误

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

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

解决方法

原因是v_msg中的outer_proccharacter varying类型,而pmsg的参数inner_proctext类型。

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

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

有人可能会争辩说结果可以简单地强制转换回 v_msg || 'tail',但是 a) 没有人为这种特殊情况实施额外的处理,并且 b) 不能保证总是有一个强制转换反方向。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...