ВВЕДЕНИЕ В PL SQL

Знаковое множество

Программа на PL/SQL представляет собой набор текстовых строк, за­писанных с использованием определенного множества знаков. Знако­вое множество PL/SQL включает:

    прописные и строчные буквы латинского алфавита А .. Z, а .. z;

    цифры 0 ..9;

    табулятор, пробел, возврат каретки;

    символы () + - * / <> = ! ~ ; : . ‘ @ % , “ # $ ^ & _ | {} ? []

PL/SQL не учитывает различия между буквами верхнего и нижнего регистров, поэтому буквы нижнего регистра эквивалентны соответ­ствующим буквам верхнего регистра, кроме случаев их употребления в строковых и символьных литералах.

Лексемы

Строка исходного текста PL/SQL состоит из символьных цепочек, на­зываемых лексемами, которые можно разбить на следующие классы:

    ограничители (простые и составные символы);

    идентификаторы, которые включают зарезервированные слова;

    литералы;

    комментарии.
Например, строка

bonus   :=  salary  *   0.10;     --  расчет  премиальных содержит следующие лексемы:

    идентификаторы bonus и salary

    составной символ-ограничитель :=

    простые символы-ограничители * и ;

    числовой литерал 0.10

    комментарий -- расчет премиальных

Для облегчения восприятия лексемы можно разделять пробелами. Смежные идентификаторы обязательно должны разделяться пробе­лами или ограничителем.

Однако нельзя включать пробелы в лексемы, не являющиеся строко­выми литералами или комментариями. Например, нельзя расщепить составной символ присваивания (:=).

 

Ограничители

Ограничитель - это простой или составной символ, который имеет спе­циальное значение в PL/SQL. Например, ограничители используются для обозначения арифметических операций: сложения, вычитания и др.

 

Простые символы

Простой символ представляет собой один знак; ниже приводится спи­сок простых символов.

+

операция сложения

-

операция вычитания или унарный минус

*

операция умножения

/

операция деления

=

операция отношения

<

операция отношения

>

операция отношения

(

левый ограничитель выражения или списка

)

правый ограничитель выражения или списка

;

символ завершения оператора

%

признак атрибута

,

разделитель элементов в списке

.

селектор компонента

@

признак удаленного доступа

ограничитель строки символов

ограничитель идентификатора в кавычках

:

признак переменной базового языка

 

Составные символы

Составные символы состоят из двух знаков; ниже приводится их спи­сок.

**

операция возведения в степень

<>

операция отношения

! =

операция отношения

~=

операция отношения

^=

операция отношения

<=

операция отношения

>=

операция отношения

: =

операция присваивания

=>

операция связывания

..

операция диапазона

||

операция конкатенации

<<

левый ограничитель метки

>>

правый ограничитель метки

--

признак однострочного комментария

/*

левый ограничитель многострочного комментария

*/

правый ограничитель многострочного комментария

 


Идентификаторы

Идентификаторы используются в PL/SQL для именования программ­ных объектов и модулей, которые включают константы, переменные, исключения, курсоры, курсорные переменные, подпрограммы и па­кеты. Ниже приводится несколько примеров.

X

 t2

phone#

credit_limit

LastName

oracle$number

Идентификатор начинается с буквы, за которой могут следовать бу­квы, цифры, знаки доллара, подчеркивания или номера (#). Другие знаки, например, дефис, наклонная черта, пробел, - запрещены, как показано в следующих примерах:

 

mine&yours

-- запрещенный амперсанд

debit-amount

-- запрещенный дефис

on/off

-- запрещенная наклонная черта

user id

-- запрещенный пробел

 

Следующие примеры показывают, что знак доллара, подчеркивания или номера может встречаться несколько раз подряд или быть завер­шающим знаком в идентификаторе:

money$$$tree

SN##

try_again_

В идентификаторах могут использоваться и прописные, и строчные буквы в произвольном порядке. PL/SQL не учитывает регистр букв, кроме случаев их употребления в строковых и символьных литералах. Таким образом, если идентификаторы различаются лишь регистром соответствующих букв, PL/SQL будет считать их одинаковыми, как показывает следующий пример:

lastname

LastName  то же, что и lastname

LASTNAME -- то же, что и lastname, а также LastName

Идентификатор не может быть длиннее 30 символов. При этом учи­тывается каждый символ, включая знаки доллара, подчеркивания и номера. Например, PL/SQL считает различными следующие иденти­фикаторы:

lastname

last_name

Идентификаторы должны быть содержательными. Поэтому избегайте таких непонятных сокращений, как срт. Используйте имена, имеющие смысл, например, cost.per.thousand.

Зарезервированные слова

Некоторые идентификаторы, называемые зарезервированными словами,имеют специальное назначение в синтаксисе PL/SQL и не могут быть переопределены. Например, слова begin и end, которые обрамляют исполняемый раздел блока или подпрограммы, вляются зарезервиро­ванными. Как показано в следующем примере, если вы попытаетесь переопределить зарезервированное слово, то получите сообщение об ошибке компиляции.

DECLARE

end BOOLEAN;  — неправильно: вызовет ошибку компиляции

Зарезервированное слово, однако, может быть частью идентифика­тора, как показывает следующий пример:

DECLARE

end_of_game BOOLEAN;     допустимо

 

Часто зарезервированные слова записываются прописными буквами, чтобы они четко выделялись при чтении. Однако, как и другие иден­тификаторы в PL/SQL, эти слова могут быть записаны строчными бу­квами или включать и прописные, и строчные буквы в произвольном порядке.

Идентификаторы в кавычках

 

В дополнение к обычным идентификаторам, PL/SQL предоставляет возможность использовать идентификаторы, заключенные в двойные кавычки. Необходимость в таких идентификаторах возникает редко, но иногда они могут оказаться полезными. Они могут содержать лю­бую цепочку воспроизводимых при печати символов, включая про­белы, но исключая двойные кавычки. Так, следующие идентификаторы вполне допустимы:

"X+Y"

"last name"

"on/off  switch"

"employee(s)"

"***  header  info  ***"

Максимальная длина идентификатора в кавычках составляет 30 симво­лов, не считая самих кавычек. В качестве идентификаторов в кавычках можно использовать и зарезервированные слова PL/SQL, но это счи­тается плохим стилем программирования.

Некоторые зарезервированные слова PL/SQL не являются таковыми в SQL. Например, зарезервированное в PL/SQL слово type может быть использовано в команде create table в качестве имени столбца базы данных. Однако, если команда SQL в вашей программе обратится к этому столбцу, вы получите сообщение об ошибке компиляции, как показывает следующий пример:

SELECT acct,   type,   bal   INTO   ...     вызовет ошибку компиляции

Эту ошибку можно исправить, заключив в кавычки записанное про­писными буквами имя столбца, как показано ниже:

SELECT acct,   "TYPE",   bal   INTO   ...

 

Имя столбца не может быть записано строчными буквами или включать буквы разных регистров (если, конечно, оно не было именно так определено в команде create table при помощи двойных кавы­чек). Например, следующая команда является неправильной:

SELECT acct,   "type",  bal  INTO  ...   — вызовет ошибку компиляции

Другой способ - создать представление, в котором злополучный стол­бец переименовывается, и в последующих командах SQL использовать представление вместо основной таблицы.

 

Литералы

Литерал - это явно заданное числовое, символьное, строковое или булево значение, не обозначенное идентификатором. В качестве при­меров можно привести числовой литерал 147 и булев литерал false.

Числовые литералы в арифметических выражениях могут быть использованы два типа числовых литералов: целые и действительные.

 

Целочисленный литерал - это целое число без десятичной точки, возможно, со знаком. Примеры записи целочисленных литералов:

030        6        -14        0        +32767

 

Действительный числовой литерал - это целое или дробное число с десятичной точкой и, возможно, со знаком. Примеры записи действи­тельных числовых литералов:

6.6667   0.0   -12.0   3.14159   +8300.00   .5   25.

 

Такие числа, как 12.0 и 25., в PL/SQL рассматриваются как действи­тельные, хотя они и имеют целочисленные значения.

Числовые литералы не могут содержать знаков доллара или запятых, но могут быть записаны в математической нотации. Число может за­канчиваться буквой Е (или е), за которой сразу же следует целое число с возможным знаком. Примеры числовых литералов в математической нотации:

2Е5        1.0Е-7        3.14159е0        -1Е38        -9.5е-3

 

Букву Е здесь следует читать как «умножить на десять в степени». Дру­гими словами, число после буквы Е - это степень десяти, на которую надо умножить число перед буквой Е, что иллюстрируется следующим примером (** - это операция возведения в степень):

5ЕЗ  =  5   *   10**3  =  5   *   1000  =  5000

 

Число после буквы Е можно интерпретировать также как число разря­дов, на которое нужно сдвинуть десятичную точку. В предыдущем при­мере подразумеваемая десятичная точка была сдвинута на три разряда вправо; в следующем примере она сдвигается на три разряда влево:

5Е-3  =   5*10**-3  =   5   *   0.001   =   0.005

 

Символьные литералы

Символьный литерал - это отдельный символ, заключенный в апо­строфы. Примеры символьных литералов

'Z'        '%'       '7' '       ' 'z'       '('

 

Символьный литерал может включать любой воспроизводимый при печати символ из знакового множества PL/SQL: букву, цифру, пробел или специальный символ.

В символьных литералах PL/SQL различает буквы верхнего и нижнего регистров. Например, литералы 'z' и 'Z' PL/SQL будет считать различ­ными.

Символьные литералы '0'..'9' не являются эквивалентом соответ­ствующих целочисленных литералов, тем не менее, эти символьные ли­тералы можно использовать в арифметических выражениях, поскольку они могут быть неявно преобразованы в целые числа.

Строковые литералы

Символьное значение может быть обозначено идентификатором или же явно записано как строковый литерал, т.е. как цепочка из нуля или нескольких символов, заключенная в апострофы. Примеры строковых литералов:

'Hello, world!'

'Здравствуй, мир!'

'10-NOV-91'

'Не said "Life is like licking honey from a thorn."'

'$1,000,000'

Все строковые литералы, кроме пустой строки (''), принадлежат к типу CHAR.

Если апострофы ограничивают строковые литералы, то как изобра­зить в строке сам апостроф? Как показывает следующий пример, нужно записать его два раза подряд (но это не двойные кавычки):

'Don''t  leave without  saving your work.'

 

В строковых литералах PL/SQL различает буквы верхнего и нижнего регистров. Например, следующие литералы считаются различными:

'baker' 'Baker'

Булевы литералы

Булевы литералы - это предопределенные значения true и false, a также пустое значение null, которое применяется в случаях, когда на­стоящее значение отсутствует, неизвестно или неприменимо. Имейте в виду, что булевы литералы - это значения сами по себе, а не символь­ные строки. Например, true является значением в той же мере, что и число 25.

 

Комментарии

Компилятор PL/SQL игнорирует комментарии, но вам не стоит этого делать. Добавление комментариев в вашу программу делает ее более понятной и легкой для чтения. Вообще говоря, комментарии должны описывать назначение и возможное применение каждого участка про­граммы. PL/SQL поддерживает два стиля комментирования: одно­строчный и многострочный.

Однострочный комментарий

Однострочный комментарий начинается двойным дефисом (--) где-нибудь в строке и продолжается до конца строки. Примеры одностроч­ных комментариев:

--  начало  обработки

SELECT  sal   INTO  salary  FROM emp     --  выборка  текущего  оклада

WHERE  empno  =   emp_id;

bonus   :=  salary  *   0.15;     --  расчет  премиальных

Обратите внимание, что комментарий можно встроить внутрь опера­тора, разместив его в конце строки.

При тестировании или отладке вам может понадобиться отключить действия в строке программы. Следующий пример показывает, как можно «закомментировать» строку:

--  DELETE  FROM emp WHERE  comm  IS  NULL;

Многострочный комментарий

Многострочный комментарий начинается с комбинации знаков (/*), заканчивается знаками (* /) и может занимать любое число строк. При­меры многострочных комментариев:

BEGIN

/* Начисление 15%-ной премии лучшим сотрудникам. */

IF rating > 90 THEN

bonus := salary * 0.15 /* размер премии

      зависит от оклада */

ELSE

bonus := 0; END IF;

/* Следующий оператор вычисляет площадь круга, используя число пи, которое выражает отношение длины окружности к диаметру. */

area := pi * radius**2;

Используя ограничители многострочного комментария, можно заком­ментировать целый участок программы, как показывает следующий пример:

 

/*

LOOP

            FETCH c1 INTO emp_rec;

            EXIT WHEN c1%NOTFOUND;

           

END LOOP

*/

Ограничения

Вложенные комментарии не допускаются. Не разрешается также ис­пользовать однострочные комментарии в блоке PL/SQL, который бу­дет динамически обрабатываться программой для предкомпилятора Oracle, где символы «конец-строки» игнорируются. В результате одно­строчный комментарий захватит не только оставшуюся часть строки, но и продолжится до конца блока. В таких ситуациях используйте мно­гострочный комментарий.

 

Выражения и сравнения

Выражения строятся из операндов и операций. Операнд - это пере­менная, константа, литерал или же вызов функции, результат которой участвует в выражении. Пример простого арифметического выраже­ния:

-X   /   2   +   3

Унарные операции, например, операция «унарный минус» (-), произ­водят действия над одним операндом; бинарные операции, такие, как операция деления (/), выполняют действия над двумя операндами. Тер­нарных операций в PL/SQL нет.

В простейшей форме выражение состоит из единственной переменной, которая предоставляет свое значение непосредственно. PL/SQL вычи­сляет выражение (находит его текущее значение), применяя указанные операции в определенном порядке к значениям операндов. Вычисле­ние выражения всегда приводит к однозначному результату, принад­лежащему к некоторому типу данных. PL/SQL определяет тип данных, анализируя выражение и контекст, в котором оно появляется.

Старшинство операций

Операции в выражении выполняются в определенном порядке, в за­висимости от их старшинства (приоритета). В таблице приведен установленный по умолчанию порядок выполнения операций, кото­рые отсортированы здесь по убыванию приоритета (в первой строке указаны наиболее приоритетные операции).

 

Операция

Смысл

**, NOT

возведение   в   степень,   логическое отрицание

+,-

унарный плюс, унарный минус

*, /

умножение, деление

+, -, ||

сложение, вычитание, конкатенация

=, !=, <, >, <=, >=, IS NULL, LIKE, BETWEEN, IN

сравнение

AND

логическое И

OR

логическое ИЛИ

Операции с более высоким старшинством применяются первыми. Например, результатом вычисления обоих выражений, приведенных ниже, будет значение 8, поскольку деление выше по старшинству, чем сложение:

5+12/4 12/4+5

Порядок применения операций с одинаковым старшинством в PL/SQL не установлен.

Управлять последовательностью вычислений можно при помощи ско­бок. Например, значением следующего выражения будет 7, а не 11, поскольку скобки изменяют порядок вычислений, определяемый по умолчанию старшинством операций.

(8   +   6)    /   2

Следующий пример показывает, что скобками всегда можно восполь­зоваться для большей выразительности, даже если в них нет необходи­мости:

(salary  *   0.05)   +   (commission  *   0.25)

 

Логические операции

Логические операции and, or и not подчиняются трехзначной логике, и результат их применения определяется таблицами истинности, приве­денными в таблице. Операции and и or - бинарные, a not унарная.


 

X

У

xANDy

xORy

NOTx

TRUE

TRUE

TRUE

TRUE

FALSE

TRUE

FALSE

FALSE

TRUE

 

TRUE

NULL

NULL

TRUE

 

FALSE

TRUE

FALSE

TRUE

TRUE

FALSE

FALSE

FALSE

FALSE

 

FALSE

NULL

FALSE

NULL

 

NULL

TRUE

NULL

TRUE

NULL

NULL

FALSE

FALSE

NULL

 

NULL

NULL

NULL

NULL

 

Как показано в таблицах истинности, and возвращает значение true только в том случае, когда истинны оба операнда. С другой стороны, or возвращает значение true, когда истинным является хотя бы один из операндов, not возвращает значение, противоположное своему опе­ранду (логическое отрицание). Например, not true возвращает false.

not null возвращает null, поскольку null - это неопределенное значе­ние. Другими словами, результат применения операции not к неопре­деленному значению будет также неопределенным. Необходимо все­гда внимательно относиться к выражениям, которые могут включать неопределенные операнды. Значения null могут стать причиной не­ожиданных результатов: см. раздел «Значения NULL в выражениях».


Порядок операций

Если для указания порядка операций не использованы скобки, порядок определяется старшинством операций. Сравните следующие выраже­ния:


 


NOT   (valid AND  done)      и       NOT valid AND done


Если обе булевы переменные valid и done имеют значение false, пер­вое выражение примет значение true. Однако результатом второго выражения будет false, так как not по старшинству выше, чем AND; поэтому второе выражение эквивалентно выражению

(NOT  valid)   AND  done

 

Следующий пример примечателен тем, что если valid имеет значение false, то результатом всего выражения будет false, независимо от значения done:

valid AND done

Аналогичное рассуждение применимо к следующему примеру: если valid имеет значение true, все выражение принимает значение true, независимо от значения done:

valid OR done

Вычисление по краткой схеме

Обрабатывая булево выражение, PL/SQL применяет вычисление по краткой схеме. Другими словами, PL/SQL прекращает вычисление бу­лева выражения в тот же момент, когда становится известным окон­чательный результат. При этом некоторые части выражения могут остаться невычисленными, что позволяет строить такие выражения, которые при полном вычислении могли бы привести к ошибке. Рас­смотрим следующее выражение с операцией or:

DECLARE

on_hand INTEGER;

on_order INTEGER;

BEGIN

IF (on_hand = 0) OR (on_order / on_hand < 5) THEN

END IF;

END;

Если значение on-hand равно нулю, левый операнд or принимает зна­чение true, и условие в операторе if истинно, независимо от значе­ния правого операнда, поэтому PL/SQL его и не вычисляет. Если бы PL/SQL попытался получить значения обоих операндов до примене­ния операции or, то при вычислении правого операнда возникла бы ошибка из-за деления на ноль. Вместе с тем необходимо заметить, что полагаться на вычисления по краткой схеме во всех случаях - это пло­хой стиль программирования, приводящий к ненадежным программам.


 


Операции сравнения

Операции сравнения производят сравнение одного выражения с дру­гим. Результатом сравнения всегда будет одно из значений true, false или null. Чаще всего операции сравнения применяются во фразе where команд манипулирования данными языка SQL и в условных операто­рах управления потоком вычислений.


Операции отношения

Операции отношения позволяют сравнивать выражения произвольной сложности. В приведенной ниже таблице поясняется смысл каждой операции.

 

Операция

Смысл

=

равно

<>, !=, ~=

не равно

<

меньше

>

больше

<=

меньше или равно

>=

больше или равно

Операции IS NULL, LIKE, BETWEEN, IN также являются операциями отношения.

Операция конкатенации

Две вертикальные черты (||) обозначают операцию конкатенации, ко­торая присоединяет одну строку к другой, как показывает следующий пример:

'suit'  ||  'case'   =   'suitcase'

Если оба операнда принадлежат к типу char, операция конкатенации вернет значение типа char. В противном случае ее результатом будет значение типа varchar.

Встроенные функции

В PL/SQL существует весьма богатый набор встроенных функций, обеспечивающих мощные возможности манипулирования данными. Встроенные функции можно разбить на следующие категории:

    функции регистрации ошибок;

    числовые (или математические) функции;

    символьные функции;

    функции преобразования;

    функции работы с датами;

    смешанные функции.

Таблица содержит список всех числовых и симфольных функций, распределенных по категориям.

Числовые

Назначение

Символьные

Назначение

ABS

Модуль

ASCII

ASCII - код

ACOS

Арккосинус

CONCAT

Конкатенация строк

ASIN

Арксинус

LENGTH

Длина строки

ATAN

Арктангенс

LOWER

Перевод вимволов в нижний регистр

COS

Косинус

REPLACE

Замена одного символа другим

COSH

Гиперболический косинус

SUBSTR

Подстрока

EXP

Экспонента

UPPER

Перевод символов в верхний регистр

LN

Натуральный логарифм

 

 

 

 

 

 

 

 

 

 

LOG

Логарифм

MOD

Остаток от деления

POWER

Везведение в степень

SIN

Синус

SINH

Гиперболический синус

SQRT

Корень квадратный

TAN

Тангенс

TANH

Гиперболический тангенс

TRUNC

Целая часть от деления

Управляющие структуры

Обзор

Из структурного программирования известно, что любая компьютер­ная программа может быть построена из базовых управляющих струк­тур, показанных на рисунке. Для решения поставленной задачи вы можете использовать их в любой комбинации.

 

Выбор (Условная конструкция)

Цикл

Последовательность

Нет(false)

 

Да(true)

 

Нет(false)

 

Да(true)

 

 

 

Выбирающая структура проверяет условие, затем выполняет ту или иную последовательность операторов в зависимости от того, истинно или ложно условие. Условие - это любая переменная или выражение, которые вырабатывают булево значение (true или false). Цикличе­ская структура повторяет выполнение последовательности операторов до тех пор, пока условие остается истинным. Последовательная струк­тура просто выполняет последовательность операторов в том порядке, в котором они встречаются.

Условное выполнение: оператор IF

Часто в силу различных обстоятельств приходится предпринимать аль­тернативные действия. Оператор if позволяет выполнять последова­тельность операторов условно. Это означает, что от значения условия зависит, будет ли выполняться последовательность. Существует три формы оператора if: if-then, if-then-else и if-then-elsif.


IF-THEN

Простейшая форма оператора if связывает условие с последователь­ностью операторов, заключенной между ключевыми словами then и end if (но не endif), следующим образом:

IF условие  THEN

последовательность_операторов; END IF;

Последовательность операторов выполняется только в том случае, если значением условия является true. Если же его значение false или null, то оператор if ничего не делает. В любом случае управление передается следующему оператору. Например:

IF sales > quota THEN

compute_bonus(empid);

UPDATE payroll SET pay = pay + bonus  WHERE empno = emp_id

END  IF;

При желании короткий оператор if можно разместить в одной строке, например:

IF х >  у THEN highх;   END  IF;

IF-THEN-ELSE

В этой форме оператора if добавлено ключевое слово else, за которым следует альтернативная последовательность операторов:

IF условие  THEN

последовательность_операторов1;

ELSE

последовательность_операторов2;

END  IF;

 

Последовательность операторов во фразе else выполняется только в том случае, если условие имеет значение false или null. Таким обра­зом, фраза else гарантирует, что какая-нибудь последовательность операторов обязательно выполнится. В следующем примере выполняется первая или вторая из команд update в зависимости от того, истинно или ложно условие:

 

IF trans_type = 'CR' THEN

UPDATE accounts SET balance = balance + credit

WHERE ...

ELSE

UPDATE accounts SET balance = balance - debit

WHERE ...

END IF;

 

IF-THEN-ELSIF

Фразы then и else могут сами включать оператор if, т.е. оператор if может быть вложенным:

IF  trans_type  =   'CR'   THEN

UPDATE  accounts  SET balance = balance  +  credit

WHERE   ...

ELSE

IF new_balance  = minimum_balance  THEN

UPDATE accounts  SET balance = balance  - debit

WHERE   ...

ELSE

RAISE  insufficient_funds;

END  IF;

END  IF;

Иногда возникает необходимость выбрать действие из нескольких вза­имоисключающих альтернатив. Третья форма оператора if исполь­зует ключевое слово elsif (но не elseif), чтобы включить дополни­тельные условия, например:

IF  условие1   THEN

последовательность_операторов1;

ELSIF условие2  THEN

  последовательность_операторов2;

   ELSE

  последовательность_операторовЗ;

END  IF;

Если первое условие имеет значение false или null, to фраза elsif проверяет другое условие. Оператор if может иметь любое число фраз elsif, причем заключительная фраза else не является обязатель­ной. Значения условий вычисляются одно за другим сверху вниз. Если какое-то условие примет значение true, to связанная с ним последова­тельность операторов выполняется, и управление передается следую­щему оператору. Если все условия при вычислении выработали false или null, то выполняется последовательность во фразе else. Рассмо­трим пример:

BEGIN

IF sales > 50000 THEN

bonus := 1500;

ELSIF sales > 35000 THEN

    bonus := 500;

ELSE

    bonus := 100;

END IF;

INSERT INTO payroll VALUES (emp_id, bonus, ...);

 

END;

 

Если значение sales больше 50000, то истинны сразу два условия: пер­вое и второе. Тем не менее переменной bonus будет присвоено правиль­ное значение, равное 1500, потому что в этом случае второе условие никогда не будет проверяться. Как только первое условие примет зна­чение true, связанный с ним оператор выполнится, и управление сразу же будет передано на команду insert.

Рекомендации

  1. Следует избегать в операторе if неуклюжих конструкций наподобие тех, что встречаются  в следующем примере:

DECLARE

overdrawn    BOOLEAN;

BEGIN

IF new_balance < minimum_balance THEN

overdrawn   := TRUE;

ELSE

overdrawn   :=  FALSE;

END IF;

IF overdrawn = TRUE THEN

RAISE  insufficient_funds;

END IF;

 

END;

В этом фрагменте программы игнорируются два полезных обстоятель­ства. Первое - значение булева рыражения может быть прямо присво­ено булевой переменной. Поэтому первый оператор if может быть полностью заменен простым присваиванием:

overdrawn   := new_balance < minimum_balance;

Второе - булева переменная сама по себе либо истинна, либо ложна. Поэтому можно следующим образом упростить условие во втором опе­раторе if:

IF overdrawn THEN   ...

  1. Где возможно, вместо вложенного оператора if применяйте фразу elsif. Это облегчает чтение и понимание текста программы. Срав­ните следующие две записи оператора if:

IF условие1 THEN

Оператор1.;

ELSE

  IF условие2 THEN       

          Оператор2;

  ELSE

      IF условиеЗ THEN

ОператорЗ;

      END IF;

  END IF;

END IF;

IF условие1 THEN

Оператор1;

ELSIF условие2 THEN

Оператор2;

ELSIF условие3 THEN

ОператорЗ;

END IF;

 

По своему действию эти операторы эквивалентны, но в первом опера­торе логика выглядит невразумительной, а во втором она четко про­слеживается.

Циклы: операторы LOOP и EXIT

LOOP

Оператор loop позволяет многократно выполнить последовательность операторов. Существует три формы оператора loop: loop, while-loop и FOR-LOOP.

Простейшая форма оператора loop представляет собой примитивный (или бесконечный) цикл, в котором между ключевыми словами loop и end loop включается последовательность операторов:

LOOP

последовательноеть_операторов;

END  LOOP;

При каждом повторении цикла выполняется последовательность опе­раторов, затем происходит возврат к началу цикла. Если дальнейшая обработка нежелательна или невозможна, то для завершения цикла можно использовать оператор exit. Оператор exit может быть раз­мещен в любом месте внутри цикла, но вне цикла его применение недопустимо. Существует две формы оператора exit: exit и exit-when.

 

 

WHILE-LOOP

Оператор while-loop связывает условие с последовательностью операторов, заключенной между ключевыми словами loop и end loop, как показано ниже:

WHILE условие  LOOP

последовательноеть_операторов;

END  LOOP;

 

Перед каждым повторением цикла вычисляется условие. Если его зна­чением является true, последовательность операторов выполняется, затем управление передается на начало цикла. Если значением условия является false или null, то цикл обходится, и управление передается следующему оператору.

Ниже следует пример:

WHILE   total   <=   25000   LOOP

SELECT  sal   INTO  salary  FROM emp

WHERE   ... total   :=  total  +  salary;

END  LOOP;

 

Число повторений зависит от условия и неизвестно до окончания ци­кла. Так как условие проверяется в начале цикла, число выполнений последовательности может оказаться и нулевым. Если в предыдущем примере начальное значение total больше 25000, то условие сразу при­мет значение false, и цикл будет пропущен.

В некоторых языках имеются конструкции loop until или repeat until, которые проверяют условие в конце цикла, а не в начале. По­этому последовательность операторов выполняется хотя бы один раз. В PL/SQL нет такой конструкции, но ее можно легко построить, на­пример, так:

LOOP

последовательность_операторов;

EXIT WHEN  булево_выражение;

END  LOOP;

 

Чтобы обеспечить выполнение цикла while хотя бы один раз, можно в условии использовать предварительно инициализированную булеву переменную, как показано в следующем примере:

done := FALSE;

WHILE NOT done LOOP

последовательность_операторов;

done := булево_выражение;

END LOOP;

 

Внутри цикла должен существовать оператор, присваивающий буле­вой переменной новое значение. В противном случае вы получите бес­конечный цикл. Например, следующие два оператора loop по своему действию эквивалентны:

WHILE  TRUE  LOOP

END LOOP;

LOOP

END LOOP;

 

FOR-LOOP

Если для цикла while число повторений не известно до тех пор, пока цикл не завершится, то в цикле for оно известно еще до входа в цикл. Цикл for повторяет свои действия для указанного диапазона целых чи­сел. Этот диапа­зон является частью схемы повторения, которая задается между ключе­выми словами for и loop. Две точки (..) обозначают операцию диа­пазона. Цикл for имеет следующий синтаксис:

FOR счетчик IN   [REVERSE]   нижняя__граница..верхняя_граница LOOP

последовательность_операторов;

END LOOP;

Границы диапазона вычисляются при первом входе в цикл и внутри цикла не изменяются.

Как показано в следующем примере, последовательность операторов выполняется по одному разу для каждого целого числа из указанного диапазона. После каждого повторения счетчик цикла увеличивается на 1.

FOR i  IN  1..3  LOOP     --  присвоить  i  значения  1,2,3

последовательность_операторов;     --  выполняется три раза

END LOOP;

Следующий пример показывает, что если нижняя граница равна верх­ней, то последовательность операторов выполняется ровно один раз:

FOR i   IN  3..3  LOOP     --  присвоить  i  значение  3

последовательность_операторов;     --  выполняется один раз

END LOOP;

По умолчанию, счетчик цикла продвигается, увеличиваясь от ниж­ней границы до верхней. Однако, если вы употребите ключевое слово reverse, цикл будет выполняться с уменьшением счетчика от верхней границы до нижней, как показано в примере ниже. После каждого по­вторения счетчик цикла уменьшается на 1.

FOR i   IN REVERSE  1..3  LOOP     --  присвоить   i  значения  3,2,1

последовательность_операторов;     -- выполняется три раза END  LOOP;

 

Тем не менее границы диапазона записываются в возрастающем (а не в убывающем) порядке.

Внутри цикла значение счетчика цикла может быть использовано, как если бы это была константа. Таким образом, счетчик цикла может участвовать в выражении, но ему нельзя присваивать значения, как видно из следующего примера:

FOR  ctr   IN   1. .10   LOOP

IF NOT  finished THEN

INSERT  INTO   ...   VALUES   (ctr,    . . .) ;     -- допустимо

factor   := ctr  *  2;     -- допустимо ELSE

ctr   :=  10;     --  недопустимо

END  IF;

END  LOOP;

EXIT

Оператор exit заставляет цикл завершиться без всяких условий. Когда встречается оператор exit, цикл немедленно завершается, и управле­ние передается следующему оператору.

 

Например:

LOOP

IF credit_rating <  3  THEN

EXIT;     --немедленно выйти из цикла

END  IF;

END LOOP; --отсюда возобновляется выполнение программы

 

Необходимо всегда помнить, что оператор exit можно использовать только внутри цикла. Если вы хотите завершить блок PL/SQL прежде, чем будет достигнуто его нормальное окончание, можно применять оператор return.

 

EXIT-WHEN

Оператор exit-when позволяет завершить цикл по условию. Когда встречается оператор exit, вычисляется значение условия во фразе when. Если условие имеет значение true, to цикл завершается, и упра­вление передается первому оператору, следующему за циклом.

 

Напри­мер:

LOOP

FETCH cl INTO . . .

EXIT WHEN cl%NOTFOUND;          -- выйти из цикла,

...                                                         -- если условие истинно

END LOOP;

CLOSE cl;

 

Пока условие не примет значение true, цикл завершиться не сможет. Поэтому операторы внутри цикла должны изменять значение условия. Если в предыдущем примере оператор fetch выберет строку, усло­вие примет значение false. Когда оператор fetch не сможет вернуть строку, значением условия станет true, цикл закончится, и управление будет передано оператору close.

Оператор exit-when может служить хорошей заменой простому опе­ратору if. Сравните, например, такие операторы:

IF count > 100 THEN

EXIT;

END IF;

 

EXIT WHEN count > 100;

 

 

По своему действию эти операторы эквивалентны, но оператор exit-when легче для чтения и понимания.

 

Метки циклов

Метка - необъ­явленный идентификатор в двойных угловых скобках - должна раз­мещаться в самом начале оператора loop, как показано в следующем примере:

<<имя_метки>>

LOOP

последовательность_операторов;

END LOOP;

Имя метки может также появиться в конце оператора loop, например:

<<my_loop>>

LOOP

………….

END  LOOP my_loop;

Если вложенные циклы имеют метки, вы можете сделать текст про­граммы более выразительным, отметив окончание каждого цикла.

При любой форме оператора exit можно завершить не только текущий цикл, но и любой другой, в который он вложен. Для этого нужно просто пометить тот внешний цикл, который вы хотите завершить. Затем вы должны указать эту метку в операторе exit, как показано ниже:

 

 

«outer»

LOOP

…..

LOOP

EXIT outer WHEN ...  -- закончить оба цикла END LOOP;

END LOOP outer;

В результате завершаются как помеченный цикл, так и все вложенные в него циклы.

 

Использование оператора EXIT

Оператор exit позволяет досрочно завершить цикл for. Например, следующий цикл может выполниться и десять раз, но если в какой-то момент оператор fetch не сможет выбрать строку, цикл завершится немедленно и независимо от того, сколько раз он выполнялся до этого:

FOR j IN 1. .10 LOOP

FETCH cl INTO emp_rec;

EXIT WHEN cl%NOTFOUND;

END LOOP;

||>ИНФОРМАТИКА<||>СПИСОК<||

Copyright © ForStu

ForStu / Лекции / Информатика / SQL/PL SQL (Стандарт) /

Copyright © 2004-2017, ForStu

Яндекс.Метрика