首页 » 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 创建时无提示,而且还不容易发现。
对不起,这篇文章暂时关闭评论。