OBJECT_NAME(@@PROCID)
在PL / sql中,当我将以下代码放在包的存储过程上时,它返回父包的名称而不是执行的存储过程.
$$PLsql_UNIT
解决方法
> V $SESSION视图具有PLsql_ENTRY_SUBPROGRAM_ID和PLsql_SUBPROGRAM_ID字段,可以引导您进入当前正在执行的过程.
本届会议是:
select PLsql_ENTRY_OBJECT_ID,PLsql_ENTRY_SUBPROGRAM_ID,PLsql_OBJECT_ID,PLsql_SUBPROGRAM_ID from V$SESSION where AUDSID = sys_context( 'userenv','sessionid' )
select PROCEDURE_NAME from ALL_PROCEDURES where OBJECT_ID = :objectId and SUBPROGRAM_ID = :subprogramId
此视图包含在包中声明的函数和过程,但不包含在包体中声明的函数和过程.
> dbms_utility.format_call_stack显示行号和源名称.可以通过owa_util.who_called_me获得解析输出.原始输出还包含对象句柄,可以让您访问匿名块的源代码.
dbms_utility.format_call_stack示例输出:
----- PL/sql Call Stack ----- object line object handle number name B87FEF1C 1 anonymous block
然后:
select sql_FULLTEXT from V$sql where CHILD_ADDRESS = 'B87FEF1C'
存储过程的源代码可以从ALL_SOURCE获得.
>一旦获得了调用方法的源代码和该代码中的行号,就可以解析它以获取过程名称.
唯一不好的例子是单行.但这是一种罕见的情况.
procedure outer is procedure inner is begin whoami; end; begin whoami; end;
您有关于此行调用whoami的信息.但你不知道它是第一次出现还是第二次出现.因此,即使解析源代码也无法引导您找到确切的解决方案.
可以通过解析源代码来处理其他情况. Here是我的尝试.样品用法:
create package APCKG is procedure PROC; end; / create package body APCKG is procedure PROC is procedure "INNER/proc" is begin dbms_output.put_line( p_stack.whoAmI ); end; begin "INNER/proc"; end; end; / begin APCKG.PROC; end;
输出:
5: YOUR_SCHEMA.PACKAGE BODY APCKG.PROCEDURE PROC.PROCEDURE "INNER/proc"
输出格式:
Line number + ': ' + Owner + [ '.' + Type + ' ' + Name ]*
所以它只返回最后一个调用者及其层次结构.在位于包体内的函数内部的另一个过程.
如果您需要精确的解决方案并使用Oracle 12,请使用utl_call_stack.此解决方案适用于先前版本(在10.2上测试).它将返回上面的单行示例的第一次出现.
UPD:
>在Oracle 9(separate package version),10和11上进行了测试.
>它确实解析了源(即词法分析,标记化等).
>纯PL / sql.
>解析匿名阻止源代码(它们也可以包含内部过程).
>包含类似于utl_call_stack的方法.
>方法whoAmI和whoCalledMe.
>支持双引号.
>支持字符串的q表示法.
>跳过多行和单行注释.
>跳过没有定义的过程和函数声明.
UPD 2:
UPD 3: