![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как поступить правильно, соблюдая каноны программирования? [D7, WinXP]
kyn66 © (2005-08-19 11:12:00)Уважаемые мастера, САБЖ. Есть таблица Таб1, в которой (после фильтра, к примеру) имеется 30 записей.
Каждая запись ессно имеет свой ID. У нее в подмастерьях имеется ешшо одна таблица Таб2, которая по ID
связана с Таб1. Мне нужно удалить все записи из Таб1 и ессно все подчиненные записи Таб2. Есть два варианта
удаления:
1) Я в цикле прохожу по всем записям Таб1 и через SQL-запрос удаляю все записи из Таб2, где есть связь по ID Таб1
while not Таб1.EOF do
begin
SQL.Add(Format('DELETE FROM %s WHERE OperID = :p1', [Tab2]));
Parameters[0].Value := Таб1.FieldByName('ID').Value;
ExecSQL;
SQL.Clear;
Таб1.Next;
end;
2) Я опять-же в цикле прохожу по Таб1, в некую переменную (S : TStrings) собираю все ID таблицы Таб1, затем SQL-запрос
выполняю тока 1 раз
SQL.Add(Format('DELETE FROM %s WHERE OperID IN (S)', [Tab2]));
ExecSQL;
И тот и другой способ отработают, но меня интересует как правильно нужно поступать?
Ega23 (2005-08-19 12:46:00) [21]Делаешь один раз и забываешь про эту проблему навсегда.
Угу. Удаляешь потом одну запись и теряешь пол-базы.
Не, автоматическое каскадное удаление - это зло. Хуже только сифилис.
afanasic (2005-08-19 12:45:00) [22]Прошу прощения, Таб1 и Таб2 необходимо поменять местами!!!
afanasic (2005-08-19 12:44:00) [23]Пример для Oracle
alter table Таб1 add constraint Имя_надстройки foregn key (id) references Таб2(id) on delete cascade;
Делаешь один раз и забываешь про эту проблему навсегда.
Что-то подобное должно быть и в других СУБД обязательно...
alex_*** (2005-08-19 12:37:00) [24]DELETE T2 FROM T2 INNER JOIN T1 ON T2.OrderID = T1.ID AND {условие}
DELETE FROM T1 WHERE {условие}
хотя, если надо снести всё, то проще [1]
Ega23 (2005-08-19 12:09:00) [25]А какая разница?
Всё дело в уровне абстракции. Сервер - это сервер. Клиент - это клиент. Могут оба физически находиться на одной машине. Могут - на разных. Механизм подключения-то - общий.
kyn66 (2005-08-19 12:03:00) [26]>> Ega23
Во, млин, спасибо, ща буду пробывать разбираться. Да, но это относится если ты пишешь клиент-сервер? А если я просто на сервере держу базы а работаю с ними в обычном режиме?
Ega23 (2005-08-19 11:55:00) [27]Вот тебе пример ХП для MS SQL, с каскадным удалением:
Print 'S_RTTIProc - процедура для работы с RTTI системы'
go
if exists (select * from sysobjects where id = object_id(N'[S_RTTIProc]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [S_RTTIProc]
GO
CREATE PROCEDURE S_RTTIProc
@ActNam varchar(32)='NONE',
.........
-- Остальные параметры
.........
As
declare
@NULLGUID uniqueidentifier,
@result int,
@x int,
@aSQL varchar(8000),
@ss varchar(8000),
@ss1 varchar(8000);
Set @NULLGUID = '00000000-0000-0000-0000-000000000000';
Set NoCount ON;
Set @Result=0;
Select @ActNam=RTrim(LTrim(UPPER(@ActNam)));
if @ActNam='CLASSFIELDS.DEL'
begin
Delete ClassFields where (@UNID=-1 or UNID=@UNID) and
(@CLSID=-1 or CLSID=@CLSID) and
(@FldTypCod=-1 or FldTypCod=@FldTypCod);
Select @Result=@UNID;
Goto Fin;
end;
if @ActNam='CLASSMETHODS.DEL'
begin
Delete ClassMethods
where (@CLSMetCod=-1 or CLSMetCod=@CLSMetCod) and
(@CLSID=-1 or CLSID=@CLSID);
Select @Result=@CLSMetCod;
Goto Fin;
end;
if @ActNam='CLASSSTATES.DEL'
begin
Delete ClassStates
where (@UNID=-1 or UNID=@UNID) and
(@CLSID=-1 or CLSID=@CLSID);
Select @Result=@CLSMetCod;
Goto Fin;
end;
if @ActNam='CLASSES.DEL'
begin
-- Сначала удалим ClassFields
exec S_RTTIProc @ActNam='ClassFields.Del', @CLSID=@CLSID;
-- Теперь удалим ClassMethods
exec S_RTTIProc @ActNam='ClassMethods.DEL', @CLSID=@CLSID;
-- Удаляем ClassStates
exec S_RTTIProc @ActNam='ClassStates.DEL', @CLSID=@CLSID;
Delete Classes where CLSID=@CLSID;
Select @Result=@CLSID;
Goto Fin;
end;
fin:
set nocount off;
return(@result);
GO
Гаврила (2005-08-19 11:39:00) [28]Из приведенных двух вариантов предпочтительнее второй.
Если источником данных является сервер - то такую логику, как удаление подчиненных записей, надо выносить на сервер.
Даже без хранимых процедур - просто настройкой свойств связи между таблицами
kyn66 (2005-08-19 11:31:00) [29]Ну, до этого я ешшо не дошел 8-(
Ega23 (2005-08-19 11:30:00) [30]А если хороший тон интересует, то забудь про прямую работу с таблицами. Должна быть прокладка в виде хранимых процедур.
Ega23 (2005-08-19 11:29:00) [31]Если ВСЕ записи, то
delete from Tab2
delete from Tab1
?