![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Query в цикле [D7]
click © (2006-11-19 19:31:00)Вот часть кода:
Query2.sql.Strings[0]:='select *';
Query2.sql.Strings[1]:='from '+chr(39)+'gider'+chr(39);
Query1.Locate('ps',TreeView1.Items[0].Item[counter].Text,[]); Query2.sql.Strings[2]:='where kodup='+chr(39)+Query1.fieldbyname('kodup').asString+chr(39);
Query2.Active:=true; Query2.First;
TreeNode1:=TreeView1.Items[0].Item[counter];
while Query2.Eof=false do
begin
Application.ProcessMessages;
TreeView1.Items.AddChild(TreeNode1,Query2.fieldbyname('gider').asString);
Query2.Next;
end;
//================
Query3.sql.Strings[0]:='select *';
Query3.sql.Strings[1]:='from '+chr(39)+'tr'+chr(39);
Query2.Locate('gider',TreeView1.Items[counter].Text,[]);
Query3.sql.Strings[2]:='where kodgider='+chr(39)+Query2.fieldbyname('kodgider').asString+chr(39);
Query3.Active:=true; Query3.First;
TreeNode1:=TreeView1.Items[counter];
while Query3.Eof=false do
begin
Application.ProcessMessages;
TreeView1.Items.AddChild(TreeNode1,Query3.fieldbyname('tr').asString);
memo1.Lines.Add(Query3.fieldbyname('tr').asString);
Query3.Next;
end;
в таком виде код работает просто отлично... а вот если первый запрос (Query2) я помещаю в цикл:
for counter:=0 to 5 do begin
Query2.sql.Strings[0]:='select *';
Query2.sql.Strings[1]:='from '+chr(39)+'gider'+chr(39);
Query1.Locate('ps',TreeView1.Items[0].Item[counter].Text,[]); Query2.sql.Strings[2]:='where kodup='+chr(39)+Query1.fieldbyname('kodup').asString+chr(39);
Query2.Active:=true; Query2.First;
TreeNode1:=TreeView1.Items[0].Item[counter];
while Query2.Eof=false do
begin
Application.ProcessMessages;
TreeView1.Items.AddChild(TreeNode1,Query2.fieldbyname('gider').asString);
Query2.Next;
end;
end;
//================
Query3.sql.Strings[0]:='select *';
Query3.sql.Strings[1]:='from '+chr(39)+'tr'+chr(39);
Query2.Locate('gider',TreeView1.Items[counter].Text,[]);
Query3.sql.Strings[2]:='where kodgider='+chr(39)+Query2.fieldbyname('kodgider').asString+chr(39);
Query3.Active:=true; Query3.First;
TreeNode1:=TreeView1.Items[counter];
while Query3.Eof=false do
begin
Application.ProcessMessages;
TreeView1.Items.AddChild(TreeNode1,Query3.fieldbyname('tr').asString);
memo1.Lines.Add(Query3.fieldbyname('tr').asString);
Query3.Next;
end;
то второй запрос (Query3) перестаёт что либо возвращать, т.е. на выходе пустые строки...
а мне надо-бы все-таки в цикле все это делать. Подскажите пожалуйста как сие сделать правильно...
click (2006-11-22 09:35:00) [1]Юрий спасибо большое!
Все получилось! А главное разобрался :)
Ветку можно закрывать....
uka (2006-11-22 08:21:00) [2]
> ЮЮ © (21.11.06 12:38) [12]
> При фиксированной структуре дерева я бы делал так.И без
> лишник телодвижений как по дереву, так и по НД(Locate);var
> root, psNode, giderNode: TTreeNode;begin Query1.SQL.Text:
> = 'select kodup, ps from ps'; Query2.SQL.Text:= 'select
> kodgider, gider from gider where kodup = :kodup'; Query1.
> Active:=true; TreeView1.Items.BeginUpdate; ScrenCursor
> := crSQLWait; root := TreeView1.Items[0]; try while
> not Query1.Eof do begin psNode := TreeView1.Items.AddChild(root,
> Query1.Fields[1].asString); Query2.Close; Query2.
> Parameters[0].AsInteger := Query2.Fields[0].Value; Query2.
> Open; while not Query2.Eof do begin giderNode
> := TreeView1.Items.AddChild(psNode, Query2.Fields[1].asString);
> ... Query2.Next; end; Query1.
> Next; end; finally TreeView1.Items.EndUpdate; Scren.
> Cursor := crDefault; end;end;
Благодарю, за подсказку. у меня был как раз этот случай.
click (2006-11-21 13:40:00) [3]Спасибо! Буду пробовать!
ЮЮ (2006-11-21 13:21:00) [4]как здесь во второй части кода:
click (21.11.06 11:44) [8]
if Query1.Locate('ps',TreeView1.Items[ну например 2 - неважно],[]) then begin
Query 2.Active:=true;
надеюсь просто опечатка. Для параметрического запроса мало Open.
надо
Query2. Close;
Query2.Parameters[0].Value := Query1.Fields[<индекс поля>].Value;
Query2. Open;
while not Query2.Eof do begin
//куда выводим результат тоже не важно...
Application.ProcessMessages;
тоже лишнее. можно ещё какую нибудь кнопочку нажать и станет выполняться ее обработчик, а потом подолжит этот.
Memo1.Lines.Add(Query2.FieldByName('gider').AsString);
Query 2.Next;
end;
end;
click (2006-11-21 13:08:00) [5]ЮЮ - спасибо Вам большое, обязательно попробую и попытаюсь разобраться...
И все же (если не надоел Вам) помогите сформировать запрос для Query2 ,без цикла и с Locate, как здесь во второй части кода:
click (21.11.06 11:44) [8]
просто для себя, хочу понять что я не так делаю...
ЮЮ (2006-11-21 12:48:00) [6]Query2.Parameters[0].AsInteger := Query2.Fields[0].Value;
следует читать как
Query2.Parameters[0].Value := Query2.Fields[0].Value;
ЮЮ (2006-11-21 12:38:00) [7]При фиксированной структуре дерева я бы делал так.
И без лишник телодвижений как по дереву, так и по НД(Locate);
var
root, psNode, giderNode: TTreeNode;
begin
Query1.SQL.Text:= 'select kodup, ps from ps';
Query2.SQL.Text:= 'select kodgider, gider from gider where kodup = :kodup';
Query1.Active:=true;
TreeView1.Items.BeginUpdate;
ScrenCursor := crSQLWait;
root := TreeView1.Items[0];
try
while not Query1.Eof do begin
psNode := TreeView1.Items.AddChild(root, Query1.Fields[1].asString);
Query2.Close;
Query2.Parameters[0].AsInteger := Query2.Fields[0].Value;
Query2.Open;
while not Query2.Eof do begin
giderNode := TreeView1.Items.AddChild(psNode, Query2.Fields[1].asString);
...
Query2.Next;
end;
Query1.Next;
end;
finally
TreeView1.Items.EndUpdate;
Scren.Cursor := crDefault;
end;
end;
click (2006-11-21 12:08:00) [8]
> ЮЮ © (21.11.06 11:50) [9]
1. connect производится через ADOConnected и проходит весьма успешно так как если я упрощаю условия запроса (скажем пишу тоже что и в Query1 только для gider а не для ps) то запрос возвращает все гидер как и положено.
2. С параметрами (Parametrs) до конца еще не разобрался, но учитывая что все запросы возвращают строки - пытаюсь это учесть...
3. Даже больше Items[0] - это все имеющиеся ps.
каждый ps может иметь в распоряжении несколько gider (а может не иметь вовсе)
каждый gider может иметь несколько tr
каждая tr имеет три tip
и вот после этого в зависимочти от выбранных итемов отсортировываются и соответственно добавляются к этому tip, записи таблицы клиентов, которые удовлетворяют всем ранее "пройденным" итемам т.е.
клиенты, которые имеют выбранный ps, gider,tr,tip
click (2006-11-21 11:54:00) [9]Имеющиеся поля: (а то пишу по памяти мог уже что нибудь напутать)
ps - название пункта[1]
kodup - код пункта [1]
_________________________
gider - пункт[2]
kodgider - код пункта [2]
kodup - код пункта [1] к которому привязан gider
ЮЮ (2006-11-21 11:50:00) [10]
> Т.е. ты сParametrs в коде - я опустил, но они там естественно
> есть ...
Неправильно заполненные или непримененные они и приведут к пустому НД.
Ты, насколько это млжно понять, пытаешься построить трех уровневое дерево дерево из трех разных таблиц?
click (2006-11-21 11:44:00) [11]Так как SlymRo предложил отредактировать мой код начиная с Query2 (а по другому у него и возможости небыло так как Query1 я не показывал :) ) , следовательно Query1 (ADOQuery) попытался сделать сам, и вобщем то, учитывая простоту запроса, много времени на это не ушло...
(сразу хочу прояснить что опыт работы c ADO это у меня первый,(впрочем и с SQL "на Вы"))...
вот что получилось: (пишу прям здесь исходников по друкой нет)
Query1.SQL.Text:='select * from ps;
Query1.Active:=true;
TreeNode1:=TreeView1.Items[0];
while not Query1.Eof do
begin
Application.ProcessMessages;
TreeView1.Items.AddChild(TreeNode1,Query2.fieldbyname('gider').asString);
Query1.Next;
end;
Здесь все в порядке запрос возвращает все значения поля ps и весьма успешно...
Теперь необходимо выполнить втрой запрос:
Query2.SQL.Text:='select gider, kodgider from gider where kodup= :kodup;';// а вот здесь проблема :(
if Query1.Locate('ps',TreeView1.Items[ну например 2 - неважно],[]) then begin
Query2.Active:=true;
while not Query1.Eof do
begin
//куда выводим результат тоже не важно...
Application.ProcessMessages;
Memo1.Lines.Add(Query2.FieldByName('gider').AsString);
Query1.Next;
end; end;
Connect, Parametrs в коде - я опустил, но они там естественно есть ...
Так вот проблема как Вы уже наверное поняли в формировании самого запроса... В тексте SQL Query2 я перепробовал кучу вариантов... ничего - на выходе пусто... Тот пример который я сейчас подставил в запрос взят из предложения SlymRo, дома же я пробовал много чего другого. Locate проходит успешно, а дальше ничего.
До того чтоб погрузить все это в цикл - я еще не дошел.... Помогите сформировать запрос пожалуйста.... до 2_30 ночи мне сегодня в голову ничего так и не пришло... а тогда уже займусь циклами...
З.Ы. Учусь...
click (2006-11-20 10:58:00) [12]Упс! Забыл ответить
> ЮЮ © (20.11.06 06:53) [1]
Нет, аутов не боюсь так как первый пример (рабочий цикл) редактировался из "нерабочего" прям здесь, на ходу так сказать, сounter забыл убрать.... туда можно поставить например единицу... А от 0 до 5 была выбрано для примера, но у TreeView Items[0].Count всегда > 38ми... (так уш задумано :) )
Когда проверялось что:
> в таком виде код работает просто отлично...
естественно counter присваевался вручную либо заменялся числом...
P.S. За совет по поводу Locate спасибо!
click (2006-11-20 10:25:00) [13]Всем принявшим участие ОГРОМНЕЙШЕЕ спасибо! Отдельное SlymRO!
Только просьба ветку пока не закрывать т.к. нет возможности проверить предложенное. Дома проверю, если больше вопросов не возникнет я сообщу!
ЮЮ (2006-11-20 09:08:00) [14]сорри, не обратил внимания на то что сдвиг обусловлен try, а не for.
SlymRO (2006-11-20 09:01:00) [15]ЮЮ © (20.11.06 8:59) [3]
Ано и так вне цикла...
ЮЮ (2006-11-20 08:59:00) [16]
> Так понятней и click (19.11.06 19:31)работает просто отлично.
> ..
Ещё и формирование текстов запросов следует вынести за цикл + выполнить Prepare
SlymRO (2006-11-20 08:47:00) [17]Так понятней и click (19.11.06 19:31)работает просто отлично...
var counter:integer;
Query2,Query3:TADOQuery;
Node,CNode:TTreeNode;
begin
Query2:=TADOQuery.Create(nil);
Query3:=TADOQuery.Create(nil);
try
Query2.Connection:=Query1.Connection;
Query2.SQL.Text:='select gider, kodgider from gider where kodup= :kodup;';
Query2.Parameters[0].Value:=-1;
Query2.Active:=true;
Query3.Connection:=Query1.Connection;
Query3.SQL.Text:='select tr from tr where kodgider= :kodgider;';
Query3.Parameters[0].Value:=-1;
Query3.Active:=true;
for counter:=0 to 5 do
begin
Query1.Locate('ps',TreeView1.Items[0].Item[counter].Text,[]);
Query2.Parameters[0].Value:=Query1.fieldbyname('kodup').Value;
Query2.Requery;
Node:=TreeView1.Items[0].Item[counter];
while not Query2.Eof do
begin
CNode:=TreeView1.Items.AddChild(Node,Query2.Fields[0].asString);
Query3.Parameters[0].Value:=Query2.Fields[1].Value;
Query3.Requery;
while not Query3.Eof do
begin
TreeView1.Items.AddChild(CNode,Query3.Fields[0].asString);
memo1.Lines.Add(Query3.Fields[0].asString);
Query3.Next;
end;
Query2.Next;
end;
end;
finally
Query2.Free;
Query3.free;
end;
end;
ЮЮ (2006-11-20 06:53:00) [18]Чему равен counter в первом случае?
И почему во втором случае именно такой диапазон counter:=0 to 5
Out of Range не пугает?
И все-таки следует писать
ifQuery1. Locate('ps',TreeView1.Items[0].Item[counter].Text,[]) then begin
end;
Чтобы анализировать почему не найдена запись, а не ловить баги среди добавленного мусора.