【问题标题】:Why a procedure cannot call another in Oracle为什么一个过程不能在 Oracle 中调用另一个过程
【发布时间】:2010-10-26 21:29:14
【问题描述】:

我在 Oracle 9i 中有 2 个过程 (A,B)。就个人而言,它们都工作正常。但是我不能创建一个调用 A 的过程 C,而 A 又调用 B。我在 C 调用 A 之前放置了一个 dbms_output.put_line,在 A 调用 B 和 B 之前放置了一个。不知何故,只有第一个 put_line 有效。这不起作用的可能原因是什么?谢谢,

CREATE OR REPLACE PROCEDURE C (num in number)
as
begin
    for r in (select col1 from Table1)
    loop
        dbms_output.put_line ('Inside C');
        A(r.col1);
    end loop;
end;

CREATE OR REPLACE PROCEDURE A (var1 IN varchar2)
AS
    v1 varchar2;
    cursor c1(c_var in varchar2) is 
       select col1 from table2 where col2=c_var;
BEGIN
    open c1(var1);
    loop
        fetch c1 into v1;
        exit when c1%notfound; 
        dbms_output.put_line ('Inside A');
        B(v1);
    end loop;
    close c1;
END;

【问题讨论】:

  • 您是否尝试过在 A 中打开光标之前放置一个 dbms_output 以确保您甚至进入循环?

标签: oracle plsql procedure


【解决方案1】:

很明显,游标 c1 为空,因此您的条件(c1%notfound 时退出)为真,并且循环在 dbms_output 调用之前终止。

如果要打印该行而不考虑空光标,请更改其位置,例如:

CREATE OR REPLACE PROCEDURE C (num in number)
as
begin
    dbms_output.put_line ('Inside C');
    for r in (select col1 from Table1)
    loop
        dbms_output.put_line ('Calling A');
        A(r.col1);
    end loop;
end;


CREATE OR REPLACE PROCEDURE A (var1 IN varchar2)
AS
    v1 varchar2;
    cursor c1(c_var in varchar2) is
       select col1 from table2 where col2=c_var;
BEGIN
    dbms_output.put_line ('Inside A');
    open c1(var1);
    loop
        fetch c1 into v1;
        exit when c1%notfound;
        dbms_output.put_line ('Calling B');
        B(v1);
    end loop;
    close c1;
END;

【讨论】:

    【解决方案2】:

    尝试在 C 中放置一个异常处理程序来检测是否有异常被抛出;像

    CREATE OR REPLACE PROCEDURE C (num in number) 
    as 
    begin 
        for r in (select col1 from Table1) 
        loop 
            dbms_output.put_line ('Inside C'); 
            A(r.col1); 
        end loop;
    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('Exception caught in C : ' || SQLCODE || ' ' || SQLERRM);
        RAISE;
    end;
    

    【讨论】:

    • 如果引发异常,它将传播到调用过程,这个 WHEN OTHERS THEN NULL 异常处理程序是不必要的,也是不好的做法。至少包括一个 RAISE 语句。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    • 2016-01-01
    • 2020-01-24
    • 1970-01-01
    • 2011-05-08
    • 1970-01-01
    • 2023-03-05
    相关资源
    最近更新 更多