#oracle #stored-procedures #views
#Oracle #хранимые процедуры #Вид
Вопрос:
Хорошо, название вопроса немного иронично, но вопрос достаточно серьезный. Иногда при компиляции объектов в схеме или импорте файла дампа я вижу следующее сообщение об ошибке:
ORA-04028: cannot generate diana for object SCOTT.VW_EMP
что это на самом деле означает и как я могу этого избежать?
Комментарии:
1. Форум dbasupport.com/forums/archive/index.php/t-36201.html говорит, что «DIANA означает описательную промежуточную атрибутивную нотацию для Ada». Звучит так, как будто что-то генерируется из вашего кода в фоновом режиме, и у него возникли некоторые проблемы 🙂
2. Большинство ссылок, которые я вижу в Google, связаны с конфликтами блокировок. Возможно, стоит изучить, если что-то блокирует этот объект.
3. @LasseV.Karlsen — как это может произойти при импорте? Когда или если impdp блокирует объекты, я не могу контролировать…
4. Я понятия не имею, я просто нашел вопрос достаточно интересным, чтобы поискать его в Google, я не эксперт Oracle (или пользователь, если на то пошло.)
5. 1: Замечательный заголовок, странная проблема, хорошая вещь, чтобы получить окончательный ответ.
Ответ №1:
Здесь уместно: PL / SQL, размер пакета, узлы дерева синтаксического анализа, строки кода.
Diana — это язык определения интерфейса Oracle для представления структуры таблиц базы данных и логики программных модулей PL / SQL в виде атрибутивных деревьев.
Существуют внутренние ограничения на количество узлов дерева синтаксического анализа. Версия компилятора устанавливает максимальное количество строк кода.
Поэтому проверьте размер логики PL / SQL и строк кода. Возможно, невозможно или даже необходимо знать фактические ограничения, которые может обрабатывать ваша версия.
Как только вы узнаете, какой размер вашего пакета правильный, половина проблемы решена.
Дайте нам знать, когда вы решите и вторую половину, спасибо.
Комментарии:
1. шурик, переполнение таблицы символов отладки могло произойти как предупреждение о надвигающейся катастрофе, может быть? должны ли мы остановиться на лечении симптома? Если бы вы отключили debug и еще больше увеличили размер пакета, gaasp, Диана позвонила бы?
Ответ №2:
Не могли бы вы поделиться своим фрагментом кода, в котором вы получаете ошибку.
Вот описание, которое может помочь вам понять, почему вы получаете ошибку: PL / SQL основан на языке программирования под названием ADA . поэтому, когда вы когда-либо пишете pgram на PL / SQL, он генерирует «DIANA» -> Описательная промежуточная атрибутивная нотация для Ada , древовидного промежуточного языка. DIANA используется внутри компиляторов и других инструментов.
Как это работает: 1) Во время компиляции исходный код PL / SQL преобразуется в системный код и генерирует соответствующий DIANA.
2) Как DIANA, так и системный код для подпрограммы или пакета хранятся в базе данных.
3) Во время выполнения они загружаются в пул общей памяти.
4) DIANA используется для компиляции зависимых подпрограмм; более конкретно, для проверки / подтверждения того, что подпрограмма все еще действительна. это необходимо, потому что, как мы знаем, подпрограмма может использовать объекты базы данных, такие как таблицы, представления, синонимы или другие хранимые процедуры. возможно, что объекты могли быть изменены / удалены / удалены при следующем запуске программы. Например: кто-то мог удалить таблицу, возможно, изменилась сохраненная процедура или функция singnature .
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 в каталоге 10.2.0.1 RMAN. Чтобы это удалось, обновите каталог как минимум до версии 10.2.0.3
Ответ №3:
Согласно документации Oracle,
PL / SQL основан на языке программирования Ada. В PL/SQL используется вариант описательной промежуточной атрибутивной нотации для Ada (DIANA), древовидного промежуточного языка. Он определяется с помощью мета-нотации, называемой Interface Definition Language (IDL). DIANA используется внутри компиляторов и других инструментов.
Во время компиляции исходный код PL / SQL преобразуется в машиночитаемый m-код. В базе данных хранятся как DIANA, так и m-код для процедуры или пакета. Во время выполнения они загружаются в пул общей памяти. DIANA используется для компиляции зависимых процедур; m-код просто выполняется.
К сожалению, вы не можете оценить количество узлов DIANA по проанализированному размеру. Для двух программных модулей с одинаковым анализируемым размером может потребоваться 1500 и 2000 узлов DIANA соответственно, потому что, например, второй модуль содержит более сложные операторы SQL.
Подробнее о вычислениях узлов DIANA читайте в этой книге «Ada-Europe ’93: 12-я международная конференция Ada-Europe, «Ада без границ», Париж, Франция, 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 определяется размером дерева синтаксического анализа. В этом дереве существует максимальное количество узлов diana.
До версии 7.3 у вас могло быть 2 * * 14 (16 Тыс.) узлов diana, а с 8.0 по 8.1.3 было разрешено 2 * * 15 (32 тыс.) узлов diana. С 8.1.3 это ограничение было ослаблено, так что теперь у вас может быть 2 * * 26 (т. Е. 64M) узлов diana в этом дереве для тел пакетов и типов.
Ограничения исходного кода
Хотя не существует простого способа перевести ограничения в терминах строк исходного кода, по нашим наблюдениям, в строке исходного кода было примерно от 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 . Это значение определяет размер DIANA в байтах, хранящихся в таблицах 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.
Ниже приведены несколько примечаний:
а) ДИАНА представлена в IDL. Линейная версия IDL хранится на диске. Фактическое дерево синтаксического анализа создается и сохраняется в общем пуле. Вот почему размер DIANA в общем пуле обычно больше, чем на диске.
б) DIANA для вызываемых процедур требуется в общем пуле только при создании процедур. В производственных системах нет необходимости в DIANA в общем пуле (но только для MCODE).
c) Начиная с версии 7.2, DIANA для тел пакетов выбрасывается, не используется и не сохраняется в базе данных. Вот почему PARSED_SIZE (т. Е. Размер DIANA) ТЕЛ ПАКЕТОВ равен 0.
Поэтому большие процедуры и функции всегда должны определяться в пакетах!
Пакет хранится в DIANA в базе данных, точно так же, как процедура. Однако для разрыва цепочки зависимостей можно использовать пакет, который, возможно, устранит это. Я считаю, что ВЕСЬ производственный (реальный) код должен быть в пакете, а не в отдельной процедуре или функции.
Ответ №4:
В Oracle 10.2.5 есть ошибка (неопубликованная ошибка 9342254; см. Документ ID 1505092.1), для которой есть исправление Oracle 11.1 и более поздних версий; Я думаю, что это, возможно, было проблемой здесь.
Вы можете обойти это, выполнив сброс общего пула:
ALTER SYSTEM FLUSH SHARED_POOL
ПРИМЕЧАНИЕ. Это очень старый вопрос, но я оставляю его здесь на случай, если кто-нибудь еще столкнется с этим вопросом. Мы с Ninesided на самом деле работаем в одной компании и столкнулись с этим независимо.
Ответ №5:
У меня была похожая проблема при компиляции больших пакетов в режиме отладки. Это происходит, если размер отладочной информации превысил ограничение компилятора на размер таблицы символов отладки. Вы можете отключить режим отладки с помощью
alter session set plsql_debug=false;
или для всей базы данных:
alter system set plsql_debug=false;
Комментарии:
1.
impdp
использует ли режим отладки при импорте объектов?