【问题标题】:Call a stored procedure with another in Oracle在 Oracle 中调用另一个存储过程
【发布时间】:2011-03-25 19:41:31
【问题描述】:

有没有人知道从另一个内部调用存储过程的方法,或者即使它可能?如果有,你会怎么做?

这是我的测试代码:

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;

【问题讨论】:

    标签: sql oracle stored-procedures


    【解决方案1】:

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

    SQL*Plus 中的三个选项是:callexec 和一个匿名 PL/SQL 块。

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

    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> 
    

    【讨论】:

      【解决方案2】:

      当然,你只是从 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;
      

      【讨论】:

      • 谢谢你,但是当我尝试使用 CALL sp_1 运行它时;我收到以下错误。错误从命令中的第 21 行开始:CALL test_sp_1 错误报告:SQL 错误:ORA-06576:不是有效的函数或过程名称 06576。00000 -“不是有效的函数或过程名称” *原因:找不到函数(如果存在 INTO 子句)或要调用的过程(如果语句没有 INTO 子句)。 *Action:更改语句以调用函数或过程
      • @Michael Lockwood - 您可以在原始问题中发布您的代码吗?此外,如果您使用 SQL*PLus 之类的工具调用函数,则需要将返回值分配给变量。
      • @ML:当 CALL 不起作用(不是有效的 PL/SQL 语句)并且 dcp 已经向您展示了如何正确使用时,为什么您仍然尝试使用 CALL?
      • 谢谢!我被困在试图用EXECEXECUTE 前面的过程名称,因为(我认为)有必要独立调用该过程 - 但出现错误。我没有意识到在另一个过程中,我可以直接按名称调用过程,而不需要前面的命令。
      • 是否可以使用调用存储过程的结果? (选择语句)
      【解决方案3】:

      @Michael Lockwood - 您无需在任何地方使用关键字“CALL”。您只需要直接提及过程调用即可。

      那是

      Begin
         proc1(input1, input2);
      end;
      /
      

      而不是

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

      【讨论】:

      • 查看他的代码和问题的修订历史,我看不到他在 PL/SQL 中使用调用的位置。该调用在任何 PL/SQL 之外,并试图测试存储过程。
      【解决方案4】:

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

      一个用于正常程序:

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

      从 SP_2 调用过程 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;
      

      【讨论】:

      • oracle 的正确答案。
      【解决方案5】:

      要从 SQLPlus 命令行调用过程,请尝试以下方法之一:

      CALL test_sp_1();
      EXEC test_sp_1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-08
        • 2018-07-04
        • 1970-01-01
        • 2014-09-17
        • 2013-03-08
        相关资源
        最近更新 更多