Oracle 如何访问PL/SQL存储过程的AST(抽象语法树)?

Oracle 如何访问PL/SQL存储过程的AST(抽象语法树)?,oracle,syntax,plsql,Oracle,Syntax,Plsql,Oracle编译存储过程时,会以DIANA格式存储该过程的AST 如何访问此AST 是否有用于处理此AST的内置工具 有一个未记录的包DUMPDIANA,用于以人类可读的格式转储Diana 文件$ORACLE_HOME\rdbms\admin\dumpdian.sql说“文档可以在/vobs/plsql/notes/dumpdiana.txt中找到”。我找不到那个文件,没有它,我们只能猜测一些参数的含义。DUMPDIANA的基本用法如下: SQL> show user USER is "

Oracle编译存储过程时,会以DIANA格式存储该过程的AST

  • 如何访问此AST
  • 是否有用于处理此AST的内置工具

有一个未记录的包DUMPDIANA,用于以人类可读的格式转储Diana

文件$ORACLE_HOME\rdbms\admin\dumpdian.sql说“文档可以在/vobs/plsql/notes/dumpdiana.txt中找到”。我找不到那个文件,没有它,我们只能猜测一些参数的含义。DUMPDIANA的基本用法如下:

SQL> show user
USER is "SYS"
SQL> @?\rdbms\admin\dumpdian

Library created.


Package created.


Package body created.

create or replace procedure hello_world
  2  as
  3  begin
  4  dbms_output.put_line('hello world');
  5* end;


Procedure created.

SQL> set serveroutput on
SQL> execute sys.DUMPDIANA.dump('HELLO_WORLD');
user: SYS

PL/SQL procedure successfully completed.
此时,应在文件夹中创建一对文件
$ORACLE_BASE/diag/rdbms/orcl12c/orcl12c/trace
。这两个文件似乎遵循命名约定:

orcl12c_ora_{PROCESS}.trc
orcl12c_ora_{PROCESS.trm
其中,trc文件是相应trm文件的可读版本,{PROCESS}是操作系统进程ID。要查找此文件,请使用来自同一会话的以下查询:

select p.spid from v$session s,v$process p 
where s.paddr = p.addr
and s.sid = sys_context('USERENV','SID');
例如,如果会话ID为8861,则可以从bash shell使用以下命令查看结果:

vim $ORACLE_BASE/diag/rdbms/orcl12c/orcl12c/trace/orcl12c_ora_8861.trc
结果很有趣。。。如果不是特别直观!例如,这里是生成的文件的一个片段。请注意HELLO_世界字符串文字

PD1(2):D_COMP_U  [
    L_SRCPOS : row 1 col 1
    A_CONTEX :
PD2(2):      D_CONTEX  [
          L_SRCPOS : row 1 col 1
          AS_LIST :  < >
      ]
    A_UNIT_B :
PD3(2):      D_S_BODY  [
          L_SRCPOS : row 1 col 1
          A_D_ :
PD4(2):            DI_PROC  [
                L_SRCPOS : row 1 col 11
                L_SYMREP : HELLO_WORLD,
                S_SPEC : PD5^(2),
                S_BODY : PD8^(2),
PD1(2):D_COMP_[
L_SRCPOS:第1行第1列
A_CONTEX:
PD2(2):D_CONTEX[
L_SRCPOS:第1行第1列
AS_列表:<>
]
A_单位B:
PD3(2):D_S_机构[
L_SRCPOS:第1行第1列
答:
PD4(2):直接程序[
L_SRCPOS:第1行第11列
你好,世界,
S_规范:PD5^(2),
立法会会议过程正式纪录,

几点注意事项。我以SYS的身份运行了它,我们知道这不是一个好的做法,我不知道为什么你不应该向普通用户授予DUMPDIANA权限。你转储的所有过程都进入同一个文件中-如果你删除该文件,它将停止工作,你需要启动一个新会话。如果它停止工作,则启动一个新会话session有时似乎可以解决问题。

这里有一个关于DIANA和IDL的优秀PDF教程,作者是撰写本文时西门子的首席顾问Pete Finnigan,专门研究和保护Oracle数据库

在其他非常有趣的事情中,您将了解到:

  • DIANA被写为IDL(接口定义语言)
  • IDL存储在4个表中(IDL_CHAR$、IDL_SB4$、IDL_UB1$和IDL_UB2$)
  • 包装器PL/SQL简单地写为IDL
  • 默认情况下未安装Dumpdiana,您需要确保也安装了DIANA、PIDL和DIUTIL PL/SQL包,并且需要将其作为SYS运行
  • 如何抛弃戴安娜树并理解它
  • 如何从DIANA重构PL/SQL源
  • 如何编写PL/SQL un包装器
  • 基于PL/SQL API的un包装的局限性
  • PL/SQLAPI本身的局限性
  • 如何枚举节点和属性
  • 一个概念的证明
你可以找到。那里有太多的内容。你会发现,也会发现,不仅是他,还有其他作者开发了很多内容


最重要的是,如果阅读后你还有问题,你可以与他联系。

我以前没有遇到过缩写AST。我唯一一次看到有关DIANA的内容是在文档的PL/SQL程序限制部分,该部分讨论了PL/SQL如何使用DIANA的变体和接口定义语言(IDL)。你为什么要访问或处理它?我不知道有什么方法可以访问它,但我相信如果你真的确定的话,你可能会找到一些
x$
表和块转储的组合来查看它。但是可能有一种更简单的方法来获取你需要的东西。Alexandre Porcelli已经在Github上发布了。显然没有t内置,可能不完整,但可能适合您的需要。@jon heller感谢您的编辑。几次(或多次)之后,当然,我发现它会将数据转储到一个文件中,这有点烦人,因为它会使数据库中的数据难以进一步处理。我们可以使用外部表将其读回,然后对其进行某种解析,或者dumpdiana是错误的路径,并且有其他方法以更为相关的方式获取ASTdly格式。此更新肯定回答了这个问题。不幸的是,结果可能仍然太神秘而没有用处。我将让悬赏保持几天,看看是否有人可以改进它。对于正在研究此的任何其他人:此文档(看起来直接来自《广告狂人》道具柜)描述了DIANA语言的一些细节。这是一些有用的理论信息,但似乎离实际解决方案还有数百小时的工作时间。