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 есть пример.
да , я думал об этом варианте, но в этом случае теряется прозрачность управления данными. также неудобны будут массовые вставки и удаления. жаль конечно, но придется кое что выносить на клиента.