Управляющие структуры
Управляющие структуры – самое важное в PL/SQL расширение по сравнению с SQL. PL/SQL позволяет не только манипулировать данными ORACLE, но и обрабатывать данные, используя операторы условного, циклического и последовательного потока управления, такие как IF-THEN-ELSE, FOR-LOOP, WHILE-LOOP, EXIT-WHEN и GOTO. В совокупности эти операторы могут обработать любую ситуацию. Часто приходится предпринимать альтернативные действия в зависимости от обстоятельств. Оператор IF-THEN-ELSE позволяет выбирать последовательность выполнения действий в зависимости от условия. Фраза IF проверяет условие; фраза THEN определяет, что делать, если условие истинно; фраза ELSE определяет, что делать, если условие ложно или недействительно. Рассмотрим приведенную ниже программу, которая обрабатывает банковскую транзакцию. Прежде чем позволить снять $500 со счета 3, она должна удостовериться, что денег на счете достаточно, чтобы покрыть расход. Если денег хватает, программа снимает сумму со счета; в противном случае вносит запись в таблицу для ревизии счетов. DECLARE acct_balance NUMBER(11, 2); acct CONSTANT NUMBER(4): = 3; debit_amt CONSTANT NUMBER(5, 2): = 500.00; BEGIN SELECT bal INTO acct_balance FROM accounts WHERE account_id = acct FOR UPDATE OF bal; IF acct_balance > = debit_amt THEN UPDATE accounts SET bal = bal - debit_amt WHERE account_id = acct; ELSE INSERT INTO temp VALUES (acct, acct_balance, 'Insufficient funds'); -- включить номер счета, текущий баланс и сообщение END IF; COMMIT; END; Последовательность операторов, которая использует результаты запроса, чтобы выбрать альтернативные действия, типична для приложений баз данных. Другим примером типовых действий является вставка или удаление строки при условии, что в другой таблице найдена строка, связанная по содержанию с данной. Используя условные операторы, можно собрать эти типовые цепочки действий в блок PL/SQL. Это может повысить эффективность работы и упростить проверки целостности.
Циклы
Оператор LOOP позволяет многократно выполнить последовательность операторов. Ключевое слово LOOP должно располагаться перед первым оператором последовательности, а ключевые слова END LOOP – за последним оператором. Следующий пример показывает простейшую форму цикла, который все время повторяет последовательность операторов: LOOP -- последовательность операторов END LOOP;
Оператор FOR-LOOP позволяет указать диапазон целых чисел и выполнить последовательность операторов один раз для каждого числа из диапазона. Предположим, например, что вы – производитель заказных автомобилей и что каждый автомобиль имеет серийный номер. Для каждого автомобиля в учетную ведомость продаж необходимо внести заказчика. Это можно сделать, используя следующий цикл FOR:
FOR i IN 1..order_qty LOOP UPDATE sales SET custno = customer_id WHERE snum = snum_seq.NEXTVAL; END LOOP;
Оператор WHILE-LOOP связывает с последовательностью операторов некоторое условие. Перед каждым повторением цикла условие вычисляется. Если результатом является TRUE, то выполняется последовательность операторов, и управление возвращается к началу цикла. Если же значением условия является FALSE или NULL, цикл обходится, и управление передается на следующий оператор. В следующем примере ищется ближайший в иерархии подчиненности руководитель служащего с номером 7902, имеющий оклад не менее $4000:
DECLARE salary emp.sal%TYPE; mgr_num emp.mgr%TYPE; last_name emp.ename%TYPE; starting_empno CONSTANT NUMBER(4): = 7902; BEGIN SELECT sal, ragr INTO salary, mgr_num FROM emp WHERE empno = starting_empno; WHILE salary < 4000 LOOP SELECT sal, mgr, ename INTO salary, mgr_num, last_name FROM emp WHERE empno = mgr num; END LOOP; INSERT INTO temp VALUES (NULL, salary, last_name); COMMIT; END;
Оператор EXIT-WHEN позволяет закончить цикл, если дальнейшая обработка нежелательна или невозможна. Когда встречается оператор EXIT, то вычисляется условие во фразе WHEN. Если результатом является TRUE, цикл заканчивается и управление передается на следующий оператор. В следующем примере цикл закончится, когда значение total превысит 25000:
LOOP ... total = total + salary; EXIT WHEN total > 25000; -- выйти из цикла, если условие истинно END LOOP; -- сюда передается управление
Оператор GOTO позволяет безусловный переход на метку. Метка – необъявленный идентификатор, заключенный в двойные угловые скобки, – должна стоять перед выполняемым оператором или блоком PL/SQL. При исполнении оператора GOTO управление передается помеченному оператору или блоку, как показано в следующем примере:
IF rating > 90 THEN GOTO calc_raise; -- переход на метку END IF; ... «calc_raise» IF job_title = 'SALESMAN' THEN -- управление передается сюда raise: = commission * 0.25; ELSE raise: = salary * 0.10; END IF;
|