我正在Oracle 10g中编写一个日志记录过程,该过程使用以下插入写入表:
INSERT INTO EXEC_LOG VALUES (
(SELECT SYS_CONTEXT('USERENV','SESSIONID') sessionid FROM dual),
strPackage, strProcedure, strEventType, strEventLevel, SYSDATE, strMessage
);
此过程在多个不同的包/过程中重用,但现在的方式是,程序员必须将其包/过程名称传递给日志记录过程( strPackage
和 strProcedure
) .
我想知道是否有一个v $视图或Oracle中的某些东西可以告诉我调用此过程的包/过程,从而消除了程序员传入 strPackage
和 strProcedure
的需要 .
例:
如果我称这两个程序:
BEGIN
log_test.testproc1;
log_test.testproc2;
END;
从这个包:
CREATE OR REPLACE PACKAGE BODY log_test IS
PROCEDURE TestProc1 IS
BEGIN
write_exec_log( ... );
END TestProc1;
PROCEDURE TestProc2 IS
BEGIN
write_exec_log( ... );
END TestProc2;
END log_test;
我希望能够从 write_exec_log
方法中评估 log_test
/ TestProc1
和 log_test
/ TestProc2
.
3 回答
从Oracle 12c开始,您可以使用内置包UTL_CALL_STACK(http://docs.oracle.com/database/121/ARPLS/u_call_stack.htm) .
如果您只对调用过程感兴趣,可以使用简短示例:
DBMS_OUTPUT.PUT_LINE(UTL_Call_Stack.Concatenate_Subprogram(UTL_Call_Stack.Subprogram(2)));
或者打印完整的调用堆栈:
包装示例:
(对不起,写完时没有sqlfiddle,没有12c)
Tom Kyte's Who_Called_Me should work.
Here是Oracle 9的
utl_call_stack
的实现(后端) . 对于Oracle 10 and 11 .另一种解决方案(使用p_stack包):
使用GWu's example,它将输出:
那些只是最后一次通话 . 或者,如果您需要完整堆栈:
这将输出:
它适用于从9到12的Oracle版本 .