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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 19.06.2017, 21:26   #41  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от smailik Посмотреть сообщение
Фильтр накладывается верно.
Да. Тогда отлично. Тогда в акс4 работает правильно, просто в toString() отображаются неполная информация.
__________________
полезное на axForum, github, vk, coub.
Старый 19.06.2017, 21:36   #42  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
Огромное спасибо. Не могу поставить благодарность под сообщением, так как сделал это уже под другим. Надо наверное пообщаться с администратором на эту тему
Старый 19.06.2017, 22:00   #43  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
поговорите с администратором. )
но лучше начните использовать АОТ для query вместо простыней кода.

и всегда экранируйте значение перед тем как записать range.value.
вот так категорически неправильно:
X++:
value(inventLocationId_From)
вот так - правильно:
X++:
value(SysQuery::value(inventLocationId_From))
разницу вы почувствуете, когда пользователь додумается поставить запятую, восклицательный, вопросительный знаки в код.
или любые друге спец.символы. http://axapta.mazzy.ru/lib/search/

=========================
Цитата:
Сообщение от smailik Посмотреть сообщение
я использовал ExistsJoin. Потом спасибо S.Kuskov тип связи изменился на InnerJoin. ... Почему бы не поднять InventLocation выше?
промоделировал в акс2012.
в общем старая добрая проблема с множественным Exist Join в нескольких подчиненных таблицах воспроизводится и в самых распоследних билдах акс2012.

Если есть несколько подчиненных таблиц с Exist Join и InnerJoin, то возникает ошибка при создании SQL-запроса. Независимо от положения подчиненных таблиц, от group by и прочих факторов.

=========================
Господи, хорошо то как в старой версии!
И все-таки лучшей версией была акс2009.
__________________
полезное на axForum, github, vk, coub.

Последний раз редактировалось mazzy; 19.06.2017 в 22:18.
Старый 19.06.2017, 22:00   #44  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,440 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Query из 7 таблиц
За это сообщение автора поблагодарили: mazzy (2).
Старый 19.06.2017, 22:08   #45  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Цитата:
Сообщение от mazzy Посмотреть сообщение
аксапта не гарантирует, что query будет выполнен одним SQL-запросом.
очень часто аксапта разбивает выполнение Query на несколько SQL-запросов.

разбитие зависит от временных таблиц, кэшируемых таблиц, сложных запросов с невложенными связями, existJoin.
https://msdn.microsoft.com/en-us/library/bb314836.aspx

вполне вероятно, что аксапта разбила запрос на несколько.
Это тоже вроде обсуждалось.
И вроде было связано с версией SQL - что-то там происходило, когда в запросе участвуют много таблиц. Типа планы оптимизации не рассчитывались... или что-то вроде того.

Кстати, алиасы таблиц раньше по-другому генерились. Помню, что были первые буквы латинского алфавита A,B,C... А теперь Т1, Т2, Т3...
Цитата:
Сообщение от db Посмотреть сообщение
SELECT A.ITEMGROUPID,A.ITEMID,A.ITEMNAME,A.ITEMTYPE,A.PURCHMODEL,A.HEIGHT,A.WIDTH,A.SALESMODEL,
A.COSTGROUPID,A.REQGROUPID,A.PRIMARYVENDORID,A.NETWEIGHT,A.DEPTH,A.UNITVOLUME,A.BOMUNITID,A.DENSITY,
A.DEL_SCRAPTYPEID,A.DIMENSION,A.DIMENSION2_,A.DIMENSION3_,A.DIMENSION4_,A.DIMENSION5_,A.COSTMODEL,
A.USEALTITEMID,A.ALTITEMID,A.INTRACODE,A.BOMMANUALCONSUMP,A.BOMMANUALRECEIPT,
A.STOPEXPLODE,A.DEL_COVPERINVENTLOCATION,A.PHANTOM,A.INTRAUNIT,A.BOMLEVEL,A.BATCHNUMGROUPID,
A.AUTOREPORTFINISHED,A.ORIGCOUNTRYID,A.STATISTICSFACTOR,A.ALTCONFIGID,A.STANDARDCONFIGID,
A.DEL_CONFIGACTIVE,A.PRODPOOLID,A.PROPERTYID,A.ABCTIEUP,A.ABCREVENUE,A.ABCVALUE,A.ABCCONTRIBUTIONMARGIN,
A.COMMISSIONGROUPID,A.DEL_BARCODE,A.DEL_BARCODETYPE,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.DEL_TEMPLATE,A.WMSPALLETTYPEID,A.ORIGSTATEID,A.STOPEXPLODEPRICE,A.WMSPICKINGQTYTIME,
A.TARAWEIGHT,A.PACKAGINGGROUPID,A.SCRAPVAR,A.SCRAPCONST,A.ITEMDIMCOMBINATIONAUTOCREATE,
A.ITEMDIMCOSTPRICE,A.ITEMIDCOMPANY,A.PBAITEMCONFIGURABLE,A.PBAINVENTITEMGROUPID,
A.GROSSWEIGHT_RU,A.PACKING_RU,A.ASSETGROUPID_RU,A.ASSETID_RU,A.RECID,
B.ITEMID,B.MODULETYPE,B.UNITID,B.PRICE,B.PRICEUNIT,B.MARKUP,B.LINEDISC,B.MULTILINEDISC,B.ENDDISC,
B.QUANTITY,B.LOWESTQTY,B.HIGHESTQTY,B.TAXITEMGROUPID,B.BLOCKED,B.DELIVERYTIME,B.INVENTLOCATIONID,
B.MANDATORYINVENTLOCATION,B.STANDARDQTY,B.MARKUPGROUPID,B.PRICEDATE,B.PRICEQTY,B.ALLOCATEMARKUP,
B.OVERDELIVERYPCT,B.UNDERDELIVERYPCT,B.SUPPITEMGROUPID,B.CALENDARDAYS,B.INTERCOMPANYBLOCKED,
B.PRICESECCUR_RU,B.MARKUPSECCUR_RU,B.RECID,C.UNITID,C.TXT,C.UNITDECIMALS,C.UNITSYSTEM,C.CODEOKEI_RU,C.RECID
FROM INVENTTABLE A(NOLOCK) ,INVENTTABLEMODULE B(NOLOCK) ,UNIT C(NOLOCK)
WHERE (A.DATAAREAID=?)
AND ((B.DATAAREAID=?)
AND ((B.MODULETYPE=?)
AND (A.ITEMID=B.ITEMID)))
AND ((C.DATAAREAID=?)
AND (B.UNITID=C.UNITID))
ORDER BY A.DATAAREAID,A.ITEMID OPTION(FAST 9)
__________________
полезное на axForum, github, vk, coub.
Старый 19.06.2017, 22:24   #46  
dim-gin is offline
dim-gin
Участник
 
41 / 30 (2) +++
Регистрация: 15.04.2014
Адрес: СПб
Если брать исходный текст с Query, то можно попробовать указать fetch mode 1:1 явно у всех DS (кроме первого, разумеется).

Если я правильно понял задачу, требуется что-то типа такого:
X++:
    Query                   q;
    QueryBuildDataSource    qbdsIJT, qbdsIJTr, qbdsIL,
                            qbdsIT;
    QueryBuildRange         qbr;
    QueryRun                qr;
    
    ;

    q = new Query();

    // смысл group by мне непонятен
    qbdsIJT = q.addDataSource(tablenum(InventJournalTable));
//    qbdsIJT.orderMode(OrderMode::GroupBy);
    qbdsIJT.addSelectionField(fieldNum(InventJournalTable, JournalId), SelectionField::Database);
    qbdsIJT.addSelectionField(fieldNum(InventJournalTable, InventLocationId), SelectionField::Database);
    qbdsIJT.addSelectionField(fieldNum(InventJournalTable, InventLocationIdTo), SelectionField::Database);
    qbdsIJT.addRange(fieldnum(InventJournalTable, JournalNameId)).value('ПРС');

    qbdsIJTr = qbdsIJT.addDataSource(tablenum(InventJournalTrans));
    qbdsIJTr.addSelectionField(fieldNum(InventJournalTrans, InventTransId), SelectionField::Database);
    qbdsIJTr.addSelectionField(fieldNum(InventJournalTrans, ItemId), SelectionField::Database);
    qbdsIJTr.addSelectionField(fieldNum(InventJournalTrans, InventDimId), SelectionField::Database);
    qbdsIJTr.addSelectionField(fieldNum(InventJournalTrans, Qty), SelectionField::Database);
    qbdsIJTr.relations(true);
    qbdsIJTr.joinMode(JoinMode::InnerJoin);
//    qbdsIJTr.orderMode(OrderMode::GROUPBY);
    qbdsIJTr.fetchMode(QueryFetchMode::One2One);

    qbdsIT = qbdsIJTr.addDataSource(tableNum(InventTable));
    qbdsIT.relations(true);
    qbdsIT.addSelectionField(fieldNum(InventTable, ItemName), SelectionField::Database);
    qbdsIT.addSelectionField(fieldNum(InventTable, ItemGroupId), SelectionField::Database);
    qbdsIT.joinMode(joinMode::InnerJoin);
//    qbdsItl.orderMode(OrderMode::GROUPBY);
    qbdsIT.fetchMode(QueryFetchMode::One2One);

    // можно объединить 2 DS в одну конструкцию
    qbdsIT = qbdsIJT.addDataSource(tableNum(InventLocation));
    qbdsIT.fetchMode(QueryFetchMode::One2One);
    qbdsIT.joinMode(JoinMode::ExistsJoin);
    qbdsIT.relations(false);
    // это на самом деле relation
    qbr = qbdsIT.addRange(fieldNum(InventLocation, InventLocationId));
    qbr.value(strFmt('(%1.%2 = %4.%5) || (%1.%3 = %4.%5)',
        qbdsIJT.name(), fieldStr(InventJournalTable, InventLocationId), fieldStr(InventJournalTable, InventLocationIdTo),
        qbdsIT.name(), fieldStr(InventLocation, InventLocationId)) );
    // прочие условия (на справочник складов)
    //qbdsIT.addRange(fieldNum(...

    // проверка, что не потерялся какой-нибудь DS
    qr = new QueryRun(q);
    if (qr.next())
        info(strFmt('%1 %2 %3',
            qr.get(tableNum(InventJournalTable)).(fieldNum(InventJournalTable, JournalId)),
            qr.get(tableNum(InventJournalTrans)).(fieldNum(InventJournalTrans, InventTransId)),
            qr.get(tableNum(InventTable)).(fieldNum(InventTable, ItemName))
            ));

    info('DAX query: '+qbdsIJT.toString());
    info(strFmt('Query qty: %1', SysQuery::qrCount(new QueryRun(q))));
В трёшке и 2009й работает. В примере объекты заменены на скл.журналы, но конструкция та же.

P.S. В стандарте, конечно же, нет полей со складами в шапке скл.журналов, добавлены вручную.

Пока строчил, уже всё порешали)))

Последний раз редактировалось dim-gin; 19.06.2017 в 22:28. Причина: опоздал с сообщением
За это сообщение автора поблагодарили: mazzy (2), smailik (1), alex55 (1).
Старый 19.06.2017, 22:32   #47  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
group by там похоже, потому что они что-то считают (судя по промелькнувшему SysQuery::count)
похоже просто код не полный.

да, проблема как раз в нескольких existsJoin в подчиненных таблицах.
с одним existsJoin никаких проблем

Цитата:
Сообщение от dim-gin Посмотреть сообщение
X++:
    // можно объединить 2 DS в одну конструкцию
    qbdsIT = qbdsIJT.addDataSource(tableNum(InventLocation));
    qbdsIT.fetchMode(QueryFetchMode::One2One);
    qbdsIT.joinMode(JoinMode::ExistsJoin);
    qbdsIT.relations(false);
    // это на самом деле relation
    qbr = qbdsIT.addRange(fieldNum(InventLocation, InventLocationId));
    qbr.value(strFmt('(%1.%2 = %4.%5) || (%1.%3 = %4.%5)',
        qbdsIJT.name(), fieldStr(InventJournalTable, InventLocationId), fieldStr(InventJournalTable, InventLocationIdTo),
        qbdsIT.name(), fieldStr(InventLocation, InventLocationId)) );
    // прочие условия (на справочник складов)
чё-то стрёмно такой workaruond применять.
опять же скорее всего, нам не все условия показали, а только самое тривиальное.

и если условия в ТЗ будут углублены и расширены (а они будут углублены)
то такой маневр будет оооочень сильно мешать.
__________________
полезное на axForum, github, vk, coub.
Старый 19.06.2017, 22:44   #48  
dim-gin is offline
dim-gin
Участник
 
41 / 30 (2) +++
Регистрация: 15.04.2014
Адрес: СПб
2 mazzy:
Да, это не самое элегантное решение. Но разве исходные 2 exists join'а с OR намного проще в выполнении для БД? Или Вы подразумеваете другой смысл под словом "мешать"?

Последний раз редактировалось dim-gin; 19.06.2017 в 22:45. Причина: опечатка
Старый 19.06.2017, 23:00   #49  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
для БД не проще.
мешать будет человеку.

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

пользователь появляется поскольку часто готовый query может оказаться в стандартном диалоге, где пользователь может его подправить. даже опытный пользователь повесится. придется делать этот range::Locked. а затем придумывать обходные пути чтобы таки как-то разрешить.

да, из кода видно, что в данном случае разработчики не парятся с критериями, а используют диалог с единственным значением для фильтра в каждом range. и хорошо, если это значение можно подставить из выпадающего списка )))

но рано или поздно они могут захотеть таки перейти на полноценные критерии вместо единственного значения.

этот workaround сделает любое расширение условия по складам очень нетривиальным и сложным.
__________________
полезное на axForum, github, vk, coub.
За это сообщение автора поблагодарили: dim-gin (1).
Старый 06.09.2017, 19:37   #50  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
Всем доброго дня. Столкнулся с подобной задачей, но теперь мне надо наложить условие И на одно и тоже поле таблицы. А именно примерно следующее:
X++:
qbr.value(strfmt('((%1 >= %2) && (%1 == %3))',
                fieldStr(myTable, TransDate), 
                tableParameters.DateFrom, 
                transDateFilter));
Все это дело происходит на форме. Вверху формы фильтр по дате (transDateFilter). Есть таблица параметров (tableParameters). Суть вот в чем, мне нужно на форме отображать записи которые больше или равны дате из параметров и при этом соответствуют фильтру вверху формы, если он указан конечно.
На данный момент получаю ошибку "Ошибка расширенного диапазона запроса: Ожидается правая круглая скобка рядом с 23."
Если перед strfmt добавить SysQuery::value, то ошибки нет, но и данных нет. Прошу совета как реализовать необходимую задачу.
Старый 06.09.2017, 19:49   #51  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
равенство одним символом =, а не двумя
http://axapta.mazzy.ru/lib/search/
__________________
полезное на axForum, github, vk, coub.
Старый 06.09.2017, 19:52   #52  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
На ошибку это не повлияло.
Когда заработает надо поизучать этот вопрос http://www.axaptapedia.com/Expressions_in_query_ranges тут "=="

Последний раз редактировалось smailik; 06.09.2017 в 19:55.
За это сообщение автора поблагодарили: mazzy (2).
Старый 06.09.2017, 20:54   #53  
andrewK is offline
andrewK
Участник
 
45 / 22 (1) +++
Регистрация: 03.11.2005
По это же ссылке приведен пример работы с датой в Query:
X++:
queryBuildRange.value(strFmt('(ModifiedDate > %1)', Date2StrXpp(01\01\2000)));
Старый 06.09.2017, 21:02   #54  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
Проблема не с обычным фильтром, а с условием И по одному и тому же полю
Старый 06.09.2017, 22:25   #55  
dim-gin is offline
dim-gin
Участник
 
41 / 30 (2) +++
Регистрация: 15.04.2014
Адрес: СПб
1. А почему нельзя одно из условий отбросить в самом приложении (а не перекладывать эту функцию на БД)?
2. Даже если и нельзя, то, объединив уже предложенные советы, получаем перевариваемый вариант (2009, трёшка):
X++:
    Query                   q;
    QueryBuildDataSource    qbds;
    QueryRun                qr;
    EmplTable   empl;
    str         sRange;
    int         iCnt;
    ;

    q = new Query();
    qbds = q.addDataSource(tableNum(EmplTable));
    sRange = strFmt('(%1.%2 >= %3) && (%1.%2 = %4)',
                qbds.name(), fieldStr(EmplTable, PayEmploymentDate_RU), date2StrXpp(01\09\2017), date2StrXpp(today()));
    //info(sRange);
    qbds.addRange(fieldNum(EmplTable, PayEmploymentDate_RU)).value(sRange);
    //info(qbds.toString());
    qr = new QueryRun(q);
    while (qr.next())
        iCnt++;
        
    info(int2str(iCnt));
За это сообщение автора поблагодарили: smailik (2), dech (2).
Старый 06.09.2017, 23:20   #56  
smailik is offline
smailik
Участник
Аватар для smailik
 
250 / 70 (3) ++++
Регистрация: 10.04.2012
Адрес: Москва
Огромное спасибо. Заработался. За сегодняшнюю дату то у меня записей нет. Система правильно делала что показывала пустоту.
Старый 07.09.2017, 09:14   #57  
dech is offline
dech
Участник
Аватар для dech
Самостоятельные клиенты AX
 
647 / 350 (13) ++++++
Регистрация: 25.06.2009
Адрес: Омск
Записей в блоге: 3
Цитата:
Сообщение от smailik Посмотреть сообщение
X++:
qbr.value(strfmt('((%1 >= %2) && (%1 == %3))',
                fieldStr(myTable, TransDate), 
                tableParameters.DateFrom, 
                transDateFilter));
На данный момент получаю ошибку "Ошибка расширенного диапазона запроса: Ожидается правая круглая скобка рядом с 23."
Причина ошибки - неверное строковое представление даты. В следующий раз используйте date2StrXpp(), как в примере у dim-gin.
__________________
// no comments
За это сообщение автора поблагодарили: smailik (2).
Старый 07.09.2017, 11:28   #58  
Ace of Database is offline
Ace of Database
Участник
Аватар для Ace of Database
 
877 / 649 (23) +++++++
Регистрация: 14.10.2004
Цитата:
Сообщение от mazzy Посмотреть сообщение
И все-таки лучшей версией была акс2009.
Согласен на все 100!
__________________
Мои утилиты для Аксапты версий 3.0-2012: http://aceofdatabase.blogspot.com/
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Query для HcmPosition (запрос по таблице, соссылкой на себя же) Music DAX: Программирование 9 07.07.2016 14:54
emeadaxsupport: Microsoft Dynamics AX general performance analysis scripts page 5 Blog bot DAX Blogs 0 01.09.2014 14:11
Вложенный запрос SQL с помощью великого Query user_ax DAX: Программирование 9 07.10.2013 14:00
like запрос с использованием query Vadik Shiryakoff DAX: Программирование 7 13.03.2006 12:05

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

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

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