oracle存储过程OUT参数与postgresql pl / pgsql函数OUT参数

时间:2012-02-21 15:31:39

标签: oracle postgresql plpgsql

我正在尝试将oracle存储过程(plsql)移植到postgresql函数(pl / pgsql)。

在oracle中,我可以使用IN和OUT参数定义存储过程。

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

这将在传递给存储过程的变量中存储值1。 我可以这样称呼它:

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

在Postgresql(pl / pgsql)中,我可以定义一个像这样的函数:

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

但是我不能像在oracle中那样使用out参数。 在postgresql中,OUT参数定义返回值。 在oracle存储过程中没有返回值,而是将输出写入在调用中传递的变量

有没有我忽略的东西,允许我以与上面例子中使用的存储过程类似的方式使用pl / pgsql函数?

非常感谢任何提示。

3 个答案:

答案 0 :(得分:1)

在PostgreSQL中,PL / pgSQL或SQL函数采用参数并返回值。

他们采用指针或引用 - 以便可以操纵引用地址的值。

可以在理论上使用C-language function执行类似的操作,您可以通过引用传递值。但事实上,你不能。手册警告:

  

Warning

     

永远不要修改传递引用输入值的内容。如果你   这样做你可能会破坏磁盘上的数据,因为指针是你的   给出可能直接指向磁盘缓冲区。 Section 35.10中解释了此规则的唯一例外。

简而言之:在PostgreSQL中,你要做的事情是不可能的。

答案 1 :(得分:0)

Postgres不需要OUT参数:

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

然后像这样使用它:

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

答案 2 :(得分:0)

读一读。

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

总结一下,鉴于以下存储函数和要测试的匿名块,这是本文将要展示的一种方法。

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$