2010-08-05 210 views
28

有谁知道存在一种方式,或者甚至有可能从另一个方法调用存储过程?如果是这样,你会怎么做?在Oracle中与另一个存储过程调用存储过程

这里是我的测试代码:

SET SERVEROUTPUT ON; 

DROP PROCEDURE test_sp_1; 
DROP PROCEDURE test_sp; 

CREATE PROCEDURE test_sp 
AS 
BEGIN 
    DBMS_OUTPUT.PUT_LINE('Test works'); 
END; 
/

CREATE PROCEDURE test_sp_1 
AS 
BEGIN 
    DBMS_OUTPUT.PUT_LINE('Testing'); 
    test_sp; 
END; 
/

CALL test_sp_1; 

回答

38

你的存储过程的工作作为编码。问题在于最后一行,它无法调用任何一个存储过程。

SQL * Plus中的三种选择是:callexec和一个有害的PL/SQL块。

call似乎是一个SQL关键字,并在SQL参考中进行了说明。 http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_4008.htm#BABDEHHG语法图表明即使没有参数传递给调用例程,也需要parentesis。

CALL test_sp_1(); 

一位不愿具名的PL/SQL块是PL/SQL不是一个命名过程,函数,触发器中,等它可以用来打电话给你的程序。

BEGIN 
    test_sp_1; 
END; 
/

Exec是一个SQL * Plus命令,它是上述匿名块的快捷方式。EXEC <procedure_name>将被传递到数据库服务器作为BEGIN <procedure_name>; END;

完整的示例:

SQL> SET SERVEROUTPUT ON 
SQL> CREATE OR REPLACE PROCEDURE test_sp 
    2 AS 
    3 BEGIN 
    4  DBMS_OUTPUT.PUT_LINE('Test works'); 
    5 END; 
    6/

Procedure created. 

SQL> CREATE OR REPLACE PROCEDURE test_sp_1 
    2 AS 
    3 BEGIN 
    4  DBMS_OUTPUT.PUT_LINE('Testing'); 
    5  test_sp; 
    6 END; 
    7/

Procedure created. 

SQL> CALL test_sp_1(); 
Testing 
Test works 

Call completed. 

SQL> exec test_sp_1 
Testing 
Test works 

PL/SQL procedure successfully completed. 

SQL> begin 
    2  test_sp_1; 
    3 end; 
    4/
Testing 
Test works 

PL/SQL procedure successfully completed. 

SQL> 
13

当然,你刚刚从SP中调用它,有没有特殊的语法。

例:

PROCEDURE some_sp 
    AS 
    BEGIN 
     some_other_sp('parm1', 10, 20.42); 
    END; 

如果程序是在一个不同的模式比一个执行过程中,你需要架构名称的前缀它。

PROCEDURE some_sp 
    AS 
    BEGIN 
     other_schema.some_other_sp('parm1', 10, 20.42); 
    END; 
+0

感谢您的CALL sp_1; 我收到以下错误。 错误的命令开始行21: CALL test_sp_1 错误报告: SQL错误:ORA-06576:不是有效的函数或过程名 06576. 00000 - “不是有效的函数或过程名” *原因:可能找不到函数(如果存在INTO子句)或 过程(如果语句没有INTO子句)调用 。 *操作:更改语句以调用函数或过程 – electricsheep 2010-08-05 13:55:38

+0

@Michael Lockwood - 您可以在原始问题中发布代码吗?另外,如果您使用SQL * PLus等工具调用函数,则需要将返回值分配给变量。 – dcp 2010-08-05 13:57:51

+0

@ML:当CALL不起作用时(为不是有效的PL/SQL语句),为什么还要尝试使用CALL并且dcp向您展示了如何正确执行它? – 2010-08-05 14:04:07

2

@Michael Lockwood - 你不需要在任何地方使用关键字“CALL”。你只需要直接提到过程调用。

也就是说

Begin 
    proc1(input1, input2); 
end; 
/

,而不是

Begin 
    call proc1(input1, input2); 
end; 
/
+0

查看他的代码以及问题的修订历史,我没有看到他在PL/SQL中使用调用的地方。该调用不在任何PL/SQL之外,并且尝试测试存储过程。 – 2010-08-05 20:48:22

2

从sqlplus命令行调用的程序,请尝试以下之一:

CALL test_sp_1(); 
EXEC test_sp_1 
2

调用另一个过程一个过程:

一个一个正常的程序:

CREATE OR REPLACE SP_1() AS 
BEGIN 
/* BODY */ 
END SP_1; 

调用过程SP_1 SP_1:

CREATE OR REPLACE SP_2() AS 
BEGIN 
/* CALL PROCEDURE SP_1 */ 
SP_1(); 
END SP_2; 

呼叫与REFCURSOR或输出光标一个过程:

CREATE OR REPLACE SP_1 
(
oCurSp1 OUT SYS_REFCURSOR 
) AS 
BEGIN 
/*BODY */ 
END SP_1; 

调用过程SP_1,但是当我尝试使用运行,这将返回REFCURSOR作为输出参数

CREATE OR REPLACE SP_2 
(
oCurSp2 OUT SYS_REFCURSOR 
) AS `enter code here` 
BEGIN 
/* CALL PROCEDURE SP_1 WITH REF CURSOR AS OUTPUT PARAMETER */ 
SP_1(oCurSp2); 
END SP_2; 
+0

对于oracle而言很重要。 – 2013-08-21 11:50:52

+0

Sirve igual si es number el out?是否需要输出? – 2017-11-22 14:28:27