----------------------------------------------------------------
ЧАСТЬ II
СПРАВОЧНИК ПО ЯЗЫКУ
ГЛАВА 9
----------------------------------------------------------------
ЭЛЕМЕНТЫ ЯЗЫКА
Грамматика, которая знает, как управлять даже королями.
Мольер
Эта глава при посредстве синтаксических диаграмм показывает, как
формировать предложения PL/SQL из команд, параметров и отдельных
элементов языка. Ее можно использовать как быстрый справочник
по синтаксису и соглашениям кодирования PL/SQL. Кроме того,
здесь даются замечания по использованию и приводятся краткие
примеры.
Элементы языка 9-1
Эта глава содержит следующие разделы:
Предложение присваивания Атрибут %NOTFOUND
Блоки Предложение NULL
Предложение CLOSE Предложение OPEN
Комментарии Пакеты
Предложение COMMIT Таблицы PL/SQL
Условия Процедуры
Курсоры Предложение RAISE
Предложение DELETE Записи
Прагма EXCEPTION_INIT Предложение RETURN
Исключения Предложение ROLLBACK
Предложение EXIT Атрибут %ROWCOUNT
Выражения Атрибут %ROWTYPE
Предложение FETCH Предложение SAVEPOINT
Атрибут %FOUND Предложение SELECT INTO
Функции Предложение SET TRANSACTION
Предложение GOTO Курсор SQL
Предложение IF Функция SQLCODE
Предложение INSERT Функция SQLERRM
Атрибут %ISOPEN Атрибут %TYPE
Литералы Предложение UPDATE
Предложение LOCK TABLE Переменные и константы
Предложение LOOP
Каждый из этих разделов включает все или некоторые из следующих
секций:
Описание
Синтаксис
Ключевые слова и параметры
Замечания по использованию
Примеры
Связанные темы
Для иллюстрации синтаксиса PL/SQL используются легко читаемые
синтаксические диаграммы. Не беспокойтесь, если вы не знакомы с
правилами построения таких диаграмм. Следующий раздел сообщает
вам все необходимые сведения о них.
9-2 Руководство пользователя и справочник по PL/SQL
----------------
Использование синтаксических диаграмм
Если вы не уверены, как синтаксически правильно записать
предложение PL/SQL, обратитесь к синтаксической диаграмме этого
предложения. СИНТАКСИЧЕСКАЯ ДИАГРАММА с помощью линий и стрелок
изображает синтаксис отдельного предложения или элемента PL/SQL.
Вы можете проверить или составить любое предложение по его
синтаксической диаграмме.
Как читать синтаксические диаграммы
-----------------------------------
Диаграмма использует линии со стрелками, показывающими, как
упорядочены команды, параметры и другие элементы языка в
предложении. Следуйте по диаграмме в направлении стрелок. Вам
помогут следующие символы:
-------- Отмечает начало диаграммы.
-------- Отмечает конец диаграммы.
--------- Показывает, что диаграмма продолжается на следующей
строке.
--------- Показывает, что диаграмма продолжается с предыдущей
строки.
---------¬ Представляет цикл.
¦
Команды и иные ключевые слова показаны прописными, а параметры
строчными буквами. Операторы, разделители и терминаторы
показаны как обычно.
Если диаграмма содержит несколько возможных путей, вы должны
выбрать путь, подходящий для вашего случая.
Если имеется выбор из нескольких ключевых слов, операторов или
параметров, то эти опции изображаются в виде вертикального
списка. В следующих примерах вы должны выбрать один из
элементов списка и продолжить движение по диаграмме вдоль
соответствующей линии:
--T-------T-- --T-- date_литерал -----T-- --- / --¬
+-- + --+ +-- date_переменная --+ +-- * --+
L-- - --- +-- date_функция -----+ +-- - --+
+-- NULL -------------+ --+-- + --+--¬
L-- (date_выражение) -- ¦
Элементы языка 9-3
Обязательные параметры
Обязательные параметры могут появляться поодиночке или в
вертикальном списке альтернатив. Одиночные обязательные
параметры появляются на ОСНОВНОМ ПУТИ, т.е. на той
горизонтальной линии, по которой вы продвигаетесь. В следующем
примере имя_курсора является обязательным параметром:
---------- CLOSE ------------ имя_курсора --------- ; --------------
Если имя вашего курсора - c1, то, согласно диаграмме, следующее
предложение синтаксически правильно:
CLOSE c1;
Если хотя бы один из параметров в вертикальном списке появляется
на основном пути, это означает, что выбор параметра обязателен.
Иными словами, вы должны выбрать один из параметров, но
необязательно тот из них, который изображен вдоль основного
пути. В следующем примере вы обязаны выбрать один из четырех
типов выражений:
----------------------T-- num_выражение -----T----------------------
+-- char_выражение ----+
+-- date_выражение ----+
L-- boolean_выражение --
Необязательные параметры
Если параметры появляются в вертикальном списке ниже основного
пути, то они необязательны, т.е. вы не обязаны выбирать один из
них. В следующем примере, вместо того, чтобы спускаться по
вертикальной линии к параметру, вы можете продолжить движение по
основному пути:
------------- COMMIT ----T----------T-T---------------------T- ; ---
L-- WORK --- L-- COMMENT 'текст' ---
Согласно этой диаграмме, все приведенные ниже предложения
синтаксически правильны:
COMMIT;
COMMIT WORK;
COMMIT COMMENT 'In-doubt transaction; notify Order Entry';
COMMIT WORK COMMENT 'In-doubt transaction; notify Order Entry';
9-4 Руководство пользователя и справочник по PL/SQL
Синтаксические циклы
Циклы позволяют вам повторять синтаксис, заключенный в них,
любое число раз. В следующем примере список объявлений
находится в цикле. Следовательно, выбрав один тип объявления,
вы можете вернуться по циклу и снова выбрать такой же или иной
тип.
--------T----------------------------------------------------T-------
¦ -----------------------------------¬ ¦
L--- DECLARE ---V---T-- объявление_переменной; --T-+--
+-- объявление_курсора; -----+
+-- объявление_исключения;---+
+-- объявление_записи; ------+
+-- объявление_таблицы_plsql-+
+-- объявление_процедуры; ---+
L-- объявление_функции; ------
Согласно этой диаграмме, все следующие примеры корректны:
Первый пример:
DECLARE
credit_limit CONSTANT NUMBER(9,2) := 5000.00;
Второй пример:
DECLARE
over_limit EXCEPTION;
past_due EXCEPTION;
Третий пример:
DECLARE
account_name CHAR(25);
over_limit EXCEPTION;
new_balance NUMBER(9,2);
old_balance NUMBER(9,2);
past_due EXCEPTION;
Элементы языка 9-5
Составные диаграммы
Части составной диаграммы следует рассматривать так, как будто
они соединены концами. Следующий пример показывает диаграмму из
двух частей:
---- INSERT --- INTO --- имя_таблицы -T---------------------------T--
¦ ------ , -------¬ ¦
L- ( -- имя_столбца -+- ) --
----- , ------------¬
--------T-- VALUES - ( --- plsql_выражение -+- ) -----T----- ; -----
L----------- select_предложение ---------
Предположим, есть таблица salaries со столбцами grade, low,
middle и high. Тогда, согласно этой диаграмме, следующее
предложение корректно:
INSERT INTO salaries (grade, low, high) VALUES (4,2000,2999);
Как кодировать предложение по синтаксической диаграмме
------------------------------------------------------
Чтобы составить предложение по диаграмме, начните с метки начала
и передвигайтесь по линиям и стрелкам. Встретив ключевое слово,
воспроизведите его точно как показано (безразлично, строчными
или прописными буквами). Встретив параметр, подставьте вместо
него значение, идентификатор или объект, который он
представляет. (Если для параметра существует собственная
диаграмма, пройдите по ней, а затем вернитесь). Встретив
оператор, разделитель или терминатор, воспроизведите его точно
как показано. Разделяйте ключевые слова и идентификаторы
пропусками.
В следующем примере вам встречается сначала ключевое слово,
затем параметр, и, наконец, терминатор:
---------- GOTO ------------ имя_метки --------- ; -----------------
Если ваша метка имеет имя end_loop, то, согласно диаграмме, вы
должны записать предложение следующим образом:
GOTO end_loop;
Не забывайте прочитать описания параметров и замечания по
использованию. Использование некоторых ключевых слов может
потребовать кодирования фраз, которые обычно не обязательны.
Например, если вы используете ключевое слово CONSTANT в
объявлении_переменной, то вы должны включить фразу
инициализации.
9-6 Руководство пользователя и справочник по PL/SQL
----------------
Предложение присваивания
Описание
--------
Предложение присваивания устанавливает текущее значение
переменной, формального параметра, поля в записи или строки в
таблице PL/SQL. Для дополнительной информации обратитесь к
разделу "Объявления и присваивания" в главе 2.
Синтаксис
---------
предложение_присваивания ::=
---- имя_объекта --------- := ---- plsql_выражение ---- ; ----------
объект ::=
----------------------T-- plsql_переменная --------T----------------
+-- запись.поле -------------+
+-- plsql_таблица(индекс) ---+
L-- :хост_переменная ---------
Альтернативно, вы можете использовать предложения SELECT и
FETCH, чтобы заставить ORACLE присвоить значение переменной.
Для дополнительной информации см. разделы "FETCH" и "SELECT
INTO" ниже в этой главе.
Ключевые слова и параметры
--------------------------
имя_объекта
Этот параметр задает имя ранее объявленного объекта, которому вы
хотите присвоить значение.
plsql_выражение
Это сколь угодно сложное выражение. Синтаксис plsql_выражения
определяется в разделе "Выражения" ниже в этой главе. Значение
plsql_выражения присваивается объекту, идентифицированному
параметром имя_объекта. Тип данных plsql_выражения должен быть
совместим с типом данных объекта (или преобразуем в него). Для
дополнительной информации о совместимости типов данных
обратитесь к разделу "Преобразования типов данных" в главе 2.
plsql_переменная
Ссылка на переменную PL/SQL, ранее объявленную в текущей сфере.
поле.запись
Ссылка на поле в пользовательской (или %ROWTYPE) записи, ранее
объявленной в текущей сфере.
Элементы языка 9-7
plsql_таблица(индекс)
Ссылка на строку в таблице PL/SQL, ранее объявленной в текущей
сфере.
хост_переменная
Ссылка на хост-переменную, ранее объявленную в текущей сфере.
Для дополнительной информации о хост-объектах см. раздел
"Выражения" ниже в этой главе.
Замечания по использованию
--------------------------
По умолчанию, если объект не инициализируется в своем
объявлении, он инициализируется значением NULL при каждом входе
в блок или подпрограмму. Поэтому никогда не обращайтесь к
объекту до того, как присвоите ему значение.
Нельзя присваивать значение NULL объекту, объявленному как NOT
NULL. При попытке сделать это возбуждается предопределенное
исключение VALUE_ERROR.
Булевской переменной можно присваивать лишь значения TRUE, FALSE
или NULL. Операторы отношений, применяемые к выражениям PL/SQL,
возвращают булевское значение. Поэтому следующее присваивание
законно:
DECLARE
out_of_range BOOLEAN;
...
BEGIN
...
out_of_range := (salary < minimum) OR (salary > maximum);
Как показывает следующий пример, вы можете присвоить значение
plsql_выражения конкретному полю записи:
DECLARE
emp_rec emp%ROWTYPE;
BEGIN
...
emp_rec.sal := current_salary + increase;
Более того, вы можете присвоить значения одновременно всем полям
записи. PL/SQL разрешает агрегатные присваивания между двумя
записями, если их объявления ссылаются на один и тот же курсор
или таблицу. Например, следующее присваивание законно:
DECLARE
emp_rec1 emp%ROWTYPE;
emp_rec2 emp%ROWTYPE;
dept_rec dept%ROWTYPE;
BEGIN
...
emp_rec1 := emp_rec2;
9-8 Руководство пользователя и справочник по PL/SQL
Следующее присваивание НЕЗАКОННО, потому что нельзя использовать
оператор присваивания для присваивания записи списка значений:
dept_rec := (60, 'PUBLICITY', 'LOS ANGELES');
Можно присвоить значение выражения PL/SQL конкретной строке
таблицы PL/SQL, используя синтаксис
plsql_таблица(значение_первичного_ключа) := plsql_выражение;
В следующем примере значение переменной last_name, переведенное
в прописные буквы, присваивается третьей строке таблицы PL/SQL с
именем ename_tab:
ename_tab(3) := UPPER(last_name);
Примеры
-------
wages := hours_worked * hourly_salary;
country := 'France';
costs := labor + supplies;
done := (count > 100);
dept_rec.loc := 'BOSTON';
comm_tab(5) := sales * 0.15;
Связанные темы
--------------
Выражения, FETCH, SELECT INTO, Переменные и константы
Элементы языка 9-9
----------------
Блоки
Описание
--------
Основной программной единицей в PL/SQL является блок. Блок
PL/SQL определяется с помощью следующих ключевых слов:
* DECLARE
* BEGIN
* EXCEPTION
* END
Эти четыре ключевых слова разбивают блок PL/SQL на три части:
* декларативную часть
* исполняемую часть
* часть обработки исключений
Обязательна лишь исполняемая часть.
В любом месте блока, где можно поместить выполнимое предложение,
вы можете вставить новый, вложенный блок PL/SQL. Для
дополнительной информации обратитесь к разделам "Структура
блоков" и "Сфера и видимость" в главе 2.
Синтаксис
---------
plsql_блок ::=
------------------------T-------------------T------------------------
L-- <<имя_метки>> ---
-----T------------------------------------------------T---------------
¦ ---------------------------------¬¦
L--- DECLARE ---T- объявление_переменной; ---T-+-
+- объявление_курсора; ------+
+- объявление_исключения;----+
+- объявление_записи; ------+
+- объявление_plsql_таблицы;-+
+- объявление_процедуры;-----+
L- объявление_функции;--------
----- BEGIN -------- ряд_предложений ---------------------------------
-----T------------------------------------------------T---- END ------
¦ -----------------------------¬ ¦
L-- EXCEPTION ----- обработчик_исключений; --+---
----------------------T---------------T-------- ; -------------------
L-- имя_метки ---
9-10 Руководство пользователя и справочник по PL/SQL
Ключевые слова и параметры
--------------------------
имя_метки
Это необъявляемый идентификатор задает необязательное имя блока
PL/SQL. Имя блока должно удовлетворять соглашениям для
ИДЕНТИФИКАТОРА, описанным в разделе "Идентификаторы" в главе 2.
Имя блока, если оно используется, должно появиться в начале
блока, и должно быть заключено в двойные угловые скобки.
(Однако в среде SQL*Plus первая строка, которую вы вводите, не
может начинаться с имени метки.) Имя блока может также
(необязательно) появиться в конце блока.
Из-за правил сферы PL/SQL, если вы объявляете объект в
окружающем блоке и переобъявляете его в подблоке, то подблок не
может обращаться к объекту в окружающем блоке. Однако, если
окружающий блок имеет метку (имя_блока), то вложенный блок может
ссылаться на объект окружающего блока с помощью синтаксиса:
имя_блока.глобальный_идентификатор
В следующем примере вы сравниваете две переменных типа INTEGER,
объявленных в окружающем блоке и подблоке с одинаковыми именами:
<>
DECLARE
x INTEGER;
BEGIN
...
DECLARE
x INTEGER;
BEGIN
...
IF x = outer.x THEN
...
END IF;
END;
END outer;
Элементы языка 9-11
DECLARE
DECLARE обозначает начало декларативной части блока PL/SQL,
содержащей локальные объявления. Объекты, объявляемые локально,
существуют только в текущем блоке и всех его подблоках. Эти
объекты невидимы блокам, окружающим текущий блок.
Декларативная часть блока PL/SQL не обязательна. Она
заканчивается неявно словом BEGIN, которое начинает исполняемую
часть блока.
PL/SQL не допускает ссылок вперед. Вы должны объявить объект,
прежде чем ссылаться на него в других предложениях, в том числе
в других объявлениях.
В декларативной части блока можно использовать прагму
EXCEPTION_INIT, чтобы ассоциировать имена исключений с номерами
ошибок ORACLE. Обратитесь к разделу "Использование
EXCEPTION_INIT" в главе 5.
объявление_переменной
Этот конструкт объявляет константу или переменную PL/SQL.
Синтаксис объявления_переменной приведен в разделе "Переменные и
константы" ниже в этой главе.
объявление_курсора
Этот конструкт объявляет явный курсор PL/SQL. Синтаксис
объявления_курсора приведен в разделе "Курсоры" ниже в этой
главе.
объявление_исключения
Этот конструкт объявляет исключение PL/SQL. Синтаксис
объявления_исключения приведен в разделе "Исключения" ниже в
этой главе.
объявление_записи
Этот конструкт объявляет пользовательскую запись. Синтаксис
объявления_записи приведен в разделе "Записи" ниже в этой главе.
объявление_plsql_таблицы
Этот конструкт объявляет таблицу PL/SQL. Синтаксис
объявления_plsql_таблицы приведен в разделе "Таблицы PL/SQL"
ниже в этой главе.
объявление_процедуры
Этот конструкт объявляет процедуру. Синтаксис
объявления_процедуры приведен в разделе "Процедуры" ниже в этой
главе.
объявление_функции
Этот конструкт объявляет функцию. Синтаксис объявления_функции
приведен в разделе "Процедуры" ниже в этой главе.
9-12 Руководство пользователя и справочник по PL/SQL
BEGIN
Это ключевое слово обозначает начало исполняемой части блока
PL/SQL, которая содержит выполняемые предложения. Это
единственная обязательная часть блока или подпрограммы PL/SQL;
иными словами, блок или подпрограмма должны содержать хотя бы
одно исполняемое предложение. Это предложение может быть
пустым, как показывает следующий пример:
BEGIN
NULL;
END;
ряд_предложений
Этот параметр обозначает последовательность предложений.
Синтаксис этого параметра имеет вид:
ряд_предложений ::=
--------------------¬
------------------------- предложение ; --+------------------------
где "предложение" может быть любым законным предложением PL/SQL,
в том числе другим блоком PL/SQL. Заметьте, что объявления
переменных, констант и исключений не являются предложениями.
предложение
Вы используете этот конструкт языка для создания алгоритмов.
Существуют предложения PL/SQL для последовательного,
итеративного и условного управления, а также для обработки
ошибок. Предложения PL/SQL имеют свободный формат, т.е. их
можно переносить со строки на строку, при условии, что вы не
расщепляете между строками ключевые слова, разделители или
литералы. Каждое предложение PL/SQL должно заканчиваться точкой
с запятой (;).
Элементы языка 9-13
Синтаксис предложения PL/SQL:
предложение ::=
----T-----------------T---T-- предложение_присваивания --T----------
L- <<имя_метки>> -- +-- exit_предложение ----------+
+-- goto_предложение ----------+
+-- if_предложение ------------+
+-- loop_предложение ----------+
+-- null_предложение ----------+
+-- raise_предложение ---------+
+-- return_предложение --------+
+-- sql_предложение -----------+
L-- plsql_блок -----------------
sql_предложение
Ниже приведен синтаксис sql_предложения, которое определено в
PL/SQL как специальное подмножество всех предложений SQL, из
которого исключены предложения определения данных и предложения
управления данными:
sql_предложение ::=
--------------------------T-- close_предложение ------------T-------
+-- commit_предложение -----------+
+-- delete_предложение -----------+
+-- fetch_предложение ------------+
+-- insert_предложение -----------+
+-- lock_table_предложение -------+
+-- open_предложение -------------+
+-- rollback_предложение ---------+
+-- savepoint_предложение --------+
+-- select_предложение -----------+
+-- set_transaction_предложение --+
L-- update_предложение ------------
9-14 Руководство пользователя и справочник по PL/SQL
EXCEPTION
Это ключевое слово обозначает начало части обработки исключений
блока PL/SQL. Когда возбуждается исключение, нормальная работа
блока останавливается, и управление передается на
соответствующий обработчик исключений. После завершения работы
обработчика выполнение продолжается с предложения, следующего за
блоком, вызвавшим исключение.
Если в текущем блоке нет обработчика для возбужденного
исключения, то управление передается в окружающий блок. Этот
процесс повторяется до тех пор, пока не будет найден обработчик
исключения, или пока не будут исчерпаны окружающие блоки. Если
PL/SQL не смог найти обработчика для данного исключения, то
выполнение самого внешнего блока PL/SQL прекращается, и ошибка
"необрабатываемое исключение" возвращается в окружение, из
которого был вызван PL/SQL. Для дополнительной информации
обратитесь к главе 5.
обработчик_исключений
Синтаксис обработчика_исключений приведен в разделе "Исключения"
ниже в этой главе. В общем случае, обработчик исключений
указывает имена конкретных исключений и определяет предложения,
которые будут выполняться при возбуждении любого из этих
исключений, как показывает следующий пример:
/* ZERO_DIVIDE и VALUE_ERROR - предопределенные исключения. */
EXCEPTION
WHEN ZERO_DIVIDE THEN -- деление на 0
ROLLBACK;
WHEN VALUE_ERROR THEN -- нарушение ограничения
INSERT INTO audit_table
VALUES(trans_id, kind, amount, 'Overflow Error');
COMMIT;
...
END;
END
Ключевое слово END обозначает конец блока PL/SQL. Оно должно
быть последним ключевым словом в блоке. Ни END IF, завершающее
предложение IF, ни END LOOP, завершающее предложение LOOP, не
могут заменить ключевого слова END.
Элементы языка 9-15
Пример
------
-- доступен на диске в файле EXAMP11
DECLARE
numerator NUMBER;
denominator NUMBER;
the_ratio NUMBER;
LOWER_LIMIT CONSTANT NUMBER := 0.72;
SAMP_NUM CONSTANT NUMBER := 132;
BEGIN
SELECT x, y INTO numerator, denominator FROM result_table
WHERE sample_id = samp_num;
the_ratio := numerator/denominator;
IF the_ratio > lower_limit THEN
INSERT INTO ratio VALUES (samp_num, the_ratio);
ELSE
INSERT INTO ratio VALUES (samp_num, -1);
END IF;
COMMIT;
EXCEPTION
WHEN ZERO_DIVIDE THEN
INSERT INTO ratio VALUES (samp_num, 0);
COMMIT;
WHEN OTHERS THEN
ROLLBACK;
END;
Связанные темы
--------------
Исключения, Курсоры, Переменные и константы, Процедуры
9-16 Руководство пользователя и справочник по PL/SQL
----------------
CLOSE
Описание
--------
Предложение CLOSE освобождает ресурсы, удерживаемые открытым
курсором, для повторного их использования. После закрытия
курсора из него больше нельзя извлекать никаких строк.
Информация параметров и синтаксически разобранное представление
ассоциированного запроса помечаются как доступные для повторного
использования. Для дополнительной информации обратитесь к
разделу "Обработка транзакций" в главе 4.
Синтаксис
---------
close_предложение ::=
------------- CLOSE ------- имя_курсора --- ; ----------------------
Ключевые слова и параметры
--------------------------
имя_курсора
Этот параметр должен быть именем ранее объявленного и открытого
курсора.
Замечания по использованию
--------------------------
После того как курсор закрыт, вы можете повторно открыть его,
чтобы заново вычислить параметры и реинициализировать активное
множество, - либо с помощью явной команды OPEN, либо посредством
курсорного цикла FOR, чтобы неявно открыть курсор. Попытка
выполнить любую другую операцию на закрытом курсоре возбуждает
предопределенное исключение INVALID_CURSOR.
Вы должны закрыть курсор, прежде чем повторно открывать его.
Связанные темы
--------------
DECLARE, FETCH, OPEN
Элементы языка 9-17
----------------
Комментарии
Описание
--------
Комментарии описывают назначение и использование сегментов кода,
и тем самым способствуют его читабельности. PL/SQL поддерживает
две формы комментариев: однострочные и многострочные.
Однострочный комментарий начинается с двойного дефиса (--) и
заканчивается концом строки. Многострочный комментарий
начинается с пары символов /* и заканчивается парой символов */,
и может занимать несколько строк. Для дополнительной информации
обратитесь к разделу "Комментарии" в главе 2.
Синтаксис
---------
комментарий ::=
---------------------- -- ------ текст -----------------------------
----------------- /* ----- текст ------ */ -------------------------
Замечания по использованию
--------------------------
Комментарии могут появляться в предложении у конца строки.
Однако нельзя вкладывать комментарии друг в друга. Кроме того,
нельзя использовать однострочные комментарии в блоке PL/SQL,
который будет динамически обрабатываться программой
прекомпилятора PL/SQL, потому что при этом символы конца строки
игнорируются, и, как следствие, однострочный комментарий
распространится до конца блока, а не до конца строки. В таких
случаях используйте многострочные комментарии.
При отладке программы комментарий позволяет временно отключить
часть кода программы. Следующий пример показывает, как можно
"закомментировать" предложение SQL:
-- UPDATE dept SET loc = my_loc WHERE deptno = my_deptno;
С помощью многострочных комментариев можно "закомментировать"
целый участок кода.
Примеры
-------
-- вычислить площадь круга
area := pi * radius**2; -- pi равно 3.14159
/* вычислить площадь
круга */
area := pi * radius**2; /* pi равно 3.14159 */
9-18 Руководство пользователя и справочник по PL/SQL
----------------
COMMIT
Описание
--------
Предложение COMMIT завершает текущую транзакцию и делает
постоянными все изменения, осуществленные в течение этой
транзакции. До этого момента другие пользователи не могут
видеть измененных данных; они видят данные в том состоянии,
каким оно было к моменту начала транзакции. Для дополнительной
информации обратитесь к разделу "Обработка транзакций" главы 4.
Синтаксис
---------
commit_предложение ::=
------------- COMMIT ----T----------T-T---------------------T- ; ---
L-- WORK --- L-- COMMENT 'текст' ---
Ключевые слова и параметры
--------------------------
COMMIT и COMMIT WORK
Оба варианта, COMMIT и COMMIT WORK, работают одинаково.
Ключевое слово WORK необязательно и предназначено лишь для
улучшения читабельности.
COMMENT
COMMENT задает комментарий, который ассоциируется с текущей
транзакцией и используется чаще всего с распределенными
транзакциями. Текст должен представлять собой литерал в
апострофах длиной не более 50 символов.
Замечания по использованию
--------------------------
Предложение COMMIT освобождает все блокировки строк и таблиц.
Оно также стирает все точки сохранения, созданные вами после
последней операции COMMIT или ROLLBACK. До тех пор, пока вы не
выполнили COMMIT, справедливы следующие утверждения:
* Вы можете видеть ваши изменения, выдавая запросы по тем
таблицам, которые вы модифицировали, но другие
пользователи не могут видеть этих изменений, опрашивая те
же самые таблицы.
* Если вы передумали или хотите исправить ошибку, вы можете
выполнить откат (отмену) изменений. Это осуществляется
предложениями ROLLBACK или ROLLBACK TO. Для
дополнительной информации обратитесь к разделу "ROLLBACK"
ниже в этой главе.
Если COMMIT выполняется при открытом курсоре, который был
объявлен как FOR UPDATE, то любая последующая операция FETCH на
этом курсоре возвратит ошибку. Однако курсор при этом останется
открытым, так что вы должны закрыть его. Для дополнительной
информации смотрите разделы "Использование FOR UPDATE" и
"Извлечения между COMMIT'ами" в главе 4.
Элементы языка 9-19
Если распределенная транзакция сбивается, то текст, заданный в
фразе COMMENT, помогает вам диагностировать проблему. Если
распределенная транзакция в каком-либо смысле сомнительна,
ORACLE сохраняет ваш комментарий в словаре данных вместе с
идентификатором транзакции. Для дополнительной информации о
распределенных транзакциях обратитесь к документу ORACLE7 Server
Application Developer's Guide.
Встроенный SQL разрешает использовать после слов COMMIT WORK
необязательный параметр RELEASE. Этот параметр, выполняющий
функции команды DISCONNECT, указывает, что вы хотите
отсоединиться от базы данных после подтверждения транзакции.
Так как PL/SQL, однако, не допускает предложений управления
данными, таких как CONNECT, GRANT или REVOKE, он не допускает и
параметра RELEASE.
Связанные темы
--------------
ROLLBACK, SAVEPOINT
9-20 Руководство пользователя и справочник по PL/SQL
----------------
Условия
Описание
--------
Условия PL/SQL составляют основу для условного управления. Как
и у булевских выражений, результатом вычисления условия может
быть TRUE, FALSE или NULL. Более того, условие PL/SQL
допускается всюду, где допустимо булевское выражение.
В предложениях условного управления, если условие PL/SQL дает
TRUE, выполняется соответствующая последовательность
предложений. Если условие PL/SQL дает FALSE либо NULL, то
соответствующая последовательность предложений НЕ выполняется.
Для дополнительной информации обратитесь к разделу "Выражения и
сравнения" в главе 2.
Синтаксис
---------
plsql_условие ::= булевское_выражение
булевское_выражение ::=
-------------------T-- AND --T-------------------¬
¦ L-- OR ---- ¦
-------T-------T--T-- булевский_литерал -------T----+--------------
L- NOT -- +-- булевская_переменная ----+
+-- булевская_функция -------+
+-- прочие_булевские_формы --+
L-- (булевское_выражение) ----
прочие_булевские_формы ::=
-------------------------- plsql_выражение --------------------------
--T---------------------- оператор_сравнения --- plsql_выражение-T--
+-------------- IS ---------T-------T----- NULL ---------------+
¦ L- NOT -- ¦
+----------------T-------T------ LIKE ---- образец ------------+
¦ L- NOT -- ¦
+---T-------T-- BETWEEN --- plsql_выраж -- AND -- plsql_выраж -+
¦ L- NOT -- ¦
¦ -------- , ---------¬ ¦
+---T-------T- IN -- ( --- plsql_выражение -+----- ) ---------+
¦ L- NOT -- ¦
L-----T- имя_курсора -T-------T-- %NOTFOUND --T-----------------
L- SQL ---------- +-- %FOUND -----+
L-- %ISOPEN -----
Элементы языка 9-21
Ключевые слова и параметры
--------------------------
AND, OR, NOT
AND, OR и NOT - это булевские операторы, работающие согласно
логике трех состояний, иллюстрируемой таблицами истинности на
Рис.2-4 в главе 2. AND возвращает TRUE, если оба операнда
истинны. OR возвращает TRUE, если любой из операндов истинен.
NOT возвращает противоположное значение (логическое отрицание)
своего операнда. NOT NULL возвращает NULL, так как пустые
значения не определены. Для дополнительной информации см.
замечания по использованию, а также раздел "Логические
операторы" в главе 2.
булевский_литерал
БУЛЕВСКИЙ_ЛИТЕРАЛ - это константа TRUE, FALSE или NULL.
Значения TRUE и FALSE нельзя вставлять в столбец базы данных.
булевская_переменная
БУЛЕВСКАЯ_ПЕРЕМЕННАЯ - это любая переменная или константа,
объявленная в ОБЪЯВЛЕНИИ_ПЕРЕМЕННОЙ с типом BOOLEAN. Булевская
переменная может принимать лишь три значения: TRUE, FALSE или
NULL. Однако нельзя извлекать или выбирать в булевскую
переменную значение столбца. Кроме того, арифметические
операции на булевских переменных НЕЗАКОННЫ.
булевская_функция
БУЛЕВСКАЯ_ФУНКЦИЯ - это вызов любой функции, возвращающей
значение типа BOOLEAN.
булевское_выражение
Если БУЛЕВСКОЕ_ВЫРАЖЕНИЕ окружено скобками и является частью
большего БУЛЕВСКОГО_ВЫРАЖЕНИЯ, то PL/SQL вычисляет выражение в
скобках первым. Затем результат подставляется как единственное
булевское значение в большее выражение.
plsql_выражение
Это выражение произвольной сложности. Синтаксис PLSQL_ВЫРАЖЕНИЯ
определяется в разделе "Выражения" ниже в этой главе.
оператор_сравнения
Операторы сравнения позволяют сравнивать сколь угодно сложные
выражения. Эти операторы описаны в разделе "Операторы
сравнения" в главе 2.
IS [NOT] NULL
Оператор IS NULL возвращает булевское значение TRUE, если его
операнд есть NULL, и FALSE в противном случае.
9-22 Руководство пользователя и справочник по PL/SQL
[NOT] LIKE
Оператор LIKE используется для сравнения символьной строки с
образцом. При таких сравнениях прописные и строчные буквы
считаются различными. LIKE возвращает булевское значение TRUE,
если строка удовлетворяет образцу, и FALSE в противном случае.
образец
Это выражение представляет собой символьную строку, используемую
в операторе LIKE для сопоставления с заданным строковым
значением. Образец может включать два специальных символа.
Символ подчеркивания (_) считается совпадающим с любым одиночным
символом строкового значения. Символ процента (%) считается
совпадающим с нулем или более любых символов строкового
значения.
[NOT] BETWEEN
Оператор BETWEEN проверяет, лежит ли значение в заданном
интервале. Он означает "больше или равно значение1" и "меньше
или равно значение2".
[NOT] IN
Оператор IN проверяет членство в множестве. Он означает "равно
любому члену множества". Множество может содержать значения
NULL, но они игнорируются. Более того, выражение вида
значение NOT IN множество
дает FALSE, если множество содержит NULL.
имя_курсора
Этот параметр должен быть именем ранее объявленного курсора.
%NOTFOUND, %FOUND, %ISOPEN
%NOTFOUND, %FOUND и %ISOPEN - это атрибуты курсора. Каждый
курсор, явно объявленный вами, имеет эти атрибуты. Они
позволяют вам получать полезную информацию о выполнении
многострочного запроса. Атрибуты курсора позволяют также
обращаться к личной области SQL курсора SQL, что дает информацию
о последнем выполненном предложении SQL. Для дополнительной
информации обратитесь к разделу "Управление курсорами" в главе
4.
Элементы языка 9-23
Замечания по использованию
--------------------------
PLSQL_УСЛОВИЕ позволяет сравнивать лишь значения совместимых
друг с другом (или преобразуемых друг в друга) типов данных.
Для дополнительной информации обратитесь к разделу
"Преобразования типов данных" в главе 2.
Когда PL/SQL вычисляет БУЛЕВСКОЕ_ВЫРАЖЕНИЕ, NOT имеет высший
приоритет, затем AND, и в последнюю очередь OR. Однако вы можете
использовать скобки, чтобы изменить умалчиваемый порядок
вычислений.
Логические операторы OR и AND вычисляют сначала свой левый
операнд. Если значение результата операции можно определить по
значению левого операнда, то правый операнд не вычисляется.
Конкретно, если левый операнд операции OR равен TRUE или левый
операнд операции AND равен FALSE, то правый операнд вычисляться
не будет.
Операторы сравнения могут применяться к операндам типа BOOLEAN.
По определению, TRUE больше, чем FALSE. Сравнения, в которых
участвует NULL, всегда дают NULL.
Значения булевских выражений могут присваиваться только
булевским переменным, но не хост-переменным и не столбцам базы
данных. Более того, не существует неявных или явных
преобразований типа данных из булевского или в булевский тип.
Связанные темы
--------------
Предложение присваивания, EXIT, Выражения, IF, LOOP
9-24 Руководство пользователя и справочник по PL/SQL
----------------
Курсоры
Описание
--------
Объявление курсора именует курсор и ассоциирует его с запросом.
КУРСОР - это рабочая область, используемая ORACLE при обработке
многострочных запросов для отслеживания текущей строки. Для
дополнительной информации обратитесь к разделам "Курсоры" в
главе 1 и "Управление курсорами" в главе 4.
Синтаксис
---------
объявление_курсора ::=
---------------------- CURSOR - имя_курсора -------------------------
---------------T------------------------------------------T----------
¦ ---------------- , ----------------¬ ¦
L-(-- имя_параметра -- тип_параметра -+-)--
-------------------- IS ----- select_предложение --------------------
спецификация_курсора ::=
---------------------- CURSOR - имя_курсора -------------------------
---------------T------------------------------------------T----------
¦ ---------------- , ----------------¬ ¦
L-(-- имя_параметра -- тип_параметра -+-)--
-------- RETURN -----------T- имя_типа -------------T----------------
+- переменная%TYPE ------+
+- таблица.столбец%TYPE -+
L- таблица%ROWTYPE -------
тело_курсора ::=
---------------------- CURSOR - имя_курсора -------------------------
---------------T------------------------------------------T----------
¦ ---------------- , ----------------¬ ¦
L-(-- имя_параметра -- тип_параметра -+-)--
-------- RETURN -----------T- имя_типа -------------T----------------
+- переменная%TYPE ------+
+- таблица.столбец%TYPE -+
L- таблица%ROWTYPE -------
-------------------- IS ----- select_предложение --------------------
Элементы языка 9-25
Ключевые слова и параметры
--------------------------
имя_курсора
Этот идентификатор задает имя, по которому вы будете обращаться
к курсору. Синтаксис ИМЕНИ_КУРСОРА совпадает с синтаксисом
имени функции, и подчиняется обычным правилам сферы. См. раздел
"Идентификаторы" в главе 2.
имя_параметра
Это формальный параметр курсора. См. раздел "Идентификаторы" в
главе 2.
Параметр курсора может использоваться в запросе всюду, где
допускается константа. Формальные параметры курсора должны быть
входными параметрами. Для информации о модах параметров
обратитесь к главе 6. Запрос может также обращаться к другим
переменным PL/SQL в своей сфере.
тип_параметра
Специфицирует тип данных параметра курсора. Тип данных
соответствующего фактического параметра, передаваемого курсору
(в предложении OPEN), должен быть совместимым с ТИПОМ_ПАРАМЕТРА
(или преобразуемым в него). Для дополнительной информации
обратитесь к разделу "Преобразования типов данных" в главе 2.
RETURN
Это ключевое слово вводит фразу RETURN, которая определяет тип
данных значения, возвращаемого курсором. В фразе RETURN можно
использовать атрибут %ROWTYPE, чтобы указать запись,
представляющую строку таблицы базы данных. В фразе RETURN
нельзя использовать атрибут %TYPE для представления типа данных
переменной, константы или столбца базы данных.
Тело курсора должно содержать предложение SELECT и такую же
фразу RETURN, как в соответствующей спецификации курсора. Более
того, число и типы данных элементов списков SELECT в фразе
RETURN должны совпадать.
имя_типа
Специфицирует тип данных результирующего значения, возвращаемого
курсором. Для дополнительной информации см. раздел "Типы
данных" в главе 2.
%TYPE
Атрибут %TYPE представляет тип данных переменной, константы или
столбца базы данных.
таблица.столбец
Ссылается на таблицу и столбец в базе данных, которые должны
быть доступны в момент обработки объявления.
таблица
Ссылается на таблицу в базе данных, которая должны быть доступна
в момент обработки объявления.
9-26 Руководство пользователя и справочник по PL/SQL
%ROWTYPE
Атрибут %ROWTYPE определяет запись, представляющую строку
таблицы базы данных. Столбцы в строке таблицы и соответствующие
поля записи имеют одинаковые имена и типы данных.
select_предложение
Это - запрос, ассоциированный с ИМЕНЕМ_КУРСОРА, который
возвращает множество значений. Синтаксис SELECT_ПРЕДЛОЖЕНИЯ
совпадает с синтаксисом конструкта SELECT_INTO_ПРЕДЛОЖЕНИЕ,
которое определено в разделе "SELECT INTO" ниже в этой главе, с
той разницей, что SELECT_ПРЕДЛОЖЕНИЕ не может иметь фразы INTO.
Если объявление курсора определило параметры, каждый из этих
параметров должен быть использован в SELECT_ПРЕДЛОЖЕНИИ.
Замечания по использованию
--------------------------
Ссылки вперед не допускаются в PL/SQL. Поэтому вы должны
объявить курсор, прежде чем ссылаться на него в предложениях
OPEN, FETCH или CLOSE. Кроме того, вы должны заранее объявить
все переменные, на которые ссылаетесь в объявлении курсора. Для
дополнительной информации см. раздел "Объявление курсора" в
главе 4.
Нельзя присваивать значения курсору или использовать его имя в
выражениях. Однако имена курсоров подчиняются тем же правилам
сферы, что и имена переменных. Для дополнительной информации
обратитесь к разделу "Сфера и видимость" в главе 2.
Слово SQL зарезервировано в PL/SQL как умалчиваемое имя для
неявных курсоров ORACLE, и не может использоваться в объявлении
курсора.
Вы извлекаете данные из курсора, сначала открыв его предложением
OPEN, а затем выполняя для него предложение FETCH. Поскольку
предложение FETCH специфицирует целевые переменные,
использование фразы INTO в предложении SELECT в
ОБЪЯВЛЕНИИ_КУРСОРА было бы избыточным, и считается незаконным.
Сфера параметров курсора локальна по отношению к этому курсору,
что означает, что к ним можно обращаться лишь в запросе,
используемом в определении курсора. Значения параметров курсора
используются в ассоциированном запросе при открытии курсора.
Запрос также может обращаться к другим переменным PL/SQL внутри
их сферы. ТИП_ПАРАМЕТРА не может иметь ограничения. Например,
вы должны специфицировать NUMBER, но не NUMBER(11,2).
Примеры
-------
CURSOR c1 IS
SELECT ename, job, sal FROM emp WHERE deptno = 20;
CURSOR c2 (start_date DATE) IS
SELECT empno, sal FROM emp WHERE hiredate > start_date;
Связанные темы
--------------
CLOSE, FETCH, OPEN, SELECT INTO
Элементы языка 9-27
----------------
DELETE
Описание
--------
Предложение DELETE удаляет целые строки данных из указанной
таблицы или обзора. Для полного описания предложения DELETE
обратитесь к документу ORACLE7 Server SQL Language Reference
Manual.
Синтаксис
---------
delete_предложение ::=
--------- DELETE ---T----------T--- ссылка_на_таблицу --T----------T-
L-- FROM --- L- алиас ---
-----------T----------------------------------------------T--- ; ----
L--- WHERE --T-- условие_поиска ---------------+
L-- CURRENT OF ---- имя_курсора ---
где ССЫЛКА_НА_ТАБЛИЦУ имеет следующий синтаксис:
------------T----------T-----T- таблица -T-----T------------T-------
L- схема. -- L- обзор ---- L- @связьБД --
Ключевые слова и параметры
--------------------------
ссылка_на_таблицу
Таблица (или обзор), специфицируемая ССЫЛКОЙ_НА_ТАБЛИЦУ, должна
существовать в базе данных, с которой вы соединены во время
выполнения предложения DELETE, и вы должны иметь привилегии
DELETE.
алиас
Это другое (обычно краткое) имя таблицы или обзора; обычно
используется в фразе WHERE.
WHERE условие_поиска
Этот параметр специфицирует условия выбора удаляемых строк из
таблицы или обзора. Удаляются лишь те строки, которые
удовлетворяют УСЛОВИЮ_ПОИСКА. Если УСЛОВИЕ_ПОИСКА опущено,
будут удалены все строки таблицы или обзора.
WHERE CURRENT OF имя_курсора
Этот параметр ссылается на последнюю строку, обработанную
предложением FETCH, ассоциированным с ИМЕНЕМ_КУРСОРА. Курсор
должен быть заранее объявлен с фразой FOR UPDATE OF, и должен
быть открыт и позиционирован на нужную строку. Если курсор не
открыт, фраза CURRENT OF вызовет ошибку.
9-28 Руководство пользователя и справочник по PL/SQL
Замечания по использованию
--------------------------
PLSQL_ВЫРАЖЕНИЕ (за исключением выражений типа BOOLEAN) можно
использовать в предложении DELETE всюду, где можно
специфицировать литерал.
Предложение DELETE ... WHERE CURRENT OF ИМЯ_КУРСОРА можно
использовать после выполнения FETCH на открытом курсоре (это
включает и неявные операции FETCH, выполняемые в курсорном цикле
FOR), при условии, что ассоциированный запрос был объявлен с
фразой FOR UPDATE OF. Предложение DELETE ... WHERE CURRENT OF
ИМЯ_КУРСОРА удаляет текущую, т.е. только что извлеченную,
строку.
Неявный курсор SQL% и атрибуты курсора %NOTFOUND, %FOUND и
%ROWCOUNT позволяют вам получать полезную информацию о
выполнении предложения DELETE. Подробнее об этом см. в разделе
"Управление курсорами" в главе 4.
Предложение DELETE может удалить одну или несколько строк, но
может и не удалить ни одной строки. Если удалена хотя бы одна
строка, происходит следующее:
* SQL%NOTFOUND дает FALSE
* SQL%FOUND дает TRUE
* SQL%ROWCOUNT возвращает число удаленных строк
Если не удалено ни одной строки, происходит следующее:
* SQL%NOTFOUND дает TRUE
* SQL%FOUND дает FALSE
* SQL%ROWCOUNT возвращает число 0
Примеры
-------
Следующее предложение удаляет из таблицы bonus всех сотрудников,
жалованье которых меньше заданной квоты:
DELETE FROM bonus WHERE sales_amt < quota;
Элементы языка 9-29
----------------
Прагма EXCEPTION_INIT
Описание
--------
EXCEPTION_INIT назначает имя коду ошибки ORACLE. Это позволяет
вам обращаться к внутренним исключениям по именам, вместо того
чтобы использовать для всех них ключевое слово OTHER в
обработчике исключений. Для дополнительной информации смотрите
раздел "Использование EXCEPTION_INIT" в главе 5.
Синтаксис
---------
exception_init_прагма ::=
-- PRAGMA -- EXCEPTION_INIT (имя_исключения, номер_ошибки) ------;--
Ключевые слова и параметры
--------------------------
PRAGMA
Это ключевое слово обозначает, что данное предложение является
директивой компилятора, которое обрабатывается в период
компиляции, а не в период исполнения. Прагма не влияет на смысл
программы; она просто поставляет информацию компилятору.
имя_исключения
Этот параметр является именем исключения, объявленного ранее в
ОБЪЯВЛЕНИИ_ИСКЛЮЧЕНИЯ.
номер_ошибки
НОМЕР_ОШИБКИ может быть любым действительным номером ошибки
ORACLE. Это тот же код, который возвращает функция SQLCODE.
Замечания по использованию
--------------------------
Прагма EXCEPTION_INIT должна появляться в той же декларативной
секции, что и соответствующее исключение, но после объявления
самого исключения. Таким образом, прагма EXCEPTION_INIT может
использоваться лишь в декларативной части блока PL/SQL,
подпрограммы или пакета.
Любому коду ошибки может быть назначено лишь одно имя.
9-30 Руководство пользователя и справочник по PL/SQL
Пример
------
DECLARE
invalid_table EXCEPTION;
PRAGMA EXCEPTION_INIT(invalid_table, -942);
/* -942 - это код ошибки ORACLE, генерируемый при *
/* обращении к несуществующей таблице базы данных */
BEGIN
...
EXCEPTION
WHEN invalid_table THEN
-- обработать ошибку
...
END;
Связанные темы
--------------
Исключения, EXCEPTION_INIT, SQLCODE
Элементы языка 9-31
----------------
Исключения
Описание
--------
Объявление исключения объявляет имя для определенного
пользователем исключения. Когда исключение возбуждается
(внутренне или через RAISE), нормальное выполнение блока PL/SQL
останавливается, и выполняются предложения в соответствующем
обработчике исключений. Когда обработчик завершается,
управление возвращается во внешнее по отношению к блоку
окружение. Для дополнительной информации см. главу 5.
Синтаксис
---------
объявление_исключения ::=
--------- имя_исключения ------ EXCEPTION ------- ; ----------------
обработчик_исключений ::=
--------- OR --------¬
--- WHEN --T----- имя_исключения -+--T- THEN --- ряд_предложений---
L--------- OTHERS ----------
Ключевые слова и параметры
--------------------------
имя_исключения
Этот параметр является именем, которое вы даете исключению.
Синтаксис ИМЕНИ_ИСКЛЮЧЕНИЯ совпадает с синтаксисом конструкта
ИДЕНТИФИКАТОР. См. раздел "Идентификаторы" в главе 2.
WHEN
Вы можете заставить одну и ту же последовательность предложений
обрабатывать несколько исключений, задав за словом WHEN список
имен исключений и разделяя эти имена словом OR. При возбуждении
любого исключения из этого списка будет выполнена
ассоциированная последовательность предложений.
С каждой фразой WHEN можно ассоциировать собственный список
исключений и собственную последовательность предложений. Однако
имя любого исключения может появиться лишь один раз в части
обработки исключений блока PL/SQL или подпрограммы.
OTHERS
OTHERS обозначает все остальные исключения, не перечисленные
поименно в части обработки исключений блока. Слово OTHERS
необязательно и допускается только в последнем обработчике
исключений. Нельзя включать слово OTHERS в список исключений за
ключевым словом WHEN.
ряд_предложений
Это последовательность предложений. См. раздел "Блоки" выше в
этой главе.
9-32 Руководство пользователя и справочник по PL/SQL
Замечания по использованию
--------------------------
Объявление исключения может появляться только в декларативной
части блока, подпрограммы или пакета. Правила сферы для
исключений те же, что и для переменных. Заметим, однако, что
исключения отличаются от переменных и констант тем, что их
нельзя передавать как параметры подпрограммам.
Некоторые исключения являются предопределенными в PL/SQL.
Перечень таких исключений приведен в разделе "Предопределенные
исключения" в главе 5. PL/SQL объявляет предопределенные
исключения глобально в пакете STANDARD, так что вам не требуется
объявлять их. Переопределение предопределенных исключений
чревато ошибками, так как ваше локальное объявление перекрывает
глобальное объявление. В таких случаях вы должны использовать
квалифицированную ссылку, чтобы сослаться на предопределенное
исключение, например:
EXCEPTION
WHEN invalid_number OR STANDARD.INVALID_NUMBER THEN
...
Часть обработки исключений блока PL/SQL не обязательна.
Обработчики исключений, если есть, должны находиться в конце
блока. Они вводятся ключевым словом EXCEPTION. Часть обработки
исключений блока заканчивается тем же самым ключевым словом END,
которое завершает весь блок.
Исключение должно возбуждаться лишь в случае ошибки, которая
делает невозможным или нежелательным продолжение обработки.
Если в текущем блоке нет обработчика исключений для
возбужденного исключения, то это исключение ПРОДВИГАЕТСЯ в
окружающий блок согласно следующим правилам:
* Если для текущего блока есть окружающий блок, то
исключение передается в этот блок. Теперь окружающий
блок становится текущим, а исключение воспроизводит себя
в нем. Если обработчик исключения не находится и в этом
блоке, процесс поиска повторяется.
* Если текущий блок не имеет окружающего блока, то PL/SQL
возвращает ошибку "необрабатываемое исключение" в
хост-окружение.
Лишь одно исключение в каждый момент времени может быть активно
в части обработки исключений блока. Поэтому если исключение
возбуждается внутри обработчика, оно немедленно продвигается в
окружающий блок, который просматривается на предмет обнаружения
обработчика для вновь возбужденного исключения. С этого момента
исключение продвигается обычным образом.
Обработчик исключений может обращаться лишь к тем переменным,
которые доступны в текущем блоке.
Элементы языка 9-33
Пример
------
DECLARE
bad_employee_num EXCEPTION;
bad_acct_num EXCEPTION;
...
BEGIN
...
EXCEPTION
-- пользовательские исключения
WHEN bad_employee_num OR bad_acct_num THEN
ROLLBACK;
-- предопределенное исключение
WHEN ZERO_DIVIDE THEN
INSERT INTO inventory_table VALUES (prod_name, quantity);
COMMIT;
END;
Связанные темы
--------------
Блоки, EXCEPTION_INIT, RAISE
9-34 Руководство пользователя и справочник по PL/SQL
----------------
EXIT
Описание
--------
Используйте предложение EXIT для выхода из цикла. Это
предложение имеет две формы: безусловную (EXIT) и условную (EXIT
WHEN). Обе формы позволяют указать имя цикла, из которого
осуществляется выход. Для дополнительной информации см. раздел
"Последовательное управление" в главе 3.
Синтаксис
---------
exit_предложение ::=
-- EXIT --T---------------T--T----------------------------T-- ; ----
L-- имя_метки --- L-- WHEN --- plsql_условие ---
Ключевые слова и параметры
--------------------------
EXIT
Если опущены как ИМЯ_МЕТКИ, так и фраза WHEN, то осуществляется
немедленный выход из текущего цикла. Выполнение продолжается с
предложения, следующего за циклом.
имя_метки
Этот параметр идентифицирует цикл, из которого вы хотите выйти.
Используя ИМЯ_МЕТКИ, вы можете выйти не только из текущего
цикла, но из любого цикла, окружающего текущий цикл, при
условии, что внешний цикл был поименован в окружающем
LOOP_ПРЕДЛОЖЕНИИ.
plsql_условие
Этот параметр задает условие, которое вычисляется каждый раз,
когда PL/SQL встречает это предложение EXIT при нормальном
выполнении последовательности предложений цикла. Если результат
вычисления PLSQL_УСЛОВИЕ есть TRUE, PL/SQL немедленно
осуществляет выход из текущего (или указанного) цикла. Это
эквивалентно следующему предложению:
IF plsql_условие THEN EXIT; END IF;
Синтаксис PLSQL_УСЛОВИЯ определен в разделе "Условия" выражения"
выше в этой главе.
Замечания по использованию
--------------------------
EXIT_ПРЕДЛОЖЕНИЕ может использоваться только внутри
РЯДА_ПРЕДЛОЖЕНИЙ, содержащихся внутри LOOP_ПРЕДЛОЖЕНИЯ.
PL/SQL позволяет составлять бесконечные циклы. Например, цикл
WHILE TRUE LOOP ... никогда не закончится нормальным образом. В
таком случае вы ОБЯЗАНЫ использовать EXIT_ПРЕДЛОЖЕНИЕ, чтобы
выйти из цикла.
Элементы языка 9-35
Когда вы используете EXIT_ПРЕДЛОЖЕНИЕ для преждевременного
выхода из курсорного цикла FOR, курсор закрывается
автоматически. (Курсор также автоматически закрывается при
возбуждении исключения внутри такого цикла.)
Пример
------
В следующем примере предложение EXIT НЕЗАКОННО, потому что
нельзя выходить непосредственно из блока; вы можете выходить
только из цикла.
DECLARE
amount NUMBER;
maximum NUMBER;
BEGIN
...
BEGIN
...
IF amount >= maximum THEN
EXIT;
END IF;
END;
...
END;
Следующий цикл нормально выполняется десять раз, но может выйти
и раньше, если обнаружит, что данных больше нет:
FOR i IN 1..10
LOOP
FETCH c1 INTO emp_rec;
EXIT WHEN c1%NOTFOUND;
total := total + emp_rec.comm;
END LOOP;
Следующий пример демонстрирует использование ИМЕНИ_МЕТКИ:
<>
FOR i IN 1..10 LOOP
...
<>
FOR j IN 1..100 LOOP
...
EXIT outer_loop WHEN ... ; -- выход из обоих циклов
END LOOP inner;
END LOOP outer;
Связанные темы
--------------
Условия, LOOP
9-36 Руководство пользователя и справочник по PL/SQL
----------------
Выражения
Описание
--------
Выражение - это комбинация переменных, констант, литералов и
операторов. (В некоторых контекстах разрешается использовать
также хост-переменные. Для дополнительной информации обратитесь
к разделу "Использование хост-переменных" в главе 8.)
Компилятор PL/SQL опрделяет тип данных выражения по типам
переменных, констант, литералов и операторов, составляющих это
выражение. Каждый раз, когда выражение вычисляется, оно дает
результат этого типа. Для дополнительной информации см. раздел
"Выражения и сравнения" в главе 2.
Синтаксис
---------
plsql_выражение ::=
------------------------T-- числовое_выражение -----T---------------
+-- символьное_выражение ---+
+-- календарное_выражение --+
L-- булевское_выражение -----
числовое_выражение ::=
-----------------------------T- / -T------------------¬
¦ +- * -+ ¦
¦ +- - -+ ¦
¦ L- + -- ¦
---T-----T---T-- числовой_литерал ------------T-T---------------T+-
+- + -+ +-- числовая_переменная ---------+ L- **целое_выр --
L- - -- +-- ссылка_на_хост_объект -------+
+-- числовая_функция ------------+
+-- NULL ------------------------+
+-- (числовое_выражение) --------+
L-T- имя_курсора -T- %ROWCOUNT ---
L- SQL ----------
символьное_выражение ::=
--------------- || ----------------¬
-----------------T-- символьный_литерал ------T--+-----------------
+-- символьная_переменная ---+
+-- ссылка_на_хост_объект ---+
+-- символьная_функция ------+
+-- NULL --------------------+
L-- (символьное_выражение) ---
Элементы языка 9-37
календарное_выражение ::=
------------------T-- календарный_литерал ------T-------------------
+-- календарная_переменная ---+
+-- ссылка_на_хост_объект ----+
+-- календарная_функция ------+
+-- NULL ---------------------¦
L-- (календарное_выражение) ---
Ключевые слова и параметры
--------------------------
булевское_выражение
Этот параметр обозначает выражение, результат которого есть
TRUE, FALSE или NULL. Синтаксис БУЛЕВСКОГО_ВЫРАЖЕНИЯ приведен в
разделе "Условия" выше в этой главе.
Компоненты числового_выражения
------------------------------
числовой_литерал
Этот параметр обозначает числовой литерал, т.е. литерал, который
можно неявно преобразовать в числовое значение.
числовая_переменная
Этот параметр обозначает имя ранее объявленной переменной или
константы типа NUMBER, или типа, который можно неявно
преобразовать в тип NUMBER.
ссылка_на_хост_объект
См. подраздел "Хост-объекты" ниже в этом разделе.
числовая_функция
Этот параметр обозначает вызов функции, возвращающей значение
типа NUMBER или типа, который можно неявно преобразовать в тип
NUMBER. Примерами могут служить функции ABS, SQRT или LENGTH.
NULL
Ключевое слово NULL представляет пустое значение. Если такое
значение используется в ЧИСЛОВОМ_ВЫРАЖЕНИИ, результатом всегда
будет значение NULL.
целое_выр
Этот параметр представляет выражение с целым значением.
+, -
Символы плюс (+) и минус (-) являются унарными операторами, если
они являются первыми символами в ЧИСЛОВОМ_ВЫРАЖЕНИИ. Символ +
не имеет никакого эффекта. Символ минус инвертирует знак
результирующего значения ЧИСЛОВОГО_ВЫРАЖЕНИЯ. При использовании
внутри ЧИСЛОВОГО_ВЫРАЖЕНИЯ символы плюс и минус являются
соответственно операторами сложения и вычитания.
/, *, **
Символы /, * и ** обозначают соответственно операторы деления,
умножения и возведения в степень.
9-38 Руководство пользователя и справочник по PL/SQL
Компоненты символьного_выражения
--------------------------------
символьный_литерал
Этот параметр обозначает любой действительный строковый литерал.
Определение СТРОКОВОГО_ЛИТЕРАЛА приведено в разделе "Литералы"
ниже в этой главе.
символьная_переменная
Этот параметр обозначает имя ранее объявленной строковой
переменной или константы. Для дополнительной информации
обратитесь к разделу "Переменные и константы" ниже в этой главе.
ссылка_на_хост_объект
См. подраздел "Хост-объекты" ниже в этом разделе.
символьная_функция
Этот параметр обозначает вызов функции, возвращающей значение
типа CHAR. Примерами могут служить функции UPPER() и SQLERRM().
||
Символ || обозначает оператор конкатенации. Результатом
конкатенации строки1 и строки2 является строка символов,
содержащая из символов строки1, за которыми следуют символы
строки2. Пример:
'Good' || ' Morning.' дает результат 'Good Morning.'
NULL
Ключевое слово NULL представляет пустое значение. В операции
конкатенации значение NULL не оказывает влияния на результат,
как показывает следующий пример:
'suit' || NULL || 'case' дает результат 'suitcase'
Символьная строка нулевой длины ('') называется ПУСТОЙ СТРОКОЙ и
трактуется как пустое значение:
'suit' || '' || 'case' дает результат 'suitcase'
Компоненты календарного_выражения
---------------------------------
календарный_литерал
Этот параметр задает строковый литерал, содержащий правильную
дату. Определение СТРОКОВОГО_ЛИТЕРАЛА приведено в разделе
"Литералы" ниже в этой главе. Два примера:
'09-JUL-59' '09-DEC-77'
календарная_переменная
Этот параметр обозначает имя ранее объявленной переменной или
константы типа DATE, или типа, который можно неявно
преобразовать в тип DATE.
ссылка_на_хост_объект
См. следующий подраздел, "Хост-объекты".
Элементы языка 9-39
календарная_функция
Этот параметр обозначает вызов функции, возвращающей значение
типа DATE или типа, который можно неявно преобразовать в тип
DATE. Примерами могут служить функции TO_DATE, LAST_DAY или
NEXT_DAY.
NULL
Ключевое слово NULL представляет пустое значение. Если такое
значение используется в КАЛЕНДАРНОМ_ВЫРАЖЕНИИ, результатом
всегда будет NULL.
Хост-объекты
------------
Объекты из внешнего (хост-) окружения называются ХОСТ-ОБЪЕКТАМИ.
Например, в среде встроенного PL/SQL ХОСТ-ПЕРЕМЕННОЙ называется
переменная, объявленная в хост-языке. ПОЛЕ ФОРМЫ в среде
SQL*Forms представляет собой еще один пример хост-объекта. Для
дополнительной информации о хост-переменных обратитесь к главе
8. Синтаксис ССЫЛКИ_НА_ХОСТ_ОБЪЕКТ имеет следующий вид:
ссылка_на_хост_объект ::=
---------T-- :числовой_хост_объект -----T---T----------------T------
+-- :символьный_хост_объект ---+ L-- :индикатор ---
L-- :календарный_хост_объект ---
:числовой хост_объект
Этот параметр обозначает имя ранее объявленного объекта типа
NUMBER, или типа, который можно неявно преобразовать в тип
NUMBER.
:символьный хост_объект
Этот параметр обозначает имя ранее объявленного объекта типа
CHAR, или типа, который можно неявно преобразовать в тип CHAR.
:календарный хост_объект
Этот параметр обозначает имя ранее объявленного объекта типа
DATE, или типа, который можно неявно преобразовать в тип DATE.
(Например, это может быть объект типа CHAR в умалчиваемом
формате даты 'DD-MON-YY'.)
:индикатор
Этот параметр обозначает индикатор значения или состояния
хост-переменной. Например, в среде встроенного PL/SQL
целочисленная ИНДИКАТОРНАЯ ПЕРЕМЕННАЯ используется для
присваивания пустых значений входным хост-переменным и для
индикации пустых или усеченных значений выходных
хост-переменных. Для дополнительной информации об индикаторных
переменных обратитесь к главе 8.
9-40 Руководство пользователя и справочник по PL/SQL
Замечания по использованию
--------------------------
Все операции выполняются согласно их предопределенному порядку
старшинства. Этот порядок, по убыванию старшинства, следующий:
* скобки
* возведение в степень
* унарные операторы
* умножение и деление
* сложение, вычитание и конкатенация
Порядок выполнения нескольких операторов одинакового старшинства
не определен.
Если скобки окружают выражение, являющееся частью большего
выражения, то выражение в скобках вычисляется первым. Затем
результат используется как единственное значение в большем
выражении.
В PLSQL_ВЫРАЖЕНИИ разрешается использовать лишь значения с
типами данных, совместимыми друг с другом или преобразуемыми
друг в друга. Для дополнительной информации обратитесь к
разделу "Преобразования типов данных" в главе 2.
Примеры
-------
5.0 -- числовое_выражение с числовым_литералом
6 + b*4 -- числовое_выражение
'JONES' -- символьное_выражение с символьным_литералом
'FAT' || 'CATS' -- символьное_выражение с конкатенацией
last_name -- символьное_выражение с символьной_переменной
'26-NOV-65' -- календарное_выражение (строковый литерал)
Связанные темы
--------------
Предложение присваивания, Условия, Константы и переменные
Элементы языка 9-41
----------------
FETCH
Описание
--------
Предложение FETCH извлекает очередную строку данных из активного
множества (т.е. множества строк, которые удовлетворяют запросу,
ассоциированному с курсором). Извлекаемые данные записываются в
переменные, которые соответствуют столбцам, выбираемым запросом.
Синтаксис
---------
fetch_предложение ::=
--------- , --------¬
-- FETCH --- имя_курсора --- INTO --T--- имя_переменной -+-T-- ; --
L---- имя_записи --------
Ключевые слова и параметры
--------------------------
имя_курсора
Этот параметр является именем явно объявленного и заранее
открытого курсора. Соглашения об именах приведены в разделе
"Идентификаторы" в главе 2.
INTO имя_переменной
INTO ИМЯ_ПЕРЕМЕННОЙ определяет скалярные переменные, в которые
будут записаны извлеченные данные. Все переменные в списке
ИМЕН_ПЕРЕМЕННЫХ должны быть заранее объявлены.
Для каждого столбца, возвращаемого запросом, который
ассоциирован с курсором, должна быть специфицирована
соответствующая переменная в списке ИМЕН_ПЕРЕМЕННЫХ. Кроме
того, типы данных столбцов, возвращаемых запросом, должны быть
совместимыми с типами соответствующих переменных (или
преобразуемыми в эти типы). Для дополнительной информации
обратитесь к разделу "Преобразования типов данных" в главе 2.
9-42 Руководство пользователя и справочник по PL/SQL
INTO имя_записи
Этот параметр указывает, что извлекаемые данные должны быть
помещены в переменную-запись, объявленную с атрибутом %ROWTYPE,
как показывает следующий пример:
DECLARE
CURSOR c1 IS SELECT ename, empno FROM emp;
emp_rec c1%ROWTYPE;
...
BEGIN
OPEN c1;
...
LOOP
FETCH c1 INTO emp_rec;
EXIT WHEN c1%NOTFOUND;
...
END LOOP;
CLOSE c1;
END;
После этого вы можете обращаться к извлеченным данным каждого
столбца через конструкт ИМЯ_ЗАПИСИ.ИМЯ_СТОЛБЦА. Например,
c1.ename адресует данные, возвращенные из столбца ENAME.
Замечания по использованию
--------------------------
В PL/SQL, предложение SELECT INTO должно возвращать ровно одну
строку данных. Если это предложение не возвращает ни одной
строки, возбуждается предопределенное исключение NO_DATA_FOUND.
Если оно возвращает более одной строки, возбуждается
предопределенное исключение TOO_MANY_ROWS. Для обработки
многострочных запросов вы должны использовать не предложение
SELECT INTO, а курсорный цикл FOR или предложение FETCH.
FETCH обычно используется со следующей логикой:
...
OPEN my_cursor;
...
LOOP
FETCH my_cursor INTO my_record;
EXIT WHEN my_cursor%NOTFOUND;
...
-- обработать извлеченные данные
...
END LOOP;
Элементы языка 9-43
Все выражения в фразе WHERE запроса, ассоциированного с
курсором, вычисляются лишь в момент открытия курсора, как
показывает следующий пример:
DECLARE
multiplied_sal NUMBER(10);
multiplier NUMBER(10) := 2;
CURSOR my_cursor IS SELECT multiplier*sal FROM emp;
BEGIN
OPEN my_cursor; -- здесь multiplier равен 2
LOOP
FETCH my_cursor INTO multiplied_sal;
EXIT WHEN my_cursor%NOTFOUND;
...
-- обработать извлеченные данные
...
multiplier := multiplier + 1;
/* Это не влияет на FETCH. sal по-прежнему *
* будет умножаться на 2. */
END LOOP;
END;
Несмотря на то, что multiplier наращивается после каждой
операции FETCH, извлекаться будет всегда значение 2*SAL, потому
что курсор был открыт при значении multiplier, равном 2. Чтобы
изменить активное множество или значения выражений в запросе, вы
должны закрыть и заново открыть курсор с новыми значениями
входных переменных (в данном случае, multiplier).
Однако, вы можете ассоциировать с операцией FETCH несколько
списков ИМЕН_ПЕРЕМЕННЫХ или несколько ИМЕН_ЗАПИСЕЙ. Например,
после первой операции FETCH вы можете выполнить очередную
операцию FETCH на том же курсоре, но с другим списком имен
переменных. На самом деле, каждая FETCH может использовать свой
список имен переменных, как показывает следующий пример:
DECLARE
CURSOR my_cursor IS SELECT ename FROM emp;
var1 emp.ename%TYPE;
var2 emp.ename%TYPE;
var3 emp.ename%TYPE;
BEGIN
OPEN my_cursor;
FETCH my_cursor INTO var1; -- извлекает первую строку
FETCH my_cursor INTO var2; -- извлекает вторую строку
FETCH my_cursor INTO var3; -- извлекает третью строку
...
CLOSE my_cursor;
END;
9-44 Руководство пользователя и справочник по PL/SQL
Если вы выполняете FETCH, но в активном множестве больше нет
строк, атрибут %NOTFOUND для этого курсора устанавливается в
TRUE. В этот момент значения INTO-переменных не определены.
Обычно вы можете использовать курсорный цикл FOR вместо того,
чтобы явно открывать курсор, использовать FETCH и закрывать
курсор.
Связанные темы
--------------
Предложение присваивания, CLOSE, Курсоры, LOOP, %NOTFOUND, OPEN,
%ROWTYPE, SELECT INTO
Элементы языка 9-45
----------------
Атрибут %FOUND
Описание
--------
Курсоры PL/SQL имеют четыре атрибута, включая %FOUND. Эти
атрибуты, присоединяемые к имени курсора, помогают обращаться к
полезной информации курсора. Для дополнительной информации см.
раздел "Управление курсорами" в главе 4.
PL/SQL использует два типа курсоров: явные и неявные. PL/SQL
неявно объявляет курсор (с именем SQL) для любого предложения
манипулирования данными SQL, включая однострочные запросы.
Перед выполнением первого предложения SQL, не ассоциированного с
явным курсором, SQL%FOUND дает NULL. Впоследствии, этот атрибут
дает TRUE, если операция INSERT, UPDATE или DELETE затронула
хотя бы одну строку, или если операция SELECT INTO вернула хотя
бы одну строку. В противном случае SQL%FOUND дает FALSE.
В случае многострочных предложений SELECT вы можете явно
объявить курсор для обработки возвращаемых строк. После
открытия курсора, но до выполнения первой операции FETCH,
атрибут ИМЯ_КУРСОРА%FOUND дает NULL. После каждой операции
FETCH этот атрибут дает TRUE, если операция вернула очередную
строку данных, и FALSE в противном случае.
Синтаксис
---------
атрибут_%found ::=
--------------------- имя_курсора%FOUND ----------------------------
Ключевые слова и параметры
--------------------------
имя_курсора
Этот параметр должен быть именем явно объявленного курсора или
именем неявного курсора (SQL).
Замечания по использованию
--------------------------
Атрибут %FOUND можно использовать в процедурных предложениях, но
НЕ в предложениях SQL. Атрибут %FOUND ассоциирован с каждым
явным курсором. Вы можете открыть одновременно несколько
курсоров и в каждый момент времени знать, какие из них еще имеют
доступные строки в их активных множествах. Если курсор не
открыт, то обращение к нему через атрибут %FOUND возбуждает
предопределенное исключение INVALID_CURSOR.
Когда явный курсор открыт, строки базы данных, удовлетворяющие
запросу этого курсора, идентифицированы и образуют активное
множество. Каждая операция FETCH возвращает очередную строку из
активного множества. Атрибут %FOUND указывает, была ли
возвращена строка последней операцией FETCH для соответствующего
открытого курсора. Когда активное множество становится пустым
(так может оказаться и перед первой операцией FETCH), очередная
операция FETCH устанавливает атрибут %FOUND в FALSE.
9-46 Руководство пользователя и справочник по PL/SQL
Примеры
-------
В следующем примере, блок PL/SQL извлекает по одному числу из
каждой из двух таблиц и вставляет их сумму в третью таблицу.
Блок завершает свою работу по исчерпании любой из первых двух
таблиц.
-- доступен на диске в файле EXAMP12
DECLARE
CURSOR num1_cur IS SELECT num FROM num1_tab
ORDER BY sequence;
CURSOR num2_cur IS SELECT num FROM num2_tab
ORDER BY sequence;
num1 num1_tab.num%TYPE;
num2 num2_tab.num%TYPE;
pair_num NUMBER := 0;
BEGIN
OPEN num1_cur;
OPEN num2_cur;
LOOP -- loop through the two tables and get
-- pairs of numbers
FETCH num1_cur INTO num1;
FETCH num2_cur INTO num2;
IF (num1_cur%FOUND) AND (num2_cur%FOUND) THEN
pair_num := pair_num + 1;
INSERT INTO sum_tab VALUES (pair_num, num1 + num2);
ELSE
EXIT;
END IF;
END LOOP;
CLOSE num1_cur;
CLOSE num2_cur;
END;
В следующем примере, %FOUND используется, чтобы выполнить
операцию INSERT при успешном выполнении операции UPDATE:
UPDATE emp SET sal = sal * 1.1 WHERE ename = my_ename;
IF SQL%FOUND THEN
INSERT INTO bonus_amts VALUES (my_deptno, my_ename, my_sal);
END IF;
Связанные темы
--------------
CLOSE, Курсоры, DELETE, FETCH, INSERT, %NOTFOUND, OPEN,
SELECT INTO, UPDATE
Элементы языка 9-47
----------------
Функции
Описание
--------
Функция - это поименованная программная единица, которая
принимает параметры и возвращает вычисленное значение. Для
дополнительной информации обратитесь к разделу "Функции" в главе
6.
Функция имеет две части: спецификацию и тело. Спецификация
функции начинается ключевым словом FUNCTION и заканчивается
фразой RETURN, которая специфицирует тип данных результирующего
значения. Объявления аргументов необязательны. Функции, не
принимающие аргументов, записываются без скобок.
Тело функции начинается ключевым словом IS и заканчивается
ключевым словом END, за которым может следовать необязательное
имя функции. Тело функции имеет три части: декларативную часть,
исполняемую часть и необязательную часть обработки исключений.
Декларативная часть содержит объявления типов, курсоров,
констант, переменных, исключений и подпрограмм. Эти объекты
локальны и перестают существовать при выходе из функции.
Исполняемая часть содержит предложения, которые присваивают
значения, управляют выполнением и манипулируют данными ORACLE.
Часть обработки исключений содержит обработчики исключений,
которые имеют дело с исключениями, возбуждаемыми во время
выполнения функции.
Синтаксис
---------
спецификация_функции ::=
----- FUNCTION --- имя_функции ----T--------------------------T------
¦ ----- , -----¬ ¦
L-- ( -- аргумент -+- ) ---
-------- RETURN -----------T- имя_типа -------------T----- ; -------
+- переменная%TYPE ------+
+- таблица.столбец%TYPE -+
L- таблица%ROWTYPE -------
9-48 Руководство пользователя и справочник по PL/SQL
объявление_функции ::= тело_функции
тело_функции ::=
----- FUNCTION --- имя_функции ----T--------------------------T------
¦ ----- , -----¬ ¦
L-- ( -- аргумент -+- ) ---
-------- RETURN -----------T- имя_типа -------------T----- IS -------
+- переменная%TYPE ------+
+- таблица.столбец%TYPE -+
L- таблица%ROWTYPE -------
--------------T------------------------------------------T-----------
¦ -------------------------------------¬ ¦
L---T-- объявление_переменной; ----T---+---
+-- объявление_курсора; -------+
+-- объявление_исключения; ----+
+-- объявление_записи; --------+
+-- объявление_plsql_таблицы; -+
+-- объявление_процедуры; -----+
L-- объявление_функции; --------
---------------------- BEGIN ----- ряд_предложений ------------------
-----T------------------------------------------------T---------------
¦ -----------------------------¬ ¦
L-- EXCEPTION ----- обработчик_исключений; --+---
------------------- END -------T-----------------T---- ; -----------
L-- имя_функции ---
где АРГУМЕНТ имеет следующий синтаксис:
---- имя_аргумента --T-----------T---T- имя_типа -------------T------
+- IN ------+ +- переменная%TYPE ------+
+- OUT -----+ +- таблица.столбец%TYPE -+
L- IN OUT --- L- таблица%ROWTYPE -------
----------------T----------------------------T----------------------
+----- := -----T-- значение --
L-- DEFAULT ----
Элементы языка 9-49
Ключевые слова и параметры
--------------------------
имя_функции
Этот идентификатор именует функцию. Соглашения об именах
описаны в разделе "Идентификаторы" в главе 2.
имя_аргумента
Этот идентификатор именует формальный параметр и представляет
собой переменную, объявленную в спецификации функции и
адресуемую в теле функции. Соглашения об именах описаны в
разделе "Идентификаторы" в главе 2.
RETURN
Это ключевое слово вводит фразу RETURN, специфицирующую тип
данных результирующего значения.
имя_типа
Специфицирует тип данных формального параметра или
результирующего значения. Для дополнительной информации см.
раздел "Типы данных" в главе 2.
В отличие от спецификатора типа в объявлении переменной,
спецификатор типа в объявлении аргумента не может иметь
ограничения. Например, следующее объявление acct_id незаконно:
FUNCTION ... (acct_id INTEGER(5)) ... IS -- незаконно
BEGIN ... END;
таблица.столбец
Ссылка на таблицу и столбец базы данных, которые должны быть
доступны в момент обработки объявления.
%TYPE
Атрибут %TYPE представляет тип данных переменной, константы или
столбца базы данных.
таблица
Ссылка на таблицу базы данных, которая должна быть доступна в
момент обработки объявления.
%ROWTYPE
Атрибут %ROWTYPE указывает запись, представляющую строку таблицы
базы данных. Столбцы в строке и соответствующие поля записи
имеют одинаковые имена и типы данных.
объявление_переменной
Этот конструкт объявляет переменные и константы. Его синтаксис
описан в разделе "Переменные и константы" ниже в этой главе.
объявление_курсора
Этот конструкт объявляет явный курсор. Его синтаксис описан в
разделе "Курсоры" выше в этой главе.
объявление_исключения
Этот конструкт объявляет исключения. Его синтаксис описан в
разделе "Исключения" выше в этой главе.
9-50 Руководство пользователя и справочник по PL/SQL
объявление_записи
Этот конструкт объявляет пользовательские записи. Его синтаксис
описан в разделе "Записи" ниже в этой главе.
объявление_plsql_таблицы
Этот конструкт объявляет таблицы PL/SQL. Его синтаксис описан в
разделе "Таблицы PL/SQL" ниже в этой главе.
объявление_процедуры
Этот конструкт объявляет процедуру. Его синтаксис описан в
разделе "Процедуры" ниже в этой главе.
объявление_функции
Этот конструкт объявляет вложенную функцию.
ряд_предложений
Это последовательность предложений. Ее синтаксис описан в
разделе "Блоки" выше в этой главе.
обработчик_исключений
Этот конструкт ассоциирует исключение с последовательностью
предложений, которая будет выполняться при возбуждении
исключения. Синтаксис ОБРАБОТЧИКА_ИСКЛЮЧЕНИЙ описан в разделе
"Исключения" выше в этой главе.
IN, OUT, IN OUT
Эти моды параметров определяют поведение формальных параметров.
Мода IN позволяет передавать значения вызываемой подпрограмме.
Мода OUT позволяет возвращать значения вызывающей программе.
Мода IN OUT позволяет передавать входные значения вызываемой
подпрограмме и возвращать обновленные значения вызывающей
программе.
DEFAULT или :=
Это ключевое слово или оператор присваивания позволяют вам
инициализировать параметры IN умалчиваемыми значениями.
Замечания по использованию
--------------------------
Каждая функция должна содержать хотя бы одно предложение RETURN.
В противном случае PL/SQL возбудит предопределенное исключение
PROGRAM_ERROR во время выполнения.
Функция вызывается как часть выражения. Например, функция
sal_ok может быть вызвана следующим образом:
promotable := sal_ok(new_sal, new_title) AND (rating > 3);
Идентификатор функции трактуется как выражение, возвращающее
результат.
Элементы языка 9-51
Внутри функции параметр IN выступает как константа. Поэтому ему
нельзя присвоить значение. Параметр OUT выступает как
неинициализированная переменная. Поэтому его значение нельзя
присваивать другим переменным или переприсвоить самому себе.
Параметр IN OUT выступает как инициализированная переменная.
Поэтому ему можно присвоить значение, а его значение можно
присваивать другим переменным. Сводка информации о модах
параметров приведена в табл.6-1 в главе 6.
Избегайте использования моды OUT или IN OUT в функциях.
Назначение функции - принять нуль или более аргументов и
возвратить единственное значение. Возврат функцией нескольких
результирующих значений является плохой практикой
программирования. Кроме того, функции должны быть свободны от
ПОБОЧНЫХ ЭФФЕКТОВ, то есть не должны изменять значений
переменных, не локальных для данной функции. Так, функция не
должна изменять значений своих фактических параметров.
Вы можете написать спецификацию функции и ее тело как единицу.
Альтернативно, вы можете отделить спецификацию функции от ее
тела. Таким способом вы можете скрыть детали реализации,
помещая функцию в пакет.
Вы можете определять функции в теле пакета, не объявляя их
спецификаций в спецификации пакета. Однако такие функции можно
будет вызывать только изнутри пакета.
Функции можно определять с помощью любого инструмента ORACLE,
поддерживающего PL/SQL. Однако, для того, чтобы быть доступными
для общего пользования, функции необходимо создавать (CREATE) и
сохранять в базе данных ORACLE.
Вы можете выдавать предложение CREATE FUNCTION интерактивно из
SQL*Plus или SQL*DBA. Полный синтаксис предложения CREATE
FUNCTION приведен в документе SQL Language Reference Manual.
Связанные темы
--------------
Курсоры, Исключения, Пакеты, Таблицы PL/SQL, Процедуры, Записи
Пример
------
Следующая функция возвращает баланс указанного банковского
счета:
FUNCTION balance (acct_id INTEGER) RETURN REAL IS
acct_bal REAL;
BEGIN
SELECT bal INTO acct_bal FROM accts WHERE acctno = acct_id;
RETURN acct_bal;
END balance;
9-52 Руководство пользователя и справочник по PL/SQL
----------------
GOTO
Описание
--------
Предложение GOTO безусловно передает управление с текущего
предложения на выполнимое предложение или блок PL/SQL. Метка
должна быть уникальна в своей сфере, и должна непосредственно
предшествовать предложению (или блоку), на которое вы хотите
передать управление. GOTO передает управление на предложение,
следующее за <<ИМЕНЕМ_МЕТКИ>>, либо в текущем блоке, либо в
первом из окружающих блоков, в котором найдется такое ИМЯ_МЕТКИ.
Для дополнительной информации см. раздел "Последовательное
управление" в главе 3.
Синтаксис
---------
объявление_имени_метки ::=
---------------- << ---- имя_метки ---- >> -------------------------
goto_предложение ::=
---------------- GOTO ---- имя_метки ---- ; ------------------------
Ключевые слова и параметры
--------------------------
имя_метки
Это необъявляемый идентификатор, помещающий предложение или
блок, на который вы хотите передать управление. Синтаксис
ИМЕНИ_МЕТКИ совпадает с синтаксисом ИДЕНТИФИКАТОРА, определенным
в разделе "Идентификаторы" в главе 2.
Вы используете ИМЯ_МЕТКИ в GOTO_ПРЕДЛОЖЕНИИ, чтобы передать
управление на предложение (или блок), следующее за конструктом
<<ИМЯ_МЕТКИ>>. Для дополнительной информации об ИМЕНИ_МЕТКИ
обратитесь к разделу "Блоки" выше в этой главе.
Замечания по использованию
--------------------------
Некоторые возможные назначения предложения GOTO незаконны. В
частности, предложение GOTO не может передавать управление в
предложение IF, в предложение LOOP или в подблок. Например,
следующее предложение GOTO незаконно:
BEGIN
...
GOTO update_row; -- незаконный переход в предложение IF
...
IF valid THEN
...
<>
UPDATE emp SET ...
END IF;
END;
Элементы языка 9-53
Из текущего блока предложение GOTO может перейти в другое место
блока или в окружающий блок, но не в обработчик исключений. Из
обработчика исключений, GOTO_ПРЕДЛОЖЕНИЕ может перейти в
окружающий блок, но не в текущий блок.
Если вы используете GOTO_ПРЕДЛОЖЕНИЕ для выхода из курсорного
цикла FOR, то курсор автоматически закрывается. (Курсор также
автоматически закрывается при возбуждении исключения внутри
такого цикла.)
Данное ИМЯ_МЕТКИ может появиться в блоке ровно один раз, хотя
оно может появляться в других блоках, включая окружающие блоки и
подблоки. GOTO_ПРЕДЛОЖЕНИЕ передает управление на предложение,
следующее за <<ИМЕНЕМ_МЕТКИ>>, либо в текущем блоке, либо в
первом из окружающих блоков, в котором найдется такое ИМЯ_МЕТКИ.
Примеры
-------
Предложение GOTO нельзя использовать для перехода на любое
ключевое слово. Оно должно передавать управление на выполняемое
предложение или блок. Например, следующая передача управления
незаконна:
BEGIN
...
FOR ctr IN 1..50 LOOP
DELETE FROM emp WHERE ...
IF SQL%FOUND THEN
GOTO end_loop;
END IF;
...
<>
END LOOP; -- не является выполняемым предложением
END;
Чтобы исправить последний пример, достаточно добавить
предложение NULL:
BEGIN
...
FOR ctr IN 1..50 LOOP
DELETE FROM emp WHERE ...
IF SQL%FOUND THEN
GOTO end_loop;
END IF;
...
<>
NULL; -- выполняемое предложение, ничего не делающее
END LOOP;
END;
9-54 Руководство пользователя и справочник по PL/SQL
Нельзя переходить внутрь предложения IF, так что следующая
передача управления незаконна:
BEGIN
...
GOTO my_label; -- незаконно
IF a > b THEN
b := b - c;
<>
x := x + 1;
END IF;
END;
Для дополнительных примеров допустимых и недопустимых применений
предложения GOTO обратитесь к разделу "Последовательное
управление" в главе 3.
Элементы языка 9-55
----------------
IF
Описание
--------
Предложение IF выполняет последовательность предложений, если
удовлетворено заданное условие. Для дополнительной информации
см. раздел "Условное управление" в главе 3.
Синтаксис
---------
if_предложение ::=
----- IF ---- plsql_условие ---- THEN ---- ряд_предложений ----------
---T---------------------------------------------------------------T--
¦ ------------------------------------------------------------¬ ¦
L--- ELSIF --- plsql_условие ---- THEN ---- ряд_предложений -+--
---T-------------------------------T--- END IF; ---------------------
L-- ELSE ---- ряд_предложений ---
Ключевые слова и параметры
--------------------------
plsql_условие
Это условие, ассоциируемое с последовательностью предложений,
которая будет выполняться лишь при истинности данного условия.
Синтаксис PLSQL_УСЛОВИЯ приведен в разделе "Условия" выше в этой
главе.
ряд_предложений
Этот параметр представляет последовательность предложений.
Синтаксис РЯДА_ПРЕДЛОЖЕНИЙ определен в разделе "Блоки" выше в
этой главе.
THEN
Это ключевое слово ассоциирует условие, стоящее перед THEN, с
РЯДОМ_ПРЕДЛОЖЕНИЙ, следующим за THEN. А именно, если вычисление
условия дает TRUE, то РЯД_ПРЕДЛОЖЕНИЙ выполняется.
ELSIF
Это ключевое слово вводит новое условие, которое будет
вычисляться, если все предыдущие условия (т.е. условие после
начального IF и все условия, ассоциированные с предыдущими
ELSIF) дают FALSE или NULL.
ELSE
За ключевым словом ELSE не следует никакого условия. Если
управление достигает ELSE, то выполняется следующий за ELSE
РЯД_ПРЕДЛОЖЕНИЙ.
9-56 Руководство пользователя и справочник по PL/SQL
Замечания по использованию
--------------------------
Есть три формы предложений IF: IF-THEN, IF-THEN-ELSE и
IF-THEN-ELSIF. Простейшая форма предложения IF ассоциирует
условие с последовательностью предложений, окружаемой ключевыми
словами THEN и END IF. Эта последовательность предложений
выполняется, только если условие дает TRUE. Если условие дает
FALSE или NULL, то предложение IF ничего не делает. В любом
случае, управление передается на следующее предложение.
Вторая форма предложения IF добавляет ключевое слово ELSE, за
которым следует альтернативная последовательность предложений.
Последовательность предложений в фразе ELSE выполняется, только
если условие дает FALSE или NULL. Таким образом, фраза ELSE
гарантирует, что одна из последовательностей предложений будет
выполнена.
Третья форма предложения IF использует ключевое слово ELSIF,
чтобы ввести дополнительные условия. Если первое условие дает
FALSE или NULL, фраза ELSIF проверяет следующее условие. В
предложении IF может быть сколько угодно фраз ELSIF; последняя
фраза ELSE необязательна. Условия вычисляются по одному сверху
вниз. Если любое условие даст TRUE, выполняется соответствующая
последовательность предложений, и управление передается на
следующее за IF предложение (без вычисления оставшихся условий).
Если все условия дадут FALSE или NULL, выполняется
последовательность предложений в фразе ELSE, если она есть.
Так как обработка предложения IF завершается после выполнения
РЯДА_ПРЕДЛОЖЕНИЙ, только один РЯД_ПРЕДЛОЖЕНИЙ может быть
выполнен предложением IF.
Фразы THEN и ELSE могут включать предложения IF. Иными словами,
предложения IF можно вкладывать друг в друга.
Примеры
-------
В следующем примере, если shoe_count имеет значение 10, оба
условия, специфицированные в предложении IF, истинны. Однако,
поскольку обработка предложения IF заканчивается после
установления истинности первого условия и выполнения
соответствующего РЯДА_ПРЕДЛОЖЕНИЙ, переменной order_quantity
будет правильно присвоено значение 50. Условие, ассоциированное
с ELSIF, не вычисляется, и работа продолжится с предложения
INSERT.
IF shoe_count < 20 THEN
order_amt := 50;
ELSIF shoe_count < 30 THEN
order_amt := 20;
ELSE
order_amt := 5;
END IF;
INSERT INTO purchase_order VALUES (shoe_type, order_quantity);
Элементы языка 9-57
В следующем примере, в зависимости от значения score, в таблицу
grades вставляется одно из трех сообщений состояния:
IF score < 70 THEN
fail := fail + 1;
INSERT INTO grades VALUES (student_id, 'Failed');
ELSIF score IS NULL THEN
INSERT INTO grades VALUES (student_id, 'Unknown');
ELSE
pass := pass + 1;
INSERT INTO grades VALUES (student_id, 'Passed');
END IF;
Связанные темы
--------------
Условия
9-58 Руководство пользователя и справочник по PL/SQL
----------------
INSERT
Описание
--------
Предложение INSERT добавляет новые строки данных в таблицу или
обзор в базе данных. Для полного описания предложения INSERT
обратитесь к документу ORACLE7 Server SQL Language Reference
Manual.
Синтаксис
---------
insert_предложение ::=
-- INSERT -- INTO -- ссылка_на_таблицу -T-------------------------T--
¦ ------- , ------¬ ¦
L- ( -- имя_столбца -+-)--
--------- , --------¬
---------T-- VALUES ---- ( --- sql_выражение --+-- ) ---T--- ; -----
L------------- select_предложение ---------------
где ССЫЛКА_НА_ТАБЛИЦУ имеет следующий синтаксис:
------------T----------T-----T- таблица -T-----T------------T-------
L- схема. -- L- обзор ---- L- @связьБД --
Ключевые слова и параметры
--------------------------
ссылка_на_таблицу
Идентификатор ССЫЛКА_НА_ТАБЛИЦУ задает имя таблицы (или обзора),
в которую вы хотите вставить данные. Таблица должна
существовать в базе данных, к которой вы присоединены во время
выполнения предложения INSERT, и вы должны иметь привилегии
INSERT.
имя_столбца
Этот параметр определяет столбец, в который будут вставляться
данные. Одно и то же имя столбца не может быть специфицировано
больше одного раза в списке ИМЕН_СТОЛБЦОВ. Имена столбцов не
обязаны задаваться в том порядке, в каком они были определены в
таблице или обзоре (в CREATE TABLE или CREATE VIEW). Если вы
объявляете список ИМЕН_СТОЛБЦОВ, включающий не все столбцы
таблицы, то значения не включенных столбцов будут установлены в
NULL или в умалчиваемые значения, которые были специфицированы в
предложении CREATE TABLE.
Элементы языка 9-59
VALUES (sql_выражение, ...)
Присваивает значения одного или нескольких SQL_ВЫРАЖЕНИЙ,
заданных в списке значений, соответствующим столбцам из списка
ИМЕН_СТОЛБЦОВ. Если список ИМЕН_СТОЛБЦОВ отсутствует, то
значения SQL_ВЫРАЖЕНИЙ присваиваются столбцам таблицы в том
порядке, в каком они были определены в предложении CREATE TABLE
при создании таблицы. Конструкт SQL_ВЫРАЖЕНИЕ обозначает любое
выражение, действительное в SQL. Для дополнительной информации
обратитесь к документу ORACLE7 Server SQL Language Reference
Manual.
Для каждого ИМЕНИ_СТОЛБЦА в списке имен столбцов должно быть
предоставлено ровно одно SQL_ВЫРАЖЕНИЕ в списке значений.
Значения ассоциируются со столбцами в том порядке, в каком они
указаны. Если список ИМЕН_СТОЛБЦОВ отсутствует, значения должны
быть предоставлены для всех столбцов таблицы.
Типы данных вставляемых значений должны быть совместимы с типами
соответствующих столбцов (или преобразуемы в них). Для
дополнительной информации см. раздел "Типы данных" в главе 2.
select_предложение
Это - запрос, который извлекает данные из базы данных для
вставки их в таблицу (или обзор). Синтаксис SELECT_ПРЕДЛОЖЕНИЯ
совпадает с синтаксисом конструкта SELECT_INTO_ПРЕДЛОЖЕНИЕ,
который определен в разделе "SELECT INTO" ниже в этой главе, с
той разницей, что SELECT_ПРЕДЛОЖЕНИЕ не может иметь фразу INTO.
В этом варианте предложения INSERT в таблицу или представление
будет вставлено столько строк, сколько возвращает
SELECT_ПРЕДЛОЖЕНИЕ. SELECT_ПРЕДЛОЖЕНИЕ должно возвращать
значение для каждого столбца из списка ИМЕН_СТОЛБЦОВ, или, если
этот список отсутствует, для каждого столбца таблицы или
представления. Как и для фразы VALUES, необходимо позиционное
попарное соответствие между элементами в списке SELECT и
столбцами в списке ИМЕН_СТОЛБЦОВ.
Замечания по использованию
--------------------------
Если используется ключевое слово VALUES со списком значений, то
все календарные и символьные литералы должны быть заключены в
апострофы ('). Числовые литералы не заключаются в апострофы.
Неявный курсор SQL и атрибуты курсора %NOTFOUND, %FOUND,
%ROWCOUNT и %ISOPEN позволяют вам получать полезную информацию о
выполнении предложения INSERT. Для подробностей обратитесь к
разделу "Управление курсорами" в главе 4.
9-60 Руководство пользователя и справочник по PL/SQL
Предложение INSERT может вставить одну или несколько строк, но
может и не вставить ни одной строки. Если вставлена хотя бы
одна строка, происходит следующее:
* SQL%NOTFOUND дает FALSE
* SQL%FOUND дает TRUE
* SQL%ROWCOUNT возвращает число вставленных строк
Если не вставлено ни одной строки, происходит следующее:
* SQL%NOTFOUND дает TRUE
* SQL%FOUND дает FALSE
* SQL%ROWCOUNT возвращает число 0
Примеры
-------
INSERT INTO bonus SELECT ename, job, sal, comm FROM emp
WHERE comm > sal * 0.25;
INSERT INTO emp (empno, ename, job, sal, comm, deptno)
VALUES (4160, 'STURDEVIN', 'SECURITY GUARD', 2045, NULL, 30);
DECLARE
my_deptno NUMBER;
my_dname NUMBER;
BEGIN
my_deptno := 70;
my_dname := 'Distribution';
INSERT INTO dept
VALUES (my_deptno UPPER(my_dname), 'CHICAGO');
END;
Элементы языка 9-61
----------------
Атрибут %ISOPEN
Описание
--------
Курсоры PL/SQL имеют четыре атрибута, включая %ISOPEN. Эти
атрибуты, присоединяемые к имени курсора, помогают обращаться к
полезной информации курсора. Для дополнительной информации см.
раздел "Управление курсорами" в главе 4.
PL/SQL использует два типа курсоров: явные и неявные. PL/SQL
неявно объявляет курсор (с именем SQL) для любого предложения
манипулирования данными SQL, включая однострочные запросы.
ORACLE автоматически закрывает курсор SQL после выполнения
ассоциированного с ним предложения SQL. Как результат, атрибут
SQL%ISOPEN всегда дает FALSE.
В случае многострочных предложений SELECT вы можете явно
объявить курсор для обработки возвращаемых строк. Атрибут
%ISOPEN указывает, открыт ли соответствующий курсор.
ИМЯ_КУРСОРА%ISOPEN дает TRUE, если курсор в данный момент
открыт, и FALSE в противном случае.
Синтаксис
---------
атрибут_%isopen ::=
--------------------- имя_курсора%ISOPEN ---------------------------
Ключевые слова и параметры
--------------------------
имя_курсора
Этот параметр должен быть именем явно объявленного курсора или
именем неявного курсора (SQL). Соглашения об именах приведены в
разделе "Идентификаторы" в главе 2.
9-62 Руководство пользователя и справочник по PL/SQL
Замечания по использованию
--------------------------
Атрибут %ISOPEN можно использовать в процедурных предложениях,
но нельзя использовать в предложениях SQL. Атрибут %ISOPEN
ассоциирован с каждым явным курсором. Это позволяет вам
применять этот атрибут к любому явному курсору, чтобы проверить,
открыть ли он. Если вы не уверены в состоянии курсора,
используйте атрибут %ISOPEN. Не забывайте, что SQL%ISOPEN
всегда дает FALSE.
Пример
------
...
IF NOT (my_cursor%ISOPEN) THEN
OPEN my_cursor;
END IF;
FETCH my_cursor INTO ...
...
Связанные темы
--------------
CLOSE, Курсоры, DELETE, FETCH, INSERT, OPEN, SELECT INTO, UPDATE
Элементы языка 9-63
----------------
Литералы
Литерал - это явное числовое, символьное, строковое или
булевское значение, не представленное идентификатором. Литерал
представляет сам себя. Примеры литералов: 135 или 'Tom &
Jerry'. Для более подробной информации обратитесь к разделу
"Литералы" в главе 2.
Синтаксис
---------
числовой_литерал ::=
----------------T--------T----T-- целое -----------T----------------
+-- + ---+ L-- действительное ---
L-- - ----
целое ::=
-----------¬
---------------------------- цифра -+------------------------------
действительное ::=
----T-- целое --T----------T-T----T--------------------------T------
¦ L- .целое -- ¦ L--T- E -T-T-----T- целое --
+-- .целое --------------+ L- e -- +- + -+
L-- целое. --------------- L- - --
символьный_литерал ::=
-------------------T- 'символ' -T-----------------------------------
L- '''' ------
строковый_литерал ::=
---------------¬
-------------- ' ---T- символ -T--- ' -----------------------------
L- '' ------
булевский_литерал ::=
------------------------T-- TRUE --T--------------------------------
+-- FALSE -+
L-- NULL ---
9-64 Руководство пользователя и справочник по PL/SQL
Ключевые слова и параметры
--------------------------
целое
Целое число с необязательным знаком и без десятичной точки.
действительное
Целое или дробное число с необязательным знаком и с десятичной
точкой.
цифра
Одна из цифр от 0 до 9.
символ
Элемент из набора символов PL/SQL. Для дополнительной
информации см. раздел "Набор символов" в главе 2.
TRUE, FALSE
Предопределенные булевские значения.
NULL
Предопределенное "не-значение", обозначающее отсутствующее,
неизвестное или неприменимое значение.
Элементы языка 9-65
Замечания по использованию
--------------------------
В арифметических выражениях можно использовать два вида числовых
литералов: целочисленные и действительные. Числовые литералы
должны отделяться друг от друга пунктуацией. В дополнение к
пунктуации, можно использовать пробелы.
Символьный литерал - это одиночный символ, заключенный в
апострофы. Символьные литералы включают все печатаемые символы
в наборе символов PL/SQL: буквы, цифры, пропуски и специальные
символы. PL/SQL различает прописные и строчные буквы с
символьных литералах. Например, литералы 'Q' и 'q' различны.
Строковый литерал - это последовательность из нуля или более
символов, заключенной в апострофы. Пустая строка ('') содержит
0 символов. Если необходимо включить апостроф в литерал, его
изображают в виде двойного апострофа (''). PL/SQL различает
прописные и строчные буквы с строковых литералах. Например,
литералы 'white' и 'White' различны.
Кроме того, в строковых литералах хвостовые пробелы являются
значащими, так что литералы 'White' и 'White ' различны. То,
как строковый литерал сравнивается с переменной, НЕ зависит от
этой переменной - хвостовые пробелы в литерале никогда не
отсекаются.
В отличие от "не-значения" NULL, булевские значение TRUE и FALSE
нельзя вставлять в столбец базы данных.
Примеры
-------
Примеры числовых литералов:
25 6.34 7E2 25e-03 .1, 1. +17 -4.4
Примеры символьных литералов:
'H' '&' ' ' '9' ']' 'g'
Примеры строковых литералов:
'$5,000'
'02-AUG-87'
'Don''t leave without saving your work.'
Связанные темы
--------------
Переменные и константы
9-66 Руководство пользователя и справочник по PL/SQL
----------------
LOCK TABLE
Описание
--------
LOCK TABLE позволяет вам заблокировать одну или несколько таблиц
в указанном режиме, что позволяет вам регулировать одновременный
доступ к таблицам, поддерживая ее целостность. Для
дополнительной информации обратитесь к разделу "Использование
LOCK TABLE" в главе 4.
Синтаксис
---------
---------- , -----------¬
------ LOCK TABLE ----- ссылка_на_таблицу --+------ IN -------------
------- режим_блокировки --- MODE ---T------------T--- ; ------------
L-- NOWAIT ---
где ССЫЛКА_НА_ТАБЛИЦУ имеет следующий синтаксис:
------------T----------T-----T- таблица -T-----T------------T-------
L- схема. -- L- обзор ---- L- @связьБД --
Ключевые слова и параметры
--------------------------
ссылка_на_таблицу
Этот идентификатор задает имя таблицы (или обзора), которую вы
хотите заблокировать. Таблица должна существовать в базе
данных, к которой вы присоединены во время выполнения
предложения LOCK TABLE.
режим_блокировки
Этот параметр специфицирует режим, в котором вы хотите
установить блокировку таблицы. Режим может быть одним из
следующих: ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE, SHARE, SHARE
ROW EXCLUSIVE или EXCLUSIVE.
NOWAIT
Этот параметр специфицирует, что, если запрос LOCK TABLE не
может быть удовлетворен (возможно, потому, что таблица уже
заблокирована другим пользователем), то LOCK TABLE вернет
управление пользователю, вместо того, чтобы ждать удовлетворения
запроса. Вы можете повторить попытку позже.
Элементы языка 9-67
Замечания по использованию
--------------------------
Если вы опустите ключевое слово NOWAIT, то ORACLE будет ждать
освобождения таблицы; это ожидание не имеет устанавливаемого
предела. Блокировка таблицы освобождается, когда ваша
транзакция выдает COMMIT или ROLLBACK. Для дополнительной
информации обратитесь к документу ORACLE7 Server SQL Language
Reference Manual.
Пример
------
В следующем примере таблица accts блокируется в режиме
разделения:
LOCK TABLE accts IN SHARE MODE;
Связанные темы
--------------
COMMIT, DELETE, INSERT, ROLLBACK, SAVEPOINT, UPDATE
9-68 Руководство пользователя и справочник по PL/SQL
----------------
LOOP
Описание
--------
Предложение LOOP повторно выполняет ряд предложений ноль или
более раз. Конструкт цикла окружает последовательность
предложений, которые требуется повторять. PL/SQL поддерживает
следующие четыре типа циклов:
* основные циклы
* циклы WHILE
* числовые циклы FOR
* курсорные циклы FOR
Для дополнительной информации см. раздел "Итеративное
управление" в главе 3.
Синтаксис
---------
loop_предложение ::=
---T---------------T-T-------------------------------------T- LOOP --
L-<<имя_метки>>-- L- WHILE --- plsql_условие -----------+
FOR -T- параметр_числового_цикла --+
L- параметр_курсорного_цикла --
---- ряд_предложений --- ENP LOOP ---T---------------T--- ; ---------
L-- имя_метки ---
параметр_числового_цикла ::=
--- индекс --- IN ---T-----------T- целое_выр --- .. -- целое_выр --
L- REVERSE --
параметр_курсорного_цикла ::=
--- имя_записи -- IN --T- имя_курсора --T------------------------TT-
¦ ¦ ----- , -----¬ ¦¦
¦ L- ( -- параметр -+- ) --¦
L---- ( ---- select_предложение ---- ) -----
Ключевые слова и параметры
--------------------------
имя_метки
Этот необъявляемый идентификатор задает необязательное имя
цикла. Соглашения об именах описаны в разделе "Идентификаторы"
в главе 2. Если используется, ИМЯ_МЕТКИ должно быть заключено в
двойные угловые скобки и должно стоять непосредственно перед
предложением LOOP. Это же имя может (не обязательно) появиться
также в конце предложения LOOP.
Элементы языка 9-69
Вы можете использовать ИМЯ_МЕТКИ в предложении EXIT, чтобы выйти
из цикла, помеченного этим именем.
Из-за правил сферы PL/SQL, вы не можете обращаться к индексной
переменной внешнего цикла FOR из внутреннего (вложенного) цикла
FOR, если оба индекса имеют одно и то же имя, если не уточнять
имя индекса ИМЕНЕМ_МЕТКИ внешнего цикла, используя следующий
синтаксис:
имя_метки.индекс
В следующем примере вы проверяете значение индекса внешнего
цикла FOR из внутреннего цикла FOR (заметьте, что оба индекса
имеют одно и то же имя):
<>
FOR ctr IN 1..20 LOOP
...
<>
FOR ctr IN 1..10 LOOP
IF outer.ctr > ctr THEN ...
...
END LOOP inner;
END LOOP outer;
ряд_предложений
Этот параметр задает последовательность предложений, повторяемую
в цикле. Для определения конструкта РЯД_ПРЕДЛОЖЕНИЙ обратитесь
к разделу "Блоки" выше в этой главе.
Основные циклы
--------------
Основной (или бесконечный) цикл не использует ключевых слов
WHILE или FOR. Это просто РЯД_ПРЕДЛОЖЕНИЙ, окруженный ключевыми
словами LOOP и END LOOP. При каждой итерации такого цикла
выполняется указанная последовательность предложений, и
управление передается на начало цикла. Вы должны использовать
предложение EXIT, GOTO или RAISE, чтобы прекратить основной
цикл. Внутренне возбужденное исключение также завершит цикл.
Циклы WHILE
-----------
WHILE plsql_условие
В этой форме цикла условие вычисляется перед каждой итерацией
цикла. Если условие дает TRUE, последовательность предложений
внутри цикла выполняется, и управление передается снова на
начало цикла. Когда условие дает FALSE или NULL, выполнение
цикла заканчивается, и управление передается на следующее за
циклом предложение.
Определение конструкта PLSQL_УСЛОВИЕ приведено в разделе
"Условия" выше в этой главе.
9-70 Руководство пользователя и справочник по PL/SQL
Числовые циклы FOR
------------------
параметр_числового_цикла
В то время как число итераций цикла WHILE неизвестно до тех пор,
пока цикл не завершится, для цикла FOR число итераций известно
до того, как войти в цикл. Циклы FOR осуществляют свои итерации
по заданному интервалу целых чисел. (Курсорные циклы FOR,
которые повторяются по активному множеству курсора, обсуждаются
ниже.) Этот интервал является частью СХЕМЫ ИТЕРАЦИЙ, которая
окружается ключевыми словами FOR и LOOP.
Интервал вычисляется один раз, при первом входе в цикл, и больше
не перевычисляется. Последовательность предложений выполняется
один раз для каждого целого в заданном интервале. После каждой
итерации выполняется приращение индекса цикла.
индекс
Синтаксис ИНДЕКСА совпадает с синтаксисом ИДЕНТИФИКАТОРА. См.
раздел "Идентификаторы" в главе 2.
Вы не должны объявлять ИНДЕКС заранее. Он неявно объявляется
как переменная типа INTEGER. Сферой ИНДЕКСА является собственно
цикл. Поэтому вы не можете обращаться к этой переменной вне
цикла.
Неявное объявление ИНДЕКСА перекрывает любое возможное
объявление этого имени вне цикла. Поэтому одноименная с
индексом переменная, объявленная вне цикла, может использоваться
внутри цикла ТОЛЬКО с использованием метки, как показывает
следующий пример:
<>
DECLARE
num NUMBER;
BEGIN
...
FOR num IN 1..10 LOOP
...
IF main.num > 5 THEN -- обращается к явно объявленной
... -- переменной num, а не индексу
END IF;
END LOOP;
END main;
Внутри цикла ИНДЕКС рассматривается как константа. Его можно
использовать в выражениях, но вы не можете присвоить ему
значение, находясь внутри цикла.
Элементы языка 9-71
целое_выр
Этот параметр является выражением, результатом вычисления
которого должно быть целое число. Это выражение вычисляется
лишь при первом входе в цикл.
По умолчанию, ИНДЕКСУ присваивается значение левого ЦЕЛОГО_ВЫР.
Если ИНДЕКС не превышает значения правого ЦЕЛОГО_ВЫР,
РЯД_ПРЕДЛОЖЕНИЙ выполняется. Затем ИНДЕКС увеличивается на 1.
Если ИНДЕКС по-прежнему не превышает значения правого
ЦЕЛОГО_ВЫР, РЯД_ПРЕДЛОЖЕНИЙ снова выполняется. Этот процесс
повторяется до тех пор, пока ИНДЕКС не станет больше значения
правого ЦЕЛОГО_ВЫР. В этот момент цикл заканчивается.
REVERSE
По умолчанию индекс наращивается на 1 от нижней до верхней
границы. Однако, если вы используете ключевое слово REVERSE,
индекс будет изменяться в обратном направлении, от верхней
границы к нижней. После каждой итерации индекс цикла
уменьшается на 1.
Процесс организуется противоположно умалчиваемому случаю,
описанному выше. ИНДЕКСУ присваивается значение правого
ЦЕЛОГО_ВЫР. Если ИНДЕКС не меньше значения левого ЦЕЛОГО_ВЫР,
РЯД_ПРЕДЛОЖЕНИЙ выполняется. Затем ИНДЕКС уменьшается на 1.
Если ИНДЕКС по-прежнему не меньше значения левого ЦЕЛОГО_ВЫР,
РЯД_ПРЕДЛОЖЕНИЙ снова выполняется. Этот процесс повторяется до
тех пор, пока ИНДЕКС не станет меньше значения левого
ЦЕЛОГО_ВЫР. В этот момент цикл заканчивается. Пример:
FOR i IN REVERSE 1..10 LOOP -- i уменьшается с 10 до 1
-- поместите здесь предложения; они выполнятся 10 раз
...
END LOOP;
Курсорные циклы FOR
-------------------
параметр_курсорного_цикла
Курсорный цикл FOR неявно объявляет свой индекс цикла как запись
типа %ROWTYPE, открывает курсор, в цикле извлекает строки из
активного множества в поля записи, и закрывает курсор, когда все
строки обработаны или когда вы выходите из цикла.
Когда управление попадает на курсорный цикл FOR, выполняется
неявное предложение OPEN ИМЯ_КУРСОРА. Затем, для каждой строки,
которая удовлетворяет запросу, ассоциированному с
ИМЕНЕМ_КУРСОРА, выполняется неявная операция FETCH в неявно
объявленную запись ИМЯ_ЗАПИСИ и исполняется РЯД_ПРЕДЛОЖЕНИЙ.
Когда все строки исчерпаны, выполняется неявное предложение
CLOSE ИМЯ_КУРСОРА, и цикл заканчивается. Таким образом,
РЯД_ПРЕДЛОЖЕНИЙ выполняется один раз для каждой строки, которая
удовлетворяет запросу, ассоциированному с ИМЕНЕМ_КУРСОРА.
9-72 Руководство пользователя и справочник по PL/SQL
имя_записи
Этот идентификатор именует неявно объявляемую запись. Синтаксис
ИМЕНИ_ЗАПИСИ совпадает с синтаксисом ИДЕНТИФИКАТОРА, который
определен в разделе "Идентификаторы" в главе 2.
Неявно объявляемая запись имеет структуру строки данных,
извлекаемой курсором ИМЯ_КУРСОРА. Эта запись определена так,
как если бы она была объявлена следующим образом:
имя_записи имя_курсора%ROWTYPE;
Поля этой записи содержат значения из столбцов строки,
извлекаемой неявной операцией FETCH. Эти поля имеют имена,
совпадающие с именами соответствующих столбцов. Для обращения к
значениям этих полей используйте следующий синтаксис:
имя_записи.имя_столбца
Чтобы такое неявное объявление было успешным, необходимо, чтобы
каждый столбец, извлекаемый курсором, имел имя в форме простого
идентификатора, или, если это выражения, для них должны быть
предоставлены алиасы. В следующем примере для вычисляемого
элемента sal+NVL(comm,0) используется алиас wages:
CURSOR c1 IS SELECT empno, sal+NVL(comm,0) wages, job ...
имя_курсора
Этот идентификатор является именем ранее объявленного курсора
PL/SQL. Соглашения об именах приведены в разделе
"Идентификаторы" в главе 2.
При входе в курсорный цикл FOR курсор ИМЯ_КУРСОРА не должен
оказаться открытым (в результате явной операции OPEN или из-за
того, что этот курсор использовался в окружающем курсорном цикле
FOR).
параметр
Этот идентификатор именует формальный параметр курсора.
Соглашения об именах приведены в разделе "Идентификаторы" в
главе 2.
Синтаксис ПАРАМЕТРА совпадает с синтаксисом PLSQL_ВЫРАЖЕНИЯ,
который определен в разделе "Выражения" выше в этой главе.
Если курсор ИМЯ_КУРСОРА был объявлен с формальными параметрами,
то курсору должны быть переданы фактические параметры. Значения
этих параметров используются при неявном открытии курсора перед
первым выполнением цикла. Каждый передаваемый параметр должен
иметь тип данных, который совместим с типом данных
соответствующего параметра курсора, определенного в
первоначальном объявлении курсора, или может быть преобразован в
него. Для дополнительной информации обратитесь к разделу "Типы
данных" в главе 2.
Элементы языка 9-73
select_предложение
Это - запрос, который ассоциируется с недоступным вам внутренним
курсором. PL/SQL автоматически объявляет, открывает, извлекает
данные и закрывает этот внутренний курсор. Так как
SELECT_ПРЕДЛОЖЕНИЕ здесь не является независимым предложением, к
нему неприменим идентификатор неявного курсора SQL.
Синтаксис SELECT_ПРЕДЛОЖЕНИЯ совпадает с синтаксисом конструкта
SELECT_INTO_ПРЕДЛОЖЕНИЕ, которое определено в разделе
"SELECT INTO" ниже в этой главе, с той разницей, что
SELECT_ПРЕДЛОЖЕНИЕ не может иметь фразы INTO.
Замечания по использованию
--------------------------
Вы можете использовать предложение EXIT для принудительного
выхода из любого цикла. Как только условие, специфицированное в
предложении EXIT, станет истинным, вы немедленно выйдете из
цикла. Для дополнительной информации обратитесь к разделу
"EXIT" выше в этой главе.
При выходе из курсорного цикла FOR курсор автоматически
закрывается, даже если вы использовали предложение EXIT или GOTO
для преждевременного выхода из цикла. Курсор также
автоматически закрывается при возбуждении исключения внутри
цикла.
Пример
------
DECLARE
bonus REAL;
CURSOR c1 IS SELECT empno, sal, comm FROM emp;
BEGIN
FOR c1rec IN c1 LOOP
bonus := (c1rec.sal * 0.05) + (c1rec.comm * 0.25);
INSERT INTO bonuses VALUES (c1rec.empno, bonus);
END LOOP;
COMMIT;
END;
Связанные темы
--------------
CLOSE, Условия, Курсоры, EXIT, FETCH, OPEN, %ROWTYPE
9-74 Руководство пользователя и справочник по PL/SQL
----------------
Атрибут %NOTFOUND
Описание
--------
Курсоры PL/SQL имеют четыре атрибута, включая %NOTFOUND. Эти
атрибуты, присоединяемые к имени курсора, помогают обращаться к
полезной информации курсора. Для дополнительной информации см.
раздел "Управление курсорами" в главе 4.
PL/SQL использует два типа курсоров: явные и неявные. PL/SQL
неявно объявляет курсор (с именем SQL) для любого предложения
манипулирования данными SQL, включая однострочные запросы.
Перед выполнением первого предложения SQL, не ассоциированного с
явным курсором, SQL%NOTFOUND дает NULL. Впоследствии, этот
атрибут дает FALSE, если операция INSERT, UPDATE или DELETE
затронула хотя бы одну строку, или если операция SELECT INTO
вернула хотя бы одну строку. В противном случае SQL%NOTFOUND
дает TRUE.
В случае многострочных предложений SELECT вы можете явно
объявить курсор для обработки возвращаемых строк. После
открытия курсора, но до выполнения первой операции FETCH,
атрибут ИМЯ_КУРСОРА%NOTFOUND дает NULL. После каждой операции
FETCH этот атрибут дает FALSE, если операция вернула очередную
строку данных, и TRUE в противном случае.
Синтаксис
---------
атрибут_%notfound ::=
--------------------- имя_курсора%NOTFOUND--------------------------
Ключевые слова и параметры
--------------------------
имя_курсора
Этот параметр должен быть именем явно объявленного курсора или
именем неявного курсора (SQL). Соглашения об именах приведены в
разделе "Идентификаторы" в главе 2.
Замечания по использованию
--------------------------
Атрибут %NOTFOUND можно использовать в процедурных предложениях,
но НЕ в предложениях SQL. Атрибут %NOTFOUND ассоциирован с
каждым явным курсором. Вы можете открыть одновременно несколько
курсоров и в каждый момент времени знать, какие из них еще имеют
доступные строки в их активных множествах. Если курсор не
открыт, то обращение к нему через атрибут %NOTFOUND возбуждает
предопределенное исключение INVALID_CURSOR.
Когда явный курсор открыт, строки базы данных, удовлетворяющие
запросу этого курсора, идентифицированы и образуют активное
множество. Атрибут %NOTFOUND указывает, была ли возвращена
строка последней операцией FETCH для соответствующего открытого
курсора. Когда активное множество становится пустым, очередная
операция FETCH устанавливает атрибут %NOTFOUND в TRUE.
Элементы языка 9-75
Примеры
-------
В следующем примере %NOTFOUND используется для того, чтобы
возбудить исключение, если удаление сбивается:
DELETE FROM parts WHERE status = 'OBSOLETE';
IF SQL%NOTFOUND THEN
RAISE none_purged;
END IF;
В следующем примере, блок PL/SQL извлекает по одному числу из
каждой из двух таблиц и вставляет их сумму в третью таблицу.
Блок завершает свою работу по исчерпании любой из первых двух
таблиц.
-- доступен на диске в файле EXAMP13
DECLARE
CURSOR num1_cur IS SELECT num FROM num1_tab
ORDER BY sequence;
CURSOR num2_cur IS SELECT num FROM num2_tab
ORDER BY sequence;
num1 num1_tab.num%TYPE;
num2 num2_tab.num%TYPE;
pair_num NUMBER := 0;
BEGIN
OPEN num1_cur;
OPEN num2_cur;
LOOP -- loop through the two tables and get
-- pairs of numbers
FETCH num1_cur INTO num1;
FETCH num2_cur INTO num2;
EXIT WHEN (num1_cur%NOTFOUND) OR (num2_cur%NOTFOUND);
pair_num := pair_num + 1;
INSERT INTO sum_tab VALUES (pair_num, num1 + num2);
END LOOP;
CLOSE num1_cur;
CLOSE num2_cur;
END;
Связанные темы
--------------
CLOSE, Курсоры, DELETE, FETCH, %FOUND, INSERT, OPEN,
SELECT INTO, UPDATE
9-76 Руководство пользователя и справочник по PL/SQL
----------------
NULL
Описание
--------
Предложение NULL явно специфицирует отсутствие действия.
Выполнение этого предложения не имеет никакого эффекта, кроме
передачи управления следующему предложению. PL/SQL
предоставляет это предложение для улучшения читабельности. Для
дополнительной информации см. раздел "Последовательное
управление" в главе 3.
Синтаксис
---------
null_предложение ::=
-------------------------- NULL ------ ; ---------------------------
Замечания по использованию
--------------------------
Предложение NULL рекомендуется использовать для улучшения
читабельности условных предложений.
В конструкте, предполагающем альтернативные действия, явное
предложение NULL говорит читателю о том, что соответствующая
альтернатива не пропущена случайно, а, действительно, никакого
действия не требуется.
Предложение NULL не имеет никакого отношения к пустым значениям
(значениям NULL).
Примеры
-------
В следующем примере предложение NULL подчеркивает, что только
продавцы получают премии.
IF job_title = 'SALESPERSON' THEN
compute_commission(emp_id);
ELSE
NULL;
END IF;
В следующем примере предложение NULL подчеркивает, что
обработчик не обрабатывает никаких исключений, кроме явно
перечисленных.
EXCEPTION
WHEN ZERO_DIVIDE THEN
ROLLBACK;
...
WHEN OTHERS THEN
NULL;
END;
Элементы языка 9-77
----------------
OPEN
Описание
--------
Предложение OPEN вычисляет запрос, ассоциированный с явно
объявленным курсором. Оно также распределяет ресурсы,
используемые ORACLE для выполнения этого запроса. В процессе
выполнения запроса строки таблиц, удовлетворяющие поисковым
условиям запроса, идентифицируются и образуют активное
множество. Курсор устанавливается непосредственно перед первой
строкой активного множества. Для дополнительной информации см.
раздел "Обработка транзакций" в главе 4.
Синтаксис
---------
open_предложение ::=
--- OPEN --- имя_курсора ---T--------------------------------T- ; --
¦ --------- , ---------¬ ¦
L- ( -- входной_параметр -+- ) --
Ключевые слова и параметры
--------------------------
имя_курсора
Этот идентификатор задает имя курсора, ранее объявленного через
ОБЪЯВЛЕНИЕ_КУРСОРА и в настоящий момент не открытого.
Соглашения об именах приведены в разделе "Идентификаторы" в
главе 2.
входной_параметр
Этот идентификатор именует формальный параметр курсора и обычно
используется в фразе WHERE. Соглашения об именах приведены в
разделе "Идентификаторы" в главе 2. Синтаксис
ВХОДНОГО_ПАРАМЕТРА совпадает с синтаксисом PLSQL_ВЫРАЖЕНИЯ (см.
раздел "Выражения" выше в этой главе).
Если у вас были определены формальные параметры в объявлении
курсора, то вы ДОЛЖНЫ включить фактические параметры в
предложение OPEN. Все фактические параметры в предложении OPEN
должны иметь типы данных, совместимые (или преобразуемые) с
типами данных соответствующих формальных параметров. Для
дополнительной информации о обратитесь к разделу "Типы данных" в
главе 2. Помимо фактических параметров, запрос может обращаться
к переменным PL/SQL, определенным в его сфере.
9-78 Руководство пользователя и справочник по PL/SQL
Если вы не хотите принять умалчиваемые значения, каждому
формальному параметру в объявлении курсора следует сопоставить
соответствующий фактический параметр в предложении OPEN.
Формальные параметры, объявленные с умалчиваемым значением,
могут и не иметь соответствующих им фактических параметров. В
этом случае они просто принимают свое умалчиваемое значение во
время выполнения OPEN.
Не забывайте, что формальные параметры курсора должны быть
параметрами IN, так что они не могут возвращать значений
фактическим параметрам.
Чтобы сопоставить фактические параметры в предложении OPEN
формальным параметрам в объявлении курсора, вы можете
использовать позиционную или именную нотацию. (См. раздел
"Позиционная и именная нотация" в главе 6.)
Замечания по использованию
--------------------------
В общем случае, PL/SQL выполняет синтаксический разбор явного
курсора лишь при его первом открытии, а разбор предложения SQL
(и тем самым создание неявного курсора) - лишь при первом
выполнении этого предложения.
Все синтаксически разобранные предложения SQL кэшируются.
Повторный разбор предложения SQL необходим лишь в том случае,
если это предложение было вытеснено из кэша другим предложением
SQL.
Поэтому, хотя вы должны закрывать (CLOSE) курсор перед его
повторным открытием, PL/SQL, вообще говоря, не будет
осуществлять повторный разбор соответствующего предложения
SELECT. Если вы закрываете и немедленно вновь открываете
курсор, то повторного разбора не будет гарантированно.
Выполнение предложения OPEN не извлекает никаких строк активного
множества. Извлекает строки предложение FETCH. В курсоре,
объявленном FOR UPDATE, строки активного множества блокируются
при открытии курсора.
Если курсор в настоящий момент открыт предложением OPEN, вы не
можете использовать этот курсор в курсорном цикле FOR.
Элементы языка 9-79
Примеры
-------
При данном объявлении курсора:
CURSOR parts_cur IS SELECT part_num, part_price FROM parts;
следующее предложение открывает этот курсор:
OPEN parts_cur;
При данном объявлении курсора:
CURSOR emp_cur(my_ename CHAR, my_comm NUMBER DEFAULT 0)
IS SELECT ...;
любое из следующих предложений открывает этот курсор:
OPEN emp_cur('BLAKE', 300);
OPEN emp_cur(employee_name, 150);
OPEN emp_cur('LEE');
OPEN emp_cur('TRUSDALE', my_comm);
Обратите внимание, что, как показывает последний пример,
переменная, используемая как входной параметр в предложении
OPEN, может иметь такое же имя, что и формальный параметр в
объявлении курсора. Когда имя my_comm встречается в объявлении
курсора, оно относится к формальному параметру. Вне объявления
курсора это же имя относится к переменной PL/SQL. Для ясности,
однако, рекомендуется использовать уникальные имена.
Связанные темы
--------------
CLOSE, Курсоры, FETCH, LOOP
9-80 Руководство пользователя и справочник по PL/SQL
----------------
Пакеты
Описание
--------
Пакет - это объект базы данных, который группирует логически
связанные типы, программные объекты и подпрограммы PL/SQL.
Пакеты обычно состоят из двух частей, спецификации и тела, хотя
иногда в теле нет необходимости. Спефицикация пакета - это
интерфейс с вашими приложениями; она объявляет типы, переменные,
константы, исключения, курсоры и подпрограммы, доступные для
использования в пакете. Тело пакета полностью определяет
курсоры и подпрограммы, тем самым реализуя спецификацию пакета.
Для более подробной информации обратитесь к главе 7.
Синтаксис
---------
спецификация_пакета ::=
----- PACKAGE --- имя_пакета ---- IS --------------------------------
-------------------------------------¬
------------------T-- объявление_переменной; ----T---+--------------
+-- объявление_курсора; -------+
+-- спецификация_курсора; -----+
+-- объявление_исключения; ----+
+-- объявление_записи; --------+
+-- объявление_plsql_таблицы; -+
+-- объявление_процедуры; -----+
L-- объявление_функции; --------
------------------- END -------T----------------T---- ; ------------
L-- имя_пакета ---
тело_пакета ::=
----- PACKAGE BODY --- имя_пакета ---- IS ---------------------------
-------------------------------------¬
------------------T-- объявление_переменной; ----T---+--------------
+-- объявление_курсора; -------+
+-- тело_курсора; -------------+
+-- объявление_исключения; ----+
+-- объявление_записи; --------+
+-- объявление_plsql_таблицы; -+
+-- тело_процедуры; -----------+
L-- тело_функции; --------------
------------------- END -------T----------------T---- ; ------------
L-- имя_пакета ---
Элементы языка 9-81
Ключевые слова и параметры
--------------------------
имя_пакета
Этот идентификатор именует пакет. Соглашения об именах
приведены в разделе "Идентификаторы" в главе 2.
объявление_переменной
Этот конструкт объявляет переменные и константы. Его синтаксис
описан в разделе "Переменные и константы" ниже в этой главе.
объявление_курсора
Этот конструкт объявляет явный курсор. Его синтаксис описан в
разделе "Курсоры" выше в этой главе.
спецификация_курсора
Этот конструкт объявляет интерфейс к явному курсору. Его
синтаксис описан в разделе "Курсоры" выше в этой главе.
объявление_исключения
Этот конструкт объявляет исключения. Его синтаксис описан в
разделе "Исключения" выше в этой главе.
объявление_записи
Этот конструкт объявляет пользовательские записи. Его синтаксис
описан в разделе "Записи" ниже в этой главе.
объявление_plsql_таблицы
Этот конструкт объявляет таблицы PL/SQL. Его синтаксис описан в
разделе "Таблицы PL/SQL" ниже в этой главе.
спецификация_процедуры
Этот конструкт объявляет интерфейс к процедуре. Его синтаксис
описан в разделе "Процедуры" ниже в этой главе.
спецификация_функции
Этот конструкт объявляет интерфейс к функции. Его синтаксис
описан в разделе "Функции" выше в этой главе.
тело_курсора
Этот конструкт определяет реализацию явного курсора. Его
синтаксис описан в разделе "Курсоры" выше в этой главе.
тело_процедуры
Этот конструкт определяет реализацию процедуры. Его синтаксис
описан в разделе "Процедуры" выше в этой главе.
9-82 Руководство пользователя и справочник по PL/SQL
тело_функции
Этот конструкт определяет реализацию функции. Его синтаксис
описан в разделе "Функции" выше в этой главе.
ряд_предложений
Это последовательность предложений. Ее синтаксис описан в
разделе "Блоки" выше в этой главе.
обработчик_исключений
Этот конструкт ассоциирует исключение с последовательностью
предложений, которая будет выполняться при возбуждении
исключения. Синтаксис ОБРАБОТЧИКА_ИСКЛЮЧЕНИЙ описан в разделе
"Исключения" выше в этой главе.
Замечания по использованию
--------------------------
Пакеты нельзя встраивать в блок или подпрограмму PL/SQL. Однако
определять пакеты можно с помощью любого инструмента ORACLE,
поддерживающего PL/SQL.
Чтобы быть доступными для общего пользования, пакеты должны быть
созданы (CREATE) и сохранены в базе данных ORACLE. Вы можете
выдавать предложения CREATE PACKAGE и CREATE PACKAGE BODY
интерактивно, из SQL*Plus или SQL*DBA, или из хост-программы
прекомпилятора ORACLE. Для полного синтаксиса предложения
CREATE обратитесь к документу ORACLE7 Server SQL Language
Manual.
Все, что вам надо изначально знать при проектировании приложения
- это информация интерфейса в спецификациях пакетов. Вы можете
кодировать и компилировать спецификацию без тела. После того,
как спецификация откомпилирована, хранимые подпрограммы,
обращающиеся к пакету, также могут быть откомпилированы. Вы не
обязаны полностью определять тела пакетов до тех пор, пока не
будете готовы к реализации деталей приложения.
Более того, вы можете отлаживать, развивать или заменять тело
пакета, не изменяя интерфейса с этим телом (т.е. спецификации
пакета). Это значит, что вы не обязаны перекомпилировать
программы, вызывающие данный пакет.
Курсоры и подпрограммы, объявленные в спецификации пакета,
должны быть определены в теле пакета. Другие программные
объекты, объявленные в спецификации пакета, не могут быть
переобъявлены в теле пакета.
Связанные темы
--------------
Курсоры, Исключения, Функции, Таблицы PL/SQL, Процедуры, Записи
Элементы языка 9-83
----------------
Таблицы PL/SQL
Описание
--------
Таблицы PL/SQL - это объекты типа TABLE, которые моделируют
таблицы базы данных (но не являются таковыми). Таблицы PL/SQL
используют первичный ключ, чтобы предоставить вам доступ к
строкам по аналогии с массивом. Как и размер таблицы базы
данных, размер таблицы PL/SQL не ограничивается. Иными словами,
число строк в таблице PL/SQL может возрастать динамически.
Поэтому ваша таблица PL/SQL растет по мере добавления в нее
новых строк. Для более подробной информации см. раздел "Таблицы
PL/SQL" в главе 2.
Таблицы PL/SQL должны объявляться за два шага. Сначала вы
объявляете (поименованный) тип TABLE, а затем объявляете таблицы
PL/SQL этого типа.
Синтаксис
---------
объявление_plsql_таблицы ::=
------ TYPE ----- имя_типа ----- IS ---- TABLE OF -------------------
----T-- тип_столбца ------------T----T------------T-----------------
+-- переменная%TYPE --------+ L- NOT NULL --
L- таблица.столбец%TYPE -----
----------------- INDEX BY BINARY INTEGER -------------- ; ---------
plsql_таблица ::=
----------- имя_plsql_таблицы --- тип_plsql_таблицы ---- ; ---------
Ключевые слова и параметры
--------------------------
имя_типа
Этот идентификатор именует определенный пользователем
спецификатор типа, который используеипя в последующих
объявлениях таблиц PL/SQL. Соглашения об именах обсуждаются в
разделе "Идентификаторы" в главе 2.
тип_столбца
Специфицирует тип данных столбца в таблице PL/SQL. Это может
быть любой скалярный (не составной) тип данных, такой как CHAR,
DATE или NUMBER. Для дополнительной информации см. раздел "Типы
данных" в главе 2.
таблица.столбец
Ссылка на таблицу и столбец базы данных, которые должны быть
доступны в момент обработки объявления.
9-84 Руководство пользователя и справочник по PL/SQL
INDEX BY BINARY INTEGER
Первичный ключ таблицы PL/SQL должен иметь тип данных
BINARY_INTEGER, который может представлять целые со знаком
практически любой величины. Допустимый диапазон значений
BINARY_INTEGER - от -2**31 - 1 до 2**31 - 1 (-2147483647 ..
2147483647).
имя_plsql_таблицы
Этот идентификатор именует всю таблицу PL/SQL. Соглашения об
именах обсуждаются в разделе "Идентификаторы" в главе 2.
Замечания по использованию
--------------------------
Вы можете объявлять типы TABLE в декларативной части любого
блока, подпрограммы или пакета, Таблица PL/SQL может иметь один
столбец и один первичный ключ, оба непоименованные. Столбец
может принадлежать любому скалярному типу, но первичный ключ
должен принадлежать типу BINARY_INTEGER. Для спецификации типа
столбца можно использовать атрибут %TYPE.
В отличие от массива, таблица PL/SQL не ограничена (не имеет
фиксированного размера), потому что ее первичный ключ может
принимать любое значение в интервале допустимых значений для
BINARY_INTEGER. Как следствие, вы не можете инициализировать
таблицу PL/SQL в ее объявлении. Например, следующее объявление
незаконно:
job_tab JobTabTyp := ('CLERK','ANALYST','MANAGER');
Пока строке таблицы PL/SQL не присвоено значение, эта строка не
существует. При попытке обратиться к неинициализированной
строке PL/SQL возбуждает предопределенное исключение
NO_DATA_FOUND.
Таблицы PL/SQL подчиняются обычным правилам сферы и инстанциации
(инстанциация - это создание нового экземпляра программного
объекта). В пакете, таблицы PL/SQL инстанциируются при первом
обращении к этому пакету, и перестают существовать, когда вы
выходите из приложения или заканчиваете сессию базы данных. В
блоке или подпрограмме, таблицы PL/SQL инстанциируются при входе
в блок или подпрограмму, и перестают существовать, когда вы
выходите из блока или подпрограммы.
Как и скалярные переменные, таблицы PL/SQL могут объявляться как
формальные параметры процедур и функций. Ограничения, которые
применяются к скалярным параметрам, применимы и к таблицам
PL/SQL.
Элементы языка 9-85
Примеры
-------
В следующем примере вы объявляете тип TABLE с именем SalTabTyp:
DECLARE
TYPE SalTabTyp IS TABLE OF NUMBER(7,2)
INDEX BY BINARY INTEGER;
...
Вы можете использовать атрибут %TYPE, чтобы представить тип
данных столбца, например:
DECLARE
TYPE SalTabTyp IS TABLE OF emp.sal%TYPE
INDEX BY BINARY INTEGER;
...
После определения типа SalTabTyp вы можете объявлять таблицы
PL/SQL этого типа, например:
sal_tab SalTabTyp;
Идентификатор sal_tab представляет всю таблицу PL/SQL.
В следующем примере вы присваиваете сумму значений переменных
salary и increase десятой строке таблицы PL/SQL sal_tab:
sal_tab(10) := salary + increase;
Связанные темы
--------------
Предложение присваивания, Функции, Процедуры, Записи
9-86 Руководство пользователя и справочник по PL/SQL
----------------
Процедуры
Описание
--------
Процедура - это поименованный блок PL/SQL, которому можно
передавать параметры и который можно вызывать. Обычно вы
используете процедуру, чтобы выполнить некоторое действие. Для
дополнительной информации обратитесь к разделу "Процедуры" в
главе 6.
Процедура имеет две части: спецификацию и тело. Спецификация
процедура начинается ключевым словом PROCEDURE и заканчивается
именем процедуры или списком параметров. Объявления параметров
необязательны. Процедуры, не принимающие параметров,
записываются без скобок.
Тело процедуры начинается ключевым словом IS и заканчивается
ключевым словом END, за которым может следовать необязательное
имя процедуры. Тело процедуры имеет три части: декларативную
часть, исполняемую часть и необязательную часть обработки
исключений.
Декларативная часть содержит объявления типов, курсоров,
констант, переменных, исключений и подпрограмм. Эти объекты
локальны и перестают существовать при выходе из процедуры.
Исполняемая часть содержит предложения, которые присваивают
значения, управляют выполнением и манипулируют данными ORACLE.
Часть обработки исключений содержит обработчики исключений,
которые имеют дело с исключениями, возбуждаемыми во время
выполнения процедуры.
Элементы языка 9-87
Синтаксис
---------
спецификация_процедуры ::=
--- PROCEDURE --- имя_процедуры ---T--------------------------T- ; --
¦ ----- , -----¬ ¦
L-- ( -- параметр -+- ) ---
объявление_процедуры ::= тело_процедуры
тело_процедуры ::=
---- PROCEDURE -- имя_процедуры --T--------------------------T- IS --
¦ ----- , -----¬ ¦
L-- ( -- параметр -+- ) ---
--------------T------------------------------------------T-----------
¦ -------------------------------------¬ ¦
L---T-- объявление_переменной; ----T---+---
+-- объявление_курсора; -------+
+-- объявление_исключения; ----+
+-- объявление_записи; --------+
+-- объявление_plsql_таблицы; -+
+-- объявление_процедуры; -----+
L-- объявление_функции; --------
---------------------- BEGIN ----- ряд_предложений ------------------
-----T------------------------------------------------T---------------
¦ -----------------------------¬ ¦
L-- EXCEPTION ----- обработчик_исключений; --+---
------------------- END -------T-------------------T---- ; ---------
L-- имя_процедуры ---
где ПАРАМЕТР имеет следующий синтаксис:
---- имя_параметра --T-----------T---T- имя_типа -------------T------
+- IN ------+ +- переменная%TYPE ------+
+- OUT -----+ +- таблица.столбец%TYPE -+
L- IN OUT --- L- таблица%ROWTYPE -------
----------------T----------------------------T----------------------
+----- := -----T-- значение --
L-- DEFAULT ----
9-88 Руководство пользователя и справочник по PL/SQL
Ключевые слова и параметры
--------------------------
имя_процедуры
Этот идентификатор именует процедуру. Соглашения об именах
описаны в разделе "Идентификаторы" в главе 2.
объявление_переменной
Этот конструкт объявляет переменные и константы. Его синтаксис
описан в разделе "Переменные и константы" ниже в этой главе.
объявление_курсора
Этот конструкт объявляет явный курсор. Его синтаксис описан в
разделе "Курсоры" выше в этой главе.
объявление_исключения
Этот конструкт объявляет исключения. Его синтаксис описан в
разделе "Исключения" выше в этой главе.
объявление_записи
Этот конструкт объявляет пользовательские записи. Его синтаксис
описан в разделе "Записи" ниже в этой главе.
объявление_plsql_таблицы
Этот конструкт объявляет таблицы PL/SQL. Его синтаксис описан в
разделе "Таблицы PL/SQL" ниже в этой главе.
объявление_процедуры
Этот конструкт объявляет вложенную процедуру.
объявление_функции
Этот конструкт объявляет функцию. Его синтаксис описан в
разделе "Функции" ниже в этой главе.
ряд_предложений
Это последовательность предложений. Ее синтаксис описан в
разделе "Блоки" выше в этой главе.
обработчик_исключений
Этот конструкт ассоциирует исключение с последовательностью
предложений, которая будет выполняться при возбуждении
исключения. Синтаксис ОБРАБОТЧИКА_ИСКЛЮЧЕНИЙ описан в разделе
"Исключения" выше в этой главе.
имя_параметра
Этот идентификатор именует формальный параметр и представляет
собой переменную, объявленную в спецификации процедуры и
адресуемую в теле процедуры. Соглашения об именах описаны в
разделе "Идентификаторы" в главе 2.
Элементы языка 9-89
IN, OUT, IN OUT
Эти моды параметров определяют поведение формальных параметров.
Мода IN позволяет передавать значения вызываемой подпрограмме.
Мода OUT позволяет возвращать значения вызывающей программе.
Мода IN OUT позволяет передавать входные значения вызываемой
подпрограмме и возвращать обновленные значения вызывающей
программе.
имя_типа
Специфицирует тип данных формального параметра или
результирующего значения. Для дополнительной информации см.
раздел "Типы данных" в главе 2.
В отличие от спецификатора типа в объявлении переменной,
спецификатор типа в объявлении параметра не может иметь
ограничения. Например, следующее объявление emp_name незаконно:
PROCEDURE ... (emp_namt CHAR(20)) IS -- незаконно
BEGIN ... END;
таблица.столбец
Ссылка на таблицу и столбец базы данных, которые должны быть
доступны в момент обработки объявления.
%TYPE
Атрибут %TYPE представляет тип данных переменной, константы или
столбца базы данных.
таблица
Ссылка на таблицу базы данных, которая должна быть доступна в
момент обработки объявления.
%ROWTYPE
Атрибут %ROWTYPE указывает запись, представляющую строку таблицы
базы данных. Столбцы в строке и соответствующие поля записи
имеют одинаковые имена и типы данных.
DEFAULT или :=
Это ключевое слово или оператор присваивания позволяют вам
инициализировать параметры IN умалчиваемыми значениями.
Замечания по использованию
--------------------------
Исполняемая часть любой процедуры должна содержать хотя бы одно
предложение. Предложение NULL удовлетворяет этому требованию.
Процедура вызывается как предложение PL/SQL. Например,
процедура raise_salary может быть вызвана следующим образом:
raise_salary(emp_num, amount);
Внутри процедуры параметр IN выступает как константа. Поэтому
ему нельзя присвоить значение. Параметр OUT выступает как
неинициализированная переменная. Поэтому его значение нельзя
присваивать другим переменным или переприсвоить самому себе.
Параметр IN OUT выступает как инициализированная переменная.
Поэтому ему можно присвоить значение, а его значение можно
присваивать другим переменным. Сводка информации о модах
параметров приведена в табл.6-1 в главе 6.
9-90 Руководство пользователя и справочник по PL/SQL
Перед выходом из процедуры не забывайте явно присвоить значения
параметрам OUT. В противном случае значения соответствующих
фактических параметров будут не определены. При успешном выходе
из процедуры PL/SQL присваивает значения фактическим параметрам.
Однако, если вы выходите с необработанным исключением, PL/SQL НЕ
присваивает значений фактическим параметрам.
В отличие от параметров OUT и IN OUT, параметры IN могут быть
инициализированы умалчиваемыми значениями. Для дополнительной
информации см. раздел "Умалчиваемые значения параметров" в главе
6.
Вы можете написать спецификацию процедуры и ее тело как единицу.
Альтернативно, вы можете отделить спецификацию процедуры от ее
тела. Таким способом вы можете скрыть детали реализации,
помещая процедуру в пакет. Вы можете определять процедуры в
теле пакета, не объявляя их спецификаций в спецификации пакета.
Однако такие процедуры можно будет вызывать только изнутри
пакета.
Процедуры можно определять с помощью любого инструмента ORACLE,
поддерживающего PL/SQL. Однако, для того, чтобы быть доступными
для общего пользования, процедуры необходимо создавать (CREATE)
и сохранять в базе данных ORACLE. Вы можете выдавать
предложение CREATE PROCEDURE интерактивно из SQL*Plus или
SQL*DBA. Полный синтаксис предложения CREATE PROCEDURE приведен
в документе ORACLE7 Server SQL Language Reference Manual.
Пример
------
Следующая процедура дебитует указанный банковский счет:
PROCEDURE debit_account (acct_id INTEGER, amount REAL) IS
old_balance REAL;
new_balance REAL;
overdrawn EXCEPTION;
BEGIN
SELECT bal INTO old_balance FROM accts
WHERE acctno = acct_id;
new_balance := old_balance - amount;
IF new_balance < 0 THEN
RAISE overdrawn;
ELSE
UPDATE accts SET bal = new_balance
WHERE acctno = acct_id;
END IF;
EXCEPTION
WHEN overdrawn THEN
...
END debit_account;
В следующем примере вы вызываете эту процедуру, используя
именную нотацию:
debit_account(amount => 500, acct_id => 10261);
Связанные темы
--------------
Курсоры, Исключения, Функции, Пакеты, Таблицы PL/SQL, Записи
Элементы языка 9-91
----------------
RAISE
Описание
--------
Предложение RAISE останавливает нормальное выполнение блока или
подпрограммы PL/SQL и передает управление на соответствующий
обработчик исключений. Для более подробной информации см.
раздел "Пользовательские исключения" в главе 5.
Обычно предопределенные исключения возбуждаются неявно
исполнительной системой. Однако такие исключения можно
возбуждать и предложением RAISE. Пользовательские исключения
возбуждаются только явно, посредством RAISE.
Синтаксис
---------
raise_предложение ::=
-------- RAISE ---T--------------------T---- ; ---------------------
L-- имя_исключения ---
Ключевые слова и параметры
--------------------------
имя_исключения
Этот идентификатор именует возбуждаемое исключение. Он должен
быть именем либо предопределенного, либо пользовательского
исключения, объявленного через ОБЪЯВЛЕНИЕ_ИСКЛЮЧЕНИЯ.
Соглашения об именах приведены в разделе "Идентификаторы" в
главе 2.
Перечень предопределенных исключений приведен в разделе
"Обработчики исключений" выше в этой главе.
Замечания по использованию
--------------------------
Блоки и подпрограммы PL/SQL должны возбуждать исключения лишь в
тех случаях, когда встречается ошибка, делающая продолжение
обработки невозможным или нежелательным. Вы можете закодировать
предложение RAISE для данного исключения в любом месте внутри
сферы этого исключения.
Если вы возбуждаете исключение, а в текущем блоке PL/SQL нет
обработчика для этого исключения, то данное исключение
продвигается в блок, окружающий текущий блок. Этот процесс
повторяется, пока не будет найден обработчик для данного
исключения, или пока не будут исчерпаны окружающие блоки. В
последнем случае возникает ошибка "необрабатываемое исключение",
и управление возвращается в ту среду, из которой был вызван блок
PL/SQL.
Предложение RAISE можно также использовать без имени исключения.
Это допускается только в обработчике исключений, и приводит к
повторному возбуждению текущего исключения. PL/SQL ищет
подходящий обработчик исключений в окружающих блоках, начиная с
того блока, который окружает текущий блок, а не с текущего
блока.
9-92 Руководство пользователя и справочник по PL/SQL
Примеры
-------
IF quantity_on_hand = 0 THEN
RAISE out_of_stock;
END IF;
Как показывает следующий пример, предопределенное исключение
также можно возбуждать явно:
RAISE INVALID_NUMBER;
Связанные темы
--------------
Исключения
Элементы языка 9-93
----------------
Записи
Описание
--------
Записи - это объекты типа RECORD. Записи состоят из уникально
поименованных полей, в которых могут храниться данные разных
типов. Для дополнительной информации см. раздел
"Пользовательские записи" в главе 2.
Записи должны объявляться за два шага. Сначала определяется
(поименованный) тип RECORD, а затем объявляются пользовательские
записи этого типа.
Синтаксис
---------
объявление_записи ::= тип_записи + запись
тип_записи ::=
------ TYPE ----- имя_типа ----- IS ---- RECORD ---------------------
-------------------- , ----------------------¬
---- ( ---- имя_поля ---- тип_данных--T------------T-+-- ) --- ; --
L- NOT NULL --
где ТИП_ДАННЫХ имеет следующий синтаксис:
----------------------T-- тип_поля ---------------T-----------------
+-- переменная%TYPE --------+
+-- таблица.столбец%TYPE ---+
L-- таблица%ROWTYPE ---------
запись ::=
--------------- имя_записи --- тип_записи ---- ; -------------------
Ключевые слова и параметры
--------------------------
имя_типа
Этот идентификатор именует спецификатор пользовательского типа
записи и используется в последующих объявлениях записей.
Соглашения об именах приведены в разделе "Идентификаторы" в
главе 2.
имя_поля
Этот идентификатор именует поле в пользовательской записи.
Соглашения об именах приведены в разделе "Идентификаторы" в
главе 2.
тип_поля
Специфицирует тип данных поля в пользовательской записи. Это
может быть любой тип данных, включая RECORD и TABLE. Для
дополнительной информации см. раздел "Типы данных" в главе 2.
9-94 Руководство пользователя и справочник по PL/SQL
таблица.столбец
Ссылка на таблицу и столбец, которые должны быть доступны в
момент обработки объявления.
таблица
Ссылка на таблицу, которая должна быть доступна в базе данных в
момент обработки объявления.
NOT NULL
Это ограничение предотвращает присваивание полю пустых значений.
При попытке присвоить такому полю пустое значение возбуждается
предопределенное исключение VALUE_ERROR.
имя_записи
Этот идентификатор именует пользовательскую запись. Соглашения
об именах приведены в разделе "Идентификаторы" в главе 2.
Замечания по использованию
--------------------------
Вы можете объявлять типы RECORD в декларативной части любого
блока, подпрограммы или пакета. Более того, запись может быть
инициализирована в своем объявлении, как показывает следующий
пример:
DECLARE
TYPE TimeTyp IS RECORD
(second SMALLINT := 0,
minute SMALLINT := 0,
hour SMALLINT := 0);
...
Следующий пример показывает, что вы можете использовать атрибут
%TYPE, чтобы специфицировать тип данных для поля. Из него также
видно, что вы можете применить ограничение NOT NULL к объявлению
любого поля, чтобы предотвратить присваивание пустых значений
полю:
DECLARE
TYPE DeptRecTyp IS RECORD
(deptno NUMBER(2) NOT NULL,
dname dept.dname%TYPE,
loc dept.loc%TYPE);
dept_rec DeptRecTyp;
...
Элементы языка 9-95
Чтобы обращаться к индивидуальным полям в записи, вы используете
квалифицированные ссылки. Например, чтобы присвоить значение
полю dname в записи dept_rec, вы можете написать:
dept_rec.dname := 'PURCHASING';
Вместо присваивания значений отдельным полям записи можно
присвоить значения сразу всем полям в записи. Это можно сделать
двумя способами. Во-первых, вы можете присвоить одну запись
другой, если обе записи принадлежат одному и тому же типу.
Заметим, однако, что даже при полном совпадении полей
пользовательская запись и запись %ROWTYPE принадлежат разным
типам. Во-вторых, вы можете присвоить записи список значений
столбцов при помощи предложения SELECT или FETCH. Вы должны
лишь обеспечить, чтобы имена столбцов появлялись в том же
порядке, что и поля в вашей записи.
PL/SQL позволяет вам объявлять и ссылаться на ВЛОЖЕННЫЕ записи.
Иными словами, запись может быть компонентой другой записи, как
показывает следующий пример:
DECLARE
TYPE TimeTyp IS RECORD
(minute SMALLINT,
hour SMALLINT);
TYPE MeetingTyp IS RECORD
(day DATE,
time TimeTyp, -- вложенная запись
place CHAR(20),
purpose CHAR(50));
TYPE PartyTyp IS RECORD
(day DATE,
time TimeTyp, -- вложенная запись
loc CHAR(15));
meeting MeetingTyp;
seminar MeetingTyp;
party PartyTyp;
...
Следующий пример показывает, что вы можете присваивать одну
вложенную запись другой, если обе они принадлежат одному типу:
seminar.time := meeting.time;
Такие присваивания разрешаются даже в тех случаях, когда
содержащие записи относятся к разным типам данных, как
показывает следующий пример:
party.time := meeting.time;
9-96 Руководство пользователя и справочник по PL/SQL
Пользовательские записи подчиняются обычным правилам сферы и
инстанциации. В пакете, записи инстанциируются при первом
обращении к этому пакету, и перестают существовать, когда вы
выходите из приложения или заканчиваете сессию базы данных. В
блоке или подпрограмме, записи инстанциируются при входе в блок
или подпрограмму, и перестают существовать, когда вы выходите из
блока или подпрограммы.
Как и скалярные переменные, пользовательские записи могут
объявляться как формальные параметры процедур и функций.
Ограничения, применимые к скалярным параметрам, применяются и к
пользовательским записям.
Примеры
-------
В следующем примере вы объявляете тип RECORD с именем DeptRecTyp
и запись этого типа с именем dept_rec, а затем выбираете строку
значений в эту запись:
DECLARE
TYPE DeptRecTyp IS RECORD
(deptno NUMBER(2),
dname CHAR(14),
loc CHAR(13));
dept_rec DeptRecTyp;
...
BEGIN
SELECT deptno, dname, loc INTO dept_rec FROM dept
WHERE deptno = 20;
...
END;
Связанные темы
--------------
Предложение присваивания, Функции, Таблицы PL/SQL, Процедуры
Элементы языка 9-97
----------------
Предложение RETURN
Описание
--------
Предложение RETURN немедленно завершает выполнение подпрограммы
и возвращает управление вызывающей программе. Выполнение
продолжается с предложения, следующего за вызовом подпрограммы.
В функции, предложение RETURN также присваивает результирующее
значение идентификатору функции. (Не путайте предложение RETURN
с фразой RETURN, которая специфицирует тип данных
результирующего значения в спецификации функции.) Для
дополнительной информации обратитесь к разделу "Функции" в главе
6.
Синтаксис
---------
return_предложение ::=
----------- RETURN ---T----------------------T--- ; ----------------
L-- plsql_выражение ----
Ключевые слова и параметры
--------------------------
plsql_выражение
Это - выражение произвольной сложности, вычисляемое при
выполнении предложения RETURN. Синтаксис PLSQL_ВЫРАЖЕНИЯ
определен в разделе "Выражения" выше в этой главе.
Значение plsql_выражения присваивается идентификатору функции.
Тип данных plsql_выражения должен быть совместимым с типом
данных, указанном в фразе RETURN в спецификации функции. Для
дополнительной информации см. раздел "Преобразование типов
данных" в главе 2.
Замечания по использованию
--------------------------
Подпрограмма может содержать несколько предложений RETURN, ни
одно из которых не обязано быть последним лексическим
предложением в подпрограмме. Выполнение любого из них
немедленно завершает подпрограмму. Однако наличие в
подпрограмме нескольких точек выхода не является хорошей
практикой программирования.
В процедурах предложение RETURN не может содержать выражение.
Это предложение просто возвращает управление вызывающей
программе до достижения нормального конца процедуры.
Однако в функциях предложение RETURN ДОЛЖНО содержать выражение,
которое вычисляется при выполнении предложения RETURN.
Результирующее значение присваивается идентификатору функции.
Поэтому функция должна содержать хотя бы одно предложение
RETURN. В противном случае PL/SQL возбуждает предопределенное
исключение PROGRAM_ERROR во время выполнения.
9-98 Руководство пользователя и справочник по PL/SQL
Предложение RETURN можно также использовать в анонимном блоке
для немедленного выхода из этого и всех окружающих блоков.
Однако в этом случае предложение RETURN не может содержать
выражения.
Пример
------
В следующем примере функция balance возвращает баланс заданного
бухгалтерского счета:
FUNCTION balance (acct_id NUMBER) RETURN REAL IS
acct_bal REAL;
BEGIN
SELECT bal INTO acct_bal FROM accts WHERE acctno = acct_id;
RETURN acct_bal;
END balance;
Элементы языка 9-99
----------------
ROLLBACK
Описание
--------
Предложение ROLLBACK противоположно предложению COMMIT. Оно
явно отменяет все или некоторые из изменений, внесенных в базу
данных в течение текущей транзакции. Для дополнительной
информации обратитесь к разделу "Обработка транзакций" в главе
4.
Синтаксис
---------
rollback_предложение ::=
------------------- ROLLBACK --T--------T----------------------------
L- WORK --
-----T----------------------------------T-T-------------------T- ; -
L- TO -T-------------T- имя_точки -- L- COMMENT 'текст' --
L- SAVEPOINT --
Ключевые слова и параметры
--------------------------
ROLLBACK
Если предложение ROLLBACK закодировано без ключевого слова TO,
выполняется откат всех изменений текущей транзакции.
WORK
Это ключевое слово необязательно и не оказывает никакого
эффекта.
ROLLBACK TO имя_точки
ROLLBACK TO отменяет все изменения, внесенные в базу данных
после выполнения предложения SAVEPOINT с этим именем точки
сохранения, и снимает соответствующие блокировки. Идентификатор
ИМЯ_ТОЧКИ должен быть именем точки сохранения, которая была
ранее создана в текущей транзакции предложением SAVEPOINT.
Соглашения об именах приведены в разделе "Идентификаторы" в
главе 2.
SAVEPOINT
Это ключевое слово необязательно и не оказывает никакого
эффекта.
COMMENT
Ключевое слово COMMENT задает комментарий, ассоциируемый с
текущей транзакцией и обычно используемый в распределенных
транзакциях. Текст комментария должен быть литералом в
апострофах длиной не более 50 символов.
9-100 Руководство пользователя и справочник по PL/SQL
Замечания по использованию
--------------------------
Все точки сохранения, которые были созданы после той точки, к
которой вы выполняете откат, стираются. Однако сама точка, к
которой выполняется откат, не стирается. Например, если вы
создаете точки сохранения A, B, C и D (в этом порядке), а потом
выполняете ROLLBACK TO B, то стираются лишь точки C и D.
Перед выполнением каждого предложения INSERT, UPDATE и DELETE
создается неявная точка сохранения. Если предложение сбивается,
то выполняется откат к этой неявной точке. Обычно отменяется
лишь сбившееся предложение SQL, а не вся транзакция. Однако,
если это предложение возбудило необрабатываемое исключение, то
хост-окружение определяет, что следует отменить. Для более
подробной информации обратитесь к разделу "Необрабатываемые
исключения" в главе 5.
Когда распределенная транзакция сбивается, текст, заданный в
фразе COMMENT, помогает вам диагностировать проблему. При любом
сомнении в успехе транзакции ORACLE сохраняет этот текст в
словаре данных вместе с идентификатором транзакции. Для
дополнительной информации о распределенных транзакциях см.
документ ORACLE7 Server Application Developer's Guide.
Связанные темы
--------------
COMMIT, SAVEPOINT
Элементы языка 9-101
----------------
Атрибут %ROWCOUNT
Описание
--------
Курсоры PL/SQL имеют четыре атрибута, включая %ROWCOUNT. Эти
атрибуты, присоединяемые к имени курсора, помогают обращаться к
полезной информации курсора. Для дополнительной информации см.
раздел "Управление курсорами" в главе 4.
PL/SQL использует два типа курсоров: явные и неявные. PL/SQL
неявно объявляет курсор (с именем SQL) для любого предложения
манипулирования данными SQL, включая однострочные запросы.
Перед выполнением первого предложения SQL, не ассоциированного с
явным курсором, SQL%ROWCOUNT дает NULL. Впоследствии, этот
атрибут возвращает число строк, затронутых операцией INSERT,
UPDATE или DELETE, либо возвращенных операцией SELECT INTO.
%ROWCOUNT возвращает 0, если операция INSERT, UPDATE или DELETE
не затронула ни одной строки, или если операция SELECT INTO не
вернула ни одной строки.
В случае многострочных предложений SELECT вы можете явно
объявить курсор для обработки возвращаемых строк. После
открытия курсора, но до выполнения первой операции FETCH,
атрибут ИМЯ_КУРСОРА%ROWCOUNT дает 0. После каждой операции
FETCH этот атрибут увеличивается, если операция вернула
очередную строку данных.
Синтаксис
---------
атрибут_%rowcount ::=
--------------------- имя_курсора%ROWCOUNT -------------------------
Ключевые слова и параметры
--------------------------
имя_курсора
Этот идентификатор должен быть именем явно объявленного курсора
или именем неявного курсора (SQL). Соглашения об именах
приведены в разделе "Идентификаторы" в главе 2.
9-102 Руководство пользователя и справочник по PL/SQL
Замечания по использованию
--------------------------
Вы можете использовать атрибут %ROWCOUNT в процедурных
предложениях, но НЕ в предложениях SQL. Атрибут %ROWCOUNT
ассоциирован с каждым явным курсором. Это позволяет вам открыть
одновременно несколько курсоров и в каждый момент времени знать,
сколько строк извлечено из их активных множеств. Если курсор не
открыт, обращение к нему через атрибут %ROWCOUNT возбуждает
предопределенное исключение INVALID_CURSOR.
Если операция SELECT INTO возвращает более одной строки,
возбуждается предопределенное исключение TOO_MANY_ROWS, и
%ROWCOUNT будет иметь значение 1, но не истинное значение строк,
удовлетворяющих запросу.
Примеры
-------
Блок в следующем примере возвращает имя, номер и жалованье для
пяти самых высокооплачиваемых сотрудников:
-- доступен на диске в файле EXAMP14
DECLARE
CURSOR c1 IS
SELECT ename, empno, sal FROM emp
ORDER BY sal DESC; -- начать с наибольшего жалованья
my_ename CHAR(10);
my_empno NUMBER(4);
my_sal NUMBER(7,2);
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO my_ename, my_empno, my_sal;
EXIT WHEN (c1%ROWCOUNT > 5) OR (c1%NOTFOUND);
INSERT INTO temp VALUES (my_sal, my_empno, my_ename);
COMMIT;
END LOOP;
CLOSE c1;
END;
В следующем примре %ROWCOUNT используется, чтобы возбудить
исключение, если удалено неожиданно большое число строк.
DELETE FROM accounts WHERE status = 'BAD DEPT';
IF SQL%ROWCOUNT > 10 THEN
RAISE out_of_bounds;
END IF;
Связанные темы
--------------
CLOSE, Курсоры, DELETE, FETCH, INSERT, OPEN, SELECT INTO, UPDATE
Элементы языка 9-103
----------------
Атрибут %ROWTYPE
Описание
--------
Атрибут %ROWTYPE используется для того, чтобы объявить
переменную-запись с такой же структурой, как у строки таблицы
или обзора, или у строки, возвращаемой курсором. Такая строка
представляется записью, поля которой имеют такие же имена и типы
данных, что и столбцы таблицы или обзора, или столбцы,
возвращаемые курсором.
Этот атрибут используется в ОБЪЯВЛЕНИИ_ПЕРЕМЕННОЙ как тип данных
объявляемой переменной. Переменные, объявленные со
спецификатором %ROWTYPE, рассматриваются так же, как переменные,
объявленные с явным типом данных. Для дополнительной информации
обратитесь к разделу "Использование %ROWTYPE" в главе 2.
Синтаксис
---------
атрибут_%rowtype ::=
--------------------- идентификатор%ROWTYPE ------------------------
Ключевые слова и параметры
--------------------------
идентификатор
Этот параметр должен специфицировать имя курсора, ранее
объявленного в этом блоке. Соглашения об именах приведены в
разделе "Идентификаторы" в главе 2.
Альтернативно, этот идентификатор может именовать таблицу или
обзор в базе данных. Вы можете квалифицировать имя таблицы
именем владельца (ВЛАДЕЛЕЦ.ИМЯ). Таблица должна быть доступна
во время обработки объявления.
Замечания по использованию
--------------------------
Атрибут %ROWTYPE позволяет вам объявлять записи,
структурированные как строки данных в таблице базы данных. В
следующем примере вы объявляете запись, которая может хранить
целую строку из таблицы emp:
emp_rec emp%ROWTYPE;
Значения столбцов строки, возвращаемые предложением SELECT,
записываются в индивидуальные поля записи. Вы обращаетесь к
конкретному полю, используя квалифицированные ссылки. Например,
вы могли бы обратиться к полю deptno следующим образом:
IF emp_rec.deptno = 20 THEN ...
Вы можете присваивать значение выражения PL/SQL конкретному
полю, как показывает следующий пример:
emp_rec.sal := average * 1.15;
9-104 Руководство пользователя и справочник по PL/SQL
Есть два способа присвоить значения сразу всем полям записи.
Во-первых, PL/SQL разрешает агрегатные присваивания между целыми
записями, если их объявления ссылаются на одну и ту же таблицу
или курсор. Во-вторых, вы можете присвоить записи список
значений столбцов, используя предложения SELECT INTO или FETCH.
Имена столбцов должны появляться в том порядке, в каком они были
объявлены в предложениях CREATE TABLE или CREATE VIEW при
создании таблицы или обзора. Каждый столбец из строки,
извлекаемой операцией FETCH из курсора, ассоциированного с
атрибутом %ROWTYPE, должен именоваться простым идентификатором,
или, если это выражение, должен иметь алиас.
Примеры
-------
В следующем примере вы используете %ROWTYPE, чтобы объявить две
записи. Первая запись хранит строки, выбираемые из таблицы emp,
вторая - строки, извлекаемые курсором c1.
DECLARE
emp_rec emp%ROWTYPE;
CURSOR c1 IS SELECT deptno, dname, loc FROM dept;
dept_rec c1%ROWTYPE;
...
В следующем примере вы выбираете строку из таблицы emp в запись
%ROWTYPE:
DECLARE
emp_rec emp%ROWTYPE;
...
BEGIN
SELECT * INTO emp_rec FROM emp WHERE empno = my_empno;
IF (emp_rec.deptno = 20) AND (emp_rec.sal > 2000) THEN
...
END IF;
END;
Связанные темы
--------------
Курсоры, Переменные и константы
Элементы языка 9-105
----------------
SAVEPOINT
Описание
--------
SAVEPOINT именует и отмечает текущую точку в ходе обработки
транзакции. Точки сохранения, используемые в предложениях
ROLLBACK TO, позволяют вам отменять части транзакций, а не
полные транзакции. Для дополнительной информации обратитесь к
разделу "Обработка транзакций" в главе 4.
Синтаксис
---------
savepoint_предложение ::=
------------ SAVEPOINT ----- имя_точки_сохранения ---- ; -----------
Ключевые слова и параметры
--------------------------
имя_точки_сохранения
Этот необъявляемый идентификатор обозначает имя, которое вы
даете текущей точке в ходе вашей транзакции. Соглашения об
именах приведены в разделе "Идентификаторы" в главе 2.
Замечания по использованию
--------------------------
При откате к точке сохранения (ROLLBACK TO) все точки
сохранения, созданные после данной точки, стираются. Однако
сама точка, к которой выполняется откат, не стирается. ROLLBACK
без аргумента и COMMIT стирают все точки сохранения.
Если вы создаете точку сохранения в рекурсивной подпрограмме, на
каждом уровне рекурсивного спуска будут выполняться новые
экземпляры предложения SAVEPOINT. Однако ROLLBACK TO всегда
осуществляет откат к самой последней точке сохранения с данным
именем.
Имена точек сохранения можно повторно использовать внутри одной
и той же транзакции. Это перемещает запомненную точку
сохранения со старой позиции на текущую точку в транзакции.
Перед выполнением предложения INSERT, UPDATE или DELETE ORACLE
создает неявную точку сохранения. Если предложение сбивается,
выполняется откат к этой неявной точке. Обычно откатывается
лишь сбившееся предложение SQL, а не вся транзакция. Однако,
если предложение возбудило необрабатываемое исключение, то
хост-окружение само определяет, что подлежит откату. Для
дополнительной информации см. раздел "Необработанные исключения"
в главе 5.
Число точек сохранения, допускаемых в одной транзакции, по
умолчанию равно 5. Ваш АБД может поднять этот лимит (до 255),
увеличив значение параметра инициализации ORACLE SAVEPOINTS.
Связанные темы
--------------
COMMIT, ROLLBACK
9-106 Руководство пользователя и справочник по PL/SQL
----------------
SELECT INTO
Описание
--------
Предложение SELECT INTO извлекает данные из одной или нескольких
баз данных и помещает их в одну или несколько переменных. Для
полного описания предложения SELECT обратитесь к документу
ORACLE7 Server SQL Language Reference Manual.
Синтаксис
---------
select_into_предложение ::=
------------ , -------------------------¬
-- SELECT -- элемент_списка_select --T---------T--+-----------------
L- алиас --
-------- , --------¬
------ INTO --T-- имя_переменной -+-T-------------------------------
L--- имя_записи --------
---------- , ---------¬
--- FROM -- ссылка_на_таблицу -+- остаток_select_предложения -- ; --
где ССЫЛКА_НА_ТАБЛИЦУ имеет следующий синтаксис:
------------T----------T-----T- таблица -T-----T------------T-------
L- схема. -- L- обзор ---- L- @связьБД --
Ключевые слова и параметры
--------------------------
элемент_списка_select
Этот параметр задает значение, выбираемое предложением SELECT
INTO и помещаемое в соответствующую переменную или запись.
INTO имя_переменной
Этот параметр определяет скалярные переменные, в которые
помещаются выбираемые данные. Все переменные в списке
ИМЕН_ПЕРЕМЕННЫХ должны быть заранее объявлены.
Для каждого ЭЛЕМЕНТА_СПИСКА_SELECT должна быть соответствующая
переменная в списке ИМЕН_ПЕРЕМЕННЫХ. Кроме того, типы данных
соответствующих друг другу ЭЛЕМЕНТОВ_СПИСКА_SELECT и
ИМЕН_ПЕРЕМЕННЫХ должны быть совместимыми (или преобразуемыми
друг к другу). Для дополнительной информации обратитесь к
разделу "Преобразование типов данных" в главе 2.
Элементы языка 9-107
INTO имя_записи
Этот параметр указывает, что выбираемые данные должны быть
помещены в переменную-запись, которая была объявлена через
атрибут %ROWTYPE, как в следующем примере:
DECLARE
dept_rec dept%ROWTYPE;
...
BEGIN
SELECT deptno, dname, loc INTO dept_rec FROM dept
WHERE deptno = 20;
...
END;
С помощью конструкта ИМЯ_ЗАПИСИ.ИМЯ_СТОЛБЦА вы можете затем
обращаться к данным, возвращенным запросом для каждого столбца.
Например, department_rec.deptno ссылается на данные,
возвращенные для столбца deptno.
ссылка_на_таблицу
Таблица (или обзор) должна существовать в базе данных, с которой
вы соединены во время выполнения предложения SELECT INTO.
остаток_select_предложения
Этот параметр обозначает что угодно, что может синтаксически
законно следовать за фразой FROM в предложении SELECT.
Замечания по использованию
--------------------------
Неявный курсор SQL% и атрибуты курсора %NOTFIUND, %FOUND,
%ROWCOUNT и %ISOPEN позволяют вам получать полезную информацию о
выполнении предложения SELECT INTO. Для подробностей обратитесь
к разделу "Управление курсорами" в главе 4.
Предложение SELECT INTO должно возвращать ровно одну строку из
таблицы. Если это предложение возвращает несколько строк,
происходит следующее:
* возбуждается предопределенное исключение TOO_MANY_ROWS
* SQLCODE возвращает -1422 (код ошибки ORACLE ORA-01422)
* SQLERRM возвращает ошибку ORACLE "однострочный запрос
возвращает более одной строки"
* SQL%NOTFOUND дает FALSE
* SQL%FOUND дает TRUE
* SQL%ROWCOUNT возвращает число 1
9-108 Руководство пользователя и справочник по PL/SQL
Если не возвращено ни одной строки, происходит следующее:
* возбуждается предопределенное исключение NO_DATA_FOUND,
если предложение SELECT не обращалось к групповой функции
SQL (см. замечание ниже)
* SQLCODE возвращает +100 (код ошибки ORACLE ORA-01403)
* SQLERRM возвращает ошибку ORACLE "данные не найдены"
* SQL%NOTFOUND дает TRUE
* SQL%FOUND дает FALSE
* SQL%ROWCOUNT возвращает число 0
Групповые функции SQL, такие как AVG и SUM, ВСЕГДА возвращают
значение, даже если это значение есть NULL. Поэтому операция
SELECT, вызывающая групповую функцию, НИКОГДА не возбудит
исключение NO_DATA_FOUND, ибо какое-то значение будет всегда
"найдено".
Пример
------
SELECT ename, job, sal*1.1 INTO my_ename, my_job, wages FROM emp
WHERE empno = my_empno;
Связанные темы
--------------
Предложение присваивания, FETCH, %ROWTYPE
Элементы языка 9-109
----------------
SET TRANSACTION
Описание
--------
Предложение SET TRANSACTION позволяет вам установить транзакцию
в режиме только-чтения, что позволяет запросу опрашивать
несколько таблиц, тогда как другие пользователи одновременно
обновляют эти таблицы. Для дополнительной информации обратитесь
к разделу "Использование SET TRANSACTION" в главе 4.
Синтаксис
---------
set_transaction_предложение ::=
----------- SET TRANSACTION ---- READ ONLY ---- ; ------------------
Ключевые слова и параметры
--------------------------
READ ONLY
Этот параметр обязателен. Когда транзакция установлена в этот
режим, последующие запросы видят лишь то состояние базы данных,
которое было в момент начала транзакции. Использование этого
режима не влияет на других пользователей и другие транзакции.
Замечания по использованию
--------------------------
Предложение SET TRANSACTION должно быть первым предложением SQL
в транзакции и может встретиться в транзакции лишь один раз.
Далее, в этом режиме транзакции можно использовать только
предложения SELECT, COMMIT и ROLLBACK. Например, предложение
INSERT или DELETE возбудит исключение.
Пример
------
COMMIT;
SET TRANSACTION READ ONLY;
SELECT ... FROM emp WHERE ...
SELECT ... FROM dept WHERE ...
SELECT ... FROM emp WHERE ...
COMMIT;
Связанные темы
--------------
COMMIT, ROLLBACK, SAVEPOINT
9-110 Руководство пользователя и справочник по PL/SQL
----------------
Курсор SQL
ORACLE неявно открывает курсор для обработки каждого предложения
SQL, не ассоциированного с явным курсором. PL/SQL позволяет вам
обращаться к самому последнему неявно открывавшемуся курсору как
к курсору "SQL". Курсор SQL имеет четыре атрибута: %NOTFOUND,
%FOUND, %ROWCOUNT и %ISOPEN. В сочетании с именем курсора (SQL)
эти атрибуты дают информацию о выполнении последней операции
INSERT, UPDATE, DELETE и SELECT INTO. Для дополнительной
информации см. раздел "Управление курсорами" в главе 4.
Синтаксис
---------
sql_курсор ::=
-------------- SQL ----------T-- %NOTFOUND --T----------------------
+-- %FOUND -----+
+-- %ROWCOUNT --+
L-- %ISOPEN -----
Ключевые слова и параметры
--------------------------
%NOTFOUND
Перед выполнением первого предложения SQL, не ассоциированного с
явным курсором, SQL%NOTFOUND дает NULL. Впоследствии, этот
атрибут дает TRUE, если операция INSERT, UPDATE или DELETE не
затронула ни одной строки, или если операция SELECT INTO не
вернула ни одной строки. В последнем случае возбуждается
предопределенное исключение NO_DATA_FOUND, если в операции
SELECT INTO не использовалась групповая функция SQL. Однако,
если операция SELECT INTO вызывает групповую функцию SQL,
исключение NO_DATA_FOUND никогда не возбуждается, ибо групповые
функции всегда возвращают значение (даже пустое). В таких
случаях случае SQL%NOTFOUND всегда дает FALSE.
%FOUND
SQL%FOUND логически противоположен атрибуту SQL%NOTFOUND. Перед
выполнением первого предложения SQL, не ассоциированного с явным
курсором, SQL%FOUND дает NULL. Впоследствии, этот атрибут дает
TRUE, если операция INSERT, UPDATE или DELETE затронула хотя бы
одну строку, или если операция SELECT INTO вернула хотя бы одну
строку. В противном случае SQL%FOUND дает FALSE.
%ROWCOUNT
SQL%ROWCOUNT возвращает число строк, затронутых операцией
INSERT, UPDATE или DELETE либо возвращенных операцией SELECT
INTO.
%ISOPEN
ORACLE автоматически закрывает курсор SQL после выполнения
ассоциированного с ним предложения SQL. Как результат, атрибут
SQL%ISOPEN всегда дает FALSE.
Элементы языка 9-111
Замечания по использованию
--------------------------
Вы можете использовать атрибуты курсора в процедурных
предложениях, но НЕ в предложениях SQL. Перед выполнением
первого предложения SQL, не ассоциированного с явным курсором,
все атрибуты неявного курсора дают NULL.
Значения атрибутов курсора SQL всегда ссылаются на последнее
выполненное предложение SQL, не ассоциированное с явным
курсором, сколь бы давно и где бы это предложение не было
выполнено. Не забывайте, что SQL% всегда подразумевает именно
последнее такое предложение, даже если оно исполнялось в другой
сфере (скажем, во вложенном блоке). Поэтому, если вы хотите
сохранить значение такого атрибута для последующего
использования, немедленно присвойте его булевской переменной.
Примеры
-------
В следующем примере %NOTFOUND используется, чтобы вставить
строку в случае неуспеха обновления:
UPDATE emp SET sal = sal * 1.05 WHERE empno = my_empno;
IF SQL%NOTFOUND THEN
INSERT INTO emp VALUES (my_empno, my_ename, ...);
END IF;
В следующем примере SQL%ROWCOUNT используется, чтобы предпринять
действие, если удалено более 100 строк:
DELETE FROM parts WHERE status = 'OBSOLETE';
IF SQL%ROWCOUNT > 100 THEN
... -- удалено больше 100 строк
END IF;
Связанные темы
--------------
%FOUND, %NOTFOUND, %ISOPEN, %ROWCOUNT
9-112 Руководство пользователя и справочник по PL/SQL
----------------
SQLCODE
Описание
--------
Функция SQLCODE возвращает номер, ассоциированный с последним
возбужденным исключением. Эту функцию имеет смысл использовать
только в обработчике исключений. Вне обработчика SQLCODE всегда
возвращает 0.
Для внутренне определенных исключений, SQLCODE возвращает номер
ошибки ORACLE, передавшей управление обработчику. Этот номер
отрицателен, исключая случай ошибки ORACLE "no data found",
когда SQLCODE возвращает +100. Для пользовательских исключений,
SQLCODE возвращает +1, если вы не использовали прагму
EXCEPTION_INIT, чтобы ассоциировать ваше исключение с номером
ошибки ORACLE; в этом случае SQLCODE возвращает этот номер
ошибки. Для дополнительной информации обратитесь к разделу
"Использование SQLCODE и SQLERRM" в главе 5.
Синтаксис
---------
функция_sqlcode ::=
------------------------ SQLCODE -----------------------------------
Замечания по использованию
--------------------------
Нельзя использовать функцию SQLCODE непосредственно в
предложениях SQL. Например, следующее предложение НЕКОРРЕКТНО:
INSERT INTO errors VALUES (SQLCODE, ...);
Вместо этого вы должны присвоить значение этой функции локальной
переменной, а затем использовать эту переменную в вашем
предложении SQL, как показано ниже:
DECLARE
my_sqlcode NUMBER;
BEGIN
...
EXCEPTION
...
WHEN OTHERS THEN
my_sqlcode := SQLCODE;
INSERT INTO errors VALUES (my_sqlcode, ...);
END;
Функция SQLCODE особенно полезна в обработчике исключений
OTHERS, потому что она позволяет установить, какое внутреннее
исключение было возбуждено.
Связанные темы
--------------
Исключения, SQLERRM
Элементы языка 9-113
----------------
SQLERRM
Описание
--------
Функция SQLERRM возвращает сообщение об ошибке, ассоциированное
с указанным номером ошибки, или, если аргумент опущен, с текущим
значением SQLCODE. SQLERRM без аргумента имеет смысл только в
обработчике исключений. Вне обработчика, т.е. если не
возбуждено никакое исключение, SQLERRM возвращает сообщение
ORA-0000: normal, successful completion
Для внутренне определенных исключений SQLERRM возвращает
сообщение, ассоциированное с возникшей ошибкой ORACLE. Это
сообщение начинается с кода ошибки ORACLE.
Для пользовательских исключений SQLERRM возвращает сообщение
User-Defined Exception
если вы не использовали прагму EXCEPTION_INIT, чтобы
ассоциировать ваше исключение с номером ошибки ORACLE; в этом
случае SQLERRM возвращает соответствующее сообщение об ошибке.
Для дополнительной информации обратитесь к разделу
"Использование SQLCODE и SQLERRM" в главе 5.
Синтаксис
---------
функция_sqlerrm ::=
------------------ SQLERRM ---T--------------------T----------------
L-- (номер_ошибки) ---
Ключевые слова и параметры
--------------------------
номер_ошибки
Этот аргумент должен быть действительным номером ошибки ORACLE.
Для перечня номеров ошибок ORACLE обратитесь к документу ORACLE7
Server Messages and Codes Manual.
9-114 Руководство пользователя и справочник по PL/SQL
Замечания по использованию
--------------------------
Вы можете передать функции SQLERRM номер ошибки; в этом случае
SQLERRM возвратит сообщение, ассоциированное с этим номером
ошибки. Номер ошибки, передаваемый SQLERRM, должен быть
отрицателен. Нулевой код, передаваемый SQLERRM, всегда
возвращает сообщение
ORA-0000: normal, successful completion
Передача SQLERRM положительного номера ошибки (за исключением
+100) всегда возвратит сообщение
User-Defined Exception
а передача SQLERRM кода +100 возвратит сообщение
ORA-01403: no data found
Нельзя использовать функцию SQLERRM непосредственно в
предложениях SQL. Например, следующее предложение НЕКОРРЕКТНО:
INSERT INTO errors VALUES (SQLERRM, ...);
Вместо этого вы должны присвоить значение этой функции локальной
переменной, а затем использовать эту переменную в вашем
предложении SQL, как показано ниже:
DECLARE
my_sqlerrm CHAR(100);
...
BEGIN
...
EXCEPTION
...
WHEN OTHERS THEN
my_sqlerrm := SUBSTR(SQLERRM, 1, 150);
INSERT INTO errors VALUES (my_sqlerrm, ...);
END;
Строковая функция SUBSTR() гарантирует, что возможное усечение
при присваивании переменной my_sqlerrm не возбудит исключения
VALUE_ERROR. Функция SQLERRM особенно полезна в обработчике
исключений OTHERS, потому что она позволяет установить, какое
внутреннее исключение было возбуждено.
Связанные темы
--------------
Исключения, SQLCODE
Элементы языка 9-115
----------------
Атрибут %TYPE
Описание
--------
Атрибут %TYPE служит для того, чтобы объявить переменную с тем
же типом, что у столбца таблицы или обзора, либо у ранее
объявленной переменной или константы PL/SQL. Этот атрибут
используется как тип данных в ОБЪЯВЛЕНИИ_ПЕРЕМЕННОЙ или
ОБЪЯВЛЕНИИ_КОНСТАНТЫ. Переменные или константы, объявленные со
спецификатором типа %TYPE, рассматриваются так, как если бы они
были объявлены с явным именем типа. Для дополнительной
информации см. раздел "Использование %TYPE" в главе 2.
Синтаксис
---------
атрибут_%type ::=
----------T-- имя_переменной ------------------------T- %TYPE ------
L---T---------------T--- таблица.столбец ---
L-- владелец. ---
Ключевые слова и параметры
--------------------------
имя_переменной
Этот идентификатор должен быть именем переменной или константы
PL/SQL, ранее объявленной в данном блоке. Соглашения об именах
приведены в разделе "Идентификаторы" в главе 2.
владелец.
Этот параметр должен ссылаться на владельца таблицы или обзора,
который должен быть доступен в момент обработки объявления.
таблица.столбец
Этот параметр должен ссылаться на столбец таблицы (или обзора),
существующей в базе данных, к которой вы присоединены в момент
обработки объявления.
Замечания по использованию
--------------------------
Атрибут %TYPE особенно полезен при объявлении переменных,
ссылающихся на столбцы базы данных. Вы можете сослаться на
таблицу и столбец, либо на владельца, таблицу и столбец. Кроме
того, объявление с атрибутом %TYPE может включать фразу
инициализации, как показывает следующий пример:
my_comm scot.emp.comm%TYPE DEFAULT 0.0;
9-116 Руководство пользователя и справочник по PL/SQL
Однако ограничение столбца NOT NULL НЕПРИМЕНИМО к переменным,
объявленным через атрибут %ROWTYPE. В следующем примере,
несмотря на то, что столбец базы данных empno определен как NOT
NULL, вы можете присваивать пустые значения переменной my_empno:
DECLARE
my_empno emp.empno%TYPE;
...
BEGIN
my_empno := NULL; -- это работает
...
END;
Связанные темы
--------------
%ROWTYPE, переменные и константы
Элементы языка 9-117
----------------
UPDATE
Описание
--------
UPDATE изменяет значения указанных столбцов в одной или
нескольких строках таблицы или представления. Для полного
описания предложения UPDATE обратитесь к документу ORACLE7
Server SQL Language Reference Manual.
Синтаксис
---------
update_предложение ::=
----------- UPDATE ----- ссылка_на_таблицу -----T---------T----------
L- алиас --
------------------------- , --------------------------¬
-- SET --T-- имя_столбца --- = ---T-- sql_выражение ----------T-+--T-
¦ L-- (однострочное_select) --- ¦
¦ ------- , ------¬ ¦
L- ( -- имя_столбца -+- ) --- = --- (select_предложение) --
---------T--------------------------------------------T--- ; --------
L-- WHERE --T-------- условие_поиска --------+
L-- CURRENT OF --- имя_курсора ---
где ССЫЛКА_НА_ТАБЛИЦУ имеет следующий синтаксис:
------------T----------T-----T- таблица -T-----T------------T-------
L- схема. -- L- обзор ---- L- @связьБД --
Ключевые слова и параметры
--------------------------
ссылка_на_таблицу
Таблица (или обзор), специфицируемая ССЫЛКОЙ_НА_ТАБЛИЦУ, должна
существовать в базе данных, с которой вы соединены во время
выполнения предложения UPDATE, и вы должны иметь привилегии
UPDATE.
алиас
Это другое (обычно краткое) имя таблицы или обзора, обычно
используемое в фразе WHERE.
имя_столбца
Этот параметр указывает обновляемый столбец. Он должен быть
именем столбца в таблице (или обзоре), указываемой
ССЫЛКОЙ_НА_ТАБЛИЦУ. Имена столбцов не должны повторяться в
списке ИМЕН_СТОЛБЦОВ. Эти имена не обязаны появляться в
предложении UPDATE в том порядке, в каком они определены в
таблице или обзоре.
9-118 Руководство пользователя и справочник по PL/SQL
SET имя_столбца = sql_выражение
Этот параметр присваивает столбцу значение SQL_ВЫРАЖЕНИЯ. Терм
SQL_ВЫРАЖЕНИЕ обозначает здесь любое действительное выражение
SQL.
Если SQL_ВЫРАЖЕНИЕ содержит ссылки на столбцы обновляемой
таблицы, то эти ссылки разрешаются в контексте текущей строки
таблицы. Справа от знака равенства будут использоваться старые
значения столбцов.
В следующем примере вы увеличиваете жалованье каждого сотрудника
на 10%. Исходное значение столбца sal умножается на 1.1, после
чего результат записывается обратно в столбец sal.
UPDATE emp SET sal = sal * 1.1;
SET имя_столбца = однострочное_select
Эта фраза присваивает значение, извлеченное из базы данных
однострочным предложением SELECT, одиночному столбцу из списка
ИМЕН_СТОЛБЦОВ.
Синтаксис конструкта ОДНОСТРОЧНОЕ_SELECT совпадает с синтаксисом
SELECT_INTO_ПРЕДЛОЖЕНИЯ, который определен в разделе "SELECT
INTO" выше в этой главе, с той разницей, что данное предложение
не может иметь фразы INTO и должно возвращать ровно одну строку
и ровно один столбец.
SET (имя_столбца, ...) = select_предложение
Эта фраза присваивает значения, извлеченные из базы данных
предложением SELECT, столбцам из списка ИМЕН_СТОЛБЦОВ.
SELECT_ПРЕДЛОЖЕНИЕ должно возвращать ровно одну строку,
включающую все столбцы, перечисленные в скобках слева от знака
равенства.
Синтаксис конструкта SELECT_ПРЕДЛОЖЕНИЕ совпадает с синтаксисом
SELECT_INTO_ПРЕДЛОЖЕНИЯ, который определен в разделе
"SELECT INTO" выше в этой главе, с той разницей, что данное
предложение не может иметь фразы INTO.
Значения столбцов, возвращенные SELECT_ПРЕДЛОЖЕНИЕМ,
присваиваются столбцам по порядку, т.е. значение первого столбца
присваивается первому столбцу из списка ИМЕН_СТОЛБЦОВ, второго -
второму, и т.д.
В следующем коррелированном запросе, столбец item_id получает
значение, которое хранится в столбце item_id_num, а столбец
price получает значение из столбца item_price.
UPDATE inventory inv -- алиас
SET (item_id, price) = (SELECT item_id_num, item_price
FROM item_table
WHERE item_name = inv.item_name);
Элементы языка 9-119
WHERE условие_поиска
УСЛОВИЕ_ПОИСКА описывает критерий выбора обновляемых строк
таблицы. Обновляются лишь те строки, которые удовлетворяют
УСЛОВИЮ_ПОИСКА. Если оно опущено, обновляются все строки.
WHERE CURRENT OF имя_курсора
Этот параметр ссылается на последнюю строку, извлеченную
предложением FETCH, ассоциированным с курсором ИМЯ_КУРСОРА.
Указанный курсор должен был быть объявлен с фразой FOR UPDATE
OF, и должен быть открыт и позиционирован на строку. Если
курсор не открыт, фраза WHERE CURRENT OF приведет к ошибке.
Если курсор открыт, но еще не выполнялась ни одна операция FETCH
или последняя операция FETCH не возвратила строку, то
возбуждается предопределенное исключение NO_DATA_FOUND.
Замечания по использованию
--------------------------
Предложение UPDATE ... WHERE CURRENT OF ИМЯ_КУРСОРА можно
использовать после операции FETCH на открытом курсоре, при
условии, что соответствующий запрос был объявлен с фразой FOR
UPDATE OF. Предложение UPDATE ... WHERE CURRENT OF ИМЯ_КУРСОРА
обновляет текущую строку, т.е. строку, только что возвращенную
операцией FETCH.
Неявный курсор SQL и атрибуты курсора %NOTFOUND, %FOUND,
%ROWCOUNT и %ISOPEN позволяют вам получать полезную информацию о
выполнении предложения UPDATE. Для подробностей обратитесь к
разделу "Управление курсорами" в главе 4.
Предложение UPDATE может обновить одну или несколько строк, но
может и не обновить ни одной строки. Если это предложение
обновляет одну или несколько строк, происходит следующее:
* SQL%NOTFOUND дает FALSE
* SQL%FOUND дает TRUE
* SQL%ROWCOUNT возвращает число обновленных строк
Если не обновлено ни одной строки, происходит следующее:
* SQL%NOTFOUND дает TRUE
* SQL%FOUND дает FALSE
* SQL%ROWCOUNT возвращает число 0
Примеры
-------
В следующем примере, 10-процентная прибавка дается всем
аналитикам и клеркам в отделе 20:
UPDATE emp SET sal = sal * 1.10
WHERE (job = 'ANALYST' OR job = 'CLERK') AND deptno = 20;
В следующем примере изменяется как должность, так и жалованье
конкретного сотрудника:
UPDATE emp SET job = 'ANALYST', sal = sal * 1.15
WHERE ename = 'FORD';
9-120 Руководство пользователя и справочник по PL/SQL
----------------
Переменные и константы
Описание
--------
Вы можете объявлять переменные и константы в декларативной части
любого блока PL/SQL, подпрограммы или пакета. Объявление
переменной распределяет память для хранения значений этой
переменной, определяет ее тип данных и дает имя переменной, что
позволяет обращаться к ее значению. Объявление может также
присвоить начальное значение переменной и/или ограничение NOT
NULL. Для дополнительной информации см. раздел "Объявления и
присваивания" в главе 2.
Синтаксис
---------
объявление_переменной ::=
-------- имя_переменной -----T--------------T------------------------
L-- CONSTANT ---
------T-- имя_типа --------------T-----T--------------T---------------
+-- переменная%TYPE -------+ L-- NOT NULL ---
+-- таблица.столбец%TYPE --+
L-- таблица%ROWTYPE --------
--------T---------------------------------------T----- ; ------------
L--T---- := -----T-- plsql_выражение ----
L-- DEFAULT ---
Ключевые слова и параметры
--------------------------
имя_переменной
Этот параметр является именем, которое вы даете переменной или
константе. Соглашения об именах приведены в разделе
"Идентификаторы" в главе 2.
CONSTANT
Ключевое слово CONSTANT обозначает, что вы объявляете константу,
т.е. начальное значение переменной нельзя модифицировать. Для
константы вы должны предоставить PLSQL_ВЫРАЖЕНИЕ, которое
инициализирует ее значение.
имя_типа
Этот параметр специфицирует тип данных, хранящихся в переменной
или константе. Для дополнительной информации см. раздел "Типы
данных" в главе 2.
Элементы языка 9-121
%TYPE
Атрибут %TYPE представляет тип данных переменной, константы или
столбца базы данных.
таблица.столбец
Ссылка на таблицу и столбец базы данных, которые должны быть
доступны в момент обработки объявления.
таблица
Ссылка на таблицу базы данных, которая должна быть доступна в
момент обработки объявления.
%ROWTYPE
Атрибут %ROWTYPE объявляет переменную-запись с полями, имеющими
такие же имена и типы данных, что и столбцы таблицы или столбцы
строки, извлекаемой курсором.
NOT NULL
NOT NULL объявляет, что переменная или константа не может иметь
пустого значения. При попытке присвоить объекту значение NULL
возбуждается предопределенное исключение VALUE_ERROR. Если вы
используете фразу NOT NULL в объявлении переменной, то за ней
должна следовать фраза инициализации.
plsql_выражение
Это - произвольно сложное выражение, которое используется для
инициализации переменной или константы. Его синтаксис определен
в разделе "Выражения" выше в этой главе.
Тип данных PLSQL_ВЫРАЖЕНИЯ должен быть совместим с типом данных
объявляемой переменной или константы (либо преобразуем в него).
Для дополнительной информации обратитесь к разделу
"Преобразование типов данных" в главе 2.
9-122 Руководство пользователя и справочник по PL/SQL
Замечания по использованию
--------------------------
Переменные и константы инициализируются при каждом входе в блок
или подпрограмму. По умолчанию, т.е. если PLSQL_ВЫРАЖЕНИЕ не
включено в объявление переменной, начальное значение такой
переменной есть NULL.
Как общие, так и личные переменные и константы, объявленные в
спецификации пакета, инициализируются лишь один раз на всю
сессию.
Инциализирующее PLSQL_ВЫРАЖЕНИЕ обязательно при объявлении
переменных NOT NULL и при объявлении констант.
Нельзя использовать атрибут %ROWTYPE при объявлении константы.
Если %ROWTYPE используется в объявлении переменной, то
инициализирующее выражение не допускается.
Примеры
-------
Ниже приведено несколько примеров объявлений переменных и
констант:
salary REAL;
invalid BOOLEAN;
minimum_balance CONSTANT := 10.00;
acct_id INTEGER NOT NULL := 1000;
В следующем примере атрибут %TYPE предоставляет тип данных
столбца:
my_ename emp.ename%TYPE;
Связанные темы
--------------
Предложение присваивания, Выражения, %ROWTYPE, %TYPE