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

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

SQL


Страницы:   1 2

Фагот ©   (2003-03-06 13:11:00) 

Здравствуйте!
У меня есть SQL-запрос, который для большой таблицы вополняется очень долго. Можно ли сделать так, чтобы первый запрос составлял набор данных (часть таблицы), а второй с этим набором работал и мог вызываться кагда угодно и сколько угодно. Короче говоря, чтобы Query2 работал с результатами работыв Query1.
Если это всё-же возможно, то объясните, пожалуйста, попдробнее.


ЮЮ   (2003-03-12 07:10:00) [1]

Это твой запрос применялся ко всей таблице, причем, если NOT (Topic.FirstDate IS NULL), то опять должен был присвоиться NULL (не корректировка, а качели какие-то), а запрос Johnmen © (11.03.03 12:26) как раз и применяется лишь к тем записям, где Topic.FirstDate IS NULL, а не ко всей таблице (см.WHERE Topic.FirstDate IS NULL)

А долго, возможно, из-за твоего предыдущего запроса, обNILLившего до этого поле FirstDate таблицы Topic.
Попробуй повторить и почувствуй разницу :-)


sunrider   (2003-03-11 15:46:00) [2]

Можно поробовать для работы с результатом запроса
использовать ClientDataset, а данные передать в него как поток
XML. Тогда даже в случае сложного запроса из разных таблиц можно
редактировать все поля и сохранять данные в нужных таблицах


Фагот   (2003-03-11 15:39:00) [3]

Johnmen"у
Это конечно хорошо, что корректнее. Но вопрос изначально стоял в том, чтобы иметь возможность апдейтить не всю таблицу, а только её часть. В том запросе, который привёл я выбока из таблицы делается каждый раз, когда я делаю запрос, а мне посути, нужна только небольшая её часть.


Johnmen   (2003-03-11 13:21:00) [4]

>Фагот © (11.03.03 13:12)

То есть, Topic.Topic могут повторяться ?

>...это условие никак не ускоряет выполнение запроса

Просто оно корректное...:)


Фагот   (2003-03-11 13:12:00) [5]

Дак запрос-то работает крайне медленно!!!
Я хочу единожды слелать выборку из таблицы, а потом уже в этой выборке несколько раз делать апдейты! Если каждый раз применять этот запрос к полной таблице, то на моей тачке этот запрос выполняется около часа. Считай, что он каждый раз смотрит всю таблицу.
Johnmen"у - это условие никак не ускоряет выполнение запроса.


Johnmen   (2003-03-11 12:26:00) [6]

UPDATE Topic
SET Topic.FirstDate=(SELECT MAX(Stage.SecondDate) FROM Stage WHERE Topic.Topic=Stage.Topic)
WHERE Topic.FirstDate IS NULL

А в чем все-таки проблема ?


Фагот   (2003-03-11 12:18:00) [7]

Прошу прощения, но я на самом деле соврал в запросе. Реальный запрос вот:
UPDATE Topic
SET Topic.FirstDate=(SELECT MAX(Stage.SecondDate) FROM Stage WHERE Topic.Topic=Stage.Topic AND Topic.FirstDate IS NULL)


Val   (2003-03-11 12:01:00) [8]

>Johnmen © (11.03.03 11:51)
похоже, что автор просто ошибся в приведенном здесь тексте, поскольку утверждает, что данный запрос работает.


Val   (2003-03-11 11:56:00) [9]

а как с индексами на участвующие в запросе поля?


Johnmen   (2003-03-11 11:51:00) [10]

А посмотреть синтаксис INSERT влом ?


Фагот   (2003-03-11 11:46:00) [11]

Ну вот запрос
Insert Table2
Set Table2.Field2=(Select (MAX Field2) FROM Table1 where Table2.Field2=Table1.Field1)


Anatoly Podgoretsky   (2003-03-09 10:08:00) [12]

Сказали же покажи запрос


Фагот   (2003-03-09 10:01:00) [13]

В принципе, второй запрос делает изменения в таблице, поэторму, мне кажется, нельзя использовать временные таблицы, потому как потом из этой временной надо переносить в настоящую - в принципе опять те же грабли...


Val   (2003-03-07 13:17:00) [14]

>oomneeq © (07.03.03 13:04)
вопрос был адресован автору.

> На серверных платформах для этого делается Select from Select
> ...
> но для локального парадокса нужно вот так извращаться.

можно попробовать применить Local Views.


oomneeq   (2003-03-07 13:04:00) [15]

>Val © (06.03.03 14:56)
>хотелось бы посмотреть и на сам запрос
?
cм. >oomneeq © (06.03.03 14:52)

Может такой пример будет проще к пониманию:
S1:="select C.X1 as F1,min(C.X2) as F2 from C group by C.X1";

S2:="select A.F1,A.F2,B.F1,B.F2 from A," +QuasiView("TmpTableName",S1)+" B "+
"where A.F1=B.F1";

В момент присвоения S2 данного выражения происходит:
Вызов функции QuasiView, которая
1)выполнит запрос S1 и поместит результат в файл TmpTableName
2)возвратит своим резалтом TmpTableName, которое может быть использован при составлении других запросов.
В данном случае S2.

после чего к TmpTableName можно делать запрос.
что и будет сделано, когда будет выполняться S2

То есть в конечном итоге S2 будет выглядеть так
"select A.F1,A.F2,B.F1,B.F2 from A, TmpTableName B where A.F1=B.F1";
На это тебе хотелось посмотретЬ ?



NB
S1 я специально сделал с агрегацией, чтоб было оправдано разбиение на два этапа. в противном случае можно было бы обойтись одним запроосом..

На серверных платформах для этого делается Select from Select ...
но для локального парадокса нужно вот так извращаться.








Val   (2003-03-06 14:56:00) [16]

хотелось бы посмотреть и на сам запрос


oomneeq   (2003-03-06 14:52:00) [17]

поправка

FN5:=TempDBFN; // это просто получение имени временного файла
S:=Format("select B.*, QTY as Продано "+
" from "%s" B left outer join %s on (B.КОД=CODE)",
[ <имя файла другой таблицы>,KHQuasiView(FN5,S1)]);
Q:=SQLSet(S); //получили результат итогового запроса


oomneeq   (2003-03-06 14:47:00) [18]

Вот это тебе должно помочь
Надеюсь разберешься
В свое время делал для парадокса

//Для начала используемые в примере функции
//
function SQLSet(Alias,SQLStr:string):TRxQuery;
var TryAgain:boolean;
TmpTabl : TTable;
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}
if TryAgain then Cry("Захват данных другим пользователем. Нажмите OK чтобы повторить попытку.");
if not TryAgain then raise;
end
else raise
end;
until not Tryagain;
end;
except
Result.Free;
raise;
end
end;

//вот та самая VIEW-эмуляторка под парадокс
//ViewFN - имя файла для временной таблицы, куда помещать результаты
//ф-я возвращает то же имя, чтоб можно было его вставлять
//в следующий запрос - таблица-то(файл) уже создана
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;
//А вот пример использования
.....
//Первый запрос
S1:=Format("SELECT %s as CODE,SUM(%s) as QTY "+
" FROM %s,%s,"%s" WHERE %s=DETLCODE and %s=%s and "+
"(%s>=%s) and (%s<%s) GROUP BY %s",
[xdtlCode,xdtlQTY,Inventory.InvSaleNak.QDOSFileName,
Inventory.InvSaleNak.DetlTable.QDOSFileName,FN2,
xdtlCODE,xdtlNak,xnakID,xnakRegDate,SQLDate(BegPD),
xnakRegDate,SQLDate(EndPD+1),xdtlCode]);
end;
//Второй запрос, обращается к результатам первого
FN5:=TempDBFN;
S:=Format("select B.*, QTY as Продано "+
" from "%s" B left outer join %s on (B.КОД=CODE)",
[FN5, KHQuasiView(FN5,S1)]);
Q:=SQLSet(S); //получили результат итогового запроса


Наталия   (2003-03-06 14:22:00) [19]

Можно. Читай help по LocalSQL. Сохраняешь текст первого запроса в файле с расширением sql и второй запрос делаешь к этому файлу.
Это как бы аналог view. Если я правильно вопрос поняла.


Dms   (2003-03-06 13:45:00) [20]

если важна скорость - откажись от Paradox. Используй InterBase или еще что, но оптимизируя приложения под pAradox по скорости далеко не уйдешь ...


Страницы:   1 2

Наверх

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