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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 19.06.2017, 15:54   #1  
smailik is offline
smailik
Участник
Аватар для smailik
 
166 / 42 (2) +++
Регистрация: 10.04.2012
Адрес: Москва
Запрос ИЛИ в query
Всем доброго дня. AX 4. Прошу помощи вот в каком вопросе. Создаю query как написано ниже. Если запускать так то все работает. Но если раскоментировать присоединение InventTable, то система начинает игнорировать наложение range по InventLocationType.
Может кто-нибудь сталкивался с подобным? Посоветуйте как это победить?
X++:
query = new Query();

    qbdsItt = query.addDataSource(tablenum(InventTransferTable), "Transfer");
    qbdsItt.orderMode(OrderMode::GroupBy);
    qbdsItt.addRange(fieldnum(InventTransferTable, ReceiveDate)).value(strfmt('%1..%2', fromDate, toDate));
    qbdsItt.addRange(fieldnum(InventTransferTable, TransferStatus)).value(QueryValue(InventTransferStatus::Received));
    qbdsItt.addRange(fieldnum(InventTransferTable, InventLocationIdFrom)).value(inventLocationIdFrom);
 
    qbdsItl = qbdsItt.addDataSource(tablenum(InventTransferLine));
    qbdsItl.addLink(fieldnum(InventTransferLine , TransferId), fieldnum(InventTransferTable, TransferId));
    qbdsItl.joinMode(JoinMode::InnerJoin);
    qbdsItl.orderMode(OrderMode::GROUPBY);
    qbdsItl.fetchMode(QueryFetchMode::One2One);

    /* 
    qbdsIt = qbdsItl.addDataSource(tableNum(InventTable)); 
    qbdsIt.relations(true);
    qbdsIt.joinMode(joinMode::InnerJoin);    
    */

    if (inventLocationType != InventLocationType::Standard)
    {
        qbdsInventLocationFrom = qbdsItt.addDataSource(tablenum(InventLocation));
        qbdsInventLocationFrom.addLink(fieldNum(InventTransferTable, InventLocationIdFrom), fieldNum(InventLocation, InventLocationId));
        qbdsInventLocationFrom.joinMode(JoinMode::ExistsJoin);
        qbdsInventLocationFrom.fetchMode(QueryFetchMode::One2One);

        qbdsInventLocationTo = qbdsItt.addDataSource(tableNum(InventLocation));
        qbdsInventLocationTo.addLink(fieldNum(InventTransferTable, InventLocationIdTo), fieldNum(InventLocation, InventLocationId));
        qbdsInventLocationTo.joinMode(JoinMode::ExistsJoin);
        qbdsInventLocationTo.fetchMode(QueryFetchMode::One2One);

        qbrDataAreaId = qbdsInventLocationTo.addRange(fieldNum(InventLocation, DataAreaId));
        qbrDataAreaId.value(strFmt('((%1.%3 == %4) || (%2.%3 == %4))',
            qbdsInventLocationFrom.name(),
            qbdsInventLocationTo.name(),
            fieldStr(InventLocation, InventLocationType),
            any2int(inventLocationType)));
    }

    queryRun = new QueryRun(query);
 
    rowCount = SysQuery::countLoops(queryRun);
Старый 19.06.2017, 16:08   #2  
mazzy is offline
mazzy
Administrator
Аватар для mazzy
Most Valuable Professional
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
28,760 / 3627 (178) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
могу ошибаться, но если установлен group by, то он должен быть установлен у всех датасорсов.

можно совет?
не пишите запросы в коде. создайте запрос в AOT.
пропишите в коде постоянные relation, value

в коде пишите
X++:
Query q = new Query(querystr(mySuperQuery));
дальше делайте с уже созданным query устанавливайте rangevalue
например при помощи SysQuery::findOrCreateRange()

геморроя будет намного меньше.
__________________
GitHub, Facebook, mazzy.priot, mazzy.music, coub.
Старый 19.06.2017, 16:08   #3  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,101 / 1523 (57) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
А с текстом запроса что происходит?
X++:
info(qbdsItt.ToString());
Как вариант:

Вместо exists join попробовать inner join. В данном случае вроде бы уникальность записей в InventLocation позволяет.

Возможно использовать промежуточное View
За это сообщение автора поблагодарили: mazzy (2), smailik (1).
Старый 19.06.2017, 16:11   #4  
smailik is offline
smailik
Участник
Аватар для smailik
 
166 / 42 (2) +++
Регистрация: 10.04.2012
Адрес: Москва
X++:
    qbdsIt = qbdsItl.addDataSource(tableNum(InventTable));
    qbdsIt.relations(true);
    qbdsIt.joinMode(joinMode::InnerJoin);
    qbdsIt.orderMode(OrderMode::GROUPBY);
Так я тоже пробовал. Не помогло. Изначально опирался на http://www.axaptapedia.com/Expressions_in_query_ranges
Если больше вариантов не будет, то буду пробовать создавать query в AOT.
Старый 19.06.2017, 16:16   #5  
smailik is offline
smailik
Участник
Аватар для smailik
 
166 / 42 (2) +++
Регистрация: 10.04.2012
Адрес: Москва
Замена на inner join ничего не дала.
Текст запроса:
SELECT * FROM InventTransferTable WHERE ((ReceiveDate>={ts '2017-05-20 00:00:00.000'} AND ReceiveDate<={ts '2017-06-19 00:00:00.000'})) AND ((TransferStatus = 2)) AND ((InventLocationIdFrom = N'242')) JOIN * FROM InventTransferLine WHERE InventTransferTable.TransferId = InventTransferLine.TransferId JOIN * FROM InventTable WHERE InventTransferLine.ItemId = InventTable.ItemId JOIN * FROM InventLocation WHERE InventTransferTable.InventLocationIdFrom = InventLocation.InventLocationId JOIN * FROM InventLocation WHERE InventTransferTable.InventLocationIdTo = InventLocation.InventLocationId AND ((((InventLocation_1.InventLocationType == 8) || (InventLocation_2.InventLocationType == 8))))
Старый 19.06.2017, 16:33   #6  
mazzy is offline
mazzy
Administrator
Аватар для mazzy
Most Valuable Professional
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
28,760 / 3627 (178) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Цитата:
Сообщение от smailik Посмотреть сообщение
AND ((((InventLocation_1.InventLocationType == 8) || (InventLocation_2.InventLocationType == 8))))
это неправильная конструкция для SQL
вместо || в строке должен быть OR
__________________
GitHub, Facebook, mazzy.priot, mazzy.music, coub.
Старый 19.06.2017, 16:36   #7  
smailik is offline
smailik
Участник
Аватар для smailik
 
166 / 42 (2) +++
Регистрация: 10.04.2012
Адрес: Москва
Если в range "||" заменяю на "OR" то получаю ошибку
Ошибка расширенного диапазона запроса: Ожидается правая круглая скобка рядом с 48.
Старый 19.06.2017, 16:43   #8  
mazzy is offline
mazzy
Administrator
Аватар для mazzy
Most Valuable Professional
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
28,760 / 3627 (178) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
и в SQL используется = вместо ==
))
__________________
GitHub, Facebook, mazzy.priot, mazzy.music, coub.
Старый 19.06.2017, 16:49   #9  
smailik is offline
smailik
Участник
Аватар для smailik
 
166 / 42 (2) +++
Регистрация: 10.04.2012
Адрес: Москва
SQL конечно SQL-ем, но тот у меня не прямой запрос к базе, а построение query. Я конечно попробовал. Попытка - не пытка. Ошибка та же самая, только в конце "с 47."
Старый 19.06.2017, 17:00   #10  
smailik is offline
smailik
Участник
Аватар для smailik
 
166 / 42 (2) +++
Регистрация: 10.04.2012
Адрес: Москва
Если написать вот так
X++:
qbrDataAreaId.value(strFmt('(%1.%3 = %4) OR (%2.%3 = %4)', ...
то ошибки не возникает, но и результат работы не верный.
Старый 19.06.2017, 17:07   #11  
bitter is offline
bitter
Участник
 
15 / 19 (1) ++
Регистрация: 12.04.2015
Попробуйте таким образом:
X++:
qbrDataAreaId.value(strFmt('((%1.%3 = %4) || (%2.%3 = %4))', ...
Полезная ссылка по этой теме.
Старый 19.06.2017, 17:11   #12  
smailik is offline
smailik
Участник
Аватар для smailik
 
166 / 42 (2) +++
Регистрация: 10.04.2012
Адрес: Москва
Вашей ссылкой я уже пользовался. Она менее полезна чем та которую писал я, так как в этот пример ИЛИ для одной таблицы.
Предложенный вариант, тоже не помог.
Старый 19.06.2017, 17:17   #13  
mazzy is offline
mazzy
Administrator
Аватар для mazzy
Most Valuable Professional
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
28,760 / 3627 (178) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
в общем, странно.
попробуйте упростить свой запрос, чтобы выяснить причину. мне кажется, что проблема не в ИЛИ.
попробуйте создать запрос в AOT, а в коде только менять range

вот еще старые-старые комментарии внизу http://axapta.mazzy.ru/lib/search/
оно должно работать.
__________________
GitHub, Facebook, mazzy.priot, mazzy.music, coub.
Старый 19.06.2017, 17:18   #14  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
2,916 / 1540 (57) ++++++++
Регистрация: 12.10.2004
У вас Query двоится. И одна из веток отсекается.

Против такого неплохо помогает такой финт:
Вытягивать весь запрос в линейку
qbdsItt - qbdsItl - qbdsIt - qbdsInventLocationFrom - qbdsInventLocationTo
т.е. в таком порядке делать AddDatasource.
А связи прописать через вызов addlink() указав 3-м параметром имя реального датасорса к которому линкуем.
Такой вариант всегда для inner join работал (но не для outer)
За это сообщение автора поблагодарили: mazzy (2), S.Kuskov (2), smailik (1).
Старый 19.06.2017, 17:20   #15  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
2,916 / 1540 (57) ++++++++
Регистрация: 12.10.2004
А вообще для начала неплохо бы подсмотреть что уходит реально на SQL и от этого плясать.
Конечно включить query.literals(1)
Старый 19.06.2017, 17:24   #16  
mazzy is offline
mazzy
Administrator
Аватар для mazzy
Most Valuable Professional
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
28,760 / 3627 (178) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Цитата:
Сообщение от smailik Посмотреть сообщение
Замена на inner join ничего не дала.
Текст запроса:
SELECT * FROM InventTransferTable WHERE ((ReceiveDate>={ts '2017-05-20 00:00:00.000'} AND ReceiveDate<={ts '2017-06-19 00:00:00.000'})) AND ((TransferStatus = 2)) AND ((InventLocationIdFrom = N'242')) JOIN * FROM InventTransferLine WHERE InventTransferTable.TransferId = InventTransferLine.TransferId JOIN * FROM InventTable WHERE InventTransferLine.ItemId = InventTable.ItemId JOIN * FROM InventLocation WHERE InventTransferTable.InventLocationIdFrom = InventLocation.InventLocationId JOIN * FROM InventLocation WHERE InventTransferTable.InventLocationIdTo = InventLocation.InventLocationId AND ((((InventLocation_1.InventLocationType == 8) || (InventLocation_2.InventLocationType == 8))))
1. у вас точно есть enum ItemType со значением 8? просто в стандартной 2012 такого нет
2. обратите внимание на название таблиц.
в запросе у вас ДВЕ inventLocation, а в условии название таблицы InventLocation_1 и InventLocation_2.

Стройте запросы в АОТ!
в коде пишите только одну строку Query q = new Query(querystr(mySuperQuery));
и не парьтесь.
__________________
GitHub, Facebook, mazzy.priot, mazzy.music, coub.
Старый 19.06.2017, 17:32   #17  
smailik is offline
smailik
Участник
Аватар для smailik
 
166 / 42 (2) +++
Регистрация: 10.04.2012
Адрес: Москва
Цитата:
Сообщение от Logger Посмотреть сообщение
Вытягивать весь запрос в линейку
У меня ведь и так в линейку. К шапкам - строки, к строкам - номенклатуры, но как не крути склады то я только к шапке могу прицепить.
Старый 19.06.2017, 17:34   #18  
smailik is offline
smailik
Участник
Аватар для smailik
 
166 / 42 (2) +++
Регистрация: 10.04.2012
Адрес: Москва
mazzy, 1- да, 2- меня это тоже смущает, но стоит убрать InventTable из query и все работает, не смотря на такой странный вид.
Запрос в AOT - хорошо, но как в нем прописать такой range между двумя таблицами?
Старый 19.06.2017, 17:43   #19  
mazzy is offline
mazzy
Administrator
Аватар для mazzy
Most Valuable Professional
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
28,760 / 3627 (178) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Цитата:
Сообщение от mazzy Посмотреть сообщение
в коде пишите
X++:
Query q = new Query(querystr(mySuperQuery));
дальше делайте с уже созданным query устанавливайте rangevalue
например при помощи SysQuery::findOrCreateRange()

геморроя будет намного меньше.
другими словами, НЕ ОБЯЗАТЕЛЬНО СОЗДАВАТЬ запрос С НУЛЯ в коде.

пишите что-то вроде такого:
X++:
Query q = new Query(querystr(mySuperQuery));
SysQuery::findOrCreateRange(q.datasourceTable(tablenum(...)), fieldnum(...)).value(...);
все.
не надо многоэтажных конструкций. и вы всегда уверены, что датасорсы и проперти расставлены правильно с точки зрения аксапты.
__________________
GitHub, Facebook, mazzy.priot, mazzy.music, coub.
Старый 19.06.2017, 18:18   #20  
smailik is offline
smailik
Участник
Аватар для smailik
 
166 / 42 (2) +++
Регистрация: 10.04.2012
Адрес: Москва
Создал query в АОТ.
Сейчас код выглядит так.
X++:
query = new Query(querystr(myQuery));

    qbdsItt = SysQuery::findOrCreateDataSource(query, tableNum(InventTransferTable));
    qbdsItt.addRange(fieldnum(InventTransferTable, ReceiveDate)).value(strfmt('%1..%2', fromDate, toDate));
    qbdsItt.addRange(fieldnum(InventTransferTable, TransferStatus)).value(QueryValue(InventTransferStatus::Received));
    qbdsItt.addRange(fieldnum(InventTransferTable, InventLocationIdFrom)).value(inventLocationId);

    if (inventLocationType != InventLocationType::Standard)
    {
        qbdsInventLocationTo = SysQuery::findOrCreateDataSource(query, tableNum(InventLocation), tableNum(InventTransferTable));

        qbrDataAreaId = qbdsInventLocationTo.addRange(fieldNum(InventLocation, DataAreaId));
        qbrDataAreaId.value(strFmt('((%1.%3 = %4) || (%2.%3 = %4))',
            'InventLocationTo',
            'InventLocationFrom',
            fieldStr(InventLocation, InventLocationType),
            any2int(inventLocationType)));
    }

    //info(qbdsItt.ToString());

    queryRun = new QueryRun(query);

    rowCount = SysQuery::countLoops(queryRun);
При запуске висит на подсчете количества строк.
Да этого момента в AOT query не создавал, так что прошу сильно шапками не закидывать.
Вложения
Тип файла: xpo myQuery.xpo (2.9 Кб, 25 просмотров)
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
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, время: 01:31.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.