- •Основы языка pl/sql
- •Основные синтаксические конструкции языка pl/sql
- •V_ename emp.Ename%type;
- •V_sal number;
- •Курсоры pl/sql
- •V_ename emp.Ename%type;
- •V_sal emp.Sal%type;
- •If sql%notfoundthen
- •Insert into tb_error_log(id,date)
- •Values (user_id, sysdate);
- •V_account_no number;
- •V_balance number;
- •I.Until_price,
- •I.Quantity
- •Управление ходом выполнения кода pl/sql
- •If условие then операторы;
- •V_ename emp.Ename%type;
- •V_sal emp.Sal%type;
- •If c_emp%found then
- •Обработка ошибок (исключений - exception)
- •V_oraerr number;
- •V_oraerrm varchar2(255);
- •V_sal number;
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.