首页 » PostgreSQL/GaussDB » Oracle国产化改造迁移openGauss时的问题: 存储过程内部不要加”call”

Oracle国产化改造迁移openGauss时的问题: 存储过程内部不要加”call”

在存储过程内可以调用其他多个存储过程或函数,这是支持 存储过程(procedure)的数据库都支持的,近日在做oracle到opengauss系(MogDB)的plsql对象做复审时,发现在一个主存储过程内部调用了其它多个子存储过程,但只执行了其中的第一个子存储过程,Exception捕捉了错误提示SQLERRM is: query has no destination for result data, 后来发现是因为存储过程改写时内部调用子存储过程前加了”call” ,其实用”PERFORM”也没问题,简单记录。

Oracle中存储过程调用其它存储过程

create or replace procedure p1
is
begin
dbms_output.put_line('p1=================');
end;
/

create or replace procedure p2
is
begin
dbms_output.put_line('p2=================');
end;
/

create or replace procedure p3
is
begin
p1;
p2;
end;
/

SQL> exec p1;
p1=================

PL/SQL procedure successfully completed.

SQL> exec p2
p2=================

PL/SQL procedure successfully completed.

SQL> exec p3
p1=================
p2=================

PL/SQL procedure successfully completed.


openGauss调用其它存储过程

MogDB=# CREATE OR REPLACE PROCEDURE p1000()
is
BEGIN
    RAISE NOTICE 'p1000=================';
END;
/


MogDB=# CREATE OR REPLACE PROCEDURE p2000()
is
BEGIN
    RAISE NOTICE 'p2000=================';
END;
/

MogDB=# CREATE OR REPLACE PROCEDURE p3000()
is
BEGIN
call p1000();
call  p2000();
 exception
   when others then
      RAISE notice 'Error  SQLERRM is: %',SQLERRM;
END;
/
CREATE PROCEDURE

MogDB=# call p3000();
NOTICE:  p1000=================
NOTICE:  Error  SQLERRM is: query has no destination for result data
 p3000
-------

(1 row)

Note:
只执行了第一个procecure, 报错让人摸不到头脑。那执行到了exception部分,把exception去掉直接让他报错。

MogDB=# call p3000();
NOTICE:  p1000=================
ERROR:  query has no destination for result data
HINT:  If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT:  PL/pgSQL function p3000() line 3 at SQL statement

Note
这报错提示了行,但报错对于oracle dba也不是很明显,应该是执行使用perform.

CREATE OR REPLACE PROCEDURE p4001()
is
BEGIN
PERFORM p1000();
PERFORM p2000();
END;
/

MogDB=# call p4001();
NOTICE:  p1000=================
NOTICE:  p2000=================
 p4001
-------

(1 row)

MogDB=# perform p4001();
ERROR:  syntax error at or near "perform"

Note:
在存储过程内部是使用perform调用,可以正常。其实像Oracle一样只写过程名也是正常的,完全多此一举加调用。

CREATE OR REPLACE PROCEDURE p3000()
is
BEGIN
 p1000();
 p2000();
END;
/

MogDB=# call p3000();
NOTICE:  p1000=================
NOTICE:  p2000=================
 p3000
-------

(1 row)

小结:

在Postgresql中调用其它存储过程使用perform或不加调用关键字都是可以的,但不要加call 创建时无提示,而且还不容易发现。

打赏

,

目前这篇文章还没有评论(Rss)

我要评论