Oracle SQL 存储过程的调用与执行

26

问题

我想了解Oracle SQL命令CALLEXECUTE之间的区别。

我一直在使用CALL来启动存储过程,但是在与另一个开发人员交谈时,我发现他几乎完全使用EXECUTE。我在网上进行了一些研究,看看是否有做错什么的明显区别,但我没有看到这两个命令之间的明显区别,人们似乎可以互换使用它们。

根据文档,它们在与存储过程交互方面非常相似(至少如此)。

看起来CALL是通用的SQL命令,而EXECUTE似乎是专有的,因此我倾向于使用CALL而不是EXECUTE,但我不知道这对性能有何影响。

问题

  • 在启动存储过程方面,是否有一种优于另一种?有关系吗?
  • 如果关系到,有什么情况下两者都适用?
  • 它们之间有任何性能差异吗?最佳实践是什么?

1
EXECUTE 是 SQL*PLUS 命令。你使用的是哪个 SQL 客户端? - OldProgrammer
我们主要使用TOAD 11.6,两个命令都可以编译/运行。 - user2858650
1
所以,不会有性能问题。他们只是调用该过程。 - OldProgrammer
2个回答

30

在SQL*Plus中,EXEC[ute] SP()CALL SP()都可以用来执行存储过程。另外,你也可以使用BEGIN SP(); END;

但是它们之间有一些区别:

  1. CALL是Oracle SQL语法,应该可以在任何地方使用。其他能够与Oracle数据库通信的DB客户端可能支持SQL*Plus EXEC命令,也可能不支持(例如Liquibase)。

  2. CALL语句传递的参数的数据类型必须是SQL数据类型,而不能是PL/SQL专属的数据类型,如BOOLEAN。

  3. EXEC命令不仅可以用于执行存储过程,还可以执行任意语句。

  4. 如果一个存储过程没有参数,则可以使用EXEC SP;语法,但是CALL语句需要使用空括号:CALL SP();


我认为可以将过程的参数作为“命名参数”以任意顺序提供的语法,仅适用于EXECUTE和SQL*Plus。 - Mirko Klemm
@MirkoKLemm 实际上,在 CALL 中对我也起作用:CALL r_mv (method => 'C', mv => 'core_project_appls'); 用于 CREATE OR REPLACE PROCEDURE r_mv( mv IN VARCHAR2, method IN VARCHAR2 := '', skip_index IN VARCHAR2 := '*NONE*') - Dima Korobskiy

1
如果您使用Toad调用返回sys_refcursor的存储过程,CALL和EXEC之间有区别。
创建存储过程foo(i in number,o out sys_refcursor)
begin
打开o,用dual表中的i选择数据
end;
使用exec foo(1,:r);将输出1行。
使用call foo(1,:r);将输出0行。
注意:当您在参数前加上冒号时,Toad会提示您输入类型(在这种情况下是游标)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接