首页 文章

获取Oracle中的调用包/过程

提问于
浏览
2

我正在Oracle 10g中编写一个日志记录过程,该过程使用以下插入写入表:

INSERT INTO EXEC_LOG VALUES (
  (SELECT SYS_CONTEXT('USERENV','SESSIONID') sessionid FROM dual),
  strPackage, strProcedure, strEventType, strEventLevel, SYSDATE, strMessage
);

此过程在多个不同的包/过程中重用,但现在的方式是,程序员必须将其包/过程名称传递给日志记录过程( strPackagestrProcedure ) .

我想知道是否有一个v $视图或Oracle中的某些东西可以告诉我调用此过程的包/过程,从而消除了程序员传入 strPackagestrProcedure 的需要 .

例:

如果我称这两个程序:

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 / TestProc1log_test / TestProc2 .

3 回答

  • 0

    从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
  • 3

    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版本 .

相关问题