Книга: 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 ^

Оглавление книги


Генерация: 1.598. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз