![]() |
|
![]() ![]() ![]() |
|
shmelina |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 5.6.2009 Репутация: нет Всего: нет |
Речь о FireBird 2.1.
Структура базы такова, что имеет значение какой форейн сработает первый при удалении записи из таблицы. Если сначала первый сработает, то ошибки не будет. Если сначала второй сработает, то будет ошибка. Смотрите приложенную схему БД. Она упрощена для лучшего понимания проблемы. Стрелки указывают на родительские объекты (один ко многим). Цифры в скобках - для удобства объяснений: первый форейн, второй, третий. Имеется три таблицы связанные между собой форейнами. Два каскадных форейна (дочерние записи удаляются), один запрещающий удаление. ![]() Хороший сценарий. 1. Удаляем запись из Т1. 2. Срабатывает первый форейн и записи удаляются из таблицы Т3. 3. Срабатывает второй форейн и записи должны удалиться из Т2. Но нужно проверить, нет ли записей в Т3. Проверяем - их нет. Они удалены чуть раньше. Плохой сценарий. 1. Удаляем запись из Т1. 2. Срабатывает второй форейн. Должны удалиться записи из Т2, если нет для них записей в Т3. Но записи в Т3 есть - получаем ошибку. 3. Как быть? На триггеры переходить не хочется. Это сообщение отредактировал(а) shmelina - 20.11.2010, 01:56 |
|||
|
||||
cat512 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 438 Регистрация: 20.3.2007 Репутация: 1 Всего: 15 |
грохать сначала все записи из t2 предварительно связав по ключам три таблички, а потом из t1 или из t3 (зависит от логики)
|
|||
|
||||
shmelina |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 5.6.2009 Репутация: нет Всего: нет |
||||
|
||||
cat512 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 438 Регистрация: 20.3.2007 Репутация: 1 Всего: 15 |
Имелось ввиду следующее: delete from t2 where id in (select id from t3 where ....) delete from t1 where id in (select id from t3 where ....) сделай ХП на сервере и выполняй этих 2 запроса в контесте транзакции. На клиенте просто выполняй ХП Это сообщение отредактировал(а) cat512 - 20.11.2010, 15:06 |
|||
|
||||
Deniz |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1251 Регистрация: 16.10.2004 Где: Новый Уренгой Репутация: 8 Всего: 44 |
shmelina, т.е. по бизнес логике удалять из T1 можно и должны удалиться записи из Т2 и Т3, но удалять из Т2 нельзя, если есть записи в Т3?
Добавлено через 1 минуту и 52 секунды Можно жизненный пример такой бизнес-логики? -------------------- "Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с) |
|||
|
||||
shmelina |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 5.6.2009 Репутация: нет Всего: нет |
Не совсем так. "Удалять из T1 можно и должны удалиться записи из Т2 и Т3", но сначала должны удалиться из Т3, а только потом из Т2, иначе ошибка будет. Понятно? Попробую сначала коротко описать. Будут вопросы - спрашивайте. Речь идет о моих метаданных. Система сложная и для удобства я использую свои метаданные, а не системные. В Т1 хранится список объектов, которые есть в системе. В Т2 - поля объектов, в Т3 - описывается некая иерархия, состоящая из полей (Т2) объекта. Иерархия не простая, где в элементе указан код родителя. Для описания иерархии используется левый и правый код. Знакомы? Поэтому просто так удалить элемент дерева нельзя - требуется пересчитать левые и правые коды всего дерева. Даже если и можно было удалить элемент дерева, то с точки зрения бизнес-логики это не всегда возможно. Например, иерархией у меня описывается математическая формула, условие SQL-запроса и т.п. Поэтому автоматическое удаление элемента дерева будет приводить к неприятным последствиям. Т.е. нельзя удалять поле, если оно очень важно в системе. Но есть и простые ситуации, как описанная выше. Удалить объект (Т1) можно. Но также должны удалиться все его поля (Т2) и его иерархия (Т3). С точки зрения системы это нормально. Но удалить объект не получается, т.к. сначала срабатывает FK2. Таких моментов в системе несколько, где важен порядок срабатывания FK cascade. |
|||
|
||||
Deniz |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1251 Регистрация: 16.10.2004 Где: Новый Уренгой Репутация: 8 Всего: 44 |
-------------------- "Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с) |
|||
|
||||
shmelina |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 66 Регистрация: 5.6.2009 Репутация: нет Всего: нет |
В первом посте я немного упростил схему. Между Т1 и Т3 есть еще одна таблица. Она позволяет хранить несколько деревьев для одного объекта и является как бы идентификатором узлов иерархии конкретного объекта. ![]() |
|||
|
||||
Deniz |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1251 Регистрация: 16.10.2004 Где: Новый Уренгой Репутация: 8 Всего: 44 |
и через несколько постов окажется, что есть еще пара таблиц/связей и т.д., которые для "упрощения" убраны.
ИМХО, что-то не так с нормализацией БД. Далее я пас. -------------------- "Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с) |
|||
|
||||
Vas |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 830 Регистрация: 29.6.2005 Где: Stavropol region Репутация: 23 Всего: 28 |
Третья связь лишняя, неважно сколько таблиц между Т1 и Т3, по этому описанию
явно видно, что связь Т1-Т3 лишняя. Т2 уж хранит поля объектов, то бишь ссылается уже на объект системы. А в Т3 описываем некую иерархию, что здесь будет из Т1, если по связи Т2-Т1 мы можем свободно получить объект, которому принадлежит поле. -------------------- И опыт, сын ошибок трудных, И гений, парадоксов друг, И случай, бог изобретатель. ... (А.С. Пушкин) |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Базы данных и репортинг" | |
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами Обязательно указание: 1. Базы данных (Paradox, Oracle и т.п.) 2. Способа доступа (ADO, BDE и т.д.)
FAQ раздела лежит здесь! Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Базы данных и репортинг | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |