распределенная система управления базами данных oracle

advertisement
Глава 2
РАСПРЕДЕЛЕННАЯ СИСТЕМА
УПРАВЛЕНИЯ БАЗАМИ ДАННЫХ
ORACLE
2.1. Структура экземпляров Oracle.
Экземпляр Oracle — сложный комплекс структур памяти и процессов операционной системы (рис. 2.1).
Рис. 2.1. Экземпляр Oracle
2.1.1. Глобальная системная область ♦ 75
Экземпляр Oracle
Каждая база данных (БД) Oracle имеет связанный с ней экземпляр. Организация экземпляра позволяет СУБД обслуживать множество типов транзакций, обеспечивать высокую производительность,
целостность данных и безопасность. Термин процесс означает любую задачу, выполняемую без вмешательства пользователя.
Открытие БД Oracle включает три стадии.
1. Формирование экземпляра Oracle (предустановочная стадия).
2. Установка базы данных экземпляром (установочная стадия).
3. Открытие БД (стадия открытия).
Экземпляр, в котором нет базы данных, называется незанятым
(idle), но он занимает память и не выполняет никакой работы. Экземпляр может подсоединиться только к одной БД, а до тех пор,
пока не будет использован Parallel Server, БД может быть подключена
только к одному экземпляру Oracle. Экземпляр — это мозг системы
обработки данных. В экземпляре выполняются все операции, в то
время как в БД хранятся все данные.
Большинство настроек экземпляра связано с компонентами в
глобальной системной области. Но кроме них существуют и некоторые опции настройки, касающиеся фоновых процессов.
2.1.1. Глобальная системная область.
В SGA (System Global Area) хранятся структуры памяти, необходимые для манипулирования данными, анализа предложений SQL и
кэширования транзакций. К этой области одновременно имеет доступ множество процессов, которые могут считывать данные из нее
или модифицировать их. Все операции с БД используют информацию, находящуюся в SGA. SGA выделяется сразу же после создания экземпляра еще на предустановочной стадии. Освобождается
эта область только после полного выключения экземпляра.
Экземпляр Oracle представляет собой сложный комплекс взаимодействующих процессов. SGA состоит из следующих компонентов:
• разделяемый пул (SHARED POOL);
• кэш-буфер данных (DATABASE BUFFER CACHE);
• буфер журнала транзакций (REDO LOG BUFFER);
76 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.1. Структура экземпляров Oracle.
•
структуры
сервера
многозадачной
THREADED SERVER — MTS).
среды
(MULTI-
Разделяемый пул
Разделяемый пул (рис. 2.1) содержит кэш библиотеки, кэш словаря и управляющие структуры сервера (такие, как набор символов
БД). Кэш библиотеки хранит план выполнения предложений SQL.
Здесь содержатся заголовки пакетов PL/SQL и процедур, выполнявшихся ранее. Кэш словаря хранит строки словаря данных, которые были использованы для лексического анализа предложений
SQL. Сервер Oracle использует кэш библиотеки для повышения
скорости выполнения операторов SQL.
Размер разделяемого пула задается параметром SHARED POOL
SIZE в файле INIT.ORA. Размерность значения параметра — байты.
Объем пула необходимо заказывать.
Кэш-буфер данных
Кэш-буфер данных состоит из блоков памяти того же размера,
что и блоки ORACLE. Все данные, с которыми работает СУБД,
первым делом загружаются в кэш-буфер. В этих же блоках памяти
выполняется и любое обновление данных. Поэтому очень важно
правильно установить размер буфера.
СУБД переносит данные на диск — в соответствии с порядком
их размещения в списке LRU (LEAST RECENTLY USED). Этот
список отслеживает обращение к блокам данных и учитывает частоту обращений. Если выполняется обращение к блоку данных,
хранящемуся в кэш-буфере, то оно помещается в тот конец списка,
который носит название MRU (MOST RECENTLY USED). Если
серверу требуется место в кэш-буфере для загрузки нового блока, то
он решает этот момент с помощью списка LRU — какой из блоков
перенести на диск, чтобы освободить место для нового. Блоки,
наиболее отстоящие в списке от MRU, — кандидаты на удаление из
кэш-буфера. Таким образом, дольше всего остаются в кэш-буфере
те блоки, к которым чаще всего выполняется обращение. Модифи-
2.1.2. Фоновые процессы Oracle ♦ 77
Множество фоновых процессов Oracle
цированные блоки называются грязными (dirty) и помещаются в соответствующий dirty-список.
Буфер журнала транзакций
Данные о транзакциях хранятся в этом буфере до тех пор, пока
не будут переписаны в файл оперативного журнала транзакций.
После заполнения буфера его содержимое переносится в файл
журнала транзакций.
Размер буфера журнала транзакций задается параметром
LOG_BUFFER. Значение параметра указывает размер буфера в
байтах.
В результате вы получите время, которое пользовательские процессы находились в состоянии ожидания при обращении к буферу
журнала транзакций.
2.1.2. Фоновые процессы Oracle.
В процессе работы СУБД ORACLE просматривает тысячи записей в таблицах данных, отвечает на сотни запросов пользователей
одновременно. Вся работа распределяется между множеством программ, которые работают независимо одна от другой, причем у каждой своя роль. В совокупности эти программы называются фоновыми процессами ORACLE.
Множество фоновых процессов Oracle включает:
• SMON и PMON,
• RECO,
• DBWR,
• SNPn,
• LGWR,
• Dnnn,
• ARCH,
• LCKn,
• СКРТ,
• Pnnn
Также нужно обратить внимание на процессы USER и SERVER,
выполняющие обработку транзакций конечного пользователя БД.
Хотя эти процессы и не квалифицируются как фоновые, они играют значительную роль в функционировании системы.
Процессы PMON и SMON выполняют автоматическую
“уборку” после внезапно прекратившихся или завершившихся ава-
78 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.1. Структура экземпляров Oracle.
рийно процессов. После запуска БД процесс SMON (System
Monitor) выполняет автоматическое восстановление экземпляра.
Если при последнем выключении БД что-либо не было завершено,
SMON автоматически запускает незавершенные операции.
PMON — Process Monitor (Монитор процессов) выполняет автоматическую “уборку” после внезапно прекратившихся или завершившихся аварийно процессов. Эта “уборка” включает удаление сеанса, блокировок, которые были им установлены, непринятых
транзакций, освобождение ресурсов глобальной системной области, выделенных этому процессу. Фоновые процессы SMON и
PMON должны быть непременно пущены при запуске системы. В
противном случае система функционировать не будет.
Процесс DBWR (DataBase Writer) — отвечает за перенос обновленных блоков, занесенных в dirty-cписок из кэш-буфера данных в
файлы данных. Вместо того, чтобы записывать каждый блок на диск
сразу, DBWR ждет, пока не будет выполнено одно из условий, а затем просматривает dirty-cписок и все отмеченные в нем блоки переписывает на диск.
Процесс LGWR (Log Writer) — четвертый и последний фоновый процесс, запуск которого обязателен для работы СУБД
ORACLE. Этот процесс отвечает за перезапись информации из
буфера журнала транзакций, который находится в глобальной системной области, в файлы оперативного журнала. ORACLE не считает транзакцию выполненной до тех пор, пока процесс LGWR не
перезапишет данные о ней из буфера журнала транзакций в файл.
Этот процесс редко служит причиной осложнений в работе.
Фоновые процессы-диспетчера Dnnn. Остановимся подробнее на этих процессах. Все процессы сервера могут закрепляться за
определенными пользовательскими процессами, либо использоваться несколькими процессами пользователя. В последнем случае
они называются “разделяемые” (shared) процессами или серверами.
Для работы с применением разделяемого сервера необходима установка Multi Threaded Server (MTS). При использовании разделяемых
процессов, в системе должен существовать как минимум один про-
2.1.2. Фоновые процессы Oracle ♦ 79
Дополнительный фоновый процесс ARCH (Archiver)
цесс диспетчер. Процесс-диспетчер передает запросы пользователей в очередь SGA и возвращает ответы сервера соответствующему процессу пользователя. Фоновый процесс Dnnn, где nnn — это
число, задаваемое в файле init.ora. Параметр указывает протокол,
который будет использован диспетчером и количество процессов.
Дополнительный фоновый процесс ARCH (Archiver) отвечает за копирование полностью заполненного оперативного журнала
транзакций в архивные файлы журналов транзакций. Во время перезаписи в архив никакой другой процесс не может получить доступ к журналу. Во время копирования в архив система должна находиться в состоянии ожидания.
CKPT (Check Point) — это дополнительный фоновый процесс,
который отвечает за обработку контрольных точек. Необходимость
в нем возникает, когда надо снизить нагрузку на LGWR.
Процесс RECO (Recovery) отвечает за восстановление незавершенных транзакций в распределенной системе БД. Когда возникает подозрительная транзакция, RECO выполняет свои функции
автоматически без вмешательства администратора БД.
Процесс SNPn (Snapshot) выполняет автоматические обновления снимков БД и запускает процедуры в соответствии с расписанием, зафиксированным в пакете DBMS_JOB. В файле init.ora задается количество запускаемых процессов SNPn и длительность интервала, в течение которого процесс “засыпает” прежде чем выполнить задание.
Процесс LCKn (Parallel Server Lock) — в среде, производящей
параллельное обслуживание нескольких экземпляров БД, на LCKn
возлагается ответственность за координацию блокировок устанавливаемых разными экземплярами БД. Если в системе нет параллельного обслуживания, то запуск LCKn не нужен.
Процессы параллельных запросов (Parallel Query) получили в
системе наименование Pnnn. Сервер Oracle запускает и останавливает процессы Pnnn в зависимости от активности работы с БД и настройки опций параллельных запросов. Эти процессы принимают
80 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.1. Структура экземпляров Oracle.
участие в формировании индексов, таблиц и запросов. Количество
запускаемых процессов определяется двумя параметрами:
PARALLEL_MIN SERVERS и PARALLEL_MAX SERVERS, определяющими, соответственно, минимальное и максимальное количество запускаемых процессов.
2.1.3. Процессы пользователя и сервера
Приложения и утилиты связываются с СУБД посредством процессов пользователя. Каждый процесс пользователя подключается к процессу сервера. Процесс сервера анализирует и выполняет переданные ему операторы SQL и возвращает результат процессу пользователя. Кроме того, процесс сервера считывает блоки данных из файлов данных и размещает их в кэш-буфере данных.
Приложения и клиентские части связываются с сервером Oracle
посредством “процессов пользователя”. Каждый процесс пользователя имеет подключение к процессу сервера (рис. 2.1), который может быть либо жестко связан с одним процессом пользователя, либо распределяться между многими. Процесс сервера, анализирует и
выполняет переданные ему операторы SQL и возвращает результат
процессу пользователя. Так же процесс сервера считывает блоки
данных из файла данных и размещает их в кэш-буфере данных.
Каждому процессу пользователя выделяется область памяти, которая называется “глобальной областью процесса” — PGA (Process
Global Area). Содержимое PGA зависит от режима подключения
процесса пользователя к процессу сервера. Если процесс пользователя имеет выделенный процесс сервера, то в PGA размещается
информация о текущем сеансе работы пользователя, стек и информация о состоянии курсора. Если же процесс пользователя связан с
разделяемым процессом сервера, то информация о текущем сеансе
и текущем состоянии курсора хранится в SGA. В общем, это не
очень существенно, хотя некоторое увеличение размера SGA все же
потребуется. В этом и состоит разница между двумя типами взаимодействия клиента и сервера в БД Oracle.
2.2. Основные объекты СУБД ORACLE ♦ 81
Таблица, представление, пользователь
2.2. Основные объекты СУБД ORACLE.
Oracle поддерживает реляционную модель данных, поэтому, естественно, что к числу основных объектов Oracle относятся: таблица, представление, пользователь. Таблица, представление, пользователь
Таблица (TABLE) является базовой структурой реляционной
модели. Вся информация в базе данных хранится в таблицах. Таблицы состоят из множества поименованных столбцов или атрибутов. Множество значений столбца определено с помощью ограничений целостности, то есть поддерживается ограниченная концепция домена. Полное имя таблицы в базе данных состоит из имени
схемы, в данной реализации совпадающем с именем пользователя,
создавшего таблицу, и собственно имени таблицы. Таблица может
быть пустой или состоять из одной или более строк значений атрибутов. Строки значений атрибутов таблицы называются также
кортежами.
Представление (VIEW) — это поименованная, динамически
поддерживаемая сервером выборка из одной или нескольких таблиц. Оператор SELECT, определяющий выборку, ограничивает видимые пользователем данные. Сервер гарантирует актуальность
представления, то есть формирование представления (материализация соответствующего запроса), производится каждый раз при использовании представления. Используя представления, администратор безопасности ограничивает доступную пользователям часть
базы данных только теми данными, которые реально необходимы
для выполнения его работы.
Пользователь (USER) — объект, обладающий возможностью
создавать и использовать другие объекты ORACLE, а также запрашивать выполнение функций сервера. К числу таких функций относятся организация сессии, изменение состояния сервера и базы данных, запрос на выполнение операторов SQL и др. Для упрощения
решения задач идентификации и именования в базе данных
ORACLE поддерживает объекты: последовательность и синоним.
82 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.2. Основные объекты СУБД ORACLE.
Последовательность (SEQUENCE) — это объект, обеспечивающий генерацию уникальных номеров в условиях многопользовательского асинхронного доступа. Обычно элементы последовательности используются для вставки уникальных идентификационных номеров для элементов таблиц базы данных.
Синоним (SYNONYM) — это альтернативное имя-псевдоним
объекта ORACLE, который позволяет пользователям базы данных
иметь доступ к данному объекту. Синоним может быть частным и
общим. Общий (public) синоним позволяет всем пользователям базы
данных обращаться к соответствующему объекту по альтернативному имени.
Для управления эффективностью доступа к данным Oracle поддерживает объекты: индекс, табличная область и кластер.
Индекс (INDEX) — это объект базы данных, создаваемый для
повышения производительности выборки данных. Индекс создается для столбцов таблицы или для представления в пространстве базы данных и обеспечивает более быстрый доступ к данным базы
данных за счет хранения прямых ссылок на место расположения
строк, содержащих требуемые данные.
Табличная область (TABLESPACE) — именованная часть базы
данных, используемая для распределения памяти для таблиц и
индексов.
Кластер (CLUSTER) — объект, задающий способ совместного
хранения данных нескольких таблиц, содержавших информацию,
обычно обрабатываемую совместно. Кластеризация столбцов таблиц позволяет уменьшить время выполнения выборки. Строки таблиц, имеющие одинаковое значение в кластеризованных столбцах,
хранятся в базе данных специальным образом.
Для эффективного управления разграничением доступа к данным Oracle поддерживает объект роль.
Роль (ROLE) — именованная совокупность привилегий, которые могут быть предоставлены пользователям или другим ролям.
2.2. Основные объекты СУБД ORACLE ♦ 83
Cнимок и связь базы данных
ORACLE поддерживает несколько стандартных или предопределенных ролей. Специфичными для распределенных систем являются объекты ORACLE: снимок и связь базы данных.
Cнимок и связь базы данных
Снимок (SNAPSHOT) — локальная копия таблицы удаленной
базы данных, которая используется либо для тиражирования (копирования) всей или части таблицы, либо для тиражирования результата запроса данных из нескольких таблиц. Снимки могут быть модифицируемыми или предназначенными только для чтения. Снимки только для чтения возможно периодически обновлять, отражая изменения основной таблицы. Изменения, сделанные в модифицируемом
снимке, распространяются на основную таблицу и другие копии.
Связь базы данных (DATABASE LINK) — это объект базы
данных, который позволяет обратиться к объектам удаленной базы
данных. Имя связи базы данных можно рассматривать как ссылку на
параметры механизма доступа к удаленной базе данных (имя узла,
протокол и т.п.). Использование одного имени упрощает работу с
объектами удаленной базы данных.
Для программирования алгоритмов обработки данных, реализации механизмов поддержки целостности базы данных Oracle использует объекты: процедура, функция, пакет и триггер.
Процедура (PROCEDURE) — это поименованный, структурированный набор переменных и операторов SQL и PL/SQL, предназначенный для решения конкретной задачи.
Функция (FUNCTION) — это поименованный, структурированный набор переменных и операторов SQL и PL/SQL, предназначенный для решения конкретной задачи и возвращающий значение переменной.
Пакет (PACKAGE) — это поименованный, структурированный
набор переменных, процедур и функций, связанных единым функциональным замыслом. Например, ORACLE поставляет пакет
DBMS_OUTPUT, в котором собраны процедуры и функции, предназначенные для организации ввода-вывода.
84 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
Триггер (TRIGGER) — это хранимая процедура, которая запускается (автоматически выполняется) тогда, когда происходит связанное с
триггером событие. Обычно события связаны с выполнением операторов INSERT, UPDATE или DELETE в некоторой таблице.
2.3. Язык PL/SQL
2.3.1. Типы данных ORACLE.
Существует следующие типы данных в PL/SQL:
• скалярный (простой) тип;
• составной тип — запись;
• ссылочный — указатель на объект программы;
• LOB (LOCATORS) — графические образы.
Скалярные (простые) типы
Строковые типы
Тип CHARACTER — используется для хранения строк фиксиро-
ванной длины.
Синтаксис:
CHARACTER[(длина)]
CHAR[(длина)]
Максимальное значение параметра длина — 255 символов.
Тип VARCHAR используется для хранения строк переменной
длины. Следующие предложения эквивалентны:
VARCHAR[(длина)]
CHAR VARYING[(длина)]
CHARACTER VARYING[(длина)]
Если длина строки не указана явно, она полагается равной единице во всех случаях. Максимальное значение параметра длина —
2000 символов для всех трех случаев.
Пример 2.3.1 Str1 CHAR(15)
Str2 CHARACTER
VarSts1 VARCHAR(15)
VarStr2 CHARACTER VARYING(10)
2.3.1. Типы данных ORACLE ♦ 85
Числовые типы
Есть тип, характерный только для ORACLE
VARCHAR2[(длина)]
С помощью этого типа резервируется необходимое пространство для хранения строк максимальной длины 32767 байт, хотя максимальная ширина столбца базы данных типа VARCHAR2 равна
2000 байт.
Тип LONG. Для хранения больших строк переменной длины используется тип LONG[(длина)]. Если параметр длина не указан, то
предполагается, что у строки длина 2 мегабайта, максимальная длина — 2 гигабайта.
Числовые типы.
Тип INTEGER используется для представления чисел от –231 до 231
Синтаксис: INTEGER, INT
Пример 2.3.2 varint INTEGER
varint2 INT
Тип NUMBER [Только для ORACLE] — используется для пред-
ставления чисел с заданной точностью.
Синтаксис: NUMBER[(точность[,масштаб])]
Если значение параметра точность не указано явно, оно полагается равным 38. Значение параметра масштаб по умолчанию предполагается равным 0. Значение параметра точность может изменяться от 1 до 38; значение параметра масштаб может изменяться от –84
до 128. Использование отрицательных значений масштаба означает
сдвиг десятичной точки в сторону старших разрядов. Например,
определение NUMBER(7, –3) означает округление до тысяч.
Tипы DECIMAL и NUMERIC — полностью эквивалентны типу
NUMBER.
Синтаксис:
DECIMAL[(точность[,масштаб])]
DEC[(точность[,масштаб])
NUMERIC[(точность[,масштаб])]
86 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
Пример 2.3.3 Varcounter NUMBER
Vardec1 DEC
Vardec2 DEC(7)
Vardec3 DECIMAL(7,3)
Varnum NUMERIC
Битовые строки
Тип RAW [Только для ORACLE] — используется для хранения
битовых строк переменной длины. Отличие типа RAW от типов
CHAR, VARCHAR2 состоит в том, что для типов символьных строк
ORACLE (точнее SQL*Net) производит автоматическое преобразование данных при их передаче между клиентом и сервером.
Синтаксис: RAW[(длина)]
Параметр длина измеряется в байтах. Максимальное значение параметра длина — 255 байт.
Тип LONG RAW [Только для Oracle] — используется для хране-
ния больших битовых строк переменной длины.
Синтаксис: LONG RAW[(длина)]
Параметр длина измеряется в байтах. Если длина строки не указана явно, она полагается равной 2 мегабайтам. Максимальное значение параметра длина — 2 гигабайта символов. Для переменных
типа LONG RAW невозможно построение индекса.
Пример 2.3.4 Bit1 RAW(15)
Verylong1 LONG RAW(100000)
Типы дата и время
Тип DATE [Только для Oracle] — используется для хранения да-
ты и времени. Поддерживаются даты с 1 января 4712 г. до н.э. до 31
декабря 4712 г. н.э. Для начального присваивания даты обычно используется функция
ТО_DATE('символьная_строка_даты', 'формат_даты')
2.3.1. Типы данных ORACLE ♦ 87
Метод %TYPE
При определении даты без уточнения времени по умолчанию
принимается время полуночи. Функция SYSDATE присваивает переменной текущее значение даты и времени.
Синтаксис: DATE
Пример 2.3.5 BIRTHDAY DATE
Наличие специального типа для хранения даты и времени позволяет поддерживать специальную арифметику дат и времен. Добавление к переменной типа DATE целого числа означает увеличение даты на соответствующее число дней, а вычитание выполняется как определение более ранней даты. Рассмотрим несколько
примеров.
Пример 2.3.6
SQL>select sysdate from dual;
SYSDATE
15-NOV-98
SQL>select sysdate+20 “sysd+20” from dual;
sysd+20
05-DEC-98
SQL>select sysdate-20 “sysd-20” from dual;
sysd-20
26-OCT-98
Метод %TYPE.
Предопределенный метод %TYPE позволяет определить тип
переменной, совпадающий с типом атрибута некоторой таблицы,
например:
V_ENAME EM.ENAME%TYPE;
V_MIN_BALANCE EM.BALANCE%TYPE := 10
В этом примере объявляется переменная V_ENAME того же типа,
что и поле ENAME в таблице EM, а переменная V_MIN_BALANCE
того же типа, что поле BALANCE в таблице EM.
Однако для колонок NOT NULL нельзя пользоваться этим методом.
88 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
Составные типы
К составным типам относятся:
• PL/SQL записи;
• PL/SQL таблицы;
• таблица записей.
Записи
Запись — это группа родственных данных, каждое из которых
имеет имя и тип. PL/SQL запись содержит скаляр, запись или поле из PL/SQL таблицы.
Синтаксис команды создания PL/SQL записи:
--Создание типа type_name
TYPE type_name is record
(field_declaration[, field_declaration]...);
--Создание переменной типа type_name
identifier type_name;
где field_declaration есть:
field_name {field_type|variable%type
|table.column%type|table%rowtype}
[[not null] {:=default}|expr]
где
field_name — имя поля,
field_type — его тип,
expr — начальное значение field_name.
Пример 2.3.7 Type emp_record_type is record
(ename
varchar2(10),
job
varchar2(9),
sal
number(7,2));
emp_record emp_record_type;
Метод %ROWTYPE
Предопределенный метод %ROWTYPE может применяться как ко
всей таблице, так и к ее отдельным полям (атрибутам). При
использовании этого метода с таблицей или представлением
объявляется запись той же структуры, что и таблица или
представление, при этом поля записи имеют имена и типы полей
таблицы или представления.
2.3.2. Таблицы ♦ 89
Cинтаксис оператора определения таблиц
Пример 2.3.8 Declare
Emp_record
emp%rowtype;
После такого описания запись EMP_RECORD имеет те же поля,
что и запись EMP. Использование %ROWTYPE имеет ряд преимуществ:
• число и тип колонок базы данных может быть неизвестен;
• число типов колонок базы данных может меняться;
• этот атрибут полезен, когда колонка определяется с помощью
SELECT утверждения.
Если метод %ROWTYPE применяется к отдельными полям (атрибутам), происходит объявление переменной того же типа, что и
столбец в таблице, например:
dept_record dept%rowtype
2.3.2. Таблицы.
Cинтаксис оператора определения таблиц
Таблица является базовой структурой реляционной модели. Полное имя таблицы в базе данных состоит из имени схемы, как правило, совпадающем с именем пользователя, и имени таблицы.
Оператор определения таблиц имеет следующий синтаксис:
CREATE TABLE[имя_схемы.]имя таблицы
({ограничение_целостности_таблицы|имя_столбца
тип_данных_столбца
[DEFAULT выражение]
[ограничение_целостности_столбца...]},...)
[{CLUSTER имя_кластера(имя_столбца[,...])|
{PCTFREE целое|PCTUSED целое|
INITRANS целое|MAXTRANS целое|
TABLESPACE имя_табличной_области|
STORAGE размер памяти|
{RECOVERABLE|UNRECOVERABLE}}...]
[PARALLEL возможность_параллельной_обработки]
[{ENABLE проверяемые_ограничения_целостности |
DISABLE
игнорируемые_ограничения_целостности}...]
90 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
[AS запрос]
[GACHE|NOCACHE]
Ключевое слово DEFAULT указывает на то, что при вводе данных
соответствующему столбцу будет присвоено значение, определенное переменной выражение, если в операторе INSERT не указано явно другое значение столбца. Тип данных выражение должен соответствовать типу данных столбца и выражение не должно содержать
ссылок на другие выражения.
Ключевые слова PCTFREE, PCTUSED, INITRANS, MAXTRANS,
TABLESPACE, STORAGE, RECOVERABLE, UNRECOVERABLE
характеризуют пространство, распределяют его при работе с таблицей.
Ключевое слово PCTFREE определяет процент пространства блока,
который резервируется для модификации таблицы. Допустимые
значения от 0 до 99. Значение по умолчанию 10, то есть при заполнении каждого блока 10% пространства остается не использованным. Это пространство используется для записи в него данных при
выполнении в дальнейшем модификации строк таблицы.
Ключевое слово PCTUSED определяет минимальный процент использования пространства блока, при котором в него вводятся данные, по умолчанию 40, то есть если в блоке занято менее 40% пространства, в него вводятся данные при выполнении операции вставки. Сумма значений параметров PCTFREE и PCTUSED не должна
превышать 100.
Ключевое слово INITRANS определяет начальное число параллельных транзакций, которые могут выполняться для модификации данных блока. Значение по умолчанию 1. Ключевое слово MAXTRANS
определяет максимальное число параллельных транзакций, которые
могут выполняться для модификации данных блока. В большинстве
случаев явное задание этих параметров не требуется.
Ключевое слово TABLESPACE определяет имя табличной области,
в которой будет размещена таблица. Если значение параметра не
определено, то таблица размещается в табличной области, задан-
2.3.2. Таблицы ♦ 91
Иимя табличной области (ключевое слово TABLESPACE)
ной по умолчанию для пользователя, который является владельцем
схемы, содержащей таблицу.
Иимя табличной области (ключевое слово TABLESPACE)
Ключевое слово STORAGE определяет объем внешней памяти, выделяемый под таблицу. Для больших таблиц целесообразно явно
выделять требуемую память, чтобы уменьшить число запросов на
динамическое выделение пространства.
Ключевые слова RECOVERABLE и UNRECOVERABLE. Для
управления записью в журнальный файл контрольной информаRECOVERABLE,
ции
используются
ключевые
слова
UNRECOVERABLE. Значение UNRECOVERABLE может быть
использовано только с ключевым словом AS подзапрос, при этом
операция создания таблицы выполняется быстрее за счет исключения записи управляющей информации в журнал. Но при этом автоматическое восстановление операции создания таблицы в случае
сбоя становится невозможным.
Ключевое слово CLUSTER указывает привязку столбцов таблицы к
кластеру. Обычно столбцы кластера образуют из элементов первичного ключа.
Ключевое слово ENABLE указывает на включение ограничений
целостности для данной таблицы. Соответствующее ограничение
целостности должно быть определено в данном предложении создания таблицы. По умолчанию все ограничения целостности, определенные в предложении, включаются.
Ключевое слово DISABLE указывает на выключение ограничений
целостности для данной таблицы. Соответствующее ограничение
целостности должно быть определено в данном предложении создания таблицы.
Ключевое слово AS запрос включает в создаваемую таблицу строки,
являющиеся результатом выполнения запроса. Необходима определенная осторожность при использовании вставки строк через подзапрос и определение ограничений целостности в том же предложении. Если результат запроса не соответствует ограничениям це-
92 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
лостности, то Oracle не создает таблицу и возвращает сообщение
об ошибке.
Ключевое слово CACHE указывает на то, что блоки, выбираемые из
таблицы, помечаются в системном кеше, как наиболее используемые. Оно рекомендуется для маленьких таблиц, используемых для
преобразования кодов в значения. По умолчанию используется
NOCACHE, для которого выбранные блоки помещаются в конец
таблицы частот обращений к кешу.
Оператором DECLARE можно создать PL/SQL таблицу следующим образом:
TYPE type_name IS TABLE OF
{column_type|variable%TYPE
|table.column%TYPE}[not null]
[index by binary_integer];
identifier type_name;
Пример 2.3.9
TYPE ename_table_type is table of emp.ename%type
index by binary_integer;
ename_table ename_table_type;
Структура созданной PL/SQL таблицы показана на рис. 2.2.
PRIMARY KEY
COLUMN
1
2
Jones
Smith
BINARY_INTEGER
SCALAR
Рис. 2.2. Структура PL/SQL таблицы
Приведем еще пример создания PL/SQL таблицы.
Пример 2.3.10
Declare
TYPE ename_table_type is table of emp.ename%type
2.3.2. Таблицы ♦ 93
Табличные функции
index by binary_integer;
TYPE hiredate_table_type is table of date
index by binary_integer;
ename_table ename_table_type;
hiredate_table hiredate_table_type;
begin
ename_table(1):=‘Cameron’;
hiredate_table(8):=sysdate+7;
...
end;
Следующие функции облегчают работу с таблицами:
• EXISTS (N) — возвращает TRUE, если n-ый элемент в таблице существует;
• COUNT — возвращает количество элементов в данный момент в PL/SQL таблице;
• FIRST and LAST — возвращает первый и последний (самый
маленький или самый большой) индексы в PL/SQL таблице;
• PRIOR(N) — возвращает значение индекса, предшествующего индексу N в PL/SQL таблице;
• NEXT — возвращает значение индекса, следующего за индексом N в PL/SQL таблице;
• EXTEND(n,i) — увеличивает размер таблицы, присоединяет
n копий i–го элемента PL/SQL таблицы;
• TRIM(N) — удаляет N элементов из конца PL/SQL таблицы;
• DELETE(N) — удаляет N элементов из PL/SQL таблицы.
Табличные функции
Например, следующим образом можно определить таблицу, каждый элемент которой является записью:
Declare
TYPE dept_table_type is table of dept%Rowtype
index by binary_integer;
dept_table dept_table_type;
--Каждый элемент таблицы является записью
Пример 2.3.11
Declare
type e_table_type is table of emp.ename%type
94 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
index by binary_integer;
e_tab e_table_type;
В заключение повторим, что составной тип в PL/SQL есть:
• PL/SQL запись;
• PL/SQL таблица;
• PL/SQL таблица записей.
При определении составного типа необходимо использовать
предопределенный метод %ROWTYPE.
Пример 2.3.12
DEPT_RECORD DEPT%ROWTYPE;
EMP_RECORD EMP%ROWTYPE;
DEPT_RECORD содержит ту же информацию, что и поле dEPt
таблицы, аналогично EMP_RECORD содержит ту же информацию, что и записи EMP таблицы.
2.3.3. Структура программы на PL/SQL.
Язык PL/SQL является составной частью во многих продуктах Oracle. Сервер Oracle включает поддержку языка PL/SQL,
предоставляя пользователю возможность создавать и использовать на сервере процедуры и триггеры базы данных, выполняющие задачи конкретного приложения. Программы, созданные на языке PL/SQL, могут работать совместно в различных
частях прикладной системы, построенной на средствах Oracle.
Например, в приложении, использующем работу с формами,
триггер может вызывать для выполнения некоторого действия
хранимую процедуру.
Всякая программа на PL/SQL состоит из трех блоков: описаний,
исполнительного и блока обработки исключительных ситуаций. Исполнительный блок может быть структурирован с использованием операторных скобок BEGIN и END.
Синтаксически программа на PL/SQL оформляется, как представлено на рис. 2.3.
2.3.3. Структура программы на PL/SQL ♦ 95
Типы блоков в PL/SQL
DECLARE
BEGIN
EXCEPTION
END;
Рис. 2.3. Структура программы на PL/SQL
В PL/SQL существует блоки трех типов (рис. 2.4).
Безымянный блок
[DECLARE]
BEGIN
--операторы
[EXCEPTION]
--исключительная ситуация
END;
PROCEDURE
PROCEDURE name
IS
BEGIN
--операторы
[EXCEPTION]
--исключительная ситуация
END;
FUNCTION
FUNCTION name
RETURN datatype
IS BEGIN
--операторы
RETURN value;
[EXCEPTION]
--исключительная ситуация
END;
Рис. 2.4. Типы блоков в PL/SQL
В блоке DECLARE описываются переменные, константы и определяемые пользователем типы данных. Например, объявление
констант происходит следующим образом:
Identifier[CONSTANT]datatype[NOT NULL]
[:=DEFAULT |expr];
CONSTANT — это ограничение на переменную, которая не меняется в программе, но должна быть инициализирована. Две переменные в разных блоках могут иметь одинаковые имена, перемен-
96 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
ным внутри одного блока не рекомендуется давать те же имена, что
и имена столбцов в таблицах в этом блоке.
Пример 2.3.13
DECLARE
Emp NUMBER(4);
BEGIN
SELECT
emp
INTO
emp
FROM
em
WHERE ename = ‘Smith’;
END;
Такое применение переменной EMP разрешено, так как таблица
EM определена в другом блоке.
Первый оператор BEGIN отмечает начало тела основной программы. В тело программы могут быть вложены другие блоки, ограниченные операторными скобками BEGIN и END. В блоке
EXCEPTION определяются фрагменты программного кода для обработки исключительных ситуаций в программе. Последний оператор END указывает конец тела программы.
В любые части программы на PL/SQL можно включать комментарии. Текст, который начинается с символов “– –” и продолжается
до конца текущей строки, рассматривается как комментарий. Строка, начинающаяся с ключевого слова REM, также рассматривается
как комментарий.
В блоке программы PL/SQL, ограниченном операторами
DECLARE и BEGIN, описываются переменные и константы. Любая
переменная или константа должна иметь один из допустимых в
Oracle типов. Константа идентифицируется ключевым словом
CONSTANT и отличается от переменной тем, что попытка изменить
ее значение приводит к сообщению об ошибке. Присваивание значений переменным осуществляется оператором “: =”.
Рассмотрим пример простейшей программы, в которой
определяются переменные и выполняются действия по
вычислению EXP(2) и EXP(3). Команды установки переменных
окружения SERVEROUTPUT и ECHO определяют режим вывода
на терминал пользователя.
2.3.4. Управление выполнением программы ♦ 97
Поток команд
Системная процедура DBMS_OUTPUT.PUT_LINE обеспечивает
вывод данных на терминал пользователя, а функция EXP вычисляет
экспоненту. Символ “/” указывает на завершение текста процедуры и
является командой к интерпретации и выполнению процедуры.
Пример 2.3.14
SQL>set serveroutput on;
SQL>set echo on;
SQL>DECLARE
--вход:
-------Arg — начальное значение
--выход:
-------Header1, Header2 — константы для выхода
2 Header1 CONSTANT VARCHAR2(20):='Экспонента двух
равна';
3 Header2 CONSTANT VARCHAR2(20):='Экспонента трех
равна';
4 Arg NUMBER:=2;--здесь задается начальное значение
аргумента
5--Исполнительный блок
6
BEGIN
7
DBMS_OUTPUT.PUT_LINE(Headerl || Exp(Arg));
8
Arg:=Arg+1;
9
DBMS_OUTPUT.PUT_LINE (Header2 || Exp(Arg));
10 END;
11 /
2.3.4. Управление выполнением программы.
Операторы большинства языков программирования, в том числе
и языка PL/SQL, выполняются последовательно. Такая схема называется потоком команд. В PL/SQL предусмотрено несколько операторов, с помощью которых можно управлять выполнением программы. Рассмотрим соответствующие программные конструкции.
Поток команд
Оператор ветвления
Применяется одна из следующих форм оператора ветвления:
IF — THEN — END IF
IF — THEN — ELSE — END IF
98 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
IF — THEN — ELSIF — END IF
Оператор IF. . .THEN. . .ELSE позволяет проверить условие и, в
зависимости от результатов проверки (TRUE или FALSE), выполнить различные группы операторов. Альтернативная последовательность операторов определяется ключевым словом ELSE. Границы действия оператора IF определяются закрывающей операторной скобкой END IF. Для расширения структуры ветвления дополнительно предусмотрены операторные скобки ELSIF, задающие структуры ветвления более глубокого уровня.
Oracle использует следующий синтаксис конструкции ветвления
в PL/SQL:
IF условие_1
THEN операторы_1; — ветвь 1
ELSIF условие_2
THEN операторы2; — ветвь2
ELSE оператор_n — операторы альтернативы
END IF;
Обратите внимание, что оператор дополнительного ветвления
кодируется ключевым словом ELSIF (а не ELSEIF, как иногда
предполагают не очень внимательные пользователи). В предложении IF может быть сколько угодно фраз ELSIF.
Рассмотрим пример, иллюстрирующий механизм ветвления в
программах на PL/SQL. Программа выводит сообщение о принадлежности к некоторому интервалу. Для ввода данных используется
стандартное соглашение PL/SQL: переменная, имя которой предваряется знаком “&”, вводится с терминала пользователя.
Пример 2.3.15
SQL>DECLARE
--вход:
-x — переменная на входе
--выход:
- Text1,Text2,Text3-строки для вывода
2 x NUMBER;--переменная
3 Text1 VARCHAR2(30):='Переменная>=10';
4 Text2 VARCHAR2(30):='Переменная в диапазоне
2.3.4. Управление выполнением программы ♦ 99
Оператор цикла
от 0 до 10 ';
5 Text3 VARCHAR2(30):='Переменная<=0';
6 --Исполнительный блок
7
BEGIN
8
x:=&input_Data;
9
DBMS_OUTPUT.PUT_LINE(‘ ‘);
10
IF(x>10)
11
THEN DBMS_OUTPUT.PUT_LINE(Text1);
12
ELSIF(x<0)
13
THEN DBMS_OUTPUT.PUT_LINE(Text2);
14
END IF;
15 END;
16 /
Оператор цикла.
Организация цикла оформляется в программе на PL/SQL
оператором LOOP. В PL/SQL есть три типа оператора цикла:
• LOOP;
• FOR LOOP;
• WHILE LOOP.
Цикл LOOP имеет следующий синтаксис:
LOOP
Операторы
...
EXIT [WHEN УСЛОВИЕ];
END LOOP;
Последовательность операторов между LOOP и END LOOP
многократно повторяется до тех пор, пока условие не примет значение TRUE.
Условие может принимать одно из трех значений: TRUE,
FALSE, NULL. Этот оператор выполняется, по крайней мере, хотя
бы один раз, если будет отсутствовать EXIT, то последовательность
операторов будет выполняться бесконечно. Если условие принимает значение TRUE, то будет выполняться следующий за LOOP
оператор.
100 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
Цикл FOR LOOP Вторая форма оператора цикла — это цикл с
параметром, она имеет вид:
FOR counter IN [ REVERSE]
lower_bound..upper_bound loop
Оператор1;
Оператор2;
...
END LOOP;
REVERSE означает изменение параметра ЦИКЛА от верхней
границы до нижней границы, при этом нижняя граница в операторе
цикла опять стоит первой. Объявлять параметр цикла counter в
операторе DECLARE нет необходимости, он по умолчанию объявляется как целый, lower_bound — нижняя граница изменения
параметра цикла, upper_bound — верхняя граница изменения
параметра цикла.
Например:
FOR I IN 2..3 LOOP
Оператор1;
END LOOP;
Последняя форма оператора цикла имеет вид:
While условие loop
Оператор1;
Оператор2;
...
END LOOP;
Последовательность операторов между LOOP и END LOOP повторяется до тех пор, пока условие имеет значение TRUE. Условие
проверяется до выполнения последовательности операторов, если
условие принимает значение FALSE, то последовательность операторов перестает выполняться. Этот оператор может ни разу не проработать, если условие перед выполнением оператора имеет значение FALSE.
Рассмотрим пример определения числа, факториал которого является наименьшим числом, большим заданной константы (например, 109).
2.3.4. Управление выполнением программы ♦ 101
Цикл FOR LOOP
Пример 2.3.16
SQL> DECLARE
2 Arg NUMBER;--Переменная для вычисления факториала
3 I NUMBER;--Переменная-счетчик
4 Limit NUMBER:=1000000000;--Граничное значение
5 Text1 VARCHAR2(80):='Факториал числа, впервые
превышающий 1000000000';
6--Исполнительный блок
7
BEGIN
8
I:=1;
9
Arg:=1;
10
LOOP
11
EXIT WHEN ARG>Limit;
12
I :=I+1;
13
Arg:=Arg*I;
14
END LOOP;
15
DBMS_OUTPUT.PUT_LINE(Text1);
16
DBMS_OUTPUT.PUT_LINE(TO_CHAR(Arg));
17
DBMS_OUTPUT.PUT_LINE('Искомое число=' ||
TO_CHAR(I));
18 END;
19 /
20 — использовали первую форму оператора цикла
Модифицируем предыдущий пример, изменив константу и задав
условие выхода из цикла ключевым словом WHILE.
Пример 2.3.17
SQL> DECLARE
2 Arg NUMBER;--Переменная для вычисления факториала
3 I NUMBER;--Переменная-счетчик
4 Limit NUMBER:=1000000000000;--Граничное значение
5 Text1 VARCHAR2(80):='Факториал числа, впервые
превышающий 1000000000000';
6--Исполнительный блок
7
BEGIN
8
I:=1;
9
Arg:=1;
10
WHILE Arg<Limit LOOP
11
I:=I+1;
102 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
12
13
14
15
Arg := Arg* I;
END LOOP;
DBMS_OUTPUT.PUT_LINE(Text1);
DBMS_OUTPUT.PUT_LINE(TO_CHAR(Arg));
DBMS_OUTPUT.PUT_LINE('Искомое число=' ||
TO_CHAR(I));
17 END;
18 /
В результате выполнения программы будут получены следующие результаты:
• факториал числа, впервые превышающий 1 000 000 000 000
• 10461394944000 Искомое число = 15
• PL/SQL PROCEDURE SUCCESSFULLY COMPLETED.
Цикл, управляемый оператором FOR, используется в том случае,
когда точно известно, сколько раз нужно выполнять итерацию цикла. Рассмотрим пример расчета факториала заданного числа. Обратите внимание, что переменную цикла описывать в блоке
DECLARE не нужно.
Пример 2.3.18
SQL> DECLARE
2 Arg NUMBER:=1;--Переменная для вычисления
факториала
3 Limit NUMBER:=20;--Граничное значение
4 Text1 VARCHAR2(30):='Факториал числа 20=';
5 --Исполнительный блок
6
BEGIN
7
FOR I IN 1..Limit LOOP
8
Arg:=Arg*I;
9
END LOOP;
10
DBMS_OUTPUT.PUT_LINE(Text1 ||
TO_CHAR(Arg));
11 END;
12 /
2.3.5. Учебная база данных ♦ 103
Описание языка PL/SQL
Оператор GOTO
Оператор перехода GOTO позволяет осуществить переход по
метке, присутствующей в теле программы. С помощью уникального
идентификатора, заключенного в двойные угловые скобки, можно
пометить любую часть программы PL/SQL для организации безусловного перехода по метке.
2.3.5. Учебная база данных.
Описание языка PL/SQL
В следующих разделах будем рассматривать описание языка
PL/SQL на примере следующей базы данных (табл. 2.1-2.6).
Таблица 2.1. Отношение STUDENT (Студент)
STUDENT_ID
SURNAME
NAME
STIPEND
KURS
CITY
BIRTHDAY
UNIV_ID
STUDENT_ID — идентификатор студента,
SURNAME — фамилия студента,
NAME — имя студента,
STIPEND — стипендия, которую получает студент,
KURS — курс, на котором учится студент,
CITY — город, в котором живет студент,
BIRTHDAY — дата рождения студента,
UNIV_ID — идентификатор университета, в котором учится
студент.
Таблица 2.2. Отношение LECTURE (Преподаватель)
LECTURE_ID
SURNAME
NAME
CITY
UNIV_ID
LECTURE_ID — идентификатор преподавателя,
SURNAME — фамилия преподавателя,
NAME — имя преподавателя,
CITY — город, в котором живет преподаватель,
UNIV_ID — идентификатор университета, в котором работаетпреподаватель.
104 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
Таблица 3.3. Отношение SUBJECT (Предмет обучения)
SUBJ_ID
SUBJ_NAME
HOUR
SEMESTR
SUBJ_ID — идентификатор предмета обучения,
SUBJ_NAME — наименование предмета обучения,
HOUR — количество часов, отводимых на изучение предмета,
SEMESTR — семестр, в котором изучается данный предмет.
Таблица 3.4. Отношение UNIVERSITY (Университеты)
UNIV_ID
UNIV_NAME
RATING
CITY
UNIV_ID — идентификатор университета,
UNIV_NAME — фамилия студента,
RATING — рейтинг университета,
CITY — город, в котором расположен университет.
Таблица 2.5. Отношение EXAM_MARKS (Экзаменационные оценки)
EXAM_ID
STUDENT_ID
SUBJ_ID
MARK
EXAM_ID — идентификатор экзамена,
STUDENT_ID — идентификатор студента,
SUBJ_ID — идентификатор предмета обучения,
MARK — экзаменационная оценка,
EXAM_DATE — дата экзамена.
Таблица 2.6. Отношение SUBJ_LECT
(Учебные дисциплины преподавателей)
lecture _ID
SUBJ_ID
LECTURE _ID — идентификатор преподавателя,
SUBJ_ID — идентификатор предмета обучения.
EXAM_DATE
2.3.6. Курсоры ♦ 105
Явный курсор
2.3.6. Курсоры.
Ключевым понятием языка PL/SQL является курсор. Каждое
SQL утверждение, выполняемое сервером ORACLE, имеет индивидуальный курсор, связанный с:
• неявным курсором, объявленным для всех DML-утверждений;
• явным курсором, объявленным и поименованным программистом.
Явный курсор – это поименованный запрос, содержащий некоторое фиксированное число строк в выборке. Чаще всего курсор содержит данные одной строки выбираемой таблицы. По существу,
курсор является окном, через которое пользователь получает доступ
к информации базы данных. Курсоры, в частности, могут использоваться для присваивания конкретных значений переменным программы.
Рассмотрим работу явного курсора (рис. 2.5).
Объявление курсора происходит следующим утверждением:
CURSOR cursor_name IS Select_statement;
Рис. 2.5. Работа явного курсора
При этом должны выполняться следующие правила:
• нельзя включать INTO в предложение курсора;
• если требуется использовать последовательность, то необходимо применить ORDER BY в предложении курсора.
106 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
Рассмотрим пример доступа к информации, хранимой в базе
данных, с использованием курсоров. Пусть в базе данных хранится
таблица LECTURE, сформированная предложениями:
CREATE TABLE
LECTURE(LECTURE_ID NUMBER, SURNAME VARCHAR2(30),
NAME VARCHAR2(10), CITY VARCHAR2(30),
UNIV_ID NUMBER);
INSERT INTO LECTURE VALUES(1, 'Иванов', 'Иван',
'Воронеж', 100);
INSERT INTO LECTURE VALUES(2, 'Петров', 'Петр',
'Москва', 400);
INSERT INTO LECTURE VALUES(3, 'Сидоров', 'Юрий',
'Воронеж', 100);
Опишем курсор Curl, ориентированный на получение данных из
таблицы LECTURE:
Declare
CURSOR Curl IS
SELECT *
FROM LECTURE;
Первым шагом, необходимым для работы с курсором, является
открытие курсора, которое выполняется командой:
OPEN Curl;
Выборка данных из курсора может быть выполнена в набор переменных подходящих типов, командой FETCH, имеющей следующий синтаксис:
Fetch cursor_name into[variable1, variable2,...]
|[record_name];
При этом должны соблюдаться следующие правила:
• значения текущей строки записываются в переменные;
• команда FETCH должна содержать то же самое количество
переменных, которое содержит и курсор;
• каждая переменная должна соответствовать колонкам;
2.3.6. Курсоры ♦ 107
пример доступа к информации, хранимой в базе данных, с использованием
курсоров
Например:
FETCH Curl INTO Arg1, Arg2, Arg3, Arg4, Arg5;
Полностью процедура получения данных из таблицы LECTURE
представлена в примере.
Пример 2.3.19
SQL> set serveroutput on;
SQL> set echo on;
SQL> set termout on;
SQL> DECLARE
2 Arg1 NUMBER; -- Переменная для первого аргумента
3 Arg2 VARCHAR2(30); -- Переменная для второго
аргумента
4 Arg3 VARCHAR2(10); -- Переменная для третьего
аргумента
5 Arg4 VARCHAR2(30); -- Переменная для четвертого
аргумента
6
Arg5 NUMBER; -- Переменная для пятого аргумента
7
Cursor Curl IS SELECT * FROM LECTURE;
-- Определение курсора
8
BEGIN
9
Open Curl; -- Курсор должен быть открыт
10
FOR I IN 1..3 LOOP
11
FETCH Curl INTO Arg1,Arg2, Arg3,Arg4,Arg5;
12
DBMS_OUTPUT.PUT_LINE(TO_CHAR(Arg1)
13
END LOOP;
14 END;
15 /
В данной программе неудачно управление счетчиком, поскольку
цикл настроен на получение конкретного числа строк, которых может и не быть в таблице. В PL/SQL для курсоров предусмотрены
специальные методы %NOTFOUND и %FOUND, принимающие
противоположные булевские значения. Метод %NOTFOUND возвращает значение TRUE, если выборка в курсор пустая, то есть не
содержит строки. После открытия курсора, но до первой команды
FETCH, методы %FOUND, %NOTFOUND принимают неопреде-
108 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
ленное значение (UNKNOWN). Незнание этого факта может привести к достаточно распространенной ошибке. При организации
цикла с использованием оператора WHILE и выполнением проверки на истинность %FOUND на входе, цикл не будет выполнен ни
разу, несмотря на наличие данных в таблице. Метод
%ROWCOUNT возвращает число строк, выбранных после открытия курсора. Бывает полезно использование метода %ISOPEN логического типа, возвращающего TRUE, если курсор открыт: этот
метод применяется перед использованием команды FETCH для
проверки — открыт ли курсор или нет.
С учетом дополнительных объектов и методов PL/SQL рассмотрим новый вариант программы выборки строк таблицы LECTURE
c использованием курсоров. Обратите внимание на повторный вывод последней строки. Попытайтесь исправить организацию цикла
для устранения повторного вывода.
Пример 2.3.20
SQL>set serveroutput on;
SQL>set echo on;
SQL>set termout on;
SQL>DECLARE
2 TYPE Tabl_rec_type IS RECORD -–Определение
--нового типа данных
3
(Arg1 LECTURE.LECTURE_ID%TYPE, --Переменная типа
--атрибута LECTURE_ID таблицы LECTURE
4
Arg2 LECTURE.SURNAME%TYPE, --Переменная типа
--атрибута SURNAME таблицы LECTURE
5 Arg3 LECTURE.NAME%TYPE, --Переменная типа
--атрибута NAME таблицы LECTURE
6 Arg4 LECTURE.CITY%TYPE, --Переменная типа
--атрибута CITY таблицы LECTURE
7
Arg5 LECTURE.UNIV_ID%TYPE; --Переменная типа
--атрибута UNIV_ID таблицы LECTURE
8
Tаb1_гес Tabl_rec_type; --Определение объекта
--сконструированного типа
9 Cursor Curl IS SELECT * FROM LECTURE;
--Определение курсора
10 BEGIN
2.3.6. Курсоры ♦ 109
пример выборки данных с параметрическим запросом и организацией цикла
11
12
13
14
15
16
17
18
19
Open Curl; --Курсор должен быть открыт
FETCH Curl INTO Tabl_rec;
LOOP
EXIT WHEN (Curl%NOTFOUND);
DBMS_OUTPUT.PUT_LINE(Curl%ROWCOUNT || ' '
|| Tabl_rec.Arg2 || ' '|| Tabl_rec.Arg3
|| ' '|| Tabl_rec.Arg4);
FETCH Curl INTO Tabl_rec;
END LOOP;
END;
/
Курсор может содержать параметр, синтаксис такого курсора
имеет следующий вид:
CURSOR cursor_name
[(parametr_name datatype,...)]
is
select_statement;
•
•
параметр добавляется при открытии курсора;
каждый раз рекомендуется открывать курсор, когда меняется активное множество элементов.
Declare
Cursor emp_cursor
(p_deptno number, p_job varchar2) is
select empno,ename
from emp
where deptno=p_deptno
and job = p_job;
begin
open emp_cursor(10,’clerk’);
Оператор определения курсора может содержать параметрический запрос. Значения параметра задаются при открытии курсора.
Рассмотрим пример выборки данных с параметрическим запросом и организацией цикла, исключающей повторный вывод последней строки.
110 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
Пример 2.3.21
SQL> DECLARE
2 TYPE Tabl_rec_type IS RECORD
--Определение
--нового типа данных
3
(Arg1 LECTURE.LECTURE_ID%TYPE, --Переменная
--типа атрибута
--LECTURE_ID таблицы LECTURE
4
Arg2 LECTURE.SURNAME%TYPE,
--Переменная типа
-- атрибута SURNAME таблицы LECTURe
5
Arg3 LECTURE.NAME%TYPE,
--Переменная типа
--атрибута NAME таблицы LECTURE
6
Arg4 LECTURE.CITY%TYPE, --Переменная типа
--атрибута CITY таблицы LECTURE
7
Arg5 LECTURE.UNIV_ID%TYPE);
--Переменная типа
--атрибута UNIV_ID таблицы LECTURE
8
Tаb1_Rес Tabl_rec_type; --Определение объекта
--сконструированногО типа
9
Cursor Cur2(I NUMBER) IS SELECT * FROM LECTURE
WHERE CITY=’Воронеж’; --Определение
--курсора
10 BEGIN
11 Open Cur2(2); --Курсор должен быть открыт
12 FETCH Cur2 INTO Tab1_rec;
13 WHILE Cur2%FOUND LOOP
14 DBMS_OUTPUT.PUT_LINE(Cur2%ROWCOUNT || ' ' ||
Tabl_rec.Arg2 || ' ' ||
Tabl_rec.Arg3 || ' ' || Tabl_rec.Arg4);
15 FETCH Cur2 INTO Tabl_rec;
16 END LOOP;
17 END;
18 /
После выбора всех строк из таблицы курсор должен быть закрыт,
синтаксис команды:
CLOSE cursor_name;
Если возникнет необходимость, курсор может быть повторно
открыт, однако, после закрытия курсора нельзя пользоваться командой FETCH.
2.3.7. Обработка исключительных ситуаций ♦ 111
Некоторые предопределенные исключительные ситуации PL/SQL
Курсоры применяются совместно с командой LOOP, синтаксически это выглядит следующим образом:
FOR record_name in cursor_name LOOP
If record_name.attribute = 30 then
...
end loop;
Declare
Cursor Curl IS
SELECT *
FROM LECTURE; BEGIN
...
for tab1_rec in Curl loop
FETCH Curl INTO Tab1_rec;
if tab1_rec.arg1>30 then
DBMS_OUTPUT.PUT_LINE(Curl%ROWCOUNT ||' '||
Tab1_rec.Arg2 ||' '||Tab1_rec.
Arg3 ||' '||Tab1_rec.Arg4);
end loop;
end;
После инструкции IN можно пользоваться подзапросом для выборки, при этом подзапрос заключается в круглые скобки.
2.3.7. Обработка исключительных ситуаций.
Большинство развитых языков программирования обладает
встроенными механизмами обработки исключительных ситуаций.
Соответствующие языковые средства предусмотрены и в PL/SQL.
При возникновении в системе предопределенной или описанной
пользователем ситуации происходит автоматическая передача
управления в нужный фрагмент блока EXCEPTION программы на
PL/SQL, где и происходит предусмотренная обработка возникшей
исключительной ситуации.
Некоторые предопределенные исключительные ситуации PL/SQL
представлены в таблице 2.7. Полный перечень исключительных ситуаций может быть найден в руководстве по языку PL/SQL.
112 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
Таблица 2.7. Некоторые исключительные ситуации
Символическое имя предопределенной исключительной ситуации
Описание предопределенной
исключительной ситуации
LOGIN_DENIED
Неуспешное подключение к серверу (например, введен неверный пароль)
Попытка выполнить действие без подключения к серверу ORACLE
Ссылка на недопустимый курсор или недопустимая операция с курсором
Не найдены данные, соответствующие
оператору SELECT INTO
Попытка вставить значение-дубликат в
столбец с ограничением на уникальность
значения
Оператор SELECT INTO возвращает более одной строки в переменную
NOT_LOGGED_ON
INVALID_CURSOR
NO_DATA_FOUND
DUP_VAL_ON_INDEX
TOO_MANY_ROWS
VALUE_ERROR
Арифметическая ошибка, ошибка преобразования или усечения
TIMEOUT_ON_RESOURCE
Блокировка по времени при ожидании ресурса
Деление на ноль
Неудачная попытка преобразования к типу NUMBER
Внутренняя ошибка языка, устанавливается, если PL/SQL недостаточно памяти
Внутренняя ошибка PL/SQL
Попытка открыть курсор, который уже открыт
ZERO_DIVIDE
INVALID_NUMBER
STORAGE_ERROR
PROGRAM_ERROR
CURSOR_ALREADY_OPEN
Рассмотрим пример программы с обработкой исключительных ситуаций. В тексте программы пропущен оператор открытия курсора,
поэтому при обращении к методу %FOUND неоткрытого курсора
возникнет исключительная ситуация INVALID_CURSOR.
Пример 2.3.22
SQL>DECLARE
2
Arg1 LECTURE.LECTURE_ID%TYPE;
3
Arg2 LECTURE.SURNAME%TYPE;
2.3.7. Обработка исключительных ситуаций ♦ 113
Обработка нестандартных исключительных ситуаций
4
5
6
7
8
9
10
11
12
13
14
15
Arg3 LECTURE.NAME%TYPE;
Arg4 LECTURE.CITY%TYPE;
Arg5 LECTURE.UNIV_ID%TYPE;
Cursor Curl IS SELECT * FROM LECTURE;
BEGIN
FETCH Curl INTO Arg1,Arg2,Arg3,Arg4,Arg5;
WHILE Curl%FOUND LOOP
FETCH Curl INTO Arg1,Arg2,Arg3,Arg4,Arg5;
END LOOP;
EXCEPTION
WHEN INVALID_CURSOR THEN
DBMS_OUTPUT.PUT_LINE('Ошибка приложения.
He открыт курсор');
16 END;
17 /
Для обработки исключительных ситуаций, не входящих в перечень стандартных, можно использовать cпециальный обработчик
PL/SQL OTHERS или описать пользовательскую исключительную
ситуацию и запрограммировать ее обработку. Ключевое слово
OTHERS блока EXCEPTION определяет механизм универсальной
обработки исключительных ситуаций, не вошедших в список ситуаций, обрабатываемых явно в блоке EXCEPTION. Введем в текст
программы запрещенную операцию деления на ноль и обработаем
данную исключительную ситуацию в списке OTHERS. (На самом
деле в ORACLE предопределена исключительная ситуация
ZERO_DIVIDE, но в данном примере это не важно, а важно то, что
ее нет в списке блока EXCEPTION.)
Пример 2.3.23
SQL> DECLARE
2
Arg1 LECTURE.LECTURE_ID%TYPE;
3
Arg2 LECTURE SURNAME%TYPE;
4
Arg3 LECTURE.NAME%TYPE;
5
Arg4 LECTURE.CITY%TYPE;
6
Arg5 LECTURE.UNIV_ID%TYPE;
7
Cursor Curl IS SELECT * FROM LECTURE;
8
Arg6 NUMBER:=1;
9
BEGIN
Обработка нестандартных исключительных ситуаций
114 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
10
11
12
13
14
15
16
17
18
19
20
Arg6:=Arg6/0.0;
WHILE Curl%FOUND LOOP
FETCH Curl INTO Arg1,Arg2,Arg3,Arg4,Arg5;
END LOOP;
EXCEPTION
WHEN INVALID_CURSOR THEN
DBMS_OUTPUT.PUT_LINE('Ошибка приложения.
He открыт курсор');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE ('Ошибка приложения.
He диагностированная ошибка');
END;
/
Исключительная ситуация, определяемая пользователем, должна
быть описана в блоке DECLARE программы. Используется следующий синтаксис описания исключительной ситуации:
Имя_исключительной_ситуации EXCEPTION;
В программе условие возникновения исключительной ситуации
определяется стандартными средствами, обычно операторами
IF…THEN. После обнаружения условий возникновения исключительной ситуации она генерируется оператором RAISE, который
имеет следующий синтаксис:
RAISE Имя_исключительной ситуации;
Оператор RAISE генерирует исключительную ситуацию и передает управление на соответствующий обработчик исключительной
ситуации, который определен в блоке EXCEPTION. В качестве
примера в роли исключительной ситуации рассмотрим превышение значения Arg1 порога, равного 20.
Пример 2.3.24
SQL>DECLARE
2
Arg1 LECTURE.LECTURE_ID%TYPE;
3
Arg2 LECTURE.SURNAME%TYPE;
4
Arg3 LECTURE.NAME%TYPE;
5
Arg4 LECTURE.CITY%TYPE;
2.3.7. Обработка исключительных ситуаций ♦ 115
Упражнения
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Arg5 LECTURE.UNIV_ID%TYPE;
Special_case EXCEPTION; --Пользовательская
--исключительная ситуация
Cursor Curl IS SELECT * FROM LECTURE;
BEGIN
OPEN Curl;
FETCH Curl INTO Arg1,Arg2,Arg3,Arg4,Arg5;
WHILE Curl%FOUND LOOP
FETCH Curl INTO Argl,Arg2,Arg3,Arg4,Arg5;
IF Arg1>20
THEN RAISE Special_case;
END IF;
END LOOP;
EXCEPTION
WHEN Special_case THEN
DBMS_OUTPUT.PUT_LINE('Пользовательская
Исключительная ситуация’);
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Oшибка приложения.
He диагностированная ошибка');
END;
/
Упражнения.
2.1. Сделать выборку из таблицы STUDENT с использованием
курсора и цикла с методом %FOUND или %NOTFOUND
для получения данных о студентах, живущих в Москве.
2.2. Сделать выборку из таблицы SUBJECT с использованием
курсора и цикла с методом %FOUND или %NOTFOUND
для получения данных о предметах во 2-ом семестре.
2.3. Сделать выборку из таблицы UNIVERSITY с использованием
курсора и цикла с методом %FOUND или %NOTFOUND
для получения данных об университетах с рейтингом большим 200.
2.4. Сделать выборку из таблицы EXAM_MARKS с использованием курсора и цикла с методом %FOUND или %NOTFOUND
для получения сведений об экзаменах, сданных в определенную дату.
116 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
2.5. Сделать выборку из таблицы SUBJ_LECT с использованием
курсора и цикла с методом %FOUND или %NOTFOUND
для получения данных о преподавателях, читающих предмет с
данным номером.
2.6. Сделать выборку из таблицы STUDENT с использованием
курсора и цикла с методом %FOUND или %NOTFOUND
для получения данных о студентах, живущих в Москве, и использовать пользовательскую исключительную ситуацию для
исключения среди выбранных студентов тех, у которых стипендия меньше 200.
2.7. Сделать выборку из таблицы SUBJECT с использованием курсора и цикла с методом %FOUND или %NOTFOUND для
получения данных о предметах во 2-ом семестре с использованием пользовательской исключительной ситуации для исключения из полученного списка предметов с количеством
часов 72.
2.8. Сделать выборку из таблицы UNIVERSITY с использованием
курсора и цикла с методом %FOUND или %NOTFOUND
для получения данных об университетах с рейтингом большим 200 и исключить с помощью пользовательской исключительной ситуации данные об университетах, расположенных в Воронеже.
2.9. Сделать выборку из таблицы EXAM_MARKS с использованием курсора и цикла с методом %FOUND или %NOTFOUND
для получения сведений об экзаменах, сданных в определенную дату, и исключить с помощью пользовательской исключительной ситуации данные об оценках, полученных по заданному номеру предмета.
2.10. Сделать выборку из таблицы SUBJ_LECT с использованием
курсора и цикла с методом %FOUND или %NOTFOUND
для получения данных о преподавателях, читающих предмет с
данным номером, и исключить из полученного множества
данные с помощью пользовательской исключительной ситуации о преподавателях с заданной фамилией.
2.3.8. Создание пользовательских процедур и функций ♦ 117
Хранимые процедуры и функции
2.3.8. Создание пользовательских
процедур и функций.
Подпрограммы (процедуры и функции) в PL/SQL бывают хранимые и локальные. Хранимые подпрограммы во многом отличаются
от локальных. Если подпрограмма должна будет вызываться из многих блоков, то ее делают хранимой, она хранится в базе данных.
Короткие процедуры и функции рекомендуется объявлять локально
в блоке, если они вызываются только из одного конкретного фрагмента программы. Хранимые подпрограммы (процедуры и функции) хранятся в базе данных в откомпилированном виде и могут вызываться из любого блока.
В этом разделе будем рассматривать хранимые подпрограммы.
Хранимые процедуры и функции – это объекты базы данных и,
следовательно, они создаются командой CREATE и уничтожаются
командой DROP. При создании процедуры и функции должны быть
определены: имя объекта, перечень и тип параметров и логика работы процедуры или функции, описанные на языке PL/SQL
Чтобы создать процедуру или функцию, необходимо иметь системные привилегии CREATE PROCEDURE. Для cоздания процедуры, функции или пакета в схеме, отличной от текущей схемы
пользователя, требуются системные привилегии CREATE ANY
PROCEDURE. После определения имени новой процедуры или
функции необходимо задать ее имена, типы и виды параметров.
Для каждого параметра должен быть указан один из видов параметра — IN, OUT или IN OUT. Вид параметра IN предполагает, что
значение параметра должно быть определено при обращении к
процедуре и не изменяется процедурой.
Попытка изменить в теле процедуры параметр вида IN приведет
к сообщению об ошибке. Вид параметра OUT предполагает изменение значения параметра в процессе работы процедуры, то есть
параметр вида ОUТ — это возвращаемый параметр. Параметр IN
OUT — это параметр, которому при вызове должно быть присвоено значение, которое может быть изменено в теле процедуры. Па-
118 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
раметры процедур или функций имеют виды, присвоенные по
умолчанию.
Дополнительно к определениям, необходимым для процедуры, в
определении функции должен быть указан тип данных единственного возвращаемого функцией значения. Возврат значения функции выполняется командой PL/SQL RETURN. Оператор определения процедуры ORACLE использует следующий синтаксис:
CREATE[OR REPLACE]PROCEDURE
[имя_схемы.]имя_процедуры
[(имя_параметра[{IN | OUT | IN OUT}] тип_данных
[,имя_параметра[{IN | OUT | IN OUT}] тип_данных...])]
{IS | AS}
npoгpaммa_нa_PL/SQL
Ключевое слово OR REPLACE указывает на безусловное замещение старого текста процедуры. Если ключевое слово OR REPLACE
не указано, и процедура определена, то замещения старого значения кода процедуры не происходит, и возвращается сообщение об
ошибке.
В описании переменных процедуры не используется ключевое слово DECLARE. Блок определения данных начинается сразу после
ключевого слова AS (или IS, по выбору пользователя).
Рассмотрим пример создания процедуры, которая заносит в
таблицу значения, зависящие от числового параметра. Пусть
таблица сформирована предложением:
CREATE TABLE SUBJ_LECT(LECTURE_ID NUMBER,
SUBJ_ID NUMBER);
Протокол создания процедуры представлен в примере 2.3.25.
Пример 2.3.25
SQL>CREATE OR REPLACE PROCEDURE InsRec
2
(Arg1 IN NUMBER,Arg2 IN NUMBER)
3
AS
4
Coeff CONSTANT NUMBER:=0.5;
5
BEGIN
6
INSERT INTO SUBJ_LECT
2.3.8. Создание пользовательских процедур и функций ♦ 119
Пример обнаружения и исправления ошибки
7
8
END;
/
VALUES(Coeff*Arg1,Coeff*Arg2);
Исполнение созданной процедуры INSREC может быть выполнено оператором ЕХЕС языка PL/SQL. Последующая выборка из
таблицы SUBJ_LECT иллюстрирует изменения в базе данных, осуществленные вызовом процедуры INSREC.
SQL> ЕХЕС InsRec (240,120);
Чтобы уточнить выявленные в процессе синтаксического анализа ошибки, можно воспользоваться командой PL/SQL SHOW
ERRORS. Эта команда показывает ошибки, обнаруженные в процессе выполнения CREATE PROCEDURE, CREATE FUNCTION,
CREATE PACKAGE, CREATE PACKAGE BODY И CREATE
TRIGGER. Если команда SHOW ERRORS используется без параметров, то возвращаются ошибки последней компилированной
процедуры, функции, пакета, тела пакета или триггера.
Рассмотрим пример обнаружения и исправления ошибки. В
процедуре, представленной выше, добавим ошибочный оператор,
изменяющий значение параметра вида IN, который не должен изменяться.
Пример 2.3.26 Пример обнаружения и исправления ошибки
SQL>CREATE OR REPLACE PROCEDURE InsRec
2
(Arg1 IN NUMBER, Arg2 IN NUMBER)
3
AS
4
Coeff CONSTANT NUMBER:=0.5;
5
BEGIN
6
Arg1:=Arg1+200;
7 NSERT INTO SUBJ_LECT VALUES(Coeff*Arg1,
Coeff*Arg2);
8
END;
9
/
Протокол выполнения:
SQL>show errors
Errors for PROCEDURE INSREC:
120 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
LINE/COL ERROR
6/1 PLS-00363: expression 'ARG1' cannot be used
as an assignment target
6/1 PL/SQL: Statement ignored
Напомним, что функции PL/SQL отличаются от процедур тем,
что возвращают в вызывающую среду значение параметра.
Оператор определения функции ORACLE использует следующий синтаксис:
CREATE [OR REPLACE] FUNCTION
[имя_схемы.]имя_функции
[(имя_параметра[{IN | OUT | IN OUT}] тип_данных
[,имя_параметра[{IN | OUT | IN OUT}]
тип_данных...])]
RETURN тип_данных
{IS | AS}
npoгpaммa_na_PL/SQL
Описание типа данных для возвращаемого функцией значения
требуется обязательно. При описании переменных функции так же,
как и при описании переменных процедуры, не используется ключевое слово DECLARE. Блок определения данных начинается сразу
после ключевого слова IS (или AS, по выбору пользователя).
Рассмотрим пример создания функции, которая вычисляет сумму значений атрибутов, таких, что один из атрибутов попадает в заданный параметрами функции интервал. Пусть таблица сформирована предложением как, в примере 2.3.27.
Пример 2.3.27
SQL>CREATE OR REPLACE FUNCTION SumRecInt
2
(Arg1 IN NUMBER,Arg2 IN NUMBER)
3
RETURN NUMBER
4
AS
5
Sum_Var NUMBER:=0.0;
6
BEGIN
8 SELECT Sum(LECTURE_ID) INTO Sum_Var
FROM SUBJ_LECT
WHERE SUBJ_ID BETWEEN Arg1 AND Arg2;
8
RETURN Sum_Var;
2.3.8. Создание пользовательских процедур и функций ♦ 121
Упражнения 2.11–2.20
9
END;
10 /
Получим:
FUNCTION CREATED
Если характер использования приложений изменился, то для освобождения ресурсов базы данных может потребоваться уничтожить процедуру или функцию. В собственной схеме пользователю
не требуются дополнительные привилегии для уничтожения процедуры или функции. Для уничтожения процедуры или функции в
схеме другого пользователя необходимо наличие привилегии
DROP ANY PROCEDURE.
Для уничтожения процедуры ORACLE использует следующий
синтаксис:
DROP PROCEDURE [имя_схемы.]имя_процедуры
Рассмотрим пример уничтожения функции Oracle.
SQL>DROP FUNCTION SumRecInt
Function dropped;
Упражнения Упражнения 2.11—2.20
2.11. Описать процедуру, которая заносит данные в таблицу
STUDENT в зависимости от параметров процедуры, вызвать
эту процедуру.
2.12. Описать процедуру, которая заносит данные в таблицы
STUDENT и EXAM_MARKS с соблюдением ссылочной целостности, в зависимости от параметров процедуры, вызвать
эту процедуру.
2.13. Описать процедуру, которая заносит данные в таблицы
STUDENT и SUBJECT с соблюдением ссылочной целостности, в зависимости от параметров процедуры, вызвать эту
процедуру.
2.14. Описать процедуру, которая заносит данные в таблицы
STUDENT и UNIVERSITY с соблюдением ссылочной цело-
122 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
2.15.
2.16.
2.17.
2.18.
2.19.
2.20.
стности, в зависимости от параметров процедуры, вызвать эту
процедуру.
Описать процедуру, которая заносит данные в таблицу
LECTURE в зависимости от параметров процедуры, вызвать
эту процедуру.
Описать и вызвать функцию, которая вычисляет сумму баллов
для студентов, номера которых находятся в заданном интервале в таблице EXAM_MARKS.
Описать и вызвать функцию, которая вычисляет для студентов, номера которых находятся в данном диапазоне, максимальный балл по заданному предмету (с некоторым номером)
в таблице EXAM_MARKS.
Описать и вызвать функцию, которая определяет для студентов с заданной фамилией сумму баллов по заданному предмету в таблице EXAM_MARKS.
Описать и вызвать функцию, которая вычисляет для студентов, номера которых находятся в данном диапазоне, максимальный балл по заданному названию предмета.
Описать и вызвать функцию, которая вычисляет для студентов, номера которых находятся в данном диапазоне, средний
балл по заданному названию предмета.
2.3.9. Пакеты PL/SQL.
Модуль — это конструкция PL/SQL, которая позволяет хранить связанные объекты в одном месте. Модули бывают только хранимыми и
никогда локальными. Модуль — это именованный раздел объявлений. Все, что может входит в раздел объявлений блока, может входить и в модуль: типы, переменные, процедуры, функции, курсоры.
Размещение их в модуле полезно, так как это позволит ссылаться на
них из других блоков PL/SQL, в модулях можно описывать и глобальные переменные для PL/SQL.
Процедуры, функции и глобальные переменные, объединенные
общим функциональным замыслом, часто оформляют в виде единого объекта базы данных — пакета. Особенностью пакетов
PL/SQL является раздельная компиляция и хранение интер-
2.3.9. Пакеты PL/SQL ♦ 123
Поддержка перегружаемых функций и процедур
фейсной и исполнительной частей пакета. Пакет как объект состоит из двух частей: спецификации пакета и тела пакета. В спецификации пакета хранится описание процедур, функций, глобальных переменных, констант и курсоров, которые доступны для
внешних приложений. В теле пакета определяются все процедуры,
функции и переменные, включая те, которые не были определены
в спецификации пакета. Процедуры, функции и переменные, определенные в теле пакета, но не описанные в его спецификации,
являются локальными. Внешние по отношению к пакету приложения не имеют права на использование локальных объектов пакета.
Локальные объекты предназначены исключительно для использования только процедурами и функциями самого пакета.
Особенностью пакетов PL/SQL является поддержка перегружаемых функций и процедур. Процедуры или функции могут
иметь одинаковое имя, но различный по типу или количеству набор аргументов. В момент обращения к конкретной процедуре или
функции по числу и типу передаваемых аргументов автоматически
определяется требуемая процедура или функция, которая и исполняется. Поддержка перегружаемых процедур, в частности, используется в стандартном пакете DBMS_OUTPUT для единой формы обращения к процедуре PUT_LINE для вывода данных различных
типов. Поддержка перегружаемых функций и процедур
Напомним, что для создания пакета пользователь должен иметь
привилегию CREATE PROCEDURE. Создание пакета в схеме другого пользователя требует наличия привилегии CREATE ANY
PROCEDURE.
Оператор определения интерфейсной части (спецификации) пакета ORACLE использует следующий синтаксис:
CREATE [OR REPLACE] PACKAGE [имя_схемы.]имя_пакета
{IS | AS}
спецификация_пакета_на_PL/SQL
Ключевое слово OR REPLACE указывает на безусловное замещение старого текста спецификации пакета. Если ключевое слово OR
REPLACE не указано, и пакет определен в системе, то замещения
124 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
старого значения спецификации пакета не происходит, и возвращается сообщение об ошибке. Спецификация пакета начинается с
описания констант и переменных. При описании переменных пакета ключевое слово DECLARE не используется.
Рассмотрим пример создания спецификации пакета, которая состоит из описания константы, функции и процедуры.
Пример 2.3.28
SQL>CREATE OR REPLACE PACKAGE PAC
2
AS
3
PAC_CONST CONSTANT NUMBER:=20;
4
FUNCTION MUL(Arg1 NUMBER, Arg2 NUMBER)
5
RETURN NUMBER;
6
PROCEDURE AUDIT;
7
END;
8
/
Оператор определения исполнительной части (тела) пакета
ORACLE использует следующий синтаксис:
CREATE [OR REPLACE] PACKAGE BODY
[имя_схемы.]имя_пакета
{IS | AS}
cneцификация_naкema_нa_PL/SQL
Ключевое слово OR REPLACE указывает на безусловное замещение старого текста тела пакета. Если ключевое слово OR REPLACE
не указано, и пакет определен в системе, то замещения старого значения тела пакета не происходит, и возвращается сообщение об
ошибке.
Определение тела пакета начинается с описания констант и
переменных. Константы и переменные, описанные в спецификации
пакета, являются глобальными и в теле пакета повторно не описываются. При описании констант и переменных пакета ключевое слово
DECLARE не используется. Пример создания тела пакета
Рассмотрим пример создания тела пакета, спецификация которого приведена выше. Пусть функция пакета MUL выполняет умножение аргументов на константу пакета, а процедура AUDIT фик-
2.3.9. Пакеты PL/SQL ♦ 125
Пример создания тела пакета
сирует факт обращения к функции MUL записью в таблицу значения счетчика обращений и текущей даты. Предполагается, что таблица TABAUD с соответствующими типами данных атрибутов к
моменту создания тела пакета создана. Протокол создания тела пакета приведен ниже.
При описании функций и процедур пакета в отличие от описаний одиночных функций и процедур оператор CREATE не используется.
Пример 2.3.29
SQL>CREATE OR REPLACE PACKAGE BODY PAC
2
AS
3
PAC_COUNT NUMBER:=0;
4
FUNCTION MUL(Arg1 NUMBER, Arg2 NUMBER)
5
RETURN NUMBER IS
6
BEGIN
7
AUDIT;
8
RETURN Arg1* PAC_CONST+Arg2*PAC_CONST;
9
END;
10 PROCEDURE AUDIT IS
11 BEGIN
12
PAC_COUNT:=PAC_COUNT+1;
13
INSERT INTO TabAUD
VALUES (PAC_COUNT, SYSDATE);
14
COMMIT;
15
END;
16 END;
17 /
Package body created.
Константа или переменная, описанная в спецификации пакета, может быть доступна из пользовательской программы (конечно, если процедуре или функции такой доступ разрешен). Чтобы
обратиться к глобальной переменной или константе пакета, нужно указать в качестве префикса имя пакета. Ниже приведен пример, иллюстрирующий возможность доступа к глобальной константе пакета и невозможность доступа к частной переменной
пакета.
126 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
SQL>EXEC DBMS_OUTPUT.PUT_LINE(PAC.PAC_CONST);
20.0
PL/SQL procedure successfully completed.
SQL>EXEC DBMS_OUTPUT.PUT_LINE(PAC.PAC_COUNT);
begin
dbms_output.put_line(pac.pac_count);
end;
ERROR at line 1;
ORA-06550: line I, column 34:
PLS-00302: component 'PAC_COUNT' must be declared
ORA-06550: line I, column 7:
PL/SQL: Statement ignored
Чтобы вызвать процедуру или функцию пакета, в вызове нужно
указать в качестве префикса имя пакета.
В заключение раздела рассмотрим пример использования функции созданного пакета.
SQL>EXEC DBMS_OUTPUT.PUT_LINE(PAC.MUL(lll,222));
PL/SQL procedure successfully completed.
При использовании переменных пакета инициализация локальных переменных пакета происходит при запуске сервера Oracle. В
данном случае, после останова и повторного запуска сервера, счетчик обращений PAC_COUNT будет установлен в нулевое состояние. Если по смыслу решаемой задачи требуется независимое от
остановов сервера приращение счетчика, можно воспользоваться
таким объектом, как последовательность.
Для освобождения ресурсов сервера может потребоваться уничтожить пакет. В собственной схеме пользователю не требуются дополнительные привилегии для уничтожения пакета. Для уничтожения пакета в схеме другого пользователя необходима привилегия
DROP ANY PROCEDURE.
Для уничтожения спецификации пакета и тела пакета Oracle использует следующий синтаксис:
DROP PACKAGE [BODY] [имя_схемы.]имя_пакета
2.3.9. Пакеты PL/SQL ♦ 127
Упражнения 2.21–2.26
Необязательное ключевое слово BODY указывает, что уничтожается
только тело пакета. Если ключевое слово BODY опущено, то удаляется и спецификация, и тело пакета. Параметр имя_пакета задает
имя уничтожаемого пакета. Пример уничтожения пакета рассматривается ниже:
SQL > DROP PACKAGE PAC;
Package dropped
Упражнения Упражнения 2.21—2.26
2.21. Создать пакет, состоящий из функции с параметрами, процедуры без параметров. Функция подсчитывает количество студентов, получающих стипендию, заданную параметром. Процедура подсчитывает число обращений к функции и заносит
это число, размер стипендии, количество студентов, получающих ее, в новую таблицу, созданную заранее.
2.22. Создать пакет, состоящий из функции с параметрами, процедуры без параметров. Функция подсчитывает количество студентов, живущих в городе, заданном параметром. Процедура
подсчитывает количество обращений к функции и заносит
это количество, название города, количество студентов, живущих в этом городе, в новую таблицу, созданную заранее.
2.23. Создать пакет, состоящий из функции с параметрами, процедуры без параметров. Функция подсчитывает количество
предметов, по которым получена оценка, заданная параметром, более чем у 20 человек. Процедура подсчитывает число
обращений к функции и заносит это число, оценку и количество предметов в новую таблицу, созданную заранее.
2.24. Создать пакет, состоящий из функции с параметрами, процедуры без параметров. Функция подсчитывает количество университетов с рейтингом, заданным параметром. Процедура
подсчитывает количество обращений к функции и заносит
это количество, величину рейтинга, количество университетов
с этим рейтингом в новую таблицу, созданную заранее.
2.25. Создать пакет, состоящий из функции с параметрами, процедуры без параметров. Функция подсчитывает количество пре-
128 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
подавателей, работающих в университете, заданным параметром. Процедура подсчитывает количество обращений к
функции и заносит это количество, номер университета, количество преподавателей в новую таблицу, созданную заранее.
2.26. Создать пакет, состоящий из функции с параметрами, процедуры без параметров. Функция подсчитывает количество
предметов, прочитанных в семестре, номер которого задан
параметром, с количеством часов, заданным другим параметром. Процедура подсчитывает число обращений к функции и
заносит это число, номер семестра, количество часов и количество предметов в новую таблицу, созданную заранее.
2.3.10. Триггеры базы данных
Триггер базы данных – это процедура PL/SQL, которая автоматически запускается при возникновении определенных событий, связанных с выполнением операций вставки, удаления или модификации
данных таблицы. Событие, управляющее запуском триггера, описывается в виде логических условий. Когда возникает событие, соответствующее условиям триггера, сервер ORACLE автоматически запускает триггер, то есть интерпретирует код программы триггера, записанный на языке PL/SQL.
Обычно триггеры используют для выполнения сложных проверок ограничений целостности, многоаспектных проверок выполнения правил разграничения доступа и т.п.
Триггер запускается при выполнении одной из трех операций
изменения содержимого таблицы: INSERT, DELETE или
UPDATE. Триггер может запускаться и несколькими операторами,
но хотя бы один оператор из тройки должен быть обязательно указан в условии запуска триггера. Если перечень операторов, запускающих триггер, включает оператор UPDATE, то для условий срабатывания могут быть указаны конкретные изменяемые столбцы.
Код триггера может выполняться либо до, либо после тех операторов, которые инициировали запуск триггера. Например, если
триггер запускается для проверки полномочий пользователя на
2.3.10. Триггеры базы данных ♦ 129
Операторные триггеры и строчные триггеры
право выполнения операции, то, конечно, нужно использовать
триггер с запуском до выполнения операции (с ключевым словом
BEFORE). Если триггер применяется для формирования данных
для аудиторской записи, то разумно использовать триггер с запуском после выполнения операции (с ключевым словом AFTER).
Код триггера может быть ассоциирован либо с операцией над
таблицей в целом, либо с каждой строкой, над которой выполняется операция. В зависимости от этого триггеры подразделяют на операторные триггеры и строчные триггеры. Операторные триггеры обычно используют для проверки правил разграничения доступа, оперирующих таблицей в целом, а строчные триггеры часто используют для проверки ограничений целостности при вставке строк.
Условие запуска строчного триггера может быть уточнено дополнительным логическим условием.
Чтобы создать триггер, необходимо иметь системные привилегии CREATE TRIGGER. Для создания триггера в схеме, отличной
от текущей схемы пользователя, требуются системные привилегии
CREATE ANY TRIGGER. Оператор определения триггера
ORACLE использует следующий синтаксис:
Операторные триггеры и строчные триггеры
CREATE[OR REPLACE] TRIGGER[имя схемы.]имя_триггера
{BEFORE | AFTER}
{INSERT | DELETE |
UPDATE[OF имя_столбца[,имя_столбца...]]}
[OR {INSERT | DELETE |
UPDATE[OF имя_столбца[,имя_столбца...]]}...]
ON [имя_схемы.]{имя_таблицы | имя_представления}
[FOR EACH ROW] [WHEN условие]
cneцификации_naкema_нa_PL/SQL
Ключевое слово OR REPLACE указывает на безусловное замещение старого текста триггера. Если ключевое слово OR REPLACE не
указано, и триггер определен в системе, то замещения старого значения триггера не происходит, и возвращается сообщение об
ошибке.
130 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
Ключевые слова BEFORE или AFTER указывают на выполнение
кода триггера либо до, либо, соответственно, после операторов манипулирования данными, инициировавших запуск триггера.
Ключевые слова INSERT, DELETE или UPDATE определяют
конкретный оператор, запускающий триггер. Для оператора
UPDATE могут быть указаны столбцы, изменение которых запускает
триггер. Если конкретные столбцы не указаны, то триггер запускает
изменение любого столбца. Необязательное ключевое слово OR
присоединяет дополнительный оператор, запускающий триггер.
Ключевое слово ON задает имя таблицы или представления, ассоциированного с триггером.
Необязательное ключевое слово FOR EACH ROW определяет триггер
как строчный.
Необязательное ключевое слово WHEN задает дополнительное логическое условие, сужающее область действия триггера.
Прежде чем перейти к примеру, построения триггера, приведем
некоторые дополнительные сведения об обработке исключительных
ситуаций в ORACLE. Процедура RAISE_APPLICATION_ERROR
применяется для подключения к механизму обработки ошибок
пользовательских точек входа. С ее помощью можно обработать до
1000 определяемых пользователем ошибок с номерами в диапазоне от
-20000 до -20999. Вызов процедуры RAISE_APPLICATION_ERROR
приводит к генерации исключительной ситуации и завершению
выполнения вызвавшей процедуру программы (сравните с рассмотренным выше оператором PL/SQL RAISE). При этом в среду, вызвавшую программу, возвращается номер и текстовое сообщение о
типе ошибки.
Рассмотрим пример триггера, который выполняется, если значение вводимого атрибута “уклоняется по модулю” от среднего значения для текущего состояния таблицы больше, чем на 30. Пусть
таблица Tab1 сформирована предложениями:
CREATE TABLE Таb1(At1 NUMBER);
INSERT INTO Таb1 VALUES(10);
2.3.10. Триггеры базы данных ♦ 131
Протокол создания триггера
INSERT INTO Таb1 VALUES(30);
INSERT INTO Таb1 VALUES(50);
Протокол создания триггера представлен ниже. При срабатывании триггера предусмотрена генерация стандартной обработки
ошибки, которой присваивается номер -20002 с соответствующим
диагностирующим сообщением. Обратите внимание на предопределенную переменную:new.At1, содержащую (по ее смыслу) вводимое значение атрибута At1.
Пример 2.3.30
SQL>CREATE OR REPLACE TRIGGER TRIG_TBI
2
BEFORE INSERT ON Таb1
3
FOR EACH ROW
4
DECLARE
5
StatAvg NUMBER;
6
StatN NUMBER;
7
BEGIN
8
SELECT COUNT(At1),SUM(At1) INTO StatN, StatAvg
9
FROM Tab1;
10 IF (ABS(StatAvg-StatN*(:new.At1))>30*StatN)
11 THEN RAISE_APPLICATION_ERROR(-20002,
'Слишком большое уклонение');
12 END IF;
13 END;
14 /
Trigger created.
Работу механизма триггера проиллюстрируем на примере. При
вводе значения, достаточно близкого к среднему (в данном случае
40), триггер не запускается, и “ничего не происходит”. При вводе
значения атрибута, равного 90, соответствующая статистика указывает на большое уклонение, происходит срабатывание триггера, и
новая строка не включается. Операция выборки подтверждает ожидаемое изменение в таблице.
SQL>insert into tab1 values(40);
I row created.
SQL>insert into tab1 values(90);
insert into tab1 values(90)
132 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
ERROR at line 1:
ORA-20002: Слишком большое уклонение
ORA-06512: at “SYSTEM. TRIG_TBI”, line 9
ORA-04088: error during execution of trigger
'SYSTEM .TRIG_TBI'
SQL>select * from tab1;
Следующий пример иллюстрирует возможность обработки исключительной ситуации средствами пользовательской исключительной ситуации. В данном случае создается триггер, который при
превышении заданного порога уклонения вводимого значения атрибута выводит диагностическое сообщение. При этом данные в
таблицу вводятся.
Пример 2.3.31
SQL>CREATE OR REPLACE TRIGGER TRIG_TB2
2
BEFORE INSERT ON Таb1
3
FOR EACH ROW
4
DECLARE
5
StatAvg NUMBER;
6
StatN NUMBER;
7
Special_case EXCEPTION; --Пользовательская
--исключительная ситуация
8
BEGIN
9
SELECT COUNT(At1),SUM(At1) INTO StatN, StatAvg
10 FROM Tab1;
11 IF (ABS(StatAvg – StatN*(:new.At1))>30)
12 THEN RAISE Special_case;
13 END IF;
14 EXCEPTION
15 WHEN Special_case THEN
16 DBMS_OUTPUT.PUT_LINE('Слишком большое уклонение');
17 WHEN OTHERS THEN
18 DBMS_OUTPUT.PUT_LINE('He диагностированная
ошибка триггера');
19 END;
20 /
Trigger created.
2.3.10. Триггеры базы данных ♦ 133
Ограничения использования предложений языка SQL в коде триггера Oracle
При вводе значения атрибута, равного 90, происходит срабатывание триггера TRIG_TB2. Выводится диагностическое сообщение,
и вводится новая строка. Представленная операция выборки подтверждает ожидаемое изменение в таблице.
SQL> insert into tabl values(90);
Слишком большое уклонение
В отличие от процедур, функций и пакетов сервер ORACLE не
хранит код триггера в виде скомпилированного блока PL/SQL. При
первом запуске триггера его код считывается из словаря данных,
компилируется, и скомпилированная версия сохраняется в области
SGA. Поэтому для часто используемых триггеров целесообразно
код, отвечающий за процедурную часть триггера, включать в хранимую процедуру, а в теле триггера оставлять только запись условий запуска и вызовы соответствующих процедур и функций.
На предложения языка SQL, включенные в код триггера
ORACLE, наложены следующие ограничения. Тело триггеpa не
может включать в себя явное использование управляющих операторов COMMIT, ROLLBACK и SAVEPOINT, операторов языка
определения данных CREATE, ALTER и DROP, операторов,
управляющих разграничением доступа GRANT и REVOKE, а также неявное выполнение перечисленных операторов через вызовы
процедур и функций.
Строчный триггер срабатывает один раз для каждой строки.
Внутри триггера можно обращаться к строке, обрабатываемой в
данный момент. Для этого служат две псевдозаписи — :OLD и
:NEW, синтаксически они рассматриваются как записи, хотя записями не являются, поэтому их называют псевдозаписями. Тип обеих
псевдозаписей определяется как
Ограничения использования предложений языка SQL в коде триггера Oracle
Активирующая_таблица%ROWTYPE;
Псевдозапись :OLD не определена для операторов INSERT, а
псевдозапись :NEW — для оператора DELETE, при этом генерироваться ошибка не будет, но значения полей обеих записей будут
NULL значениями. Двоеточие перед :NEW и :OLD обязательно,
134 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.3. Язык PL/SQL
это двоеточие используется для ограничения переменных привязки.
Операции, которые выполняются над записями, не могут быть выполнены псевдозаписями. :OLD и :NEW нельзя передавать процедурам и функциям, принимающим аргументы типа Активирующая_таблица%ROWTYPE.
Упражнения
2.27. Создать триггер, который считает среднюю стипендию и выдает диагностическое сообщение при превышении заданного
порога уклонения вводимого значения атрибута в зависимости
от средней стипендии, при этом происходит заполнение некоторой таблицы.
2.28. Создать триггер, который считает средний балл в заданный
день и выдает диагностическое сообщение при превышении
заданного порога уклонения вводимого значения атрибута в
зависимости от среднего балла, при этом происходит заполнение некоторой таблицы.
2.29. Создать триггер, который определяет границы изменения номеров предметов и выдает диагностическое сообщение при
превышении заданного порога уклонения вводимого значения
атрибута, при этом происходит заполнение таблицы.
2.30. Создать триггер, который определяет границы изменения номеров преподавателей и выдает диагностическое сообщение
при превышении заданного порога уклонения вводимого значения атрибута, при этом происходит заполнение некоторой
таблицы.
2.31. Создать триггер, который вычисляет средний рейтинг университетов и выдает диагностическое сообщение при превышении заданного порога уклонения вводимого значения атрибута в зависимости от величины среднего рейтинга, при этом
происходит заполнение некоторой таблицы.
2.32. Создать триггер, который определяет границы изменения номеров лекторов в зависимости от номеров читаемых курсов и
выдает диагностическое сообщение при превышении задан-
2.4. Связь с удаленной базой данных ♦ 135
Пример связи с удаленной базой данных
ного порога уклонения вводимого значения атрибута, при
этом происходит заполнение некоторой таблицы.
2.4. Связь с удаленной базой данных.
Для создания связи пользователю в локальной базе данных необходимо иметь некоторую точку входа в удаленной базе данных.
Данная точка входа может совпадать с именем пользователя, который создает связь, а может иметь и другое имя. Для создания общей
(PUBLIC) связи необходимо пользователю обладать привилегией
CREATE PUBLIC DATABASE LINK. Оператор создания связи с
удаленной базой данных имеет следующий синтаксис:
CREATE [PUBLIC] database link имя_связиБД
[CONNECT to имя_пользователя IDENTIFIED BY
пароль_пользователя]
USING 'строка_связи'
Если параметр PUBLIC отсутствует, то создается связь, доступная только создавшему ее пользователю. При наличии этого параметра создается связь, доступная всем пользователям.
Параметр ИМЯ_СВЯЗИБД задает имя создаваемой связи. Параметры ИМЯ_ПОЛЬЗОВАТЕЛЯ, ПАРОЛЬ_ПОЛЬЗОВАТЕЛЯ задают имя пользователя и его пароль в удаленной базе данных. Строка
'СТРОКА_СВЯЗИ' определяет имя раздела параметров SQL*NET,
задающего спецификации связи с удаленной базой данных. Если
фраза, содержащая имя пользователя и пароль, отсутствует, будем
пользоваться текущим именем пользователя и его паролем.
Создав связь с удаленной базой данных, можно обращаться к
таблицам в удаленной базе данных в запросах, при этом необходимо после имени таблицы в удаленной базе данных добавить
@ИМЯ_СВЯЗИ во фразе FROM оператора SELECT.
Пример 2.4.1 Пример связи с удаленной базой данных
Пусть определяется связь с удаленной базой данных T1_ora_link,
которая связывает пользователя Т1 с паролем Т1_ora в базе данных,
136 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.4. Связь с удаленной базой данных.
определяемой строкой связи SUN. После создания связи можно
выполнить любой запрос:
SQL>CREATE database link T1_ora_link
connect to t1 identified by t1_ora
using ‘sun’;
dtabase link created.
SQL>Select * from tab1@T1_ora_link;
Чтобы скрыть от пользователя факт, что таблица tab1 пользователя T1 находится на удаленной базе данных, можно использовать
синоним.
Синоним — это объект базы данных, используемый для альтернативного именования. Наличие синонимов позволяет приложениям
обеспечить независимость от того, в какой схеме размещена таблица или представление, а также — в какой конкретно локальной базе
данных распределенной системы хранятся требуемые приложению
данные.
Для создания синонима необходимо быть владельцем или иметь
привилегию SELECT объекта, для которого создается синоним.
Если надо создать синоним в схеме другого пользователя или синоним типа PUBLIC, то необходимо иметь привилегию CREATE
PUBLIC SYNONYM или CREATE ANY SYNONYM.
Оператор определения синонима имеет следующий синтаксис:
CREATE [PUBLIC] synonym [имя_схемы.]имя_синонима
FOR [имя_схемы.]имя объекта[@имя_связиБД];
Скроем факт, что таблица tab1 пользователя T1 находится на
удаленной базе с помощью синонима:
SQL>CREATE synonym suntab1 for
t1.tab1@ T1_ora_link;
Tеперь можно работать с таблицей suntab1.
SQL>SELECT * FROM suntab1;
2.4.1. Снимки ♦ 137
Оператор определения снимков
Для удаления определенной связи с удаленной базой данных используется команда DROP PUBLIC LINK. Для выполнения этой
команды необходимо быть владельцем связи с удаленной базой
данных либо иметь привилегию DROP ANY DATABASE LINK.
Для отмены общей связи необходимо иметь привилегию DROP
PUBLIC DATABASE LINK. Оператор уничтожения связи с удаленной базой данных имеет следующий синтаксис:
DROP [public] database link имя_связи;
Рассмотрим пример отмены связи с удаленной базой данных с
именем T1_ORA_LINK:
SQL>DROP database link T1_ora_link;
2.4.1. Снимки.
Снимок — это поименованная, динамически поддерживаемая сервером выборка из одной или нескольких таблиц или представлений,
обычно размещенных на удаленной базе данных. При помощи снимков администратор безопасности обеспечивает доступ пользователям к тем частям базы данных, которые необходимы им для работы.
Чтобы механизм снимков работал на локальной и удаленной базе
данных, должен быть установлен пакет DBMS_SNAPSHOT, в котором размещены процедуры обновления снимков.
Оператор определения снимков имеет следующий вид:
CREATE SNAPSHOT [имя_схемы.]имя_снимка
[{PCTFREE целое | PCTUSED целое |
INITRANS целое | MAXTRANS целое |
TABLESPACE имя_табличной_области |
STORAGE размер памяти}] |
[CLUSTER имя_кластера (имя_столбца [,…])]
[USING INDEX]
[{PCTFREE целое | PCTUSED целое |
INITRANS целое | MAXTRANS целое |
TABLESPACE имя_табличной_области |
STORAGE размер памяти}] |
[REFRESH [{FAST | COMPLETE | FORCE }]
138 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.4. Связь с удаленной базой данных.
[START WITH дата_1] [NEXT дата_2]]
[FOR UPDATE]
AS запрос;
Ключевые слова PCTFREE, PCTUSED, INITRANS, MAXTRANS,
TABLESPACE, STORAGE характеризуют пространство, распределяемое при работе со снимком.
Ключевое слово PCTFREE определяет размер блоков, резервируемых для дальнейшей работы со снимком, допустимые значения от 0
до 99, значение по умолчанию 10, то есть если этот параметр не
указан, то 10% пространства остается не использованным для записи в него данных для дальнейшей модификации строк снимка.
Ключевое слово PCTUSED определяет минимальный процент использования пространства блока, при котором в него вводятся данные, допустимые значения от 1 до 99. Значение по умолчанию 40,
то есть если этот параметр не указан, то в блоке занято менее 40%
пространства, в него вводятся данные при выполнении операции
вставки. Сумма значений параметров PCTFREE и PCTUSED не
должна превышать 100.
Ключевое слово INITRANS определяет начальное число параллельных транзакций, которые могут выполняться для модификации
данных блока. Значение по умолчанию 1. Параметр MAXTRANS
определяет максимальное число параллельных транзакций, которые
могут выполняться для модификации данных блока.
Ключевое слово TABLESPACE определяет имя табличной области,
если оно не указано, то снимок располагается в табличной области
пользователя, который является владельцем снимка.
Ключевое слово STORAGE определяет объем внешней памяти, выделяемой под снимок.
Ключевое слово CLUSTER указывает привязку столбцов снимка к
кластеру.
Ключевое слово USING INDEX определяет создание индекса для
уменьшения времени доступа к данным снимка. Параметры
2.4.1. Снимки ♦ 139
Пример определения снимков
PCTFREE, PCTUSED, INITRANS, MAXTRANS, TABLESPACE,
STORAGE характеризуют пространство, отводимое для индекса
снимка.
Ключевое слово REFRESH определяет технологию обновления
снимка. Параметр COMPLETE означает, что при обновлении данных снимка заново выполняется запрос, формирующий снимок.
При задании параметра FAST при обновлении данных снимка используется информация об измененных данных в мастер-таблице,
хранящаяся в журнальном файле снимка. При используемом по
умолчанию параметре FORCE решение о технологии обновления
снимка принимается системой (обычно это быстрое обновление).
Ключевое слово START WITH определяет с помощью параметра
дата_1 дату первого обновления снимка. Ключевое слово NEXT определяет с помощью параметра дата_2 интервал между автоматическими обновлениями снимка. Если параметр REFRESH отсутствует, то автоматического обновления данных снимка не происходит,
так же не происходит автоматического обновления данных снимка
при отсутствии обоих ключевых слов START WITH и NEXT.
Ключевое слово FOR UPDATE указывает на возможность изменения данных снимка.
Ключевое слово AS запрос включает в создаваемый снимок строки,
являющиеся результатом выполнения запроса.
Пример 2.4.2 Пример определения снимков
Пусть таблица tab1 размещена на удаленном сервере, и доступ к
ней осуществляется с помощью связи с именем T1_ora_link:
SQL>CREATE SNAPSHOT snap_suntab1
AS SELECT * FROM tab1@ T1_ora_link WHERE AT1>0;
SQL>SELECT * FROM snap_suntab1;
Для модификации снимка с целью установки частоты автоматического изменения в 1 час можно воспользоваться командой
ALTER SNAPSHOT. Ключевое слово REFRESH сделает его об-
140 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.4. Связь с удаленной базой данных.
новляемым автоматически, изменения, введенные в мастер-таблице,
автоматически будут появляться в снимке.
SQL>ALTER SNAPSHOT snap_suntab1 REFRESH COMPLETE
2 START WITH SYSDATE NEXT SYSDATE + 1/24;
SQL>SELECT FROM snap_suntab1;
2.4.2. Последовательности.
Последовательность – это объект базы данных, генерирующий
неповторяющиеся целые числа.
Числа, создаваемые последовательностью, могут либо возрастать
постоянно, либо до определенного предела, либо при достижении
определенного предела, начинать возрастать заново с начального
значения. Последовательность может создавать цепочки как увеличивающихся чисел, так и уменьшающихся, можно задавать и приращение значений последовательности. Для создания последовательности требуется привилегия CREATE SEQUENCE. Для создания последовательности в схеме другого пользователя необходимо
иметь привилегию CREATE ANY SEQUENCE.
Оператор определения последовательности имеет следующий
синтаксис:
CREATE SEQUENCE [имя_схемы.]имя_последовательности
[INCREMENT BY приращение]
[START WITH начальное_значение]
[MAXVALUE наибольшее_значение | NOMAXVALUE]
[MINVALUE наименьшее_значение | NOMINVALUE]
[CYCLE | NOCYCLE]
[CACHE число_элементов | NOCACHE]
[ORDER | NOORDER]
Ключевое слово INCREMENT BY определяет интервал между последовательными номерами. Если этот параметр имеет отрицательное значение, то последовательность убывающая, если положительное — то последовательность возрастающая. Значением по
умолчанию является 1, параметр приращения может быть любым
целым числом не равным нулю.
2.4.2. Последовательности ♦ 141
Оператор определения последовательности
Ключевое слово START WITH параметром начальное_значение задает
первый генерируемый номер. Если этот параметр отсутствует, то
для возрастающих последовательностей первый генерируемый номер равен значению параметра MINVALUE, а для убывающей последовательности MAXVALUE.
Ключевое слово MAXVALUE параметром наибольшее_значение задает
максимальное значение, которое будет генерироваться последовательностью. Это число должно быть больше, чем начальное_значение
и наименьшее_значение. Это число может быть любым числом с количеством знаков, не превышающим 28. Отсутствие верхней границы
указывается ключевым словом NOMAXVALUE, которое определяет для убывающих последовательностей значение –1, а для возрастающих последовательностей 1027.
Ключевое слово MINVALUE параметром наименьшее_значение задает
минимальное число, которое будет генерироваться последовательностью. Это число должно быть меньше чем начальное_значение и
наибольшее_значение. Это число может быть любым числом с количеством знаков, не превышающем 28. Отсутствие нижней границы
указывается ключевым словом NOMINVALUE, которое определяет
для убывающих последовательностей значение –1026, а для возрастающих последовательностей 1.
Ключевое слово NOCYCLE является значением, используемым по
умолчанию, и означает завершение генерирования последовательности по достижении конца последовательности. Если при определении последовательности указан параметр CYCLE, то после достижения очередным членом последовательности значения наибольшее_значение (для возрастающих последовательностей) выдается значение параметра наименьшее_значение. Если параметры наименьшее_значение и наибольшее_значение не указаны, то используются их
значения по умолчанию.
Ключевое слово CACHE указывает на использование техники кеширования, что обеспечивает более быструю генерацию элементов
последовательности. Ключевое слово число_элементов определяет
142 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.4. Связь с удаленной базой данных.
количество элементов области кеша, это число не должно превышать разницы между MAXVALUE и MINVALUE.
Ключевое слово ORDER обеспечивает генерацию последовательных элементов точно в порядке поступления запросов.
Одна последовательность может использоваться для генерации
первичных ключей для нескольких таблиц. Если два пользователя обращаются к одной последовательности, то каждый из них не видит
последовательные номера, сгенерированные для другого пользователя.
Псевдостолбец NEXTVAL используется для генерирования очередного номера из указанной последовательности. Обращение
имеет следующий вид:
Имя_последовательности.NEXTVAL;
Псевдостолбец CURVAL используется для ссылки на текущее
значение последовательного номера, до ссылки на CURVAL в текущем сеансе NEXTVAL должен быть использован хотя бы один
раз. Обращение к CURVAL имеет следующий синтаксис:
Имя_последовательности.CURVAL;
Рассмотрим пример создания последовательности с именем
SEQ1. Начальный элемент последовательности определен 2, параметры наибольшее_значение и наименьшее_значение определены равными
3 и 1 соответственно, параметр цикла равен 2, параметр кеширования равен 2: Пример создания последовательности
SQL>CREATE SEQUENCE SEQ1
MAXVALUE 3 MINVALUE 1 START
SQL>SELECT SEQ1.NEXTVAL FROM
NEXTVAL
2
SQL>SELECT SEQ1.NEXTVAL FROM
NEXTVAL
3
SQL>SELECT SEQ1.NEXTVAL FROM
NEXTVAL
1
WITH 2 CYCLE CACHE 2;
DUAL;
DUAL;
DUAL;
2.4.2. Последовательности ♦ 143
Упражнения 2.33–2.38
Этот пример показывает циклическое образование элементов
последовательности.
Псевдостолбец NEXTVAL обычно используется для итерации
значений первичных ключей. Для получения текущего значения
используется псевдостолбец CURVAL.
Пусть таблица сформирована предложением
SQL>CREATE TABLE TAB1 (At1 NUMBER PRIMARY KEY);
Рассмотрим пример, иллюстрирующий применение псевдостолбцов последовательности:
SQL>INSERT INTO TAB1 VALUES (SEQ1.NEXTVAL);
Этим действием мы добавили строку в таблицу.
SQL>SELECT SEQ1.CURVAL FROM DUAL;
CURVAL
1
Для удаления последовательности используется команда DROP
SEQUENCE. Для выполнения данной операции необходимо быть
владельцем последовательности либо иметь привилегию DROP
ANY SEQUENCE.
Оператор удаления последовательности имеет следующий синтаксис:
DROP SEQUENCE [имя_схемы.]имя_последовательноси
Пример уничтожения последовательности:
DROP SEQUENCE SEQ1;
Упражнения Упражнения 2.33—2.38
2.33. Создать таблицу Student и заполнить ее с использованием последовательностей. Создать связь с другим пользователем и
прочитать у него первичный ключ таблицы SUBJECT.
2.34. Создать таблицу SUBJECT и заполнить ее с использованием
последовательностей. Создать связь с другим пользователем и
прочитать у него первичный ключ таблицы Student.
144 ♦ Глава 2. Распределенная система управления базами данных Oracle
2.4. Связь с удаленной базой данных.
2.35. Создать таблицу LECTURE и заполнить ее с использованием
последовательностей. Создать связь с другим пользователем и
прочитать у него первичный ключ таблицы Student.
2.36. Создать таблицу UNIVERCITY и заполнить ее с использованием последовательностей. Создать связь с другим пользователем и прочитать у него первичный ключ таблицы Student.
2.37. Создать таблицу EXAM_MARKS и заполнить ее с использованием последовательностей. Создать связь с другим пользователем и прочитать у него первичный ключ таблицы
UNIVERSITY.
2.38. Создать таблицу SUBJ_LEC и заполнить ее с использованием
последовательностей. Создать связь с другим пользователем и
прочитать у него первичный ключ таблицы UNIVERCITY.
Download