Страница 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);
						}
:eek: Только почему-то не срабатывает условие ?

Код: Выделить всё

									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 делаете?