18.11.2008, 18:09 | #1 |
Участник
|
Вложенный датасорс с QueryRun
Есть такой код:
X++: static void Test_Query(Args _args) { CustTable custTable; AddressState addressState; Query query = new Query(); QueryRun qr = new queryRun(query); QueryBuildDataSource qbds = qr.query().addDataSource(tableNum(CustTable)); QueryBuildDataSource qbdsJoin; int i; ; qbds.addSelectionField(fieldnum(CustTable,RecId),SelectionField::Count); qbds.addSortField(fieldnum(CustTable,CashDisc)); qbds.addSortField(fieldnum(CustTable,CountryRegionId)); qbds.addSortField(fieldnum(CustTable,State)); qbds.orderMode(OrderMode::GroupBy); qbdsJoin = qbds.addDataSource(tablenum(AddressState)); qbdsJoin.relations(false); qbdsJoin.orderMode(OrderMode::OrderBy); qbdsJoin.joinMode(JoinMode::OuterJoin); qbdsJoin.addlink(fieldnum(CustTable,CountryRegionId),fieldnum(AddressState,CountryRegionId)); qbdsJoin.addlink(fieldnum(CustTable,State),fieldnum(AddressState,StateId)); qbdsJoin.addSelectionField(fieldnum(AddressState,Name)); if (qr.prompt()) { i=0; while (qr.next()) { custTable = qr.get(tableNum(CustTable)); addressState = /* ЧТО ЗДЕСЬ ДОЛЖНО БЫТЬ*/ print strfmt("%1 %2 (%3 records)",addressState.Name, custTable.CashDisc ,custTable.RecId); i+=custTable.RecId; } } pause; } X++: addressState = qr.get(tableNum(ddressState )); Или вообще релейшн неправильно построен? То тогда как верно это сделать? |
|
18.11.2008, 18:15 | #2 |
MCITP
|
ну у вас же аутер джоин как никак:
X++: qbdsJoin.joinMode(JoinMode::OuterJoin); X++: addressState = qr.get(tableNum(AddressState ));
__________________
Zhirenkov Vitaly |
|
18.11.2008, 18:15 | #3 |
Участник
|
Это Вы правильно пытаетесь:
X++: addressState = qr.get(tableNum(ddressState )); Upd: оказывается уже ответили :-)
__________________
Функциональное тестирование сайтов |
|
18.11.2008, 18:18 | #4 |
Участник
|
Добавьте SortField по этому полю.
|
|
18.11.2008, 18:25 | #5 |
MCITP
|
Посмотрел запрос повнимательнее:
X++: .... qbds.orderMode(OrderMode::GroupBy); .... qbdsJoin.orderMode(OrderMode::OrderBy); .... У вас весь запрос получается ГрупБай, и поэтому даже добавив X++: qbdsJoin.addSelectionField(fieldnum(AddressState,Name)); PHP код:
И только в этом случае, для тех записей где AddressState в принципе есть (а не по аутерДжоин) вы в переменной AddressState увидите одно единственное поле "Name" - все остальные будет пустые.
__________________
Zhirenkov Vitaly Последний раз редактировалось ZVV; 18.11.2008 в 18:30. Причина: qbdsJoin.addSortField(fieldnum(AddressState,Name)); |
|
18.11.2008, 18:28 | #6 |
Участник
|
При замене OuterJoin на InnerJoin ничего не изменилось, кроме количества выводимых строк(что понятно) - но addressState.name по-прежнему пусто
Цитата:
Добавьте SortField по этому полю.
X++: qbds.addSortField(fieldnum(AddressState,Name)); X++: qbdsJoin.addSortField(fieldnum(AddressState,Name)); |
|
18.11.2008, 18:46 | #7 |
MCITP
|
Цитата:
Сообщение от Peppi
При замене OuterJoin на InnerJoin ничего не изменилось, кроме количества выводимых строк(что понятно) - но addressState.name по-прежнему пусто
Добавила строку : X++: qbds.addSortField(fieldnum(AddressState,Name)); X++: qbdsJoin.addSortField(fieldnum(AddressState,Name)); X++: qbdsJoin.addSortField(fieldnum(AddressState,Name)); X++: qbdsJoin.orderMode(OrderMode::GroupBy); И можно посмотреть SQL который вывалился в ошибку, чтоб увидеть какая в нём проблема. Ещё есть такая очень полезная функция X++: info(qbds.toString());
__________________
Zhirenkov Vitaly |
|
|
За это сообщение автора поблагодарили: Peppi (1). |
18.11.2008, 18:51 | #8 |
MCITP
|
А если придираться до конца, то явно должно быть начало вот такое
X++: qbds.orderMode(OrderMode::GroupBy); qbds.addSortField(fieldnum(CustTable,CashDisc)); qbds.addSortField(fieldnum(CustTable,CountryRegionId)); qbds.addSortField(fieldnum(CustTable,State)); qbds.addSelectionField(fieldnum(CustTable,CashDisc)); // !!! т.к. вы его потом вычитываете в переменной qbds.addSelectionField(fieldnum(CustTable,RecId),SelectionField::Count);
__________________
Zhirenkov Vitaly |
|
19.11.2008, 09:22 | #9 |
Участник
|
Спасибо, я подумала, что одно упоминание group by делает весь запрос групбай и соответственно не указывала явно это. Как только добавила группировку, все получилось, спасибо большое за объяснение!
|
|
19.11.2008, 16:49 | #10 |
Участник
|
Еще возник теперь такой вопрос, как строку запроса(часть where)
X++: Table1.Field1!= Value1 && Table1.Field1!= Value2 && Table1.Field1!= Value3 && Код вида : X++: qbds.addRange(fieldnum(Table1,Field1)).value(SysQuery::valueNot(Value1)); qbds.addRange(fieldnum(Table1,Field1)).value(SysQuery::valueNot(Value2)); qbds.addRange(fieldnum(Table1,Field1)).value(SysQuery::valueNot(Value3)); ((NOT (Field1= Value1)) OR (NOT (Field1= Value2)) OR (NOT (Field1= Value3)) И как правильнее записать строку вида X++: Table1.Field4< SomeDate |
|
19.11.2008, 17:03 | #11 |
MCITP
|
Пишу "на глаз", возможны синтаксические ошибки:
1. X++: qbr.value(strFmt('( (%1.%2 != %3) && (%1.%2 != %4) )' ,qbds.name() ,FieldId2Name(tableNum(MyTable), fieldNum(MyTable, MayField)) ,value1 // если строка, нужно взять в двойные кавычки, если енум - то в виде числа (int) ,value2); X++: qbr.value(strFmt('<%1', queryValue(SomeDate)));
__________________
Zhirenkov Vitaly |
|
19.11.2008, 17:34 | #12 |
Ищущий знания...
|
можно ещё вот так:
1. X++: qbr.value(strFmt("!%1, !%2, !%3", value1, value2, value3));
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
20.11.2008, 09:39 | #13 |
Участник
|
Хмм... Интересно, я имела запрос, написанный на Х++, записала его с помощью QueryRun абсолютно аналогично, но он стал работать катастрофически медленно! Это нормально???
|
|
20.11.2008, 09:49 | #14 |
Ищущий знания...
|
Посмотрите какой запрос уходит в БД в обоих случаях, может в итоге у вас разные запросы получились, и второй не оптимален.
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
20.11.2008, 10:15 | #15 |
MCITP
|
Да, смотрите запрос к БД, возможно хинты появились или же не такие они и одинаковые у Вас.
Второй вариант - смотря как организована обработка этих запросов в цикле, может тоже по-разному. В общем случае ответа дать нельзя. Если хотите, выкладите сюда код и sql, тогда можно будет о чём-то поговорить.
__________________
Zhirenkov Vitaly |
|
20.11.2008, 11:10 | #16 |
Участник
|
Исходный запрос:
X++: while select RecId, CostAmountPosted, CostAmountAdjustment, Qty, DatePhysical, Direction from searchInventTrans where searchInventTrans.DatePhysical <= endDate && inventTable.ItemId == searchInventTrans.ItemId && searchInventTrans.Direction != InventDirection::None && searchInventTrans.StatusIssue != StatusIssue::OnOrder && searchInventTrans.StatusIssue != StatusIssue::Picked && searchInventTrans.StatusIssue != StatusIssue::ReservOrdered && searchInventTrans.StatusIssue != StatusIssue::ReservPhysical && searchInventTrans.StatusIssue != StatusIssue::QuotationIssue && searchInventTrans.StatusReceipt != StatusReceipt::Registered && searchInventTrans.StatusReceipt != StatusReceipt::Arrived && searchInventTrans.StatusReceipt != StatusReceipt::QuotationReceipt && searchInventTrans.StatusReceipt != StatusReceipt::Ordered { ... } X++: qbds.addSelectionField(fieldnum(InventTrans,RecId)); qbds.addSelectionField(fieldnum(InventTrans,CostAmountPosted)); qbds.addSelectionField(fieldnum(InventTrans,CostAmountAdjustment)); qbds.addSelectionField(fieldnum(InventTrans,Qty)); qbds.addSelectionField(fieldnum(InventTrans,DatePhysical)); qbds.addSelectionField(fieldnum(InventTrans,Direction)); qbds.addRange(fieldnum(InventTrans,DatePhysical)).value(strFmt('<%1', queryValue(endDate))); qbds.addRange(fieldnum(InventTrans,ItemId)).value(inventTable.ItemId); qbds.addRange(fieldnum(InventTrans,Direction)).value(SysQuery::valueNot(InventDirection::None)); qbds.addRange(fieldnum(InventTrans,StatusIssue)).value(strFmt("!%1, !%2, !%3, !%4, !%5" ,any2int(StatusIssue::OnOrder) ,any2int(StatusIssue::Picked) ,any2int(StatusIssue::ReservOrdered) ,any2int(StatusIssue::ReservPhysical) ,any2int(StatusIssue::QuotationIssue))); qbds.addRange(fieldnum(InventTrans,StatusReceipt)).value(strFmt("!%1, !%2, !%3, !%4" ,any2int(StatusReceipt::Registered) ,any2int(StatusReceipt::Arrived) ,any2int(StatusReceipt::QuotationReceipt) ,any2int(StatusReceipt::Ordered))); while (qr.next { searchInventTrans=qr.get(tablenum(InventTrans)); ... } X++: exec sp_cursorprepexec @p1 output,@p2 output,N'@P1 nvarchar(8),@P2 datetime,@P3 nvarchar(42),@P4 int,@P5 int,@P6 int,@P7 int,@P8 int,@P9 int,@P10 int,@P11 int,@P12 int,@P13 int',N'SELECT A.RECID,A.COSTAMOUNTPOSTED,A.COSTAMOUNTADJUSTMENT,A.QTY,A.DATEPHYSICAL,A.DIRECTION FROM INVENTTRANS A WHERE (([email="DATAAREAID=@P1"]DATAAREAID=@P1[/email]) AND ((((((((((((DATEPHYSICAL<[email="=@P2"]=@P2[/email]) AND ([email="ITEMID=@P3"]ITEMID=@P3[/email])) AND (DIRECTION<>@P4)) AND (STATUSISSUE<>@P5)) AND (STATUSISSUE<>@P6)) AND (STATUSISSUE<>@P7)) AND (STATUSISSUE<>@P8)) AND (STATUSISSUE<>@P9)) AND (STATUSRECEIPT<>@P10)) AND (STATUSRECEIPT<>@P11)) AND (STATUSRECEIPT<>@P12)) AND (STATUSRECEIPT<>@P13)))',@p5 output,@p6 output,@p7 output,N'dat','Nov 25 2005 12:00:00:000AM',N'DPI-01',0,6,3,5,4,7,3,4,6,5 select @p1, @p2, @p5, @p6, @p7 а при измененном запросе: X++: exec sp_cursorprepexec @p1 output,@p2 output,N'@P1 nvarchar(8)',N'SELECT A.ITEMGROUPID,A.ITEMID,A.ITEMNAME,A.ITEMTYPE,A.PURCHMODEL,A.HEIGHT,A.WIDTH,A.SALESMODEL,A.DEL_COSTGROUPID,A.REQGROUPID,A.EPCMANAGER,A.PRIMARYVENDORID,A.NETWEIGHT,A.DEPTH,A.UNITVOLUME,A.BOMUNITID,A.DENSITY,A.DIMENSION,A.DIMENSION2_,A.DIMENSION3_,A.DIMENSION4_,A.COSTMODEL,A.USEALTITEMID,A.ALTITEMID,A.INTRACODE,A.PRODFLUSHINGPRINCIP,A.PBAITEMAUTOGENERATED,A.BOMMANUALRECEIPT,A.STOPEXPLODE,A.PHANTOM,A.INTRAUNIT,A.BOMLEVEL,A.BATCHNUMGROUPID,A.AUTOREPORTFINISHED,A.ORIGCOUNTRYREGIONID,A.STATISTICSFACTOR,A.ALTCONFIGID,A.STANDARDCONFIGID,A.PRODPOOLID,A.PROPERTYID,A.ABCTIEUP,A.ABCREVENUE,A.ABCVALUE,A.ABCCONTRIBUTIONMARGIN,A.COMMISSIONGROUPID,A.CONFIGURABLE,A.SALESPERCENTMARKUP,A.SALESCONTRIBUTIONRATIO,A.SALESPRICEMODELBASIC,A.MINAVERAGESETTLE,A.NAMEALIAS,A.PRODGROUPID,A.PROJCATEGORYID,A.GROSSDEPTH,A.GROSSWIDTH,A.GROSSHEIGHT,A.STANDARDPALLETQUANTITY,A.QTYPERLAYER,A.SORTCODE,A.CONFIGSIMILAR,A.SERIALNUMGROUPID,A.DIMGROUPID,A.MODELGROUPID,A.ITEMBUYERGROUPID,A.TAXPACKAGINGQTY,A.WMSPALLETTYPEID,A.ORIGSTATEID,A.DEL_STOPEXPLODEPRICE,A.WMSPICKINGQTYTIME,A.TARAWEIGHT,A.PACKAGINGGROUPID,A.SCRAPVAR,A.SCRAPCONST,A.STANDARDINVENTCOLORID,A.STANDARDINVENTSIZEID,A.ITEMDIMCOMBINATIONAUTOCREATE,A.ITEMDIMCOSTPRICE,A.ITEMIDCOMPANY,A.ALTINVENTSIZEID,A.ALTINVENTCOLORID,A.FORECASTDMPINCLUDE,A.PALLETTAGGING,A.ITEMTAGGINGLEVEL,A.FISCALLIFOAVOIDCALC,A.FISCALLIFONORMALVALUE,A.FISCALLIFOGROUP,A.FISCALLIFONORMALVALUECALC,A.BOMCALCGROUPID,A.PBAITEMCONFIGURABLE,A.PBAINVENTITEMGROUPID,A.PBAHIDEDIALOG,A.PBAHIDEAPPROVAL,A.PBAAUTOSTART,A.PBAMANDATORYCONFIG,A.PACKING_RU,A.ASSETGROUPID_RU,A.ASSETID_RU,A.INTRASTATEXCLUDE_LT,A.INTRASTATWEIGHT_CZ,A.INTRASTATPROCID_CZ,A.PKWIUCODE_PL,A.SADRATECODE_PL,A.RECVERSION,A.RECID FROM INVENTTABLE A WHERE ([email="DATAAREAID=@P1"]DATAAREAID=@P1[/email]) ORDER BY A.DATAAREAID,A.ITEMID',@p5 output,@p6 output,@p7 output,N'dat' select @p1, @p2, @p5, @p6, @p7 |
|
20.11.2008, 11:26 | #17 |
MCITP
|
ну у вас же во втором SQL вообще нет никаких условий, конечно будет медленнее, вы бы глянули сначала на саму кверю, как она у вас сформировалась.
и то ли вы вообще "кверите" PS не понял фишку с e-mailами
__________________
Zhirenkov Vitaly |
|
20.11.2008, 11:33 | #18 |
Участник
|
Цитата:
Ой) и я не поняла как так получилось) |
|
20.11.2008, 11:33 | #19 |
MCITP
|
ааа, так а QueryRun вы собственно когда инициализировали?
До того как построить квери?
__________________
Zhirenkov Vitaly |
|
20.11.2008, 11:36 | #20 |
Участник
|
|
|
|
|