Книга: Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
Обработка исключения REASSIGN_SALES
Обработка исключения REASSIGN_SALES
Теперь вернемся к нашей процедуре DELETE_EMPLOYEE. В главе 30, когда эта процедура сталкивалась с ситуацией, где удаляемый служащий имеет заказы в картотеке, она выдавала пользовательское исключение REASSIGN_SALES и просто прекращала работу, отменяла выполненные действия и посылала сообщение исключения работающему с ней человеку.
Однако мы можем заставить процедуру обработать эту ситуацию и позволить процедуре завершиться. Например, обработчик может обнулить ключ SALES_REP и послать сообщение другой процедуре, которая создаст записи в таблице протокола для каждой соответствующей записи продаж.
Мы начинаем с создания таблицы протокола:
SET TERM ^;
CREATE TABLE EMPLOYEE_LOG (
EMP_NO SMALLINT,
TABLE_AFFECTED CHAR(31),
FIELD_AFFECTED CHAR(31),
FIELD_VALUE VARCHAR(20),
USER_NAME VARCHAR(31),
DATESTAMP TIMESTAMP) ^
COMMIT ^
Затем нам нужно создать процедуру, которая будет выполнять протоколирование. Она будет достаточно общей, потому что мы полагаем, что подобная процедура протоколирования может понадобиться и для других задач в этой системе:
CREATE PROCEDURE LOG_ACTION (
EMP_NO SMALLINT,
TABLE_AFFECTED CHAR(31),
FIELD_AFFECTED CHAR(31),
FIELD_VALUE VARCHAR (20))
AS
BEGIN
INSERT INTO EMPLOYEE_LOG
VALUES (:EMP_NO, :TABLE_AFFECTED, :FIELD_AFFECTED,
:FIELD_VALUE, CURRENT_USER, CURRENT_TIMESTAMP) ;
END ^
Последнее, что нужно сделать, - это добавить код обработки исключения в нашу процедуру DELETE_EMPLOYEE:
RECREATE PROCEDURE DELETE_EMPLOYEE (
:emp_num INTEGER)
AS
DECLARE VARIABLE PO_NUMBER CHAR(8);
BEGIN
IF (EXISTS (SELECT PO_NUMBER FROM SALES
WHERE SALES_REP = : emporium)) THEN
EXCEPTION reassign_sales;
В этом месте, если появится исключение, последующие операторы не будут выполняться, и управление будет передано на первый оператор WHEN, который может обрабатывать это исключение.
UPDATE department ...
SET ...
. . .
. . .
DELETE FROM employee
WHERE emp_no = :emp_num;
Вот блок обработчика. Первым делом он в цикле просматривает таблицу SALES и устанавливает SALES_REP в NULL во всех строках, где появляется код нашего удаляемого служащего. В каждой итерации этого цикла он вызывает процедуру протоколирования, передавая ей код служащего вместе с информацией о записи SALES:
WHEN EXCEPTION REASSIGN_SALES DO
BEGIN
FOR SELECT PO_NUMBER FROM SALES
WHERE SALES_REP = :emp_num
INTO :PO_NUMBER
AS CURSOR С
DO
BEGIN
UPDATE SALES SET SALES_REP = NULL
WHERE CURRENT OF C;
EXECUTE PROCEDURE LOG_ACTION (
emp_num, ' SALES ', ' POJSIUMBER', : PO_NUMBER) ;
END
После завершения цикла главная процедура еще раз вызывает саму себя для завершения обработки, которая была пропущена по причине исключения:
EXECUTE PROCEDURE DELETE?EMPLOYEEl (:emp_num) ;
END
END^
COMMIT ^
- Исключения в действии
- Обработка перехваченных ошибок
- 5.4 Команда trap: обработка прерываний
- 15.3. Обработка изображений при помощи RMagick
- 1.2.7. Исключения
- 15.1.3. Обработка сигналов управления заданиями
- ГЛАВА 4 Обработка исключений
- Обработка запросов с помощью PHP
- ГЛАВА 6. Структурированная обработка исключений
- Обработка ошибок
- Скрипт «Обработка входящего звонка от потенциального клиента»
- Исключения и обработчики исключений