Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > Как в запр.в TQuery2 исп. НД,полученный от TQuery1


Автор: AlexV 12.12.2002, 21:19
Подскажите пожалуйста
Как в запросе select в TQuery2 использовать набор данных, полученный в результате запуска TQuery1 ?
То есть нужно выполнить что-то типа TQuery2.SQL.Add('select ... from TQuery1 where ...');
Но так нельзя ?

Автор: oomneeq 12.12.2002, 21:53
Цитата(AlexV @ 12.12.2002, 13:19)
Подскажите пожалуйста
Как в запросе select в TQuery2 использовать набор данных, полученный в результате запуска TQuery1 ?
То есть нужно выполнить что-то типа TQuery2.SQL.Add('select ... from TQuery1 where ...');
Но так нельзя ?

ну вот прям так конечно нельзя
но добиться того что хочется можно другими путями
например
1)состряпать из TQuery1 VIEW
(create view as TQuery1.SQL.Text - если DB-платформа VIEW поддерживает)

2)Написать для ТQuery такой запрос, чтоб выбирал cразу  то что надо
(select ... from (TQuery1.SQL.Text) опять же DB должен позволять
констукцию select from select )

3)сохранить результсет от TQuery1 во временную таблицу, сделать запрос к ней
(нормальный вариант для локальных DB уп Paradox)

Автор: AlexV 12.12.2002, 22:11
3-й вариант мне понравился больше других, поскольку я подключаюсь к Paradox.
У меня возникала такая идея, но возникал вопрос:
Как сохранить результат Query1 в новую таблицу dbf ?

Автор: AlexV 12.12.2002, 22:13
.. извиняюсь, я подключаюсь к dbf (FoxPro)
Но все равно вопрос тот же
Как сохранить результат Query1 в новую таблицу dbf ?

Автор: neutrino 12.12.2002, 22:35
А можно использовать вложенные запросы?

P.S. Я в этом не силен. Просто как раз про них читал...


Автор: oomneeq 13.12.2002, 09:09
Цитата(AlexV @ 12.12.2002, 14:13)
.. извиняюсь, я подключаюсь к dbf (FoxPro)
Но все равно вопрос тот же
Как сохранить результат Query1 в новую таблицу dbf ?

Завтра с работы заброшу сюда пример для парадокса
если работаете через бде то для дбф он должен тоже сгодится.

Автор: oomneeq 13.12.2002, 09:13
Цитата(neutrino @ 12.12.2002, 14:35)
А можно использовать вложенные запросы?

P.S. Я в этом не силен. Просто как раз про них читал...

А что ты называешь вложенными?
Select from select .. ?
если да, то не все БД его подерживают
а локальные так ваще вряд ли.
В завтрашнем примере будет имитация такой вложенности
а пока  - спааатьь :)

Автор: Fantasist 13.12.2002, 15:08
А чем view хуже?
Здесь уже почти все обсудили:

http://www.forum.vingrad.ru/cgi-bin/newforum/ikonboard.cgi?act=ST;f=2;t=4788;st=0

А в таблицу, это вроде так:

SELECT ... FROM ... INTO <имя таблицы>

Автор: AlexV 13.12.2002, 15:51
Я работаю с ADO. Подключаюсь к dbf. Вложенный запрос пробовал, но выдавались какие-то ошибки, и как я понял, dbf не поддерживает сложные вложенные запросы. Тем вложенность несколькоуровневая и более того, вложенные запросы с группировкой.
Поэтому я считаю, что лучше не лепить все в кучу, а выполнять запросы последовательно, сохраняя промежуточные результаты во временные таблицы.
Как это сделать, я пока не знаю.
У кого есть идеи ?

Автор: oomneeq 13.12.2002, 18:30
Цитата(AlexV @ 13.12.2002, 07:51)

Ну вот обещаный пример
надеюся разберетесь...
останутся вопросы, задавайте смело.

function SQLSet(Alias,SQLStr:string):TRxQuery;
var TryAgain:boolean;
   TmpTabl : TTable;
   DS      : TClientDataSet;
   S       : String;
begin
Result:=TRxQuery.Create(nil);
Result.ParamCheck:=false; //to prevent Alias sign to be interpreded as Param sign (:)
try
   with Result do begin
    if Alias<>'' then begin
     DataBaseName:=Alias;
     SQLStr:=DelAllSubstr(':'+Alias+':',SQLStr);
    end;
    SQL.Text:=SQLStr;
    repeat
     try
      TryAgain:=false;
      Open;
     except
      on E:EDBEngineError do begin
       TryAgain:=(E as EDBEngineError).Errors[0].Errorcode=10245;{File is locked}
       TryAgain:=(E as EDBEngineError).Errors[0].Errorcode=10245;{File is locked}
       if TryAgain then Cry('Захват данных другим пользователем. Нажмите OK чтобы повторить попытку.');
       if not TryAgain then raise;
      end
      else raise
     end;
    until not Tryagain;
   end;
  except
   Result.Free;
   raise;
  end
end;

function KHQuasiView(ViewFN,SQLStmnt:string):string;
var TmpQ:TQuery;
    TmpT:TTable;
begin
TmpQ:=SQLSet(SQLStmnt);
TmpT:=TTable.Create(nil);
TmpT.TableName:=ViewFN;
TmpT.BatchMove(TmpQ,batCopy);
TmpQ.Free;
Result:='"'+ViewFN+'"';
TmpT.Free;
end;

Автор: Medved 15.12.2002, 18:43
Использовать передачу параметров через свойство DateSource компонента TQuery

или использовать вложенный подзапрос.....

(второй вариант ИМХО предпочтительней)


Автор: AlexV 16.12.2002, 15:22
использовать вложенный подзапрос ?
только что попробовал - не получилось.
Пишет [Microsoft][ODBC Visual FoxPro Driver ]Syntax error.
По раздельности было 3 запроса, первые 2 независимые, а 3-й использует результаты первых 2-х.

analitF1
SELECT * FROM analit WHERE (((analit.SCHET)='621' Or (analit.SCHET)='622'))

MAIN_DT621
SELECT * FROM main WHERE (((main.DT_SCHET)="621"));

SELECT AnalitF1.CODE, AnalitF1.NAME, Sum(MAIN_DT621.SUMMA) AS Sum1
FROM AnalitF1 INNER JOIN MAIN_DT621 ON AnalitF1.CODE = MAIN_DT621.DT_CODE
GROUP BY AnalitF1.CODE, AnalitF1.NAME


Вот SQL код TADOQuery после склейки (подзапросы):

SELECT AnalitF1.CODE, AnalitF1.NAME, Sum(MAIN_DT621.SUMMA) AS Sum1
FROM (SELECT * FROM analit AnalitF1 WHERE (((analitF1.SCHET)='621' Or (analitF1.SCHET)='622'))) INNER JOIN (SELECT * FROM main MAIN_DT621 WHERE (((main.DT_SCHET)="621"))) ON AnalitF1.CODE = MAIN_DT621.DT_CODE
GROUP BY AnalitF1.CODE, AnalitF1.NAME

Если подзапросами не получается, то мож первым способом воспользоваться.
Насчет первого способа: Как это в DataSource в TADOQuery запихать параметры?

Автор: Medved 16.12.2002, 19:59
Во-первых Select from select ..  - это детище Майкрософтовских программистов, которое я не рекомендую использовать, так как это отклонение от стандарта SQL.

я уже писал, как правильно создавать вложеные подзапросы, вот линк: http://www.forum.vingrad.ru/cgi-bin/newforum/ikonboard.cgi?act=ST;f=2;t=4788



Во-вторых, про передачу параметров через свойство DateSource компонента TQuery

Вот пример:
1)таблица расхода товара (Rashod)- компонент RasQuery (TQuery), к нему подвязан TDataSource - dsRasQuery;
В ней имеются поля NameTovar, Data, Kolvo;

2)таблица товаров (Tovar) - компонент TovarQuery, подвязан dsTovarQuery.
В ней имеются поля NameTovar, Description, Year;

в RasQuery SQL запрос следующего вида:
Код

SELECT * FROM Rashod
WHERE NameTovar = :NameTovar
ORDER BY Date, Kolvo


в TovarQuery:
Код

SELECT NameTovar FORM Tovar
WHERE Year = '2002'


Теперь, свойству DataSource компонента RasQuery пристваиваем dsTovarQuery.

Вот и все!

Должен заметить, что  в качестве значения параметра :NameTovar берется текущее значение поля NameTovar из НД TovarQuery, как если бы это было назначено при помощи оператора

Код

RashodQuery.ParamByName('NameTovar').Value := TovarQuery.FieldByName('Tovar').Value;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)