Страница 1 из 2
Как ускорить запрос
Добавлено: 26 май 2010, 12:13
BlazeBio
Есть такой
Код: Выделить всё
create view v1
as select
katmc.*
from katmc where (katmc.nrec=soprorda.cmc) and (katmc.nrec=sporder.cmc);
А есть такой неработающий. Компилятор просит ключ для soprorda и sporder
Код: Выделить всё
create view v1
as select
katmc.*
from katmc where ((katmc.nrec==soprorda.cmc and katmc.nrec=sporder.cmc));
и третий вариант
Код: Выделить всё
create view v1
as select
katmc.*
from katmc where ((katmc.nrec==soprorda.cmc(noindex) and katmc.nrec=sporder.cmc(noindex)));
Можно ли что-то сделать, чтобы ускорить эти запросы ?
Добавлено: 26 май 2010, 12:19
Vik
Жутковатые вьюхи вы тут нарисовали) Может поясните, что хотите сделать?
Добавлено: 26 май 2010, 12:25
BlazeBio
Да я знаю

.
Код: Выделить всё
if (v1.Getfirst katmc =tsok)
{
do
{
if (Getfirst sklorder where ((katsopr.nrec == sklorder.csopr /*and 1==sklorder.vidorder*/)) =tsok)
{
do
{
If (Getfirst soprorda where (( spsopr.nrec == soprorda.cspsopr(noindex) and v1.katmc.nrec==soprorda.cmc(noindex)))=Tsok )
{
do
{
If (Getfirst sporder where ((sklorder.nrec == sporder.csklorder and v1.katmc.nrec==sporder.cmc))=tsok)
{
do
{
//'L_SKLAD::ACTCOMPL.EDITSOPR.SCRHEADERFROM.b_SCRHEADERFROM_Формирование_ордеров'
if (b=1 and 0=sklorder.vidorder)
{
sporder.rsrprice:=soprorda.price;
update current sporder;
rescanpanel(#sporder);
message('РО1 '+sporder.rsrprice);
}
if (b=1 and 1=sklorder.vidorder)
{
sporder.rsrprice:=spsopr.rprice;
update current sporder;
rescanpanel(#sporder);
message('РО2 '+sporder.rsrprice);
}
if (b=0 and 1=sklorder.vidorder)
{
sporder.rsrprice:=soprorda.price;
update current sporder;
rescanpanel(#sporder);
message('ПО1 '+sporder.rsrprice);
}
if (b=0 and 0=sklorder.vidorder)
{
sporder.rsrprice:=spsopr.rprice;
update current sporder;
rescanpanel(#sporder);
message('ПО2 '+sporder.rsrprice);
}
//'L_SKLAD::ACTCOMPL.EDITSOPR.SCRHEADERTO.b_SCRHEADERTO_Формирование_ордеров'
}
while (Getnext sporder where ((sklorder.nrec == sporder.csklorder and v1.katmc.nrec==sporder.cmc))=tsok);
}
}
While (getnext soprorda where ((spsopr.nrec==soprorda.cspsopr(noindex) and v1.katmc.nrec==soprorda.cmc(noindex)))=Tsok );
}
}
while (Getnext sklorder where ((katsopr.nrec == sklorder.csopr /*and 1==sklorder.vidorder*/))=tsok);
}
}
while (v1.Getnext katmc =tsok);
}
Как оказалось, что обычный пробег по таблице katmc не привёл ни к чему. Использовалось только значение из окна EDITSOPR. А view вроде как работает ну очень уже уж долго

.
А связаны таблицы SOPRORDA и SPSOPR только через katmc.nrec.
Добавлено: 26 май 2010, 12:41
Vik
В общем, я мало что понял, чего вы пытаетесь сделать. От всей этой вложенности if - ов c GetFirst where (()) стоит избавиться.
"А связаны таблицы SOPRORDA и SPSOPR только через katmc.nrec." - тоже не понял, чего вы этим хотели сказать.
Может вы имели ввиду что-нить типа такого:
Код: Выделить всё
create view
var
p_cSklOrder : comp
from
SpOrder
,SoprOrda
where
((
p_cSklOrder == SpOrder.cSklOrder
and SpOrder.cSpSopr == SoprOrdA.cSpSopr
))
Добавлено: 26 май 2010, 13:01
BlazeBio
В этом запросе SOPRORDA и SOPRORDER ссылаются на SPSOPR.NREC. Но может быит несколько SPORDER.RSRPRICE и несколько SOPRORDA.PRICE. Допустим 3 и 3. Нужно, чтобы цена SOPRORDA.PRICE. записаль в определённую позицию цены SPORDER.RSRPRICE. Два браузера,в которых фигурируют эти цены, различаются только по katmc.name и katmc.barkod.
Мне необходимо, чтобы по Katmc.name происходил update SPORDER.RSRPRICE. Вот в этом то и загвоздка.
Добавлено: 26 май 2010, 13:37
Vik
Честно говоря, я с этими таблицами и документами сталкивался очень давно, поэтому подзабыл, что за табличка SOPRORDA. Но я так понял,
вы хотите что -то такое:
Код: Выделить всё
create view
var
p_cSklOrder : comp
as select
SOPRORDA.PRICE
from
SklOrder
,SpOrder
,SoprOrdA
where
(( p_cSklOrder == SklOrder.Nrec
and SklOrder.Nrec == SpOrder.cSklOrder
and SklOrder.cSopr == SoprOrdA.cSoprDoc
and SpOrder.cMc == SoprOrdA.cMc
));
......................
p_cSklOrder := xxxxxxxxxxxh
FixRelations(p_cSklOrder )
..................
_Loop SpOrder
{
...................
if (getFirst SoprOrdA = tsOk)
{
..........
}
}
..............
Если для какого-то конкретного ордера.
Добавлено: 26 май 2010, 14:20
edward_K
во 2 одно = пропущено.
про 1 и 3 даже говорить не хочется - никогда так не пишите. В индексных отборах слева условия, справа табла а никак все привыкли писать в обычном SQL.
Добавлено: 26 май 2010, 15:36
BlazeBio
А где равно должно быть ?
Добавлено: 26 май 2010, 15:48
BlazeBio
Vik пробовал таким образом:
Код: Выделить всё
If (getfirst sklorder where ((katsopr.nrec==sklorder.csopr)) = tsOk)
{
do
{
p_cSklOrder:=sklorder.nrec;
FixRelations(p_cSklOrder );
//message(p_cSklOrder);
v1._loop Sporder
{//message (SPORDER.rsrprice);
if (v1.getFirst SoprOrdA = tsOk)
{
if (b=1 and 0=sklorder.vidorder)
{
v1.sporder.rsrprice:=soprorda.price;
update current sporder;
rescanpanel(#sporder);
message('РО1 '+v1.sporder.rsrprice);
}
if (b=1 and 1=sklorder.vidorder)
{
v1.sporder.rsrprice:=v1.spsopr.rprice;
update current sporder;
rescanpanel(#sporder);
message('РО2 '+v1.sporder.rsrprice);
}
if (b=0 and 1=sklorder.vidorder)
{
v1.sporder.rsrprice:=v1.soprorda.price;
update current sporder;
rescanpanel(#sporder);
message('ПО1 '+v1.sporder.rsrprice);
}
if (b=0 and 0=sklorder.vidorder)
{
v1.sporder.rsrprice:=v1.spsopr.rprice;
update current sporder;
rescanpanel(#sporder);
//message('ПО2 '+sporder.rsrprice);
}
}
}
}
while (getnext sklorder where ((katsopr.nrec==sklorder.csopr)) = tsOk);
}
не срабатывает _loop почему-то ?
Добавлено: 26 май 2010, 16:29
edward_K
create view v1
as select
katmc.*
from katmc where ((katmc.nrec==soprorda.cmc and katmc.nrec== sporder.cmc and soprorda.csopr == sporder.csopr ));
как то так
Добавлено: 26 май 2010, 16:36
BlazeBio
Таких полей как soprorda.csopr и sporder.csopr не существует. Такой запрос непроходит. Может вы имели что-то другое ввиду ?
Добавлено: 26 май 2010, 17:22
Vik
Почему вам так нравится использовать getFirst where (()) getNext where (()). Это же на производительности не в лучшую сторону сказывается. Опишите все нужные вам связи во вьюхе. Вы пляску от акта начинаете? Может тогда связка со складским ордером вообще не нужна?
Что -то типа:
Код: Выделить всё
621 == KatSopr.VidSopr
and 1 ==SpSopr.PrMc
and KatSopr.Nrec == SpSopr.cSopr
and SpSopr.Nrec == SpOrder.cSpSopr
and p_wVidOrder == SpOrder.VidOrder
and SpSopr.Nrec == SoprOrdA.cSpSopr
and SpOrder.cMc == SoprOrdA.cMc (noindex)
тогда для всех актов на комплектование :
Код: Выделить всё
_Loop KatSopr
_Loop SpSopr
_Loop SpOrder
{
if (GetFirst SoprOrdA = tsOk)
{}
}
}
Если нужно для конкретного акта, подправьте вьюху, уберите цикл по катсопру..
Добавлено: 26 май 2010, 17:23
BlazeBio
Попробовал сделать тот же запрос, но без view
Код: Выделить всё
if (Getfirst sklorder where ((katsopr.nrec == sklorder.csopr /*and 1==sklorder.vidorder*/)) =tsok)
{
do
{
If (Getfirst sporder where ((sklorder.nrec == sporder.csklorder))=tsok)
{
do
{ message('sklorder.nrec='+sklorder.nrec);
message('sklorder.vidorder='+sklorder.vidorder);
If (Getfirst soprorda where ((SklOrder.cSopr == SoprOrdA.cSoprDoc and SpOrder.cMc == SoprOrdA.cMc))=tsok)
{
do
{message('SPSOPR.RPRICE='+spsopr.rprice);
message('sklorder.nrec2='+sklorder.nrec);
message('sklorder.vidorder2='+sklorder.vidorder);
if (b=1 and word(0)=sklorder.vidorder)
{
sporder.rsrprice:=soprorda.price;
update current sporder;
rescanpanel(#sporder);
message('РО1 '+sporder.rsrprice);
}
if (b=1 and word(1)=sklorder.vidorder)
{
sporder.rsrprice:=spsopr.rprice;
update current sporder;
rescanpanel(#sporder);
message('РО2 '+sporder.rsrprice);
}
if (b=0 and word(1)=sklorder.vidorder)
{
sporder.rsrprice:=soprorda.price;
update current sporder;
rescanpanel(#sporder);
message('ПО1 '+sporder.rsrprice);
}
if (b=0 and word(0)=sklorder.vidorder)
{
sporder.rsrprice:=spsopr.rprice;
update current sporder;
rescanpanel(#sporder);
message('ПО2 '+sporder.rsrprice);
}
//'L_SKLAD::ACTCOMPL.EDITSOPR.SCRHEADERTO.b_SCRHEADERTO_Формирование_ордеров'
}
while (Getnext soprorda where ((SklOrder.cSopr == SoprOrdA.cSoprDoc and SpOrder.cMc == SoprOrdA.cMc ))=tsok);
}
}
While (Getnext sporder where ((sklorder.nrec == sporder.csklorder))=tsok);
}
}
while (Getnext sklorder where ((katsopr.nrec == sklorder.csopr /*and 1==sklorder.vidorder*/))=tsok);
}

Только почему-то не срабатывает условие ?
Код: Выделить всё
if (b=1 and word(1)=sklorder.vidorder)
{
sporder.rsrprice:=spsopr.rprice;
update current sporder;
rescanpanel(#sporder);
message('РО2 '+sporder.rsrprice);
}
Месаджы до
Код: Выделить всё
If (Getfirst soprorda where ((SklOrder.cSopr == SoprOrdA.cSoprDoc and SpOrder.cMc == SoprOrdA.cMc))=tsok)
{
...
}
страбатывают. После (внутри if) почему-то не выводится месадж, когда sklorder.vidorder2 =1, а только sklorder.vidorder2 =0, хотя до нормально выводит sklorder.vidorder =1 и sklorder.vidorder =0. Из-за этого не срабатывает условие.
Может кто-нибудь объяснить почему так происходит ?
Добавлено: 26 май 2010, 17:30
BlazeBio
Я использую getFirst where (())... getNext where (()), потому что как сейчас loop часто не срабатывает.
На счёт ордеров. При формировании ордеров формируются два ордера приходный и расходный. После формирования именно в этих конкретных сформировавшихся ордерах нужно произвести update.
Я бы рад произвести через _loop, но почему или идёт полный цикл по таблице или если использовать view v1 никакого цикла не происходит. Вот я интересуюсь почему ?
Добавлено: 26 май 2010, 18:21
Vik
Код: Выделить всё
create view ForReprice
var
p_cKatSopr : comp
from
SpSopr
,SpOrder
,SoprOrdA
where
((
1 ==SpSopr.PrMc
and p_cKatSopr == SpSopr.cSopr
and SpSopr.Nrec == SpOrder.cSpSopr
and SpSopr.Nrec == SoprOrdA.cSpSopr
and SpOrder.cMc == SoprOrdA.cMc (noindex)
)) ;
Procedure Reprice(pp_cSopr: comp; b : byte);
{
ForReprice.p_cKatSopr := pp_cSopr;
FixRelations(ForReprice.p_cKatSopr);
ForReprice._Loop SpSopr
{
ForReprice._Loop SpOrder
{
if ( b = ForReprice.SpOrder.VidOrder )
{
ForReprice.update current SpOrder
set SpOrder.RSrPrice := ForReprice.SpSopr.rPrice ;
}
else
{
if (ForReprice.GetFirst SoprOrdA = tsOk )
{
ForReprice.update current SpOrder
set SpOrder.RSrPrice := ForReprice.SoprOrdA.Price ;
}
}
}
}
}
Еще вопрос. В вашем коде вьюха единственная, или нет? Вы случайно не вчерашний alter interface делаете?