Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СУБД Oracle / Лекции / Лек_ORAC / L45 / Основы языка PL_SQL.doc
Скачиваний:
61
Добавлен:
16.04.2013
Размер:
120.32 Кб
Скачать

I.Until_price,

I.Quantity

FROM order_items i,

product_descriptions p

WHERE i.product_id = p.product_id

AND i.order_id = o.order_id

)

FROM order o

WHERE order_date BETWEEN TO_DATE(’01-Jan-03’)

AND TO_DATE(’31-Jan-03’)

;

odate order.order_date%TYPE;

ostatus order.order_status%TYPE;

od_cur ref_cursor;

t_name product_descriptions.translated_name%TYPE;

price order_items.until_price%TYPE;

qty order_items.until_quantity%TYPE;

BEGIN

OPEN order_cur;

LOOP

FETCH order_cur INTO odate, ostatus, od_cur;

EXIT WHEN order_cur%NOTFOUND;

LOOP

FETCH od_cur INTO tname, price, qty;

EXIT WHEN od_cur%NOTFOUND;

DBMS_OUTPUT.put_line(odate || ‘,’ || ostatus

||‘,’|| tname ||‘,’|| price||‘,’|| qty);

END LOOP;

END LOOP;

CLOSE order_cur;

END;

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

Курсорное выражение открывается автоматически при выборке родительской строки.

Курсорные выражения могут быть вложенными. Вложенный курсор закрывается в следующих случаях:

  • Закрывается родительский курсор

  • Родительский курсор выполняется повторно

  • Во время выборки родительской строки генерируется исключение

Управление ходом выполнения кода pl/sql

Операторы типа IF-THEN-ELSE

Синтаксис:

If условие then операторы;

[ELSEIF условие THEN операторы; ]

[. . .]

[ELSE операторы;]

END IF;

-- схемы применения операторов IF-THEN-ELSE --

Примеры.

IF job=’SALEMAN’ THEN

v_raise := sal * .10;

ELSE

IF job=’CLERK’ THEN

v_raise := sal*.15;

ELSE;

v_raise := sal*.20;

END IF;

END IF;

IF job=’SALEMAN’ THEN

v_raise := sal * .10;

ELSEIF job=’CLERK’ THEN

v_raise := sal * .15;

ELSE;

v_raise := sal * .20;

END IF;

Пример использования с проверкой атрибута курсора.

Procedure TEST2

IS

CURSOR c_emp IS

SELECT ename, sal FROM emp;

V_ename emp.Ename%type;

V_sal emp.Sal%type;

BEGIN

OPEN c_emp;

FETCH c_emp INTO v_ename, v_sal;

If c_emp%found then

dbms_output(v_ename);

ELSE

dbms_output(‘Data not found.’);

END IF

CLOSE c_emp;

END; -- Proc TEST2

Конструкции CASE.

  • Инструкции CASE

    • Простые

    • Поисковые

  • CASE-выражения

    • Простые

    • Поисковые

Синтаксис поисковойCASE-инструкции:

CASE

WHEN условие_1 THEN операторы;

[WHEN условие_2 THEN операторы;]

. . .

ELSE операторы;

END CASE;

Здесь последовательно проверяет условия и при обнаружении первого истинного условия возвращает соответствующее значение(при этом оставшиеся условия не проверяются).

ПростаяCASE-инструкция имеет такой синтаксис:

CASE проверяемое_выражение

WHEN значение_1 THEN операторы;

[WHEN значение_2 THEN операторы;]

. . .

ELSE операторы;

END CASE;

Конструкция ELSEявляется обязательной.

Отметим, что инструкция CASEаналогична множественной конструкцииIF-THEN-ELSEIF-…-ELSE.

IF проверяемое_выражение=значение_1 THEN операторы;

[ELSEIF проверяемое_выражение=значение_2 THEN операторы;]

[. . .]

ELSE операторы;

END IF;

Таким образом, указанный выше пример условного выполнения можно написать и так с помощью CASE-инструкций:

CASE

WHEN job=’SALEMAN’ THEN

v_raise := sal * .10;

WHEN job=’CLERK’ THEN

v_raise := sal * .15;

ELSE

v_raise := sal * .20;

END CASE;

CASE job

WHEN ’SALEMAN’ THEN

v_raise := sal * .10;

WHEN ’CLERK’ THEN

v_raise := sal * .15;

ELSE

v_raise := sal * .20;

END CASE

Обратите внимание, что если в простойCASE-инструкции проверяемое выражение естьNULL, то будет выполняться блокELSE, но не блокWHENNULL. Например.

CASE job

WHEN ‘SALEMAN’ THEN v_raise := sal * .10;

WHEN ‘CLERK’ THEN v_raise := sal * .15;

WHEN NULL THEN v_raise := 0;

ELSE v_raise := sal * .20;

END CASE

CASE-выражениевозвращает значение и может стоять в любом месте программы, где разрешено использовать другие значения.

Отметим, что в любых CASE-выражениях конструкцияELSEтоже обязательна.

Синтаксис простого CASE-выражения:

CASE проверяемое_выражение

WHEN сверяемое_значение_1 THEN возвращаемое_значение_1

[WHEN сверяемое_значение_2 THEN возвращаемое_значение_2]

. . .

ELSE возвращаемое_значение_n

END

Пример:

v_full_name := CASE v_short_name

WHEN ‘ru’ THEN ‘Россия’

WHEN ‘ua’ THEN ‘Украина’

WHEN ‘de’ THEN ‘Германия’

ELSE ‘Неизвестная страна’

END;

Поисковое CASE-выражениепоследовательно проверяет условия и при обнаружении первого истинного условия возвращает соответствующее значение (при этом оставшиеся условия не проверяются). Синтаксис:

CASE

WHEN условие_1 THEN возвращаемое_значение_1

[WHEN условие_2 THEN возвращаемое_значение_2]

. . .

ELSE возвращаемое_значение_n

END

Пример:

v_women_type := CASE

WHEN age<=1 THEN ‘дитя’

WHEN age>1 AND age<=14 THEN ‘девочка’

WHEN age>14 AND age<=30 THEN ‘девушка’

WHEN age>30 AND age<=45 THEN ‘женщина’

WHEN age>45 AND age<=55 THEN ‘ягодкаопять’

WHEN age>55 AND age<=70 THEN ‘пожилаядама’

ELSE ‘старушка’

END;

Обратите внимание, что в CASE-выражениях отсутствуют точки с запятой (в примерах точка с запятой указывала на окончание оператораPL/SQL, но не на окончаниеCASE-выражения).

Таким образом, CASE-выражения далеко не эквивалентныCASE-инструкциям, а, следовательно, и конструкциямIF-THEN-ELSE.

Организация циклов (loop)

  • Условный цикл, пока не выполнится условие (when-цикл)

  • Условный цикл, пока выполняется условие (while-цикл)

  • Счётный цикл (for-цикл)

Схема when-цикла

[<<имя_цикла>>]

LOOP

[операторы;]

[EXIT [имя_цикла] [WHEN условие_выхода];]

[операторы;]

END LOOP;

Схема while-цикла

WHILE условие_продолжения

LOOP

[операторы;]

END LOOP;

Схема for-цикла

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

LOOP

[операторы;]

END LOOP;

Примечание: (между значениями границ стоят две точки)

Пример.

BEGIN

FOR just_a_num IN 1..10

LOOP

dbms_output.put_line(just_a_num);

END LOOP;

END;

Оператор GOTO.

Выполняет абсолютный переход на метку. Применять не рекомендуется. Синтаксис:

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

Пример.

BEGIN

. . .

IF v_delta < 0 THEN GOTO m_abandon;

. . .

<<m_abandon>> NULL;

END;

В этом примере использован переход к метке m_abandonдля того, чтобы обойти большой блок программы.

Оператор NULL стоящий после метки ничего не делает – это пустой оператор. Его единственное осмысленное применение – стоять после метки, если там не нужно ставить какой-нибудь реальный оператор.

Ограничения на использование оператора GOTO:

  • Нельзя передавать управление за пределы инструкции IF, цикла или вложенного блока

  • Нельзя передавать управление в инструкцию IF, цикл или вложенный блок

  • из одного раздела инструкции IFв другой (например, из разделаIF-THENв разделELSE)

  • Нельзя передавать управление в подпрограмму или из подпрограммы

  • Нельзя передавать управление из исполняемого раздела в раздел исключений блока PL/SQL(такую передачу делает инструкцияRAISE)

  • Нельзя передавать управление из раздела исключений в исполняемый раздел блока PL/SQL.

Соседние файлы в папке L45