views:

67

answers:

2

I have 2 procedures (A,B) in Oracle 9i. In individual, they all work fine. But I cannot make a procedure C that calls A, which in turn calls B. I put a dbms_output.put_line before C calls A, before A calls B and one in B. Somehow, only the first put_line works. What are the possible reasons why this doesn't work? Thank you,

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;
+2  A: 

Obviusly, cursor c1 is empty, so your condition (exit when c1%notfound) is true and loop is terminated before the dbms_output call.

If you want to print the line regardless of a empty cursor, change it's position, for example:

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;
jachguate
A: 

Try putting an exception handler in C to detect if an exception is being thrown; something like

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;
Bob Jarvis
If an exception is being raised it will propagate to the calling procedure, this WHEN OTHERS THEN NULL exception handler is unnecessary and bad practice. At the very least include a RAISE statement.
pablo