Кто такая Диана и почему она не позволяет компилировать объекты моей базы данных? - PullRequest
24 голосов
/ 14 октября 2011

ОК, так что название вопроса немного насмешливо, но вопрос достаточно серьезный.Иногда при компиляции объектов в схеме или импорте файла дампа я вижу следующее сообщение об ошибке:

ORA-04028: cannot generate diana for object SCOTT.VW_EMP

что это на самом деле означает и как этого избежать?

Ответы [ 5 ]

4 голосов
/ 28 октября 2011

Здесь уместно: PL / SQL, размер пакета, узлы дерева разбора, строки кода.

Diana - это язык определения интерфейса Oracle, который представляет структуру таблиц базы данных и логику программных модулей PL / SQL в видеприписанные деревья.

Существуют внутренние ограничения на количество узлов дерева разбора.Версия компилятора устанавливает максимальное количество строк кода.

Итак, проверьте размер логики PL / SQL и строки кода.Может быть невозможным или даже необходимым знать фактические ограничения, которые может обрабатывать ваша версия.

Как только вы узнаете, где выбрать правильный размер вашего пакета, половина проблемы будет решена.

Дайте нам знать, когда вы решите и вторую половину, спасибо.

3 голосов
/ 14 февраля 2013

Не могли бы вы поделиться своим фрагментом кода, в котором вы получаете ошибку.

Вот описание, которое может помочь вам понять, почему вы получаете ошибку: PL / SQL основан на языке программирования ADA,поэтому, когда вы пишете pgram в PL / SQL, она генерирует нотацию «DIANA» -> Descriptive Intermediate Attributed для Ada, древовидного промежуточного языка.DIANA используется внутренне компиляторами и другими инструментами.

Как это работает: 1) Во время компиляции исходный код PL / SQL транслируется в системный код и генерирует соответствующую DIANA.

2) ОбаDIANA и системный код для подпрограммы или пакета хранятся в базе данных.

3) Во время выполнения они загружаются в пул общей памяти.

4) DIANA используется длякомпилировать зависимые подпрограммы;более конкретно, чтобы проверить / подтвердить, что подпрограмма все еще действует.это необходимо, потому что, как мы знаем, подпрограмма может использовать объекты базы данных, такие как таблицы, представления, синонимы или другие хранимые процедуры.Вполне возможно, что объекты могут быть изменены / удалены / отброшены при следующем запуске программы.Например: кто-то мог отбросить таблицу, возможно, изменилась хранимая процедура или структура функции.

5) После выполнения проверки с использованием DIANA системный код просто запускается.

Ограничениев вашей программе:

В пуле совместно используемой памяти спецификация пакета, спецификация ADT, отдельная подпрограмма или анонимный блок ограничены 67108864 (2 ** 26) узлами DIANA, которые соответствуют токенам, таким как идентификаторы, ключевые слова, операторы и тд.Это позволяет использовать ~ 6 000 000 строк кода, если вы не превысите ограничения, наложенные компилятором PL / SQL

, вы можете обратиться по этой ссылке: http://docs.oracle.com/cd/E14072_01/appdev.112/e10472/limits.htm#

Теперь перейдем к вашей проблеме - ora-04028:

Это может быть вызвано одной из следующих причин:

1) Есть некоторые ошибки, которые выдают эту ошибку при выборе из вида, в котором вызывается функция, которая также выбирает изтот же вид

2) Сервер базы данных, клиент или каталог rman не имеют адекватной версии.Вам нужно будет исправить

3) Вы пытаетесь зарегистрировать экземпляр Oracle 11g в каталоге RMAN 10.2.0.1.Чтобы это удалось, обновите каталог как минимум до версии 10.2.0.3

2 голосов
/ 02 сентября 2014

Согласно документации Oracle ,

PL / SQL основан на языке программирования Ada. В PL / SQL используется вариант дескриптивной промежуточной атрибутивной нотации для Ada (DIANA), древовидного промежуточного языка. Он определяется с помощью мета-нотации под названием Язык определения интерфейса (IDL). DIANA используется внутри компиляторами и другими инструментами.

Во время компиляции исходный код PL / SQL транслируется в машиночитаемый m-код. И DIANA, и m-код для процедуры или пакета хранятся в базе данных. Во время выполнения они загружаются в пул общей памяти. DIANA используется для компиляции зависимых процедур; М-код просто выполняется.

К сожалению, вы не можете оценить количество узлов DIANA из проанализированного размера. Для двух программных блоков с одинаковым анализируемым размером может потребоваться 1500 и 2000 узлов DIANA, соответственно, потому что, например, второй блок содержит более сложные операторы SQL.

Спроси у Тома

Подробнее о расчетах узлов DIANA читайте в этой книге "Ada-Europe '93: 12-я Международная конференция Ada-Europe," Ada Sans Frontieres ", Париж, Франция, 14-18 июня 1993 г. Слушания"

Следующая заметка о поддержке хорошо освещает эту тему ...

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:         

Обзор

Эта статья содержит информацию об ограничениях размера пакета PL / SQL. Когда пределы достигнута, вы получаете следующую ошибку:

PLS-123 Program too large

Ограничения на размер пакетов PL / SQL

В выпусках до 8.1.3 большие программы приводили к ошибке PLS-123. Это произошло из-за подлинных ограничений в компиляторе; не в результате ошибки.

При компиляции модуля PL / SQL компилятор создает дерево разбора. Максимальный размер Единица PL / SQL определяется размером дерева разбора. Максимальное количество узлов дианы существует в этом дереве.

До 7,3, вы можете иметь 2 * * 14 (16 КБ) узлов Дианы и от 8,0 до 8,1,3, 2 * * 15 (32 КБ) узлы дианы были разрешены. В 8.1.3 этот предел был ослаблен, так что теперь вы можете иметь 2 * * 26 (то есть 64M) узлов дианы в этом дереве для тел пакетов и типов.

Ограничения исходного кода

Хотя не существует простого способа перевести ограничения в терминах строк исходного кода, мы наблюдали, что в каждой строке исходного кода было приблизительно от 5 до 10 узлов. До 8.1.3 компилятор мог без проблем компилировать до 3000 строк кода.

Начиная с 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

Это приблизительная оценка. Если в вашем коде много пробелов, длинных идентификаторов и т. Д., Вы можете в конечном итоге с исходным кодом больше, чем это. Вы также можете получить меньший исходный код чем это, если ваши источники используют очень короткие идентификаторы и т. д.

Обратите внимание, что это на единицу программы, поэтому тела пакета, скорее всего, столкнутся с этим предел.

Как проверить текущий размер пакета

Чтобы проверить размер пакета, ближайший связанный номер, который вы можете использовать, это PARSED_SIZE в представление словаря данных USER_OBJECT_SIZE. Это значение обеспечивает размер ДИАНЫ в байты хранятся в таблицах SYS.IDL_xxx $ и НЕ имеют размер в общем пуле.

Размер части DIANA кода PL / SQL (используемого во время компиляции) НАМНОГО больше в общий пул, чем в системной таблице.

Например, у вас могут начаться проблемы с ограничением в 64 КБ, когда PARSED_SIZE в USER_OBJECT_SIZE не превышает 50 КБ.

Для пакета анализируемый размер или размер DIANA имеет смысл только для всего объекта, а не отдельно для спецификации и тела.

Если вы выбрали parsed_size для пакета, вы получите отдельный исходный код и размеры кода для спецификации и тела, но только значимый проанализированный размер для всего объекта, который выводится в строке для спецификации пакета.0 выводится для parsed_size в строке для тела пакета.

Следующий пример демонстрирует это поведение:

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';  

  .....

Oracle сохраняет DIANA и MCODE в базе данных.MCODE - это фактический код, который выполняется, в то время как DIANA для конкретного библиотечного модуля X содержит информацию, необходимую для компиляции процедур с использованием библиотечного модуля X.

Ниже приведены несколько примечаний:

a) DIANAпредставлен в IDL.Линейная версия IDL хранится на диске.Фактическое дерево разбора создается и сохраняется в общем пуле.Вот почему размер DIANA в общем пуле обычно больше, чем на диске.

b) DIANA для вызываемых процедур требуется в общем пуле только при создании процедур.В производственных системах нет необходимости в DIANA в общем пуле (но только для MCODE).

c) Начиная с версии 7.2, DIANA для корпусов пакетов выбрасывается, не используется и не сохраняется в базе данных.Вот почему PARSED_SIZE (т.е. размер DIANA) ОРГАНОВ ПАКЕТА равен 0.

Поэтому в процедурах всегда должны быть определены большие процедуры и функции!

Пакетхранится в DIANA в базе данных, как процедура.Однако пакет может использоваться для разрыва цепочки зависимостей, что, возможно, и устранит это.Я уверен, что ВСЕ производственный (реальный) код должен быть в пакете, а не в отдельной процедуре или функции.

1 голос
/ 09 октября 2014

В Oracle 10.2.5 есть ошибка (неопубликованная ошибка 9342254; см. Doc ID 1505092.1), для которой существует исправление Oracle 11.1 и новее; Я думаю, что это могло быть проблемой в игре здесь.

Вы можете обойти его, выполнив сброс общего пула:

ALTER SYSTEM FLUSH SHARED_POOL

NB. Это очень старый вопрос, но я оставляю его здесь на тот случай, если кто-нибудь еще столкнется с этим вопросом. Ninesided и я на самом деле работаем в одной компании, и столкнулись с этим независимо.

0 голосов
/ 14 октября 2011

У меня была похожая проблема при компиляции больших пакетов в режиме отладки. Это происходит, если размер отладочной информации превышал лимит компилятора на размер таблицы символов отладки. Вы можете отключить режим отладки с помощью

alter session set plsql_debug=false; 

или для всей базы данных:

alter system set plsql_debug=false;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...