Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Глюки ADO часть 2-ая [D3, D4, D5, D6, MSSQL, Access]


Страницы:   1 2

RAVEN ©   (2002-01-28 15:45:00) 

Доброё время суток, Мастера! Проблема в следующем: Мне нужно удалить некоторые записи из одной таблицы. Всё бы ничего, но эти записи подчинены иерархии, т.е. одна является дочерней другой и т.д... Если какие-нибудь предложения будут по поводу удаления, готов их выслушать(заранее спасибо). Но проблема в том, что мой способ удаления что-то не совсем корректно работает. Значит способ такой. Я вешаю на обработчик события BeforeDelete набора данных(DS:TADODataSet, например), такую строку

PostMessage(MainForm.Handle,DSM_DELETEDOCUMENT,Integer(DataSet),DataSet.Fields[0].AsInteger);

Ниже приведён обработчик мессаджа DSM_DELETEDOCUMENT

procedure TMainForm.DeleteDocument(var Message:TMessage);
var DS:TADODataSet;
Value:integer;
begin
Value:=Message.LParam;
DS:=TADODataSet(Message.WParam);
if not (DS.State=dsInactive) then
While DS.Locate("Parent",Value,[]) do DS.Delete;
end;
При трассировке события BeforeDelete и AfterDelete срабатывают, но дочерние записи удаляются или не все или не удаляются вообще, а главная материнская запись удаляется всегда. Помогите пожалуйста понять что происходит?


RAVEN   (2002-02-04 12:58:00) [1]

Ребята, всем спасибо огромное, но я сделал всё-таки по своему с PostMessage просто у меня на процедуре обработки AfterDelete стояла процедура которая "тормозила" обработку сообщений. Я её тоже на мессаг "посадил" и всё заработало. Ещё раз всем спасибо.


Delirium   (2002-01-30 18:56:00) [2]

А действительно! Эй RAVEN, решение твоей проблемы элементарно!
kig, а ты молоток!


kig   (2002-01-30 18:50:00) [3]

Если таблицу открыть - то блокировка наблюдается - если толкать команду из sql - то все удаляет нормально.


Delirium   (2002-01-30 18:48:00) [4]

Нет, так как возникает проблема с блокировкой, по крайней мере в ACCESS2000


kig   (2002-01-30 18:44:00) [5]

А связь таблицы один-к-многим саму на себя (ID - IDParent) + каскадное удаление не подходит? (Правда в этом случае признаком root значение IDParent = значение ID).


Fay   (2002-01-30 17:55:00) [6]

Пардон! Не понял сразу , что речь об ACCSESS-е


Delirium   (2002-01-30 12:05:00) [7]

>handra
Дело тут не в разнице между Send и Post, и не в каскадном удалении - таблица одна, и не в рекурсивной процедуре - работаем с ACCESS. Хотя с последним, стоит подумать, я никогда не создавал поцедуры в ACCESS, но попробывать можно.


handra   (2002-01-30 11:34:00) [8]

Еще, у меня Access2002 (входит в Office XP) - чумовая вещь, поддерживает каскадные удаление и обновление...


handra   (2002-01-30 11:07:00) [9]

Хэх, а кто-нить разницу между SendMessage и PostMessage помнит?
Так вот, SendMessage возвращает управление после отработки сообщения, а PostMessage возвращает управление сразу (помещает сообщение в очередь). И наверняка, отсутствую внешний ключ (foreign key) Table.Parent->Table.ID
И, если используется MSSQL2000, почему не сделать каскадное удаление? Или оформить все в виде хранимой процедуры.
P.S. я такие задачи всегда решал с помощью рекурсивной хранимой процедуры...


Alex Y   (2002-01-30 05:47:00) [10]

2 RAVEN для этого тебе и нужен флаг Deleting.
Событие да, будет вызываться, однако флаг тебя просто выводит из него. А по окончании удаления меняешь флаг и событие опять становится работоспособным.


Delirium   (2002-01-29 17:33:00) [11]

Тогда делай как Alex Y сказал


RAVEN   (2002-01-29 17:10:00) [12]

>DeliriumГоспода, БД на акцессе (файл-серверная), а клиент на Делфях.


Delirium   (2002-01-29 16:57:00) [13]

Тебе нужна рекурсивная процедура удаления в MSSQL


RAVEN   (2002-01-29 16:47:00) [14]

>Delirium

procedure TForm1.ADOTable1BeforeDelete(DataSet: TDataSet);
begin
ADOTable1.Connection.Execute("delete MyTable where idField in (...)");
end;

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


RAVEN   (2002-01-29 16:38:00) [15]

>FAY Ну суть таблы такая:
ID Parent Field1, Field2,...
Поле ID и Parent одного типа, т.е. целочисленные, в Parent заносится ID родительского док-та, если стоит 0, то родителя нет. Всё.


RAVEN   (2002-01-29 16:33:00) [16]

>AlexY Дело в том что DeleteChilds будет вызывать метод Delete у той же таблицы. Т.е. будет возникать бесконечная рекурсия.


Fay   (2002-01-29 12:04:00) [17]

Опиши таблу


Delirium   (2002-01-29 11:59:00) [18]

А я бы сделал так:

procedure TForm1.ADOTable1BeforeDelete(DataSet: TDataSet);
begin
ADOTable1.Connection.Execute("delete MyTable where idField in (...)");
end;

procedure TForm1.ADOTable1AfterDelete(DataSet: TDataSet);
begin
ADOTable1.Requery;
end;

а что будет на месте "..." - это уже из условий задачи.


Alex Y   (2002-01-29 10:03:00) [19]

Попробуй такой вариант:

Deleting := False - признак процесса удаления

provedure tMyTable.BeforeDelete(...)
begin
if Deleting then Exit;
Deleting := True;
DeleteChilds(FieldByName("Parent").AsString); // Ушел в
рекурсию
Deleting := False;
end;


RAVEN   (2002-01-29 08:38:00) [20]

Я наверное чего-то не понимаю, но потомки в дереве тоже могут рассматриваться как родители. Самый лучший способ удалить узлы дерева это рекурсивная процедура, но с событием это не прокатит, можно также сформировать список ключей удаляемых родительских(относительно дочерних узлов)хотя это самый извращённый способ. Может я просто заработался. Если не трудно, приведите пожалуйста пример вышесказанных Вами слов.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо