Oracle регистрация типов дополнительных сведений тдс
В многочисленных темах на форуме в качестве перехода на статическую регистрацию
предлагается прописать SID_LIST_LISTENER соответствующими значениями.
Надо ли понимать из Вашего ответа, что будут существовать два вида регистрации ?
Если да, то тогда почему в качестве рецепта для решения ORA-12514 предлагается переход на статическую форму регистрации ? Скрипт подправили, но динамическая форма осталась (это к вопросу номер 2).
Потому, что динамическая регистрация происходит не мгновенно, а по таймауту (после старта инстанции) - поэтому лучше статикой, чтобы не ловить ошибок, а подключаться без проблем.
Правильно ли я понял, что прописав в лисенере сей параметр, динамическая регистрация будет отключена ?
Я оперирую терминами, взятыми из приведенной цитаты из литературы:
. Процесс PMON Oracle отвечает за динамическую регистрацию имен служб баз данных
Oracle в слушателе.
Я оперирую терминами, взятыми из приведенной цитаты из литературы:
. Процесс PMON Oracle отвечает за динамическую регистрацию имен служб баз данных
Oracle в слушателе.
Давайте, так. Хочу понять почему для решения проблемы с ошибкой ORA-12514 постоянно советуют перейти на статическую регистрацию. (Что было понятно и мне и Вам - сами подскажите регистрацию чего именно). Если после правки SID_LIST_LISTENER начинает осуществляться статическая регистрация и при этом как-бы не ушла динамическая регистрация, то почему эта правка является решением проблемы ?
Не соглашусь: Win-довая практика показывает, что иногда интервал доходит и до минуты.
могут быть как секунды, так и минуты. регистрирует PMON, для которого есть наверно более приоритетные задачи ;)
тенденцию можно проследить в логи листенера, замеряя разницу между
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 128.17.8.8)(PORT = 1521)(QUEUESIZE=7))
)
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC))
)
)
)
Результаты команды lsnrctl с опциями status и services
LSNRCTL for Linux: Version 9.2.0.1.0 - Production on 30-СЕН-2010 14:02:04
Copyright (c) 1991, 2002, Oracle Corporation. All rights reserved.
Соединяется с (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=128.17.8.8)(PORT=1521)(QUEUESIZE=7)))
СТАТУС ПРОСЛУШИВАТЕЛЯ
------------------
Псевдоним LISTENER
Версия TNSLSNR for Linux: Version 9.2.0.1.0 - Production
Начальная Дата 29-СЕН-2010 19:48:16
Время работы 0 дней 18 час. 13 мин. 47 сек
Уровень трассировки off
Защита OFF
SNMP OFF
Файл параметров прослушивателя /opt/oracle/product/9ir2/network/admin/listener.ora
Журн.файл прослушивателя /opt/oracle/product/9ir2/network/log/listener.log
Сводка прослушивания конечных точек.
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=128.17.8.8)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC)))
Резюме Сервиса.
Служба "midas.pc.os.su" имеет 1 экземпл.
Экземпляр "midas", состояние READY, имеет 1 указат. для данной службы.
Команда выполнена успешно.
LSNRCTL for Linux: Version 9.2.0.1.0 - Production on 30-СЕН-2010 14:01:34
Copyright (c) 1991, 2002, Oracle Corporation. All rights reserved.
Соединяется с (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=128.17.8.8)(PORT=1521)(QUEUESIZE=7)))
Резюме Сервиса.
Служба "midas.pc.os.su" имеет 1 экземпл.
Экземпляр "midas", состояние READY, имеет 1 указат. для данной службы.
Указатель(-и):
установлен "DEDICATED":787 отклонен:0 состояние:ready
LOCAL SERVER
Команда выполнена успешно.
Часть содержимого алерта.
Содержимое еще одной трассировки
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 128.17.8.8)(PORT = 1521)(QUEUESIZE=7))
)
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC))
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = midas.pc.os.su)
(ORACLE_HOME = /opt/oracle/product/9ir2)
(SID_NAME = midas)
)
)
Результаты команды lsnrctl с опциями status и services
LSNRCTL for Linux: Version 9.2.0.1.0 - Production on 30-СЕН-2010 14:34:49
Copyright (c) 1991, 2002, Oracle Corporation. All rights reserved.
Соединяется с (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=128.17.8.8)(PORT=1521)(QUEUESIZE=7)))
СТАТУС ПРОСЛУШИВАТЕЛЯ
------------------
Псевдоним LISTENER
Версия TNSLSNR for Linux: Version 9.2.0.1.0 - Production
Начальная Дата 30-СЕН-2010 14:29:34
Время работы 0 дней 0 час. 5 мин. 14 сек
Уровень трассировки off
Защита OFF
SNMP OFF
Файл параметров прослушивателя /opt/oracle/product/9ir2/network/admin/listener.ora
Журн.файл прослушивателя /opt/oracle/product/9ir2/network/log/listener.log
Сводка прослушивания конечных точек.
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=128.17.8.8)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC)))
Резюме Сервиса.
Служба "midas.pc.os.su" имеет 2 экземпл.
Экземпляр "midas", состояние UNKNOWN, имеет 1 указат. для данной службы.
Экземпляр "midas", состояние READY, имеет 1 указат. для данной службы.
Команда выполнена успешно.
LSNRCTL for Linux: Version 9.2.0.1.0 - Production on 30-СЕН-2010 14:34:56
Copyright (c) 1991, 2002, Oracle Corporation. All rights reserved.
Соединяется с (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=128.17.8.8)(PORT=1521)(QUEUESIZE=7)))
Резюме Сервиса.
Служба "midas.pc.os.su" имеет 2 экземпл.
Экземпляр "midas", состояние UNKNOWN, имеет 1 указат. для данной службы.
Указатель(-и):
"DEDICATED" установлено:15 отказано:0
LOCAL SERVER
Экземпляр "midas", состояние READY, имеет 1 указат. для данной службы.
Указатель(-и):
установлен "DEDICATED":25 отклонен:0 состояние:ready
LOCAL SERVER
Команда выполнена успешно.
Часть содержимого алерта.
Содержимое еще одной трассировки
На одном из наших недавних проектов мы столкнулись с серьёзной проблемой. Веб-приложение, которое мы разрабатывали, должно было использовать внутренюю базу данных финансовой организации. Из соображений безопасности, доступ был очень сильно ограничен: любые изменения необходимо было делать при помощи хранимых процедур, а читать данные — только при помощи представлений. Таким образом, приложение должно было выполнять сложные манипуляции данными, не имея никакого представления об их структуре. Основной загвоздкой для нас было то, что наше приложение попадало в зависимость от больших и сложных процедур, для которых не существовало автоматизированных тестов.
Погуглив немного, мы обнаружили, что в штатном инструментарии Oracle SQL Developer [1] есть функционал для создания автоматизированных тестов. Мы тут же приступили к его изучению. И хотя тесты для самой сложной процедуры пришлось создавать уже после её написания, этот инструментарий всё же помог нам устранить несколько ошибок, а также существенно облегчил процесс расширения функционала и рефакторинга. Ниже я приведу пример использования TDD для построения хранимых процедур, а также поделюсь опытом в работе с инструментарием.
Пример использования
Структура данных
Приложение использует следующую структуру данных:
Для краткости, определения первичных и внешних ключей опущены.
Настройка окружения
Юнит-тестирование в SQL Developer использует базу данных для хранения тестов, их настроек, библиотеки, и результатов выполнения. В этих целях настоятельно рекомендуется создать пользователя для тестирования, затем создать в его базе данных репозиторий. Этот процесс более подробно описан в документации по юнит-тестированию [2].
Терминология тестирования Oracle
Терминология тестирования, которую использует Oracle несколько отличается от общепринятой терминоголии xUnit [3]:
xUnit | SQL Developer | Комментарий к SQL Developer |
---|---|---|
Набор тестов | Test Suite | Может включать другие наборы тестов и/или сценарии |
Тестовый сценарий | Test | Может тестировать только одну функцию или процедуру |
Тест | Test Implementation | |
Настройка контекста (setup) | Startup Process | Доступна на уровне теста и набора тестов |
Сброс контекста (tear down) | Teardown Process | см. выше |
Далее в тексте я буду использовать русский вариант терминологии xUnit.
Неожиданности
Работая с приложением, мы обнаружили, что оно не всегда работает так, как мы ожидали:
- Иногда, все пункты меню юнит-тестирования оказывались отключенными. В таких случаях необходимо щёлкнуть пункт меню View→Unit Test
- Все тесты внутри сценария используют общий набор настройки и сброса контекста, что вполне логично. Но из-за того, что редактируются они через вкладку теста, создаётся ощущение, что их можно персонализировать для каждого теста отдельно.
Разработка с помощью тестирования
Прежде чем мы сможем начать, необходимо создать пустую процедуру, а иначе невозможно будет создать тест. И хотя список аргументов можно оставить пустым, в этом нет никакой необходимости.
В случае с Oracle, имеет смысл задавать префикс для переменных, имя которых может совпасть с названием поля, так как в случае неясности, знаменитая СУБД решит спор в пользу поля. А во избежании беспорядка, проще давать префикс всем переменным без исключения.
Если параметры процедуры изменились, то каждый её тестовый сценарий необходимо обновить вручную, щёлкнув пункт контекстного меню Synchronize Test.
Первый сценарий
Самый быстрый способ создать тест — щёлкнуть правой кнопкой мыши на процедуре в дереве объектов, затем выбрать пункт меню Create Unit Test. . В появившемся окне можно сразу нажать кнопку Finish. Сценарий QUEUE_MESSAGE с единственным тестом должен появиться в панели Unit Test.
Настройка контекста
Сначала нам необходимо будет заполнить базу необходмыми данными. Для нас самым удобным оказалось использование режима PL/SQL для настройки и сброса контекста. Тем не менее, любой из вариантов легко использовать повторно при помощи публикации в библиотеку. Чтобы скопировать существующий шаг из библиотеки, достаточно выбрать его из выпадающего списка, затем нажать кнопку Copy. А если нужно использовать его без изменений, но вместо кнопки Copy необходимо нажать чекбокс Subscribe.
Идея использовать существующую БД для тестирования может показаться привлекательной. Казалось бы, сохранил данные в настройке, и восстановил при сбросе контекста… Однако следует иметь в виду, что если в процессе выполнения тестов на любом этапе произошла непредвиденная ошибка, то база данных окажется в том виде, в каком она была во время ошибки, и сброс контекста выполнен не будет. Поэтому лучше всего использовать чистую базу данных, которую не страшно и несложно полностью пересоздать в случае порчи структуры или данных.
Предполагая, что мы работаем с пустой базой данных, для настойки контекста, нам понадобится всего лишь одна вставка записи пост-оплатного клиента. Её можно тут же сохранить в библиотеке, назвав Пост-оплатный клиент.
Сброс контекста
Чтобы иметь возможность повторного прогона тестов, необходимо очистить добавленные данные. Однадко, в нашем случае, можно просто очистить все таблицы, затрагиваемые тестами. Этот шаг также нужно сохранить в библиотеку для дальнейшего использования.
Вызов
Непосредственно выполнение теста определяется при помощи задания параметров хранимой процедуры. Здесь же задаются и значения выходных параметров для проверки. Проверку выходных параметров можно отключить при помощи чекбокса Test Result. Он относится к параметрам, заданным как в таблице, так и динамически.
С виду может показаться, что задавать параметры мышкой в таблице очень удобно, однако необходимо иметь в виду, что эта таблица копированию не подлежит. Это особенно важно для процедур с большим количеством аргументов, так как для создания очередного теста их все придётся заново задавать вручную, особенно когда новый тест отличается от текущего всего лишь на одно значение. Динамический запрос (Dynamic Value Query), в отличие от таблицы, можно сохранять в библиотеке, а затем можно либо повторно использовать, либо копировать.
Как указано выше, динамический запрос более удобен в использовании. Стоит также отметить, что название выходных параметров в запросе должно быть дополнено знаком $ в конце названия:
Чтобы вернутся из режима динамического запроса в табличный, необходимо полностью очистить значение динамического запроса.
Так как мы указали проверку выходного параметра, то уже можно запустить сценарий, и увидеть сбой. Если всё сделано правильно, система должно сообщить об ошибке. Любой другой сбой на этом этапе означает некорректную настройку.
Самый простой способ успокоить тест — внаглую вписать 1 в выходной параметр в теле процедуры: SELECT 1 INTO IS_QUEUED FROM DUAL;
Утверждения
Легко предположить, что каждый тест выполняется внутри транзакции. Однако на поверку это оказалось не так. В случае возникновения непредвиденной ошибки, база данных может оказаться в непределённом состоянии. Ожидаемых ошибок такое поведение не касается.
SQL Developer не позволяет просматривать два теста одновременно. При переходе к другому тесту в дереве, текущий тест заменяется новым в той же панели. Помимо того, невозможно разбить эту панель на две независимо прокручиваемые области. Однако, очень удобно открыть исходный код процедуры параллельно с окном теста для быстрого перехода между двумя панелями.
Существует несколько способов проверки утверждений. Первым пунктом в списке — булевая функция. При создании булевой функции, диалог предоставляет вполне подходящий шаблон:
Для нашей проверки мы можем использовать этот шаблон, заменив dual на MESSAGE_QUEUE , затем применив необходимые фильтры. Условие также придётся сменить с l_count <> 0 на l_count = 1 для большей точности. После этого можно смело сохранять функцию в библиотеку для дальнейшего использования.
Все записи в библиотеке сохраняются согласно своему типу. Это означает, что, если в дальнейшем понадобится использовать, например, проверку утверждения, необходимо будет помнить не только её название, но и тип. Это очень быстро может оказаться весьма неудобным, особенно в крупных проектах.
Теперь можно убедиться, что все тесты проходят с успехом.
При работе с тестами репозиторий блокируется, поэтому по окончании работы необходимо либо закрыть SQL Developer, либо закрыть репозиторий (Deselect Repository).
И, напоследок, проверим запись транзакции. Для этого выберем следующий тип валидации — сравнение результатов запросов (Compare Query Results). Как и следует из названия, он работает очень просто: нужно указать два запроса, результаты которых совпадут. Так как точную дату и время узнать невозможно, можно довольствоваться люб значение в пределах 10 секунд:
После прогона тестов мы видим расплывчатую ошибку Validation одна недавняя транзакция: Compare query results check found differences . Где "одна недавняя транзакция" — название нашей последней проверки в библиотеке. И хотя этот вариант уже является ценным инструментом, было бы замечательно, если бы он мог показать чем же именно результаты отличаются.
Добавим нужный функционал в нашу процедуру:
Отладка
После очередного прогона тестов вдруг выясняется, что ошибка никуда не делась. Вы, наверное, уже заметили ошибку в коде выше, однако в реальных условиях ситуации бывают куда более сложными. Так как разницы инструмент на показывает, придётся выяснять причину вручную. К сожалению, отладочный функционал SQL Developer здесь ничем помочь не в состоянии. Это значит, что нам придётся прогнать тест без выполнения сброса. Для этого можно создать ещё один сценарий — отладочный. А точнее два: один — без сброса, но с тем же динамическим запросом, что и в нерабочем тесте — для того чтобы разобраться в чём дело; а второй — без настройки контекста, но со сбросом — для того чтобы убрать за первым.
После запуска первого сценария можно посмотреть содержимое таблицы, и свериться с проверочным запросом. Теперь чётко видно, что проблема заключалась именно в проверочном запросе. Не забыв запустить второй сценарий для очистки данных, поправляем условия теста, и устраиваем повторный прогон. Теперь всё в порядке. Отладочные сценарии можно оставить на будущее, а первый законченный сценарий можно поместить в новый набор тестов.
Второй сценарий
Затем необходимо проверить, чтобы транзакция не сохранялась. Для этого используем следующий тип проверки — сравнение таблиц (Compare tables). Поначалу может показаться, что сравнивать не с чем, однако, в настройке контекста есть возможность скопировать существующую таблицу во временную. Нам это прекрасно подходит — можно скопировать транзакции во временную таблицу, а после вызова процедуры сравнить результаты. Главное — не забыть эту таблицу удалить при сбросе контекста. Есть два варианта — восстановить, затем удаилить, и просто удалить. Так как восстанавливать нам нечего — выберем второй вариант. Обратите внимание, что как и в случае со сравнением запросов, единственный вариант обратной связи — есть совпадение или нет.
Полюбовавшись на ошибку после прогона тестов, можно подумать над решением. Например, можно обернуть вставку в условие, исользуя свеже-обновлённый V_IS_QUEUED:
Компилируем процедуру, прогоняем тесты — всё работает.
Прогон тестов показывает ошибку, которую мы с лёгкостью устраняем, помещая вставку внутрь условия. И на этом заканчивается наш второй сценарий.
Выводы
SQL Developer можно использовать для разработки хранимых процедур методом TDD. Невзирая на многочисленные недостатки, этот пакет предоставляет платформу для разработки хранимых процедур, позволяя разработчикам с лёгкостью и уверенностью менять и расширять функционал существующих процедур.
К сожалению, тестовый репозиторий можно создать только в СУБД Oracle. Кроме того, попытки использовать сторонние СУБД типа PostgreSQL или даже MySQL в качестве базы данных для тестирования, заканчиваются крахом подсистемы теститования. Также выяснилось, что использование SQL Developer в системах непрерывной интеграции вызывает массу проблем, но это уже отдельная история.
Продолжаем разговор об объектно-ориентированных возможностях Oracle и PL/SQL в целом, и об объектных представлениях в частности. При работе с объектными типами существует несколько способов получения информации о созданных вами типах и представлениях. Если возможностей команды SQL*Plus DESCRIBE окажется недостаточно, вероятно, придется перейти на прямые запросы к словарю данных Oracle.
Словарь данных
Типы, определяемые пользователем (объекты и коллекции), в словаре данных относятся к категории TYPE . Определения и тела объектных типов находятся в представлении USER_SOURCE (или DBA_SOURCE , или ALL_SOURCE ), как и спецификации и тела пакетов. В табл. 1 перечислены некоторые полезные запросы.
Таблица 1. Элементы словаря данных для объектных типов
Вопрос
Запрос, используемый для получения ответа
Какие объектные типы и типы коллекций я создал?
SELECT * FROM user types;
SELECT * FROM user_objects WHERE object type = 'TYPE';
Как выглядят мои иерархии объектных типов?
SELECT RPAD(' ', 3*(LEVEL-1)) || type name
WHERE typecode = 'OBJECT'
CONNECT BY PRIOR type name = supertype name;
Какие атрибуты содержит тип foo ?
SELECT * FROM user_type_attrs
WHERE type_name = 'FOO';
Какие методы содержит тип foo?
SELECT * FROM user_type_methods
WHERE type_name = 'FOO';
Какие параметры получают методы foo?
SELECT * FROM user_method_params
WHERE type_name = 'FOO';
Какой тип данных возвращает метод bar типа foo ?
SELECT * FROM user_method_results
WHERE type_name = 'FOO' AND method_name = 'BAR';
Как выглядит исходный код foo , включая все команды ALTER ?
SELECT text FROM user source
WHERE name = 'FOO'
AND type = 'TYPE' /* или 'TYPE BODY' */ ORDER BY line;
Какие объектные таблицы реализуют foo ?
SELECT table_name FROM user_object_tables WHERE table_type = 'FOO';
Какие столбцы содержит объектная таблица f oo_tab (включая скрытые)?
SELECT column_name, data_type, hidden_column, virtual_column
WHERE table name = 'FOO TAB';
Какие столбцы реализуют foo ?
SELECT table_name, column_name FROM user_tab_columns WHERE data type = 'FOO';
Какие объекты базы данных зависят от foo ?
SELECT name, type FROM user_dependencies
WHERE referenced name = 'FOO';
Какие объектные представления я создал, какие OID при этом использовались?
SELECT view_name, view_type, oid_text FROM user_views
WHERE type text IS NOT NULL;
Как выглядит моя иерархия представлений? (Требует использования временной таблицы в версиях Oracle, которые не могут использовать подзапрос с CONNECT BY )
CREATE TABLE uvtemp AS
SELECT v.view_name, v.view_type, v.superview_name, v1.view_type superview_type FROM user_views v, user_views v1
WHERE v.superview_name = v1.view_name (+);
SELECT RPAD(' ', 3*(LEVEL-1)) || view_name
CONNECT BY PRIOR view_type = superview_type;
DROP TABLE uvtemp;
На основе какого запроса было определено представление foo_v ?
SET LONG 1000 -- or greater SELECT text FROM user_views
WHERE view name = 'FOO V';
Какие столбцы присутствуют в представлении foo_v ?
SELECT column_name, data_type_mod, data_type FROM user_tab_columns
WHERE table name = 'FOO V';
При работе со словарем данных Oracle могут возникнуть недоразумения из-за того, что объектные таблицы не видны в представлении USER_TABLES . Вместо этого список объектных таблиц присутствует в USER_OBJECT_TABLES (а также USER_ALL_TABLES ).
Привилегии
С объектными типами связана группа привилегий системного уровня:
- CREATE [ ANY ] TYPE — создание, изменение и удаление объектных типов и тел типов. ANY означает «в любой схеме».
- CREATE [ ANY ] VIEW — создание и удаление представлений, включая объектные представления. ANY означает «в любой схеме».
- ALTER ANY TYPE — использование средств ALTER TYPE с типами в любой схеме.
- EXECUTE ANY TYPE — использование объектного типа из любой схемы для таких целей, как создание экземпляров, выполнение методов, обращение по ссылкам и разыменование.
- UNDER ANY TYPE — создание подтипа в одной схеме как производного от типа в любой другой схеме.
- UNDER ANY VIEW — создание подпредставления в одной схеме как производного от представления в любой другой схеме.
Всего существуют три разновидности привилегий объектного уровня для объектных типов: EXECUTE , UNDER и DEBUG . Также важно понимать, как традиционные привилегии DML применяются к объектным таблицам и представлениям.
Привилегия EXECUTE
Если вы хотите, чтобы ваш коллега Джо использовал один из ваших типов в своих программах PL/SQL или таблицах, предоставьте ему привилегию EXECUTE :
Если Джо обладает привилегией, необходимой для создания синонимов, и работает в Oracle9i Database Release 2 и выше, он сможет создать синоним:
и использовать его следующим образом:
Джо также может использовать уточненную ссылку на тип scott.catalog_item_t .
Если вы ссылаетесь на объектный тип в хранимой программе, а потом предоставляете привилегию EXECUTE для этой программы пользователю или роли, наличие этой привилегии для типа не обязательно, даже если программа определяется с правами вызывающего. Аналогичным образом, если пользователь имеет привилегию DML для представления, содержащего триггер INSTEAD OF для этой операции DML, пользователю не понадобятся явные привилегии EXECUTE , если триггер ссылается на объектный тип, потому что триггеры выполняются с моделью прав создателя. Тем не менее привилегия EXECUTE необходима для пользователей, выполняющих анонимные блоки, в которых используется объектный тип.
Привилегия UNDER
Привилегия UNDER дает право создания подтипов. Она предоставляется следующим образом:
Чтобы схема могла создать подтип, необходимо определить супертип с правами вызывающего ( AUTHID CURRENT_USER ).
Она также может дать получателю право создания подпредставления:
Привилегия DEBUG
Если ваш коллега использует отладчик PL/SQL для анализа кода, использующего созданный вами тип, вы можете предоставить ему привилегию DEBUG :
Предоставление этой привилегии позволит другому разработчику заглянуть «за кулисы», изучить переменные, использованные в типе, и установить точки прерывания внутри методов.
Привилегия DEBUG также применяется к объектным представлениям, давая возможность отладки исходного кода PL/SQL триггеров INSTEAD OF .
Привилегии DML
Для объектных таблиц традиционные привилегии SELECT , INSERT , UPDATE и DELETE также имеют смысл. Пользователь, обладающий только привилегией SELECT для объектной таблицы, может загрузить любые реляционные столбцы базового типа, на котором основана таблица, но ему не удастся загрузить объект как объект (то есть VALUE , TREAT , REF и DEREF ему недоступны). Другие привилегии DML — INSERT , UPDATE и DELETE — также применяются только к реляционной интерпретации таблицы.
Аналогичным образом получатель не сможет использовать конструктор или другие объектные методы, если только владелец типа объекта не предоставит ему привилегию EXECUTE для объектного типа. Все столбцы, определенные в подтипах, останутся невидимыми.
Тип данных связан с конкретным форматом хранения и ограничениями диапазона. В Oracle каждому значению или константе присваивается тип данных.
По сути, он определяет, как данные хранятся, обрабатываются и обрабатываются Oracle во время хранения и обработки данных.
Основное различие между типами данных PL / SQL и SQL заключается в том, что тип данных SQL ограничен столбцом таблицы, а типы данных PL / SQL используются в блоках PL / SQL. Подробнее об этом позже в уроке.
Ниже приведена схема различных типов данных в PL / SQL.
В этом уроке вы узнаете
ХАРАКТЕР Тип данных:
Этот тип данных в основном хранит буквенно-цифровые символы в строковом формате.
Литеральные значения всегда должны быть заключены в одинарные кавычки при назначении их типу данных CHARACTER.
Этот символьный тип данных дополнительно классифицируется следующим образом:
- Тип данных CHAR (фиксированный размер строки)
- VARCHAR2 Тип данных (переменный размер строки)
- VARCHAR Тип данных
- NCHAR (собственный фиксированный размер строки)
- NVARCHAR2 (собственный размер строки переменной)
- ДОЛГОЙ И ДОЛГОЙ СЫРЬЕ
- Oracle будет заполнять пустую переменную, если переменная не будет занимать весь объявленный для нее размер, поэтому Oracle будет выделять память для объявленного размера, даже если переменная не занимала ее полностью.
- Ограничение размера для этого типа данных составляет 1-2000 байт.
- Тип данных CHAR более подходит для использования там, где когда-либо будет установлен размер данных.
Синтаксис Объяснение:
- Первый оператор объявления объявил переменную ‘grade’ типа данных CHAR с максимальным размером 1 байт (значение по умолчанию).
- Второй оператор объявления объявил переменную ‘manager’ типа данных CHAR с максимальным размером 10 и присвоил значение ‘guru99’, которое составляет 6 байтов. В этом случае Oracle выделит для памяти 10 байтов, а не 6 байтов.
- Ограничение размера для этого типа данных составляет 1-4000 байт для размера столбца таблицы и 1-32767 байт для переменных.
- Размер определяется для каждой переменной во время объявления переменной.
- Но Oracle будет выделять память только после определения переменной, т. Е. Oracle будет учитывать только фактическую длину строки, которая хранится в переменной для выделения памяти, а не размер, указанный для переменной в части объявления.
- Всегда полезно использовать VARCHAR2 вместо типа данных CHAR для оптимизации использования памяти.
Синтаксис Объяснение:
- Вышеуказанный оператор объявления объявил переменную ‘manager’ типа данных VARCHAR2 с максимальным размером 10 и присвоил значение ‘guru99’, которое составляет 6 байтов. В этом случае Oracle выделит память всего 6 байтов.
- Во избежание изменений в поведении всегда полезно использовать VARCHAR2 вместо VARCHAR.
Синтаксис Объяснение:
- Этот набор символов может быть определен для сеанса с использованием NLS_PARAMETERS.
- Набор символов может быть UTF16 или UTF8.
- Ограничение по размеру составляет 1-2000 байт.
Синтаксис Объяснение:
- Вышеуказанный оператор объявления объявляет переменную «native» типа данных NCHAR с максимальным размером 10.
- Длина этой переменной зависит от (количества длин) на байт, как определено в наборе символов.
- Этот набор символов может быть определен для сеанса с использованием NLS_PARAMETERS.
- Набор символов может быть UTF16 или UTF8.
- Ограничение по размеру составляет 1-4000 байт.
Синтаксис Объяснение:
- Вышеуказанный оператор объявления объявляет переменную Native_var типа данных NVARCHAR2 с максимальным размером 10.
- Они в основном используются в словаре данных.
- Тип данных LONG используется для хранения данных набора символов, а тип LONG RAW — для хранения данных в двоичном формате.
- Тип данных LONG RAW принимает медиа-объекты, изображения и т. Д., В то время как LONG работает только с данными, которые могут быть сохранены с использованием набора символов.
Синтаксис Объяснение:
- Вышеуказанный оператор объявления объявляет переменную Large_text типа данных LONG и Large_raw типа данных RAW LONG.
Примечание. Использование типа данных LONG в Oracle не рекомендуется. Вместо этого тип данных LOB должен быть предпочтительным.
НОМЕР Тип данных:
Этот тип данных хранит числа с фиксированной или плавающей точкой с точностью до 38 цифр. Этот тип данных используется для работы с полями, которые будут содержать только числовые данные. Переменная может быть объявлена либо с точностью до десятичных цифр, либо без этой информации. При назначении этому типу данных значения не обязательно заключать в кавычки.
Синтаксис Объяснение:
- В приведенном выше первом объявлении объявляется, что переменная «A» имеет числовой тип данных с полной точностью 8 и десятичными цифрами 2.
- Второе объявление объявляет, что переменная ‘B’ имеет числовой тип данных с полной точностью 8 и без десятичных цифр.
- Третье объявление является наиболее общим, объявляет переменную ‘C’ с числовым типом данных без ограничений по точности или десятичным разрядам. Это может занимать до 38 цифр.
БУЛЕВЫЙ Тип данных:
Этот тип данных хранит логические значения. Он представляет собой ИСТИНА или ЛОЖЬ и в основном используется в условных выражениях. При назначении этому типу данных значения не обязательно заключать в кавычки.
Синтаксис Объяснение:
- Выше переменная Var1 объявлена как тип данных BOOLEAN. Вывод кода будет либо истинным, либо ложным в зависимости от установленного условия.
ДАТА Тип данных:
Этот тип данных хранит значения в формате даты в виде даты, месяца и года. Всякий раз, когда переменная определена с типом данных DATE вместе с датой, она может содержать информацию о времени, и по умолчанию информация о времени устанавливается в 12:00:00, если она не указана. При назначении этому типу данных значения должны быть заключены в кавычки.
Стандартный формат времени Oracle для ввода и вывода — «DD-MON-YY», и он снова устанавливается на NLS_PARAMETERS (NLS_DATE_FORMAT) на уровне сеанса.
Синтаксис Объяснение:
- В приведенном выше, переменная «Newyear» объявлен как тип DATE данных и присваивается значение Яном 1 — го , 2015 день.
- Второе объявление объявляет переменную current_date как тип данных DATE и присваивает значение с текущей системной датой.
- Обе эти переменные содержат информацию о времени.
Тип данных LOB:
Этот тип данных в основном используется для хранения и обработки больших блоков неструктурированных данных, таких как изображения, мультимедийные файлы и т. Д. Oracle предпочитает LOB вместо типа данных LONG, поскольку он более гибкий, чем тип данных LONG. Ниже приведены некоторые основные преимущества типа данных LOB над LONG.
- Количество столбцов в таблице с типом данных LONG ограничено 1, тогда как в таблице нет ограничений на количество столбцов с типом данных LOB.
- Инструмент интерфейса данных принимает тип данных LOB таблицы во время репликации данных, но не указывает столбец LONG таблицы. Эти столбцы LONG необходимо реплицировать вручную.
- Размер столбца LONG составляет 2 ГБ, тогда как LOB может хранить до 128 ТБ.
- Oracle постоянно улучшает тип данных LOB в каждом из своих выпусков в соответствии с современными требованиями, тогда как тип данных LONG постоянен и не получает много обновлений.
Таким образом, всегда хорошо использовать тип данных LOB вместо типа данных LONG. Ниже приведены различные типы данных больших объектов. Они могут хранить до 128 терабайт.
Этот тип данных хранит данные больших объектов в двоичном формате до максимального размера 128 ТБ. Он не хранит данные, основанные на деталях набора символов, поэтому он может хранить неструктурированные данные, такие как мультимедийные объекты, изображения и т. Д.
Синтаксис Объяснение:
- Выше переменная ‘Binary_data’ объявлена как BLOB.
Тип данных CLOB сохраняет данные LOB в наборе символов, тогда как NCLOB сохраняет данные в собственном наборе символов. Поскольку эти типы данных используют хранилище на основе набора символов, они не могут хранить такие данные, как мультимедиа, изображения и т. Д., Которые нельзя поместить в строку символов. Максимальный размер этих типов данных составляет 128 ТБ.
Синтаксис Объяснение:
- В приведенном выше примере переменная Character_data объявлена как тип данных CLOB.
- BFILE — это типы данных, которые хранят данные неструктурированного двоичного формата вне базы данных в виде файла операционной системы.
- Размер BFILE для ограниченной операционной системы, и они являются файлами только для чтения и не могут быть изменены.
Резюме
Мы рассмотрели различные простые типы данных, доступные в PL / SQL, а также их синтаксис. Мы узнаем о сложных типах данных в следующих темах.
Читайте также: