Форум: "Базы";
Текущий архив: 2007.02.11;
Скачать: [xml.tar.bz2];
ВнизQuery в цикле Найти похожие ветки
← →
click (2006-11-19 19:31) [0]Вот часть кода:
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) перестаёт что либо возвращать, т.е. на выходе пустые строки...
а мне надо-бы все-таки в цикле все это делать. Подскажите пожалуйста как сие сделать правильно...
← →
ЮЮ © (2006-11-20 06:53) [1]Чему равен counter в первом случае?
И почему во втором случае именно такой диапазон counter:=0 to 5
Out of Range не пугает?
И все-таки следует писатьif Query1.Locate("ps",TreeView1.Items[0].Item[counter].Text,[]) then begin
end;
Чтобы анализировать почему не найдена запись, а не ловить баги среди добавленного мусора.
← →
SlymRO (2006-11-20 08:47) [2]Так понятней и 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 08:59) [3]
> Так понятней и click (19.11.06 19:31)работает просто отлично.
> ..
Ещё и формирование текстов запросов следует вынести за цикл + выполнить Prepare
← →
SlymRO (2006-11-20 09:01) [4]ЮЮ © (20.11.06 8:59) [3]
Ано и так вне цикла...
← →
ЮЮ © (2006-11-20 09:08) [5]сорри, не обратил внимания на то что сдвиг обусловлен try, а не for.
← →
click (2006-11-20 10:25) [6]Всем принявшим участие ОГРОМНЕЙШЕЕ спасибо! Отдельное SlymRO!
Только просьба ветку пока не закрывать т.к. нет возможности проверить предложенное. Дома проверю, если больше вопросов не возникнет я сообщу!
← →
click (2006-11-20 10:58) [7]Упс! Забыл ответить
> ЮЮ © (20.11.06 06:53) [1]
Нет, аутов не боюсь так как первый пример (рабочий цикл) редактировался из "нерабочего" прям здесь, на ходу так сказать, сounter забыл убрать.... туда можно поставить например единицу... А от 0 до 5 была выбрано для примера, но у TreeView Items[0].Count всегда > 38ми... (так уш задумано :) )
Когда проверялось что:
> в таком виде код работает просто отлично...
естественно counter присваевался вручную либо заменялся числом...
P.S. За совет по поводу Locate спасибо!
← →
click (2006-11-21 11:44) [8]Так как 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 ночи мне сегодня в голову ничего так и не пришло... а тогда уже займусь циклами...
З.Ы. Учусь...
← →
ЮЮ © (2006-11-21 11:50) [9]
> Т.е. ты сParametrs в коде - я опустил, но они там естественно
> есть ...
Неправильно заполненные или непримененные они и приведут к пустому НД.
Ты, насколько это млжно понять, пытаешься построить трех уровневое дерево дерево из трех разных таблиц?
← →
click (2006-11-21 11:54) [10]Имеющиеся поля: (а то пишу по памяти мог уже что нибудь напутать)
ps - название пункта[1]
kodup - код пункта [1]
_________________________
gider - пункт[2]
kodgider - код пункта [2]
kodup - код пункта [1] к которому привязан gider
← →
click (2006-11-21 12:08) [11]
> ЮЮ © (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
← →
ЮЮ © (2006-11-21 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;
← →
ЮЮ © (2006-11-21 12:48) [13]Query2.Parameters[0].AsInteger := Query2.Fields[0].Value;
следует читать как
Query2.Parameters[0].Value := Query2.Fields[0].Value;
← →
click (2006-11-21 13:08) [14]ЮЮ - спасибо Вам большое, обязательно попробую и попытаюсь разобраться...
И все же (если не надоел Вам) помогите сформировать запрос для Query2 ,без цикла и с Locate, как здесь во второй части кода:
click (21.11.06 11:44) [8]
просто для себя, хочу понять что я не так делаю...
← →
ЮЮ © (2006-11-21 13:21) [15]как здесь во второй части кода:
click (21.11.06 11:44) [8]if Query1.Locate("ps",TreeView1.Items[ну например 2 - неважно],[]) then begin
Query2.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);
Query2.Next;
end;
end;
← →
click (2006-11-21 13:40) [16]Спасибо! Буду пробовать!
← →
uka © (2006-11-22 08:21) [17]
> ЮЮ © (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-22 09:35) [18]Юрий спасибо большое!
Все получилось! А главное разобрался :)
Ветку можно закрывать....
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2007.02.11;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.045 c