Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.06.14;
Скачать: [xml.tar.bz2];

Вниз

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

 
Андрей (начинающий)   (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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.018 c
3-1222059679
ЮЮ
2008-09-22 09:01
2009.06.14
MS Access-овские OLE-объекты. Как с ними работать без Access-а?


2-1240577756
гранит
2009-04-24 16:55
2009.06.14
Вопрос


2-1240560533
Nameziz
2009-04-24 12:08
2009.06.14
связать списки


2-1240782648
swips
2009-04-27 01:50
2009.06.14
Вызов TIdHTTP.GET в несколько потоков


2-1240558333
DDD329
2009-04-24 11:32
2009.06.14
QReport+TADOQuery





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский