Procedure execution hierarchy [message #163655] |
Fri, 17 March 2006 13:56 |
pkirangi
Messages: 74 Registered: August 2005
|
Member |
|
|
Hello All,
I have an issue, wherein I need to find out procedure execution hierarchy.
Lets say Proc A call Proc B
Proc B call Proc C
Proc C call Proc D
In Proc D I encounter an exception, and I need to insert into a error table the hierarchy of the procedure calls, in the error message.
i.e I want to say "Encountered error in D: execution flow Is A.B.C.D"
How can I generate "A.B.C.D", without having to write extra code. Is there a V$table or some internal table which I can use to figure the procedure execution hierarchy?
Thanks
PHK
|
|
|
|
Re: Procedure execution hierarchy [message #163671 is a reply to message #163655] |
Fri, 17 March 2006 15:38 |
|
Barbara Boehmer
Messages: 9100 Registered: November 2002 Location: California, USA
|
Senior Member |
|
|
I don't know how important the format is or isn't to you. I made a few quick modifications to Tom Kyte's who_called_me procedure to create a flow function that returns something a little closer to what you asked for, and included it in the revised demonstration below.
scott@ORA92> CREATE TABLE error_tab
2 (who_am_i VARCHAR2(61),
3 who_called_me VARCHAR2(61),
4 flow VARCHAR2(2000),
5 call_stack CLOB)
6 /
Table created.
scott@ORA92> create or replace function flow
2 return varchar2
3 as
4 call_stack varchar2(4096) default dbms_utility.format_call_stack;
5 n number;
6 found_stack BOOLEAN default FALSE;
7 line varchar2(255);
8 cnt number := 0;
9 v_flow varchar2(2000);
10 caller_t varchar2(30);
11 owner varchar2(30);
12 name varchar2(30);
13 lineno number;
14 begin
15 --
16 loop
17 n := instr( call_stack, chr(10) );
18 exit when ( n is NULL or n = 0 );
19 --
20 line := substr( call_stack, 1, n-1 );
21 call_stack := substr( call_stack, n+1 );
22 --
23 if ( NOT found_stack ) then
24 if ( line like '%handle%number%name%' ) then
25 found_stack := TRUE;
26 end if;
27 else
28 cnt := cnt + 1;
29 -- cnt = 1 is ME
30 -- cnt = 2 is MY Caller
31 -- cnt = 3 is Their Caller
32 if ( cnt >= 2 ) then
33 lineno := to_number(substr( line, 13, 6 ));
34 line := substr( line, 21 );
35 if ( line like 'pr%' ) then
36 n := length( 'procedure ' );
37 elsif ( line like 'fun%' ) then
38 n := length( 'function ' );
39 elsif ( line like 'package body%' ) then
40 n := length( 'package body ' );
41 elsif ( line like 'pack%' ) then
42 n := length( 'package ' );
43 elsif ( line like 'anonymous%' ) then
44 n := length( 'anonymous block ' );
45 else
46 n := null;
47 end if;
48 if ( n is not null ) then
49 caller_t := ltrim(rtrim(upper(substr( line, 1, n-1 ))));
50 else
51 caller_t := 'TRIGGER';
52 end if;
53
54 line := substr( line, nvl(n,1) );
55 n := instr( line, '.' );
56 owner := ltrim(rtrim(substr( line, 1, n-1 )));
57 name := ltrim(rtrim(substr( line, n+1 )));
58 v_flow := v_flow || '->' || caller_t || ' ' || owner || '.' || name;
59 end if;
60 end if;
61 end loop;
62 return ltrim (v_flow, '->');
63 end;
64 /
Function created.
scott@ORA92> show errors
No errors.
scott@ORA92>
scott@ORA92> CREATE OR REPLACE PROCEDURE d
2 AS
3 v_num NUMBER;
4 v_owner VARCHAR2(30);
5 v_name VARCHAR2(30);
6 v_line NUMBER;
7 v_caller_t VARCHAR2(100);
8 BEGIN
9 select to_number('a') into v_num from dual; -- cause error for testing
10 EXCEPTION
11 WHEN OTHERS THEN
12 who_called_me (v_owner, v_name, v_line, v_caller_t);
13 INSERT INTO error_tab
14 VALUES (who_am_i,
15 v_owner || '.' || v_name,
16 flow,
17 dbms_utility.format_call_stack);
18 END d;
19 /
Procedure created.
scott@ORA92> SHOW ERRORS
No errors.
scott@ORA92> CREATE OR REPLACE PROCEDURE c
2 AS
3 BEGIN
4 d;
5 END c;
6 /
Procedure created.
scott@ORA92> CREATE OR REPLACE PROCEDURE b
2 AS
3 BEGIN
4 c;
5 END b;
6 /
Procedure created.
scott@ORA92> CREATE OR REPLACE PROCEDURE a
2 AS
3 BEGIN
4 b;
5 END a;
6 /
Procedure created.
scott@ORA92> execute a
PL/SQL procedure successfully completed.
scott@ORA92> COLUMN who_am_i FORMAT A13
scott@ORA92> COLUMN who_called_me FORMAT A13
scott@ORA92> COLUMN call_stack FORMAT A45
scott@ORA92> SELECT * FROM error_tab
2 /
WHO_AM_I WHO_CALLED_ME
------------- -------------
FLOW
----------------------------------------------------------------------------------------------------
CALL_STACK
---------------------------------------------
SCOTT.D SCOTT.C
PROCEDURE SCOTT.D->PROCEDURE SCOTT.C->PROCEDURE SCOTT.B->PROCEDURE SCOTT.A->ANONYMOUS BLOCK .
----- PL/SQL Call Stack -----
object line object
handle number name
661B83F8 1 anonymous block
661C8564 13 procedure SCOTT.D
661B3C44 4 procedure SCOTT.C
661AA128 4 procedure SCOTT.B
661B909C 4 procedure SCOTT.A
66299984 1 anonymous block
scott@ORA92>
|
|
|
|
Re: Procedure execution hierarchy [message #268191 is a reply to message #163655] |
Mon, 17 September 2007 22:45 |
bikrambhuyan
Messages: 1 Registered: September 2007
|
Junior Member |
|
|
Hi,
We have the same requirement to log the stack trace information while logging the error. We are facing issues when trying to implement this in the procudure which are under the package.
But is this valid for the function or procedure within the package?
When we are running the application in debug mode we are finding that the stack trace information only return the SCHEMA.PACKAGE_NAME. This does not return the function name within the package. Also while running the function, it is showing run time error.
Any help on this will be really appreciated.
Thanks,
Bikram.
|
|
|
|
Re: Procedure execution hierarchy [message #410690 is a reply to message #163655] |
Mon, 29 June 2009 14:47 |
shailendrakr
Messages: 2 Registered: June 2009
|
Junior Member |
|
|
From the discussion above I understand that format_call_stack is not much help with procedures in a package.
Are there any other options for identifying a procedure in a package? I need this to log exceptions.
|
|
|
|