Вход/Регистрация
Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
вернуться

Борри Хелен

Шрифт:

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

Вложенные исключения в качестве точек сохранения

Вложенная архитектура блоков выполнения модулей PSQL означает, конечно, что PSQL поддерживает "вложенные" транзакции. Деятельность каждого модуля PSQL выполняется в контексте той транзакции, в которой он был вызван. Стандартный поток выполнения гарантирует, что работа либо завершится как единое целое, либо вся будет отменена. В случае хранимых процедур исключение приводит к отмене всей работы, выполненной во время вызова. В случае триггеров исключение приводит к отмене DML и всех уже выполненных действий, связанных с этой операцией.

Обработка исключений предоставляет средства для разбиения выполнения на этапы, которые могут быть отменены до определенной точки без необходимости отмены всей работы модуля. Уровень отмены определяется в точке появления ошибки и ближайшего предложения обработчика WHEN. Такая "точка сохранения" - эквивалент именованной точки сохранения в управляемой клиентом транзакции - создается в коде блока, в котором выполняется код обработчика WHEN.

Обработка исключения 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) ;

  • Читать дальше
  • 1
  • ...
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: