----------------------------------------------------------------



                                   ЧАСТЬ 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