AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 18.11.2008, 18:09   #1  
Peppi is offline
Peppi
Участник
 
31 / 11 (1) +
Регистрация: 22.10.2008
Вложенный датасорс с 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;
}
Как получить значение позиции addressState? Если делать по аналогии
X++:
addressState = qr.get(tableNum(ddressState ));
то получаем пусто, как добраться до значений во вложенном датасорсе?
Или вообще релейшн неправильно построен? То тогда как верно это сделать?
Старый 18.11.2008, 18:15   #2  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
ну у вас же аутер джоин как никак:
X++:
qbdsJoin.joinMode(JoinMode::OuterJoin);
поэтому
X++:
addressState = qr.get(tableNum(AddressState ));
это действительно правильный код, но просто там не всегда будут данные по смыслу внешнего соединения.
__________________
Zhirenkov Vitaly
Старый 18.11.2008, 18:15   #3  
Red Stranger is offline
Red Stranger
Участник
 
102 / 19 (1) ++
Регистрация: 01.04.2005
Цитата:
Сообщение от Peppi Посмотреть сообщение
то получаем пусто, как добраться до значений во вложенном датасорсе?
Это Вы правильно пытаетесь:
X++:
addressState = qr.get(tableNum(ddressState ));
Только у Вас OuterJoin. Вполне может и не быть значения.

Upd: оказывается уже ответили :-)
Старый 18.11.2008, 18:18   #4  
_scorp_ is offline
_scorp_
Участник
Аватар для _scorp_
MCBMSS
 
488 / 369 (13) ++++++
Регистрация: 25.07.2007
Адрес: Москва
Добавьте SortField по этому полю.
Старый 18.11.2008, 18:25   #5  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Посмотрел запрос повнимательнее:
X++:
....
    qbds.orderMode(OrderMode::GroupBy);
....
    qbdsJoin.orderMode(OrderMode::OrderBy);
....
Так нельзя делать, у вас ничего не выйдет, нельзя сделать часть запроса групБай, а часть ОрдерБай
У вас весь запрос получается ГрупБай, и поэтому
даже добавив
X++:
qbdsJoin.addSelectionField(fieldnum(AddressState,Name));
вы не увидите этого поля в переменной, т.к. надо ещё
PHP код:
qbdsJoin.addSortField(fieldnum(AddressState,Name)); 
добавить

И только в этом случае, для тех записей где AddressState в принципе есть (а не по аутерДжоин) вы в переменной AddressState увидите одно единственное поле "Name" - все остальные будет пустые.
__________________
Zhirenkov Vitaly

Последний раз редактировалось ZVV; 18.11.2008 в 18:30. Причина: qbdsJoin.addSortField(fieldnum(AddressState,Name));
Старый 18.11.2008, 18:28   #6  
Peppi is offline
Peppi
Участник
 
31 / 11 (1) +
Регистрация: 22.10.2008
При замене OuterJoin на InnerJoin ничего не изменилось, кроме количества выводимых строк(что понятно) - но addressState.name по-прежнему пусто
Цитата:
Добавьте SortField по этому полю.
Добавила строку :
X++:
 qbds.addSortField(fieldnum(AddressState,Name));
- Эффект тот же.
X++:
 qbdsJoin.addSortField(fieldnum(AddressState,Name));
дает ошибку "Невозможно выбрать запись в Клиенты (CustTable). Счет клиента: , .База данных SQL обнаружила ошибку."
Старый 18.11.2008, 18:46   #7  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от Peppi Посмотреть сообщение
При замене OuterJoin на InnerJoin ничего не изменилось, кроме количества выводимых строк(что понятно) - но addressState.name по-прежнему пусто

Добавила строку :
X++:
 qbds.addSortField(fieldnum(AddressState,Name));
- Эффект тот же.
X++:
 qbdsJoin.addSortField(fieldnum(AddressState,Name));
дает ошибку "Невозможно выбрать запись в Клиенты (CustTable). Счет клиента: , .База данных SQL обнаружила ошибку."
для того чтобы заработало
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  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
А если придираться до конца, то явно должно быть начало вот такое

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  
Peppi is offline
Peppi
Участник
 
31 / 11 (1) +
Регистрация: 22.10.2008
Спасибо, я подумала, что одно упоминание group by делает весь запрос групбай и соответственно не указывала явно это. Как только добавила группировку, все получилось, спасибо большое за объяснение!
Старый 19.11.2008, 16:49   #10  
Peppi is offline
Peppi
Участник
 
31 / 11 (1) +
Регистрация: 22.10.2008
Еще возник теперь такой вопрос, как строку запроса(часть where)
X++:
                  Table1.Field1!= Value1               &&
                  Table1.Field1!= Value2         &&
                  Table1.Field1!= Value3        &&
Записать с помощью addRange?
Код вида :
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
так же с помощью addRange?
Старый 19.11.2008, 17:03   #11  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Пишу "на глаз", возможны синтаксические ошибки:

1.
X++:
    qbr.value(strFmt('( (%1.%2 != %3)  && (%1.%2 != %4) )'
                    ,qbds.name()
                    ,FieldId2Name(tableNum(MyTable), fieldNum(MyTable, MayField))
                    ,value1 // если строка, нужно взять в двойные кавычки, если енум - то в виде числа (int)
                    ,value2);
2.
X++:
qbr.value(strFmt('<%1', queryValue(SomeDate)));
__________________
Zhirenkov Vitaly
Старый 19.11.2008, 17:34   #12  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
можно ещё вот так:
1.
X++:
qbr.value(strFmt("!%1, !%2, !%3", value1, value2, value3));
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 20.11.2008, 09:39   #13  
Peppi is offline
Peppi
Участник
 
31 / 11 (1) +
Регистрация: 22.10.2008
Хмм... Интересно, я имела запрос, написанный на Х++, записала его с помощью QueryRun абсолютно аналогично, но он стал работать катастрофически медленно! Это нормально???
Старый 20.11.2008, 09:49   #14  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
Цитата:
Сообщение от Peppi Посмотреть сообщение
Хмм... Интересно, я имела запрос, написанный на Х++, записала его с помощью QueryRun абсолютно аналогично, но он стал работать катастрофически медленно! Это нормально???
Посмотрите какой запрос уходит в БД в обоих случаях, может в итоге у вас разные запросы получились, и второй не оптимален.
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 20.11.2008, 10:15   #15  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Да, смотрите запрос к БД, возможно хинты появились или же не такие они и одинаковые у Вас.
Второй вариант - смотря как организована обработка этих запросов в цикле, может тоже по-разному.

В общем случае ответа дать нельзя.
Если хотите, выкладите сюда код и sql, тогда можно будет о чём-то поговорить.
__________________
Zhirenkov Vitaly
Старый 20.11.2008, 11:10   #16  
Peppi is offline
Peppi
Участник
 
31 / 11 (1) +
Регистрация: 22.10.2008
Исходный запрос:
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
Почему выбираются все поля из INVENTTABLE ?
Старый 20.11.2008, 11:26   #17  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
ну у вас же во втором SQL вообще нет никаких условий, конечно будет медленнее, вы бы глянули сначала на саму кверю, как она у вас сформировалась.
и то ли вы вообще "кверите"

PS не понял фишку с e-mailами
__________________
Zhirenkov Vitaly
Старый 20.11.2008, 11:33   #18  
Peppi is offline
Peppi
Участник
 
31 / 11 (1) +
Регистрация: 22.10.2008
Цитата:
Сообщение от ZVV Посмотреть сообщение
ну у вас же во втором SQL вообще нет никаких условий, конечно будет медленнее, вы бы глянули сначала на саму кверю, как она у вас сформировалась.
и то ли вы вообще "кверите"
Простите, пожалуйста, но я не поняла все-таки, как нет ни каких условий? А AddRange?
Цитата:
Сообщение от ZVV Посмотреть сообщение
PS не понял фишку с e-mailами
Ой) и я не поняла как так получилось)
Старый 20.11.2008, 11:33   #19  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
ааа, так а QueryRun вы собственно когда инициализировали?

До того как построить квери?
__________________
Zhirenkov Vitaly
Старый 20.11.2008, 11:36   #20  
Peppi is offline
Peppi
Участник
 
31 / 11 (1) +
Регистрация: 22.10.2008
Цитата:
Сообщение от ZVV Посмотреть сообщение
ааа, так а QueryRun вы собственно когда инициализировали?

До того как построить квери?
Да
X++:
    QueryRun             qr         = new queryRun(query);
    QueryBuildDataSource qbds       = qr.query().addDataSource(tableNum(InventTrans));
    QueryBuildDataSource qbdsJoin;
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Dynamics AX: QueryRun and Query Objects - Binding operation failed to allocate buffer space Blog bot DAX Blogs 0 03.04.2009 08:05
Простой QueryRun не работает miklenew DAX: Программирование 13 20.01.2009 14:17
OZKA's DAX Journal: Join между временной и постоянной таблицей через QueryRun. Blog bot DAX Blogs 12 14.01.2009 17:34
queryRun в рамках RunBaseBatch Smith DAX: Программирование 6 26.04.2005 11:03
Проблема: подстановка значений по дефолту в диалог QueryRun cyrus DAX: Программирование 4 21.03.2003 09:39

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 18:13.