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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 18.09.2025, 13:24   #1  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,995 / 3293 (117) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Некорректная работа Extended query в 2012-й с Array полями
Привет.
Пишем модификацию под 12-ку R3
задействовали array поля (аналог Dimension)
И вдруг выясняется что для измерений начиная с 2-ки extended query в 12-ке не работает. Хотя это было вылечено еще в 2009-й.
Обычный Query работает.

Пример - джобик отрабатывает в 2009-й
для SysDimension::Center в бд уходит запрос с фильтром такого вида
X++:
(DIMENSION2_=N'1929')
а в 2012-й аналогичный джоб приводит к
X++:
(DIMENSION=N'1929')
(имена полей в 12-ке у нас конечно другие - свои значения - здесь стоит Dimension чисто для иллюстрации)
Но если поставить обычный Query то в 12-ке тоже работает.

Может можно как-то это исправить ?
В синтаксисе extendedQuery что-то поменять.

X++:
static void Job503_TestDim(Args _args)
{
    Query       query;
    QueryBuildDataSource    qbds;
    SysQueryRun    queryRun;
    SalesTable    salesTable;
    void test(SysDimension _finSysDimension, SysDim _num)
    {
        ;
        
        setPrefix(strFmt("%1 - %2", _finSysDimension, _num));
        query = new query();
        query.literals(1);
        qbds = query.addDataSource(tableNum(SalesTable));
        qbds.addSelectionField(fieldNum(SalesTable, SalesId));
        
        // extended query для измерений начиная с 2 не работает в 12-ке
        qbds.addRange(fieldNum(SalesTable, RecId)).value(
            strFmt('((%1.%2=="%3"))',
            qbds.name(),
            fieldid2name(tablenum(SalesTable), fieldid2ext(fieldnum(SalesTable, Dimension), Dimensions::code2ArrayIdx(_finSysDimension))),
            SysQuery::value(_num)
            )
            );
        /*
        // а обычный query - работает
        qbds.addRange(fieldid2ext(fieldnum(SalesTable, Dimension), Dimensions::code2ArrayIdx(_finSysDimension))).value(
            SysQuery::value(_num)
            );
        */
        queryRun = new SysQueryRun(query);
        // info(queryRun.toString());
        info(queryRun.query().dataSourceNo(1).toString()); // поправил для 2009-й
        if (queryRun.next())
        {
            salesTable = queryRun.get(tableNum(SalesTable));
            info(strFmt("%1", salesTable.SalesId));
        }
        else
        {
            warning(strFmt("Нет записей"));
        }
    }
    ;
    
    setPrefix(strFmt("Test"));
    
    // test(SysDimension::Department, '001'); // для SysDimension::Department - все работает в Extended Query
    // test(SysDimension::Department, '002');
    test(SysDimension::Center,     '1929');  // а для SysDimension::Center - уже нет
    // test(SysDimension::Center,     '222');
}

Последний раз редактировалось Logger; 18.09.2025 в 14:13. Причина: Исправил строку info(queryRun.toString());
Старый 18.09.2025, 13:39   #2  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,995 / 3293 (117) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Дополню в несколько другой формулировке (а то уточняют - видимо не совсем понятно описал)

в общем в 12-ке есть array поле самописное и для столбцов
Filed[2]
Filed[3]
и.т.п. extendedQuery не отрабатывает. Считает что это Filed[1]

Я помню что-то подобное было в 2009-й, но начиная с какого-то сервис пака (кажется SP5) это было исправлено. - Проверил в 2009-й все хорошо на последних билдах
Старый 18.09.2025, 13:47   #3  
Pandasama is offline
Pandasama
Участник
 
469 / 140 (5) +++++
Регистрация: 11.08.2014
Адрес: Барнаул
То есть в Ax если текст запроса посмотреть - он нормальный, а в SQL уходит другой?
Это очень странно.

Или он уже в Ax кривой? если да - то где именно ломается внутри этого?
X++:
strFmt('((%1.%2=="%3"))',
            qbds.name(),
            fieldid2name(tablenum(SalesTable), fieldid2ext(fieldnum(SalesTable, Dimension), Dimensions::code2ArrayIdx(_finSysDimension))),
            SysQuery::value(_num)
Старый 18.09.2025, 13:50   #4  
Pandasama is offline
Pandasama
Участник
 
469 / 140 (5) +++++
Регистрация: 11.08.2014
Адрес: Барнаул
X++:
Dimensions::code2ArrayIdx()
вот это что? это не стандарт

ну и в SalesTable нет Dimension, там DefaultDimension в 12ке - джоб не компилится
Старый 18.09.2025, 14:05   #5  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,995 / 3293 (117) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Pandasama Посмотреть сообщение
То есть в Ax если текст запроса посмотреть - он нормальный, а в SQL уходит другой?
именно так !
Скрины не могу выкладывать - превысил лимит по картинкам.
Выглядит так
X++:
info(queryRun.query().dataSourceNo(1).toString());
выдает строку
Цитата:
SELECT WITH FORCE_LITERALS OrderId FROM TreasPayReqTable(TreasPayReqTable_1) WHERE ((((TreasPayReqTable_1.FinDimension[2]=="1929"))))
а на SQL уходит так :
Цитата:
SELECT T1.ORDERID,T1.RECID FROM TREASPAYREQTABLE T1 WHERE (((PARTITION=5637144576) AND (DATAAREAID=N'mrc')) AND (FINDIMENSION=N'1929')) ORDER BY T1.ORDERID

Последний раз редактировалось Logger; 18.09.2025 в 14:25.
Старый 18.09.2025, 14:08   #6  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,995 / 3293 (117) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от Pandasama Посмотреть сообщение
X++:
Dimensions::code2ArrayIdx()
вот это что? это не стандарт

ну и в SalesTable нет Dimension, там DefaultDimension в 12ке - джоб не компилится
Джобик написан в 2009-й.
В 12-ку наверно легко портировать - просто константы поставить например.

У нас свои самописные таблички, я мог бы выложить джобик для них, но но у вас их нет. Не сможете повторить.
Попробуйте на SalesTable.DEL_Dimension

вместо
FinDimensions::code2ArrayIdx(_finSysDimension)
можно просто поставить (_finSysDimension+ 1)
это же джоб
Старый 18.09.2025, 14:18   #7  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,995 / 3293 (117) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Кажется придумал как обойти.
Делаем вьюху по табличке.
В ней делаем поля
View.Dimension1 - мапируется на Table.Dimension[1]
View.Dimension2 - мапируется на Table.Dimension[2]
View.Dimension3 - мапируется на Table.Dimension[3]

в запросе джоиним эту вьюху по первичному ключу (или по RecId) к таблице и накладываем фильтры уже на поля вьюхи. Все работает.
Немного геморно, но рабочий вариант.

Но может можно без вьюхи ?
Старый 19.09.2025, 01:22   #8  
Товарищ ♂uatr is offline
Товарищ ♂uatr
Участник
Аватар для Товарищ ♂uatr
MCBMSS
 
337 / 915 (31) +++++++
Регистрация: 23.10.2012
Моделируем ситуацию с переиспользованием упакованный и "красивого" Query из 9-ки в 12-ке.
Создаём 2 таблицы в 9-ке:
- DimQueryPack, с полем value типа container. Хранит в себе упакованный query;
- DimTableTest, с полем Dimension типа string (array) от EDT Dimension. Нужна для выверки (Dimension Id идентичный между версиями).

Запускаем джоб в 9-ке:
X++:
static void JobDimQueryCreate_Ax5(Args _args)
{
    DimQueryPack            dqp;
    Query                   query;
    QueryBuildDataSource    qbds;
    
    int code2ArrayIdx(SysDimension _sysDimension)
    {
        return new SysDictEnum(enumnum(SysDimension)).value2Index(_sysDimension) + 1;
    }
    
    select firstOnly RecId from dqp;
    
    if (!dqp.RecId)
    {
        query = new query();
        query.literals(1);
        qbds = query.addDataSource(tableNum(DimTableTest));
        qbds.addSelectionField(fieldNum(DimTableTest, Dimension));
        
        //qbds.addRange(fieldNum(DimTableTest, RecId)).value(QueryBuildRangeCondition::create(qbds, fieldId2Name(tableNum(DimTableTest), fieldId2ext(fieldNum(DimTableTest, Dimension), 2))).value(QueryBuildRangeOperator::Equal, '1929').toString());
        qbds.addRange(fieldNum(DimTableTest, RecId)).value(
            strFmt('(( %1.Dimension[2]=="1929" ))',
            qbds.name(),
            fieldid2name(tablenum(DimTableTest), fieldid2ext(fieldnum(DimTableTest, Dimension), code2ArrayIdx(SysDimension::Center))),
            SysQuery::value('1929')
            )
            );
        
        ttsBegin;
        
        dqp.initValue();
        dqp.value = query.pack();
        dqp.insert();
        
        ttsCommit;
    }
}
Экспорт/импорт в 12-ку данных таблиц и запускаем джоб (всего их будет 3):
X++:
static void JobDimQueryCreate_Ax6(Args _args)
{
    DimQueryPack dqp;
    ;
    
    ttsBegin;
    
    dqp.initValue();
    dqp.insert();
    
    ttsCommit;
}
Через TSQL запрос меняем value в 12-ке тем, что лежит в 9-ке (в DimQueryPack).

Запускаем на обеих средах джоб:
X++:
static void JobDimTableTest(Args _args)
{
    DimQueryPack dqp;
    DimTableTest dtt;
    QueryRun     queryRun;
    ;
    
    select firstOnly RecId from dtt;
    
    if (!dtt.RecId)
    {
        ttsBegin;
        dtt.initValue();
        dtt.Dimension[1] = '1929';
        dtt.doInsert();
        
        dtt.clear();
        dtt.initValue();
        dtt.Dimension[2] = '1929';
        dtt.doInsert();
        
        ttsCommit;
    }

    setPrefix(strFmt("Test"));

    while select dqp
    {
        queryRun = new SysQueryRun(dqp.value);
        
        if (queryRun.next())
        {
            info(strFmt("%1", queryRun.get(tableNum(DimTableTest)).RecId));
        }
        else
        {
            warning(strFmt("Нет записей"));
        }
    }
}
Получаем результат, который ничем не отличается от исходного, изложенного в оригинальном посте данной ветки. Это всё было нужно для проверки навязчивой мысли с подменой hex'а в упакованном blob'е. Это сложнее нежели создать view, но является разовым действием по написанию целевой функции. При этом, учитывая контекст, что всё же 12-ка умеет, не через расширенные диапазоны, "красиво" выбирать значения из полей-массивов (см. оригинальный джоб), вероятность решить проблему подобным образом всё ещё существует.

Наверняка есть и иной способ решения, например анализ и отладка низкоуровневых функций. Они начинаются с префикса qe (что в 9-ке, что в 12-ке).
Например, при работе с функцией QueryBuildRange.value интересует функция qeRangeNode :: propChanged.

Последний раз редактировалось Товарищ ♂uatr; 19.09.2025 в 01:25.
Теги
bug, extended query, extended query syntax

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
AXAPTA 2012. Работа с выпадающим списком feuerfub DAX: Функционал 1 21.11.2019 15:06
emeadaxsupport: Dynamics AX 2012 Reporting: How to add company logo into query based report Blog bot DAX Blogs 0 06.12.2012 21:11
X++: X++ Arrays Behave Differently in .NET CIL, in Dynamics AX 2012 Blog bot DAX Blogs 0 17.09.2012 23:11
dynamicsaxtraining: Purchase Blog bot DAX Blogs 0 11.03.2012 05:25
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

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

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