我正在Oracle 10g中编写一个日志记录过程,该过程使用以下插入写入表:
INSERT INTO EXEC_LOG VALUES (
(SELECT SYS_CONTEXT('USERENV','SESSIONID') sessionid FROM dual),
strPackage, strProcedure, strEventType, strEventLevel, SYSDATE, strMessage
);
此过程在多个不同的包/过程中重用,但现在的方式是,程序员必须将其包/过程名称传递给日志记录过程(strPackage
和strProcedure
)。 / p>
我想知道Oracle中是否存在av $ view或者某些内容可以告诉我调用此过程的包/过程,从而消除了程序员传入strPackage
和{{1 }}
实施例
如果我称这两个程序:
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;
方法评估log_test
/ TestProc1
和log_test
/ TestProc2
。
答案 0 :(得分: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)));
或者打印完整的调用堆栈:
FOR j IN REVERSE 1..UTL_Call_Stack.Dynamic_Depth() LOOP
DBMS_OUTPUT.PUT_LINE(UTL_Call_Stack.Concatenate_Subprogram(UTL_Call_Stack.Subprogram(j)));
END LOOP;
您的包裹示例:
CREATE OR REPLACE PACKAGE log_test IS
PROCEDURE write_exec_log(msg VARCHAR2);
PROCEDURE TestProc1;
PROCEDURE TestProc2;
PROCEDURE TestProc3;
END log_test;
/
CREATE OR REPLACE PACKAGE BODY log_test IS
PROCEDURE write_exec_log(msg VARCHAR2) IS
BEGIN
DBMS_OUTPUT.PUT_LINE(msg);
DBMS_OUTPUT.PUT_LINE('-- ');
DBMS_OUTPUT.PUT_LINE('calling procedure/function: '
||UTL_Call_Stack.Concatenate_Subprogram(
UTL_Call_Stack.Subprogram(2)
)
);
DBMS_OUTPUT.PUT_LINE('-- ');
DBMS_OUTPUT.PUT_LINE('Call Stack');
FOR j IN REVERSE 1..UTL_Call_Stack.Dynamic_Depth() LOOP
DBMS_OUTPUT.PUT_LINE(UTL_Call_Stack.Concatenate_Subprogram(
UTL_Call_Stack.Subprogram(j)
)
);
END LOOP;
END write_exec_log;
PROCEDURE TestProc1 IS
BEGIN
write_exec_log( 'msg TestProc1' );
END TestProc1;
PROCEDURE TestProc2 IS
BEGIN
write_exec_log( 'msg TestProc2' );
END TestProc2;
PROCEDURE TestProc3 IS
BEGIN
TestProc2;
END TestProc3;
END log_test;
/
exec log_test.TestProc1
exec log_test.TestProc2
exec log_test.TestProc3
(对不起,写作时没有sqlfiddle,没有12c)
答案 1 :(得分:1)
答案 2 :(得分:0)
Here是Oracle 9 utl_call_stack
的实现(后端)。对于Oracle 10 and 11。
另一种解决方案(使用p_stack包):
dbms_output.put_line( p_stack.getConcatenatedSubprograms( p_stack.whoCalledMe ) );
使用GWu's example,输出:
LOG_TEST.TESTPROC1
LOG_TEST.TESTPROC2
LOG_TEST.TESTPROC2
这些只是最后一次通话。或者,如果您需要完整堆栈:
dbms_output.put_line( p_stack.getCallStack );
dbms_output.put_line( '' );
这将输出:
493: YOUR_SCHEMA.PACKAGE BODY P_STACK.FUNCTION GETCALLSTACK.FUNCTION GETCALLSTACK
4: YOUR_SCHEMA.PACKAGE BODY LOG_TEST.PROCEDURE WRITE_EXEC_LOG
9: YOUR_SCHEMA.PACKAGE BODY LOG_TEST.PROCEDURE TESTPROC1
2: YOUR_SCHEMA.ANONYMOUS BLOCK
493: YOUR_SCHEMA.PACKAGE BODY P_STACK.FUNCTION GETCALLSTACK.FUNCTION GETCALLSTACK
4: YOUR_SCHEMA.PACKAGE BODY LOG_TEST.PROCEDURE WRITE_EXEC_LOG
13: YOUR_SCHEMA.PACKAGE BODY LOG_TEST.PROCEDURE TESTPROC2
3: YOUR_SCHEMA.ANONYMOUS BLOCK
493: YOUR_SCHEMA.PACKAGE BODY P_STACK.FUNCTION GETCALLSTACK.FUNCTION GETCALLSTACK
4: YOUR_SCHEMA.PACKAGE BODY LOG_TEST.PROCEDURE WRITE_EXEC_LOG
13: YOUR_SCHEMA.PACKAGE BODY LOG_TEST.PROCEDURE TESTPROC2
17: YOUR_SCHEMA.PACKAGE BODY LOG_TEST.PROCEDURE TESTPROC3
4: YOUR_SCHEMA.ANONYMOUS BLOCK
适用于9到12的Oracle版本。