Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.06.14;
Скачать: CL | DM;

Вниз

Удаление записей из связанных таблиц   Найти похожие ветки 

 
Андрей (начинающий)   (2009-04-19 12:45) [0]

Есть 2 таблицы. Связь "Один ко многим" (т.е. одной записи первой таблицы соответствуюет множество записей во второй). Как правильно удалять запись из первой табл. и соответствующие ей записи второй?
Таблицы не индексированы. Что лучше использовать: Locate или Next?


 
Юрий Зотов ©   (2009-04-19 12:47) [1]

Лучше проставить каскадное удаление, а не делать вручную.


 
Андрей (начинающий)   (2009-04-19 12:52) [2]


> Юрий Зотов ©   (19.04.09 12:47) [1]

Это как? Можно в 2 словах объяснить?


 
Юрий Зотов ©   (2009-04-19 12:58) [3]

Можно, но нужна дополнительная информация - какая БД и как Вы ее создавали?


 
Андрей (начинающий)   (2009-04-19 13:15) [4]


> какая БД

База на основе TTable, создана при помощи компонента VolgaDB. Выбор записей там осуществляется при помощи SQL, а удаление с его помощью не прописано, пэтому надо организовать стандартными средствами.
Я сделал так:

with .... .DataSet do begin
       try
         Open; Edit; First;
         while Locate("имя поля таблицы","значение",[]) do Delete;
         Close;
       except
         on e:Exception do SendErrorMessage(...);
       end;
end;
 
Вроде работает, но хочется узнать - правильно ли я делаю.


 
Андрей (начинающий)   (2009-04-22 09:42) [5]


>  (19.04.09 13:15) [4]

Удаление по этому методу у меня работает. Возник второй вопрос - как отменить удаление записей из обоих таблиц, если случилась ошибка при удалении какой-нибудь связанной записи? Удаляю их в обработчике BeforeDelete первой таблицы.


1 таблица:
вызывается Delete;
в обработчике BeforeDelete вызывается: while Locate(...) do Delete (для второй таблицы);


Вот, если в удалении записей второй таблицы возникает ошибка, как отменить удаление всех записей в обоих?


 
Ega23 ©   (2009-04-22 10:02) [6]


> Лучше проставить каскадное удаление, а не делать вручную.


Не лучше. on delete cascade - штука такая... Одним удалением можно всю базу грохнуть.


 
Sergey13 ©   (2009-04-22 10:10) [7]

> [5] Андрей (начинающий)   (22.04.09 09:42)
> как отменить удаление всех записей в обоих?

Нужно почитать (и вникнуть) про транзакции и разобраться с их поддержкой в твоей СУБД.


 
Anatoly Podgoretsky ©   (2009-04-22 11:10) [8]

Никаких каскадных удалений и транзакций там нет, это очень простая ДБ.


 
Anatoly Podgoretsky ©   (2009-04-22 11:10) [9]

К тому же мертвая.


 
Андрей (начинающий)   (2009-04-22 12:25) [10]


> Anatoly Podgoretsky ©   (22.04.09 11:10) [9]
> К тому же мертвая.

Почему? Из-за того, что не поддерживается создателем компонента?


 
Юрий Зотов ©   (2009-04-22 12:38) [11]

> Ega23 ©   (22.04.09 10:02) [6]

> Одним удалением можно всю базу грохнуть.

Если с головой не дружить - то можно. А если дружить и сделать все аккуратно (с выдачей предупреждения и т.п.), то все будет нормально. И ссылочная целостность будет гарантирована даже при возможных будущих изменениях в структуре БД, причем без переписки кода клиента.


 
Ega23 ©   (2009-04-22 13:07) [12]


> Если с головой не дружить - то можно. А если дружить и сделать
> все аккуратно (с выдачей предупреждения и т.п.), то все
> будет нормально. И ссылочная целостность будет гарантирована
> даже при возможных будущих изменениях в структуре БД, причем
> без переписки кода клиента.


Ага, щаз. Вот я добавляю новую таблицу (ну вот надо мне). Ставлю вторичный ключ на справочную. С опцией on delete cascade.
И код клиента (либо ХП, которая с данной сущностью работает) мне придётся переписывать.


 
Юрий Зотов ©   (2009-04-22 13:25) [13]

> Ega23 ©   (22.04.09 13:07) [12]

> И код клиента (либо ХП, которая с данной сущностью работает) мне
> придётся переписывать.

Зачем? Добавляй хоть 100 таблиц - все равно при удалении записи из справочника автоматически будут удалены все ссылающиеся на нее записи из всех таблиц, в том числе и из этих 100 новых. Без всякой переписки.


 
Ega23 ©   (2009-04-22 13:34) [14]

А как ты предупреждение-то собираешься выводить? Типа, "Вы уверены?" и всё?


 
Ega23 ©   (2009-04-22 13:34) [15]

Меня бы за такое убили.


 
AndreyV ©   (2009-04-22 13:47) [16]

> [15] Ega23 ©   (22.04.09 13:34)
> Меня бы за такое убили.

Сначала предложить пользователю удалить соответствующие данные из связанных таблиц?


 
Ega23 ©   (2009-04-22 13:51) [17]


> Сначала предложить пользователю удалить соответствующие
> данные из связанных таблиц?


Да. Ответить, что, мол, удаление невозможно. А в критических случаях - ещё и указать из-за какой сущности невозможно.


 
Юрий Зотов ©   (2009-04-22 13:53) [18]

> Ega23

> А как ты предупреждение-то собираешься выводить? Типа, "Вы
> уверены?" и всё?

Не все, а с пояснением. Чтобы юзер понимал, что он собирается сделать и к чему это приведет.

> Меня бы за такое убили.

Еще раз - все надо делать с головой. В том числе, и каскадное удаление. В каких-то ситуациях оно действительно недопустимо, а в других может быть  вполне возможно.

=======================

Но ты не о том говоришь, Олег. Если прочитать сабж внимательно, то мы увидим, что человек УЖЕ решил делать каскадное удаление и спрашивает лишь о том, КАК его сделать. И мой ответ свелся лишь к тому, как сделать ЛУЧШЕ, чтобы ничего не упустить из виду и не писать лишний код.


 
Ega23 ©   (2009-04-22 13:57) [19]

Если как - то delete cascade
Хотя я бы в ХП обернул и один фиг ручками бы выполнил.


 
Юрий Зотов ©   (2009-04-22 14:05) [20]

> Ega23 ©   (22.04.09 13:57) [19]

> Хотя я бы в ХП обернул и один фиг ручками бы выполнил.

1. И обязательно забыл бы удалить какую-то из ссылок.
2. И переписывал бы свою ХП при изменении структуры БД.
3. И при каждой переписке снова забывал бы удалить какую-то из ссылок.


 
Ega23 ©   (2009-04-22 14:18) [21]


> 1. И обязательно забыл бы удалить какую-то из ссылок.


Если бы забыл - поднялся бы exception и транзакцию можно было бы откатить.
В отличие от.


> 2. И переписывал бы свою ХП при изменении структуры БД.


НЕ вижу причин, почему в патч-скрипт на изменение структуры БД не включить пересоздание нужной ХП.


> 3. И при каждой переписке снова забывал бы удалить какую-
> то из ссылок.


Если бы снова забыл - снова поднялся бы exception и транзакцию можно было бы откатить.
В отличие от.


 
Юрий Зотов ©   (2009-04-22 14:20) [22]

> Ega23 ©   (22.04.09 14:18) [21]

> поднялся бы exception

Не факт. Например, при репликации контроль foreign keys может быть отключен.


 
Anatoly Podgoretsky ©   (2009-04-22 14:22) [23]

Да хоть каскадное удаление (автоматическое), хоть ручное ни сути ни результата не меняет. Важно понимание, что кроме родительской будут удалены подчиненые.


 
Anatoly Podgoretsky ©   (2009-04-22 14:23) [24]


> Почему? Из-за того, что не поддерживается создателем компонента?

И продавцом и автором.


 
Anatoly Podgoretsky ©   (2009-04-22 14:25) [25]

> Ega23  (22.04.2009 14:18:21)  [21]

В отличии от все откатится и так, особенно учитывая strict delete


 
Андрей (начинающий)   (2009-04-23 21:15) [26]


> Андрей (начинающий)   (22.04.09 09:42) [5]

И все-таки, абстрагируясь от развернувшейся теоретической дискуссии, ответьте, плиз, на мой вопрос [5] :)


 
Anatoly Podgoretsky ©   (2009-04-23 21:37) [27]

Создание временной таблице, в случае ошибки откат из нее.


 
Anatoly Podgoretsky ©   (2009-04-23 21:40) [28]

Вариант 2, копия таблиц, разновидность первого варианта.


 
MsGuns ©   (2009-04-24 09:24) [29]

Поддерживаю Егу на счет "вредности" каскадных удалений на уровне бизнес-логики. В конкретном приложении с аккуратной логикой и "заворачиванием" удалений в транзакции - пожалуйста, а вот в триггер - ни боже мой. Чревато Чернобылем для БД.

Как быть с предупреждениями, если делается удаление из связанных таблиц  по некоторому доп.условию, т.е. когда удаляется несколько (заранее неизвестно сколько) из главной и есно, все семейства записей из подчиненной ? На каждый пук запрос ? А если это удаление делается клиентским запросом, ничего не ведающем о каскадах ? И каким образом сервер будет вести диалог с пользователем ?


 
AndreyV ©   (2009-04-24 10:01) [30]

> [29] MsGuns ©   (24.04.09 09:24)
> Поддерживаю Егу на счет "вредности" каскадных удалений на
> уровне бизнес-логики. В конкретном приложении с аккуратной
> логикой и "заворачиванием" удалений в транзакции - пожалуйста,
> а вот в триггер - ни боже мой. Чревато Чернобылем для БД.

Да, пользователь будет склонен отвечать подтверждением на удаление, ведь иначе не сможет добится своей цели - удалить из справочника. Правильней не давать удалять с объяснением причины, и, возможно, с открытием соответсвующих форм со связными данными, но чтобы действия были осознанные.

Конечно могут быть какие-то некритические или рассчитанные, к примеру, на основе других, данные - тут и каскадом можно.


 
Андрей (начинающий)   (2009-04-24 13:32) [31]


> Anatoly Podgoretsky ©   (23.04.09 21:37) [27]

спасибо :)


 
Юрий Зотов ©   (2009-04-24 15:30) [32]

> MsGuns ©   (24.04.09 09:24) [29]
> AndreyV ©   (24.04.09 10:01) [30]

Вынужден обратить Ваше внимание на постскриптум в [18].
:o)


 
clickmaker ©   (2009-04-24 16:25) [33]

> ведь иначе не сможет добится своей цели - удалить из справочника

а нефиг удалять из справочника.
если какие-то записи там уже не нужны, на них могут быть ссылки, скажем, в архивах, которые используются для статистики, отчетности и т.п.
можно ввести поле Active или Visible, при запросе фильтровать.


 
AndreyV ©   (2009-04-24 21:08) [34]

> [32] Юрий Зотов ©   (24.04.09 15:30)
> > AndreyV ©   (24.04.09 10:01) [30]
>
> Вынужден обратить Ваше внимание на постскриптум в [18].
> :o)

Конечно, Юрий, постскриптум я помню, но есть ощущение, что автор не понимает, что делает.


 
Андрей (начинающий)   (2009-04-24 23:06) [35]


> AndreyV ©   (24.04.09 21:08) [34]
>  ... но есть ощущение, что автор не понимает, что делает.

Почему? :) Я понимю, что при возникновении ошибки в какскадном удалении без возможности отката, разрушатся связи между таблицами.
Но, т.к. я пока не планирую давать пользователю права на удаление записей таблиц и сами таблицы не слишком большие, то на данном этапе меня устроит [27].


 
ТД   (2009-04-24 23:27) [36]

ветку не читал, но "что при возникновении ошибки в какскадном удалении без возможности отката, разрушатся связи между таблицами." звучит как бред

зы
прочитал ветку. а что за бд кто-нибудь скажет? ну кроме автора, ибо он не в курсе, как видно


 
AndreyV ©   (2009-04-25 00:04) [37]

> [36] ТД   (24.04.09 23:27)
> прочитал ветку. а что за бд кто-нибудь скажет? ну кроме
> автора, ибо он не в курсе, как видно

VolgaDB [4]

> [35] Андрей (начинающий)   (24.04.09 23:06)
>
> > AndreyV ©   (24.04.09 21:08) [34]
> >  ... но есть ощущение, что автор не понимает, что делает.
>
> Почему? :) Я понимю, что при возникновении ошибки в какскадном
> удалении без возможности отката, разрушатся связи между
> таблицами.

В этой ДБ (коли нет транзакций) будет ещё хуже.


 
ТД   (2009-04-25 00:41) [38]


> AndreyV ©   (25.04.09 00:04) [37]
>  VolgaDB [4]

это что за бд? новая секретная разработка пентагона?
где про неё прочитать?


 
AndreyV ©   (2009-04-25 03:11) [39]

> [38] ТД   (25.04.09 00:41)
> > AndreyV ©   (25.04.09 00:04) [37]
> >  VolgaDB [4]
>
> это что за бд? новая секретная разработка пентагона?
> где про неё прочитать?

Вестимо где:
http://yandex.ru/yandsearch?text=VolgaDB&stpar2=%2Fh0%2Ftm2%2Fs2&stpar4=%2Fs2


 
Anatoly Podgoretsky ©   (2009-04-25 11:32) [40]

> ТД  (25.04.2009 0:41:38)  [38]

Старая, особенность, что все данные загружаются в память.



Страницы: 1 2 вся ветка

Текущий архив: 2009.06.14;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.011 c
15-1239292132
CoderM
2009-04-09 19:48
2009.06.14
Реализация Captcha


15-1239169620
vrem
2009-04-08 09:47
2009.06.14
Вопрос к программистам-безлимитчикам)


15-1239277793
Palladin
2009-04-09 15:49
2009.06.14
Delphi 6 и wine под Manrdiva 2009


11-1202161306
Jon
2008-02-05 00:41
2009.06.14
Wrap text in editbox/memo


15-1239379729
Real
2009-04-10 20:08
2009.06.14
Использование компонентов от Delphi 5 в Delphi 6