![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Удаление записи в IB [D6, IB6.x]
AndbyOne © (2002-07-19 12:10:00)Уважаемые мастера подскажите как сделать удаление записи. проблема в следующем: надо для удаления использовать хранимую процедуру или триггер и если с этой записью есть связь хотя бы в одной из трёх таблиц, то не удалять эту запись, а в клиентском приложении соответственно информировать пользователя о невозможности удалить запись с указанием с какой таблицей есть связь.
Я так думаю для этого случая лучше использовать триггер и соответственно проверку написать не сложно, но как отменить удаление в триггере и отправить сообщение в приложение не знаю.
kaif (2002-07-22 13:52:00) [1]2 Desdechado © (22.07.02 11:00)
Согласен.
Desdechado (2002-07-22 11:00:00) [2]2 kaif © (21.07.02 14:34)
способ хорош, но:
1. выяснить природный номер ошибки InterBase - заточка только на IB, что не всегда гуд
2. сделав SQL запрос к rdb$relation_constraints - дополнительный траффик по сети (min 6 кб), что тоже не всегда хорошо :)
вот чел почитает, и пусть решает, что ему лучше ;)
kaif (2002-07-21 14:34:00) [3]2 Desdechado © (20.07.02 18:50)
Если чел хочет сделать вразумительное сообщение о том, какая именно ссылка мешает удалить строку, он может преспокойно в секции except On E: Exception do проверить класс ошибки, привести ошибку к классу ошибок сервера, выяснить природный номер ошибки InterBase и если это ошибка данного типа (нарушение внешнего ключа), просто выделить из текста ошибки имя этого ключа и даже если у него неименованные constraints, то сделав SQL запрос к rdb$relation_constraints он узнает имя таблицы, которой foreign key принадлежит и выдать осмысленное сообщение на русском языке с указанием русского эквивалента имени таблицы (для чего можно завести еще одну таблицу и хранить там эти русские эквиваленты, если не лень, конечно).
Fran (2002-07-21 12:00:00) [4]Чтобы юзер не испугался англ. слов пишешь
try
процедура удаления
except
ShowMessage("Не могу! Есть ссылка.");
end;
Desdechado (2002-07-20 18:50:00) [5]2 kaif
>Правильно только foreign key.
челу нужно указать, с какой таблицей есть связь. А foreign key выдаст только абстрактное ругательство о невозможности удаления.
кроме того, в данном случае вариант невозможности удаления главной записи по причине невидимости удаления зависимой записи из другой транзакции не страшен - всегда можно повторить попытку :)
kaif (2002-07-20 03:51:00) [6]2 Johnmen © (19.07.02 12:31)
Жара, видно, сказывается...
При ON DELETE CASCADE как раз сообщения о невозможности удалить не будет. Вместо этого произойдет каскадное удаление.
Нужен foreign key без delete cascade. Можно с update cascade. А можно просто, если ключи стабильные.
В триггере проверку делать нельзя. Я сам этого не знал - мне подсказали недавно (Alexandr). Дело в том, что триггер работает в контексте транзакции. Это значит, что есть вероятность удаления записи при многопользовательском доступе. Правильно только foreign key.
Desdechado (2002-07-19 17:28:00) [7]CREATE EXCEPTION N1 "нельзя!";
в триггере после проверки EXCEPTION N1;
Johnmen (2002-07-19 12:31:00) [8]Строишь Primary Key, Foreign Key, ссылочную целостность c ON DELETE CASCADE.
При попытке удалить будет возбуждена ошибка, которую и отлавливай.
Fareader (2002-07-19 12:31:00) [9]Снегенерируй внутри триггера исключение и все отменится
AlexSam (2002-07-19 12:19:00) [10]Может я что-то не понял, но связь межде таблицами может быть по ключевым полям, а не записям, продумай это!