Обсуждение: BUG #2108: Function with OUT parameters not recognized, using plpgsql
The following bug has been logged online:
Bug reference: 2108
Logged by: Tony
Email address: tony@vectorsalad.com
PostgreSQL version: 8.1.0
Operating system: Debian 1:3.3.5-8ubuntu2, 2.6.10-5-k7, i686
Description: Function with OUT parameters not recognized, using
plpgsql
Details:
Defined a function with OUT paramter. Attempts to call it fail as the
function can not be found.
Example:
<code>
CREATE OR REPLACE FUNCTION f_multiparam (
i1 integer,
i2 varchar,
OUT o1 varchar
) AS
$$
BEGIN
o1 := 'i2 was ' || i2;
END;
$$
LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION f_showperformstatus () RETURNS varchar AS
$$
DECLARE
outparameter varchar;
BEGIN
PERFORM f_multiparam(1, 'hello', outparameter);
RETURN 'successfully run';
END;
$$
LANGUAGE plpgsql;
select f_showperformstatus();
</code>
Output:
CREATE FUNCTION
CREATE FUNCTION
psql:bug2.sql:24: ERROR: function f_multiparam(integer, "unknown",
character varying) does not exist
HINT: No function matches the given name and argument types. You may need
to add explicit type casts.
CONTEXT: SQL statement "SELECT f_multiparam(1, 'hello', $1 )"
PL/pgSQL function "f_showperformstatus" line 4 at perform
It appears that the function is not defined properly in the system, with
only 2 parameters instead of 3:
\df f_multiparam
List of functions
Schema | Name | Result data type | Argument data types
--------+--------------+-------------------+----------------------------
apps | f_multiparam | character varying | integer, character varying
Explicitly casting the value 'hello' as suggested does not help. Changing
the function definition from OUT to INOUT parameter is a successful
workaround.
"Tony" <tony@vectorsalad.com> writes: > Defined a function with OUT paramter. Attempts to call it fail as the > function can not be found. Apparently, you don't understand how OUT parameters work either :-( Perhaps the examples here will help: http://www.postgresql.org/docs/8.1/static/xfunc-sql.html#XFUNC-OUTPUT-PARAMETERS regards, tom lane
Tony wrote: > CREATE OR REPLACE FUNCTION f_multiparam ( > i1 integer, > i2 varchar, > OUT o1 varchar > ) AS > $$ > BEGIN > o1 := 'i2 was ' || i2; > END; > $$ > LANGUAGE plpgsql; > > CREATE OR REPLACE FUNCTION f_showperformstatus () RETURNS varchar AS > $$ > DECLARE > outparameter varchar; > BEGIN > PERFORM f_multiparam(1, 'hello', outparameter); > RETURN 'successfully run'; > END; > $$ > LANGUAGE plpgsql; You are misunderstanding how are functions with OUT params supposed to be called, I think. Try this: CREATE OR REPLACE FUNCTION f_multiparam ( i1 integer, i2 varchar, OUT o1 varchar ) AS $$ BEGIN o1 := 'i2 was ' || i2; END; $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION f_showperformstatus () RETURNS varchar AS $$ DECLARE outparameter varchar; BEGIN SELECT INTO outparameter f_multiparam(1, 'hello'); RAISE NOTICE 'the out param is %', outparameter; RETURN 'successfully run'; END; $$ LANGUAGE plpgsql; The output I get is what I'd expect: alvherre=# select f_showperformstatus(); NOTICE: the out param is i2 was hello f_showperformstatus --------------------- successfully run (1 fila) I think this also applies to your INOUT report, but I haven't checked. -- Alvaro Herrera http://www.CommandPrompt.com/ PostgreSQL Replication, Consulting, Custom Development, 24x7 support
Alvaro Herrera wrote: > Stallone wrote: > > Please keep replies on the list. > > >>What you have done is run a SELECT which evaluates the function >>f_multiparam() passing it two parameters, and then takes the result and >>puts it INTO a local parameter. This is not the same. An OUT parameter >>is actually passed to the function and is part of the function >>specification, in this case it is defined as the third parameter. It's >>like a placeholder within the definition of the function itself, and it >>should show up on the list of parameters for that function. You can, in >>fact, have many OUT parameters in one function. This is an advantage of >>out parameters over just a plain function with a single RETURN element. >> >>At least this is how it has always worked for me. > > > Has always worked where? In Postgres? It's strange that you mention > "always" because OUT parameters are new in Postgres 8.1. Behavior in > other database systems is not directly applicable to Postgres. > > Keep in mind that in Postgres we don't have host variables, which is > what is needed to make OUT params work the way you are assuming they do. > This could be improved in the future but currently that's the way it is. > I have seriously mistaken the nature of IN/OUT parameters in Postgres. This misunderstanding all leaked over from Oracle and is not applicable at all here. Maybe this might make a good bullet point to add in Sec 36.11 "Porting from Oracle PL/SQL". I will post a note separately there.