обработка исключений на сервере.

IBX, FIBPlus, UIB, ADO, .Net и прочее-прочее-прочее, в общем все, что относится к созданию приложений, работающих с InterBase, Firebird и Yaffil - клиент-серверных, трехзвенных, консольных и т.п.

Модератор: kdv

Ответить
Dixi
Сообщения: 4
Зарегистрирован: 06 янв 2007, 13:47

обработка исключений на сервере.

Сообщение Dixi » 06 янв 2007, 15:58

Привет всем.
интересует как сделать следующее:
есть 2 таблицы подчиненные как "один ко многим" через foreign key.
при удалении из справочной таблицы элемента который еще используется в основной таблице возникает исключение violation of FOREIGN KEY constraint.
хочется вместо системного вызвать свое исключение.

есть вариант сделать так

Код: Выделить всё

CREATE EXCEPTION ON_DEL_CURRENCY 'Удаление невозможно, блаблабла';

CREATE TRIGGER DEL_CURRENCY FOR CURRENCIES
ACTIVE BEFORE DELETE POSITION 0
AS
DECLARE VARIABLE CNT INTEGER;
begin
  SELECT COUNT(*) FROM PAYMENTS WHERE  PAYMENTS.CURRENCYID=OLD.CURRENCYID INTO CNT;
  IF (CNT>0) THEN EXCEPTION ON_DEL_CURRENCY;
end
но на каждое удаление выполнять запрос, как я понимаю, сильно затормозит базу, если будет использоваться на больших объемах данных.

можно ли вызвать своё исключение, основываясь на коде возвращенной ошибки? например в триггере вызываемом after delete?
типа
when sqlcode -NNN
DO
EXCEPTION ON_DEL_CURRENCY;
где NNN код системной ошибки.
(предыдущий код сам по себе в триггере не работает, это так размышления в слух.)

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 06 янв 2007, 16:03

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

p.s. описанная Вами попытка "замены" exception - изврат натуральный.

Dixi
Сообщения: 4
Зарегистрирован: 06 янв 2007, 13:47

Сообщение Dixi » 06 янв 2007, 22:42

заметте, что то, что вы сказали я собственно сказал и сам, давайте не заниматься тавтологией. меня как раз интересует как это сделать без клиента, мне клиент вообще мало интересен. Мало ли на чем его будут писать - мне надо по максимуму все описать на сервере.

хорошо, а как тогда в триггере узнать прошла ли транзакция или нет?
зачем тогда вообще триггера типа after delete?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 06 янв 2007, 23:48

в триггере - никак. триггер выполняется до контроля FK или после. И триггер либо выполняется, либо не выполняется. Например, если есть 2 триггера на одно действие, и в первом произошла ошибка, второй триггер не будет выполняться вообще - иначе поведение сервера можно было бы посчитать идиотским.
Поэтому, никакие внешние ошибки, происходящие вне триггеров, в триггеры не могут попасть ни коим образом и ни в каком виде.

Точно так же, ни в каком операторе sql нельзя узнать "прошла транзакция" или нет, потому что транзакции находятся на более "высоком" уровне, чем sql-операторы (хотя здесь я не совсем точен, ибо в FB 2.1 обещают триггеры на commit).

Триггеры after delete нужны для того, чтобы например выполнить какое-либо действие, которое должно выполниться после успешного (!) удаления - например, сделать запись в таблицу "лога" об этом удалении, послать клиенту event, и т.п.

p.s. я тавтологией не занимаюсь ни в коей мере. В текущей реализации сервера сообщения о нарушениях контроля PK, FK и unique являются "универсальными". Попытка сделать их "менее уникальными" понятна, но в отношении constraints осуществима только в клиентском приложении - самостоятельно или при помощи таких средств как репозитарий FIBPlus и т.п.

Dixi
Сообщения: 4
Зарегистрирован: 06 янв 2007, 13:47

Сообщение Dixi » 07 янв 2007, 00:19

kdv писал(а): В текущей реализации сервера сообщения о нарушениях контроля PK, FK и unique являются "универсальными". Попытка сделать их "менее уникальными" понятна, но в отношении constraints осуществима только в клиентском приложении - самостоятельно или при помощи таких средств как репозитарий FIBPlus и т.п.
понятно :(
спасибо за ликбез.
как я понимаю, такая же ситуация и с определением исключений при инсерте когда происходит нарушение уникальности?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 07 янв 2007, 11:29

как я понимаю, такая же ситуация и с определением исключений при инсерте когда происходит нарушение уникальности?
натюрлих.

p.s. вообще если делать вставку, обновление или удаление процедурой, то в ней можно обрабатывать ошибки. в datadef.pdf есть пример.

Dixi
Сообщения: 4
Зарегистрирован: 06 янв 2007, 13:47

Сообщение Dixi » 07 янв 2007, 16:09

kdv писал(а): вообще если делать вставку, обновление или удаление процедурой, то в ней можно обрабатывать ошибки. в datadef.pdf есть пример.
да , я думал об этом варианте, но в этом случае теряется прозрачность управления данными. также неудобны будут массовые вставки и удаления. жаль конечно, но придется кое что выносить на клиента.

Ответить