简体   繁体   中英

oracle stored procedure OUT parameter vs. postgresql pl/pgsql function OUT parameter

I'm trying to port oracle stored procedures (plsql) to a postgresql function (pl/pgsql).

In oracle I can define a stored procedure with IN and OUT parameters.

CREATE OR REPLACE PROCEDURE MY_TEST(foo IN NUMBER,
                                    bar OUT NUMBER)
IS 
BEGIN
bar := 1
END

This will store a value of 1 in the variable that is passed to the stored procedure. I can call it as follows:

DECLARE
outValue NUMBER ;
BEGIN
Exec MY_TEST(10, outValue); 
DBMS_OUTPUT.PUT_LINE('Value Returned Is : '||outValue) ;
END ;

In Postgresql (pl/pgsql) I can define a function like this one:

CREATE OR REPLACE FUNCTION MY_TEST(foo IN NUMBER,
                                   bar OUT NUMBER)
BEGIN
bar := 1
END;
$body$
LANGUAGE PLPGSQL;

However I can not use the out parameter the same way as I could in oracle. In postgresql the OUT parameter defines the return value. In oracle stored procedures don't have return values, but instead write the output into the variable that is passed in the call

Is there something I overlooked, that would permit me to use pl/pgsql functions in a similar way as the stored procedure is used in the example above?

Any hints are greatly appreciated.

In PostgreSQL, PL/pgSQL or SQL functions take parameter values and return values.

They do not take pointers or references - so that the value of the referenced address could be manipulated.

You could do something like that in theory with a C-language function , where you can pass values by reference. However, de facto, you cannot. The manual warns:

Warning

Never modify the contents of a pass-by-reference input value. If you do so you are likely to corrupt on-disk data, since the pointer you are given might point directly into a disk buffer. The sole exception to this rule is explained in Section 35.10 .

In short: what you are trying to do is impossible in PostgreSQL.

You don't need an OUT parameter for Postgres:

CREATE OR REPLACE FUNCTION MY_TEST(foo IN integer)
  returns integer
as
$body$
BEGIN
    return 1;
END;
$body$
LANGUAGE PLPGSQL;

Then use it like this:

DO $body$
DECLARE 
  result integer;
begin
  result := my_test(42);
  raise notice 'Return value is: %', result;
end;
$body$

Take a read of this.

http://www.postgresonline.com/journal/archives/129-Use-of-OUT-and-INOUT-Parameters.html

In summary given the following stored function and the anonymous block to test this is one approach that the article will show.

CREATE OR REPLACE FUNCTION fn_plpgsqltestout(param_subject text, 
    OUT subject_scramble text, OUT subject_char text)
   AS
$$
BEGIN
    subject_scramble := substring($1, 1,CAST(random()*length($1) As integer));
    subject_char := substring($1, 1,1);
END;
    $$
  LANGUAGE 'plpgsql' VOLATILE;

DO $body$
DECLARE 
  o_subject_scramble TEXT;
  o_subject_char     TEXT;
begin
  --Option1
  SELECT (fn_plpgsqltestout('This is a test subject')).* INTO o_subject_scramble,o_subject_char;

  --Option2
  SELECT (fn_plpgsqltestout('This is a test subject')).subject_scramble INTO o_subject_scramble;
  SELECT (fn_plpgsqltestout('This is a test subject')).subject_char INTO o_subject_char;

  --Option3
  o_subject_scramble := (fn_plpgsqltestout('This is a test subject')).subject_scramble;
  o_subject_char := (fn_plpgsqltestout('This is a test subject')).subject_char;

  raise notice 'Return value is: %', o_subject_scramble;
  raise notice 'Return value is: %', o_subject_char;
end;
$body$

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM