在共享内存池中,包规范,对象类型规范,独立子程序或匿名块仅限于67108864(2**26)DIANA节点,这些节点对应于标识符,关键字,运算符等标记.
DIANA代表什么?我知道完整的表格.但究竟是什么呢?
我已经提到 谁是戴安娜,她为什么不让我的数据库对象编译? 所以不要将其标记为重复.
我想知道这个概念是什么,谁创造了这个术语等等.如果可能,他们如何告诉我们."这允许大约6,000,000行代码,除非你超过PL/SQL编译器施加的限制",他们如何达到该值?
Sri*_*niV 11
根据Oracle文档,
PL/SQL基于编程语言Ada.PL/SQL使用Ada的描述性中间归因表示法(DIANA)的变体,这是一种树形结构的中间语言.它使用称为接口定义语言(IDL)的元符号来定义.DIANA由编译器和其他工具在内部使用.
在编译时,PL/SQL源代码被翻译成机器可读的m代码.过程或包的DIANA和m代码都存储在数据库中.在运行时,它们将加载到共享内存池中.DIANA用于编译依赖程序; 简单地执行m代码.
不幸的是,您无法从解析的大小估计DIANA节点的数量.具有相同解析大小的两个程序单元可能分别需要1500和2000个DIANA节点,因为例如,第二个单元包含更复杂的SQL语句.
有关DIANA节点计算的更多内容,请阅读本书"Ada-Europe'93:第12届Ada-Europe国际会议","Ada Sans Frontieres",法国巴黎,1993年6月14日至18日.会议录"
以下支持说明很好地涵盖了这个主题......
Article-ID: <Note:62603.1>
Folder: PLSQL
Topic: General Information Articles
Title: 'PLS-123 Program too Large' - Size Limitations on PLSQL
Packages
Document-Type: BULLETIN
Impact: MEDIUM
Skill-Level: NOVICE
Server-Version: 07 to 08
Updated-Date: 13-JUN-2000 17:41:01
References:
Run Code Online (Sandbox Code Playgroud)
本文包含有关PL/SQL包大小限制的信息.达到限制时,您会收到以下错误:
PLS-123 Program too large
Run Code Online (Sandbox Code Playgroud)
在8.1.3之前的版本中,大型程序导致PLS-123错误.这是因为编译器的真正限制; 不是因为一个bug.
编译PL/SQL单元时,编译器会构建一个解析树.PL/SQL单元的最大大小由解析树的大小决定.此树中存在最大数量的戴安娜节点.
高达7.3,您可以拥有2**14(16K)diana节点,并且允许从8.0到8.1.3,2**15(32K)diana节点.使用8.1.3,此限制已经放宽,因此您可以在此树中为包和类型主体提供2**26(即64M)diana节点.
虽然没有简单的方法来转换源代码行的限制,但我们观察到每行源代码大约有5到10个节点.在8.1.3之前,编译器可以干净地编译多达3,000行代码.
从8.1.3开始,包体和类型体的限制被放宽,现在可以有大约6,000,000行代码.
注意:此新限制仅适用于包体和类型主体.此外,在达到此特定编译器限制之前,您现在可能会开始达到其他一些编译器限制.
就源代码大小而言,假设令牌(标识符,运算符,函数等)平均长度为四个字符.然后,最大值将是:
Up to 7.3: 4 * (2 * * 14)=64K
From 8.0 to 8.1.3: 4 * (2 * * 15)=128K
With 8.1.3: 4 * (2 * * 25)=256M
Run Code Online (Sandbox Code Playgroud)
这是一个粗略的估计.如果您的代码有许多空格,长标识符等,您最终可能会得到大于此的源代码.如果源使用非常短的标识符等,您最终可能会得到小于此的源代码.
请注意,这是每个程序单元,因此包体最有可能遇到此限制.
要检查包的大小,可以使用的最接近的相关数字是数据字典视图USER_OBJECT_SIZE中的PARSED_SIZE.此值提供存储在SYS.IDL_xxx $表中的DIANA大小(以字节为单位),而不是共享池中的大小.
PL/SQL代码(在编译期间使用)的DIANA部分的大小在共享池中比在系统表中大得多.
例如,当USER_OBJECT_SIZE中的PARSED_SIZE不超过50K时,您可能会遇到64K限制的问题.
对于包,DIANA的解析大小或大小仅对整个对象有意义,而不是对规范和正文分开.
如果为包选择parsed_size,则会为规范和正文接收单独的源和代码大小,但只有整个对象的有意义的解析大小才会在包规范的行上输出.在包体的行上为parsed_size输出0.
以下示例演示了此行为:
CREATE OR REPLACE PACKAGE example AS
PROCEDURE dummy1;
END example;
/
CREATE OR REPLACE PACKAGE BODY example AS
PROCEDURE dummy1 IS
BEGIN
NULL;
END;
END;
/
SQL> start t1.sql;
Package created.
Package body created.
SQL> select parsed_size from user_object_size where name='EXAMPLE';
PARSED_SIZE
-----------
185
0
SQL> select * from user_object_size where name='EXAMPLE';
.....
Run Code Online (Sandbox Code Playgroud)
Oracle将DIANA和MCODE存储在数据库中.MCODE是运行的实际代码,而特定库单元X的DIANA包含使用库单元X编译过程所需的信息.
以下是几点说明:
a)DIANA代表IDL.IDL的线性版本存储在磁盘上.构建实际的解析树并将其存储在共享池中.这就是共享池中DIANA的大小通常大于磁盘的原因.
b)只有在创建过程时,才需要在共享池中使用DIANA作为被调用过程.在生产系统中,共享池中不需要DIANA(但仅适用于MCODE).
c)从7.2版开始,包装体的DIANA被丢弃,未被使用,并且不存储在数据库中.这就是PACKAGE BODIES的PARSED_SIZE(即DIANA的大小)为0的原因.
因此,应始终在包内定义大的过程和函数!
包在DIANA中存储在数据库中,就像一个过程一样.然而,一个包可以用来打破依赖链,也许会让它消失.我相信所有生产(真实)代码都应该在一个包中,而不是在一个独立的程序或函数中.