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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 12.01.2009, 13:05   #1  
Blog bot is offline
Blog bot
Участник
 
25,640 / 848 (80) +++++++
Регистрация: 28.10.2006
OZKA's DAX Journal: Join между временной и постоянной таблицей через QueryRun.
Источник: http://ozka-lemming.blogspot.com/200...-queryrun.html
==============

Однажды, отлаживая нетривиальный код, наткнулся на subj. Не зная про эту «фичу», я долго удивлялся почему запрос возвращает такой странный набор данных!?! Ниже приведен простенький Job-ик, который демонстрирует существование этой возможности в DAX. В иерархии запроса временная таблица должна быть первым источником данных.



X++:
static void JoinTmpTablesOnQuery(Args _args)
{
    LedgerTrans             ledgerTrans;
    LedgerTable             ledgerTableTmp;

    int                     i;
    int                     transCnt   = 20;

    Query                   query      = new Query();
    
    QueryBuildDataSource    qbdsTable  = query.addDataSource(tableNum(LedgerTable));
    QueryBuildDataSource    qbds2Trans = qbdsTable.addDataSource(tableNum(LedgerTrans));


    QueryRun                queryRun;
    ;

    qbds2Trans.relations(true);

    ledgerTableTmp.setTmp();
    
    ledgerTableTmp.data(LedgerTable::find("02.010"));
    ledgerTableTmp.insert();
    
    ledgerTableTmp.data(LedgerTable::find("01.030"));
    ledgerTableTmp.insert();
    
    queryRun = new QueryRun(query);

    queryRun.setCursor(ledgerTableTmp, 1);
    
    i = 0;

    while (queryRun.next())
    {
        ledgerTableTmp = queryRun.getNo(1);
        ledgerTrans    = queryRun.getNo(2);

        info(strfmt("AccountNum %1 , AmountCur %2 , (tmpRecId %3 , regRecId %4)",
                     ledgerTableTmp.AccountNum,
                     ledgerTrans.AmountCur,
                     ledgerTableTmp.RecId,
                     ledgerTrans.RecId));
 
        i++;
        
        if (transCnt && i == transCnt)
            break;
    }

}

Источник: http://ozka-lemming.blogspot.com/200...-queryrun.html
__________________
Расскажите о новых и интересных блогах по Microsoft Dynamics, напишите личное сообщение администратору.
Старый 14.01.2009, 15:28   #2  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Lemming, а расскажите чуть подробнее и не так загадочно?

Что должно происходить? Я грешным делом подумал, что можно наконец-то полноценно связать временную таблицу с постоянной, т.е. фильтровать постоянную таблицу по временному набору. Но в выводимых результатах что-то этого не заметил...

Спасибо.
Старый 14.01.2009, 15:53   #3  
Lemming is offline
Lemming
Участник
Аватар для Lemming
 
1,144 / 343 (14) ++++++
Регистрация: 20.04.2004
Адрес: Москва, Чайнатаун в Люблино
Записей в блоге: 10
В приведенном джобике(если я конечно не сошел с ума ) запрос LedgerTable и LedgerTrans должен выводить проводки только по тем счетам, которые попали во временную таблицу LedgerTransTmp. (см. queryRun.setCursor(ledgerTableTmp, 1);


Job писал в DAX 4, но должно отработать и в 3-ке(в свое время увидел именно в ней). Или джоб так хитро отрабатывает только у меня?
Старый 14.01.2009, 16:17   #4  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Да нет, с queryRun.setCursor действительно работает.. На 3.0 тоже.
__________________
Zhirenkov Vitaly
Старый 14.01.2009, 16:20   #5  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Временные таблицы и query
__________________
Zhirenkov Vitaly
Старый 14.01.2009, 16:27   #6  
Lemming is offline
Lemming
Участник
Аватар для Lemming
 
1,144 / 343 (14) ++++++
Регистрация: 20.04.2004
Адрес: Москва, Чайнатаун в Люблино
Записей в блоге: 10
Цитата:
Сообщение от ZVV Посмотреть сообщение
Ну да, было дело, спрашивал, а вот то что их можно так хитро заджоинить, временную с постоянной через queryRun, я не знал

upd:

Врочем так тоже можно, хотя это наверное многие знают.
X++:
ledgerTableTmp.data(LedgerTable::find("01.030"));
    ledgerTableTmp.insert();
    
    while select ledgerTableTmp
    join ledgerTrans
        where ledgerTrans.AccountNum == ledgerTableTmp.AccountNum
    {
        info(ledgerTrans.AccountNum);
    }
    return;

Последний раз редактировалось Lemming; 14.01.2009 в 16:32.
Старый 14.01.2009, 16:33   #7  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от Lemming Посмотреть сообщение
запрос LedgerTable и LedgerTrans должен выводить проводки только по тем счетам, которые попали во временную таблицу LedgerTransTmp.
Ok, значит я думал правильно и тоже хотел именно этого. Но увы...
Цитата:
Сообщение от ZVV Посмотреть сообщение
Да нет, с queryRun.setCursor действительно работает.. На 3.0 тоже.
Получается, не у всех... У меня на 3.0, SP4, двухзвенка, Oracle 10g - НЕ РАБОТАЕТ, вылезает унылое декартово произведение.
Старый 14.01.2009, 16:43   #8  
Lemming is offline
Lemming
Участник
Аватар для Lemming
 
1,144 / 343 (14) ++++++
Регистрация: 20.04.2004
Адрес: Москва, Чайнатаун в Люблино
Записей в блоге: 10
Цитата:
Сообщение от Gustav Посмотреть сообщение
Получается, не у всех... У меня на 3.0, SP4, двухзвенка, Oracle 10g - НЕ РАБОТАЕТ, вылезает унылое декартово произведение.
Оракле под рукой увы нет...Кстати, я только что проверил и спокойно, как через qr, так и через Хрр смог две временных поджоинить. А вот временную с постоянной, когда постоянная идет "вверху" запроса
X++:
while select ledgerTrans
    join ledgerTableTmp
        where ledgerTableTmp.AccountNum == ledgerTrans.AccountNum
    {
        info(ledgerTransTmp.AccountNum);
    }
    return;
приводит к известной многим ошибке : "Временные таблицы должны быть вложенными при объединении с постоянными таблицами."
Старый 14.01.2009, 16:58   #9  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от Gustav Посмотреть сообщение
Получается, не у всех... У меня на 3.0, SP4, двухзвенка, Oracle 10g - НЕ РАБОТАЕТ, вылезает унылое декартово произведение.
3.0 sp3 kr3 Oracle9i - работает вероятно дело именно в KR?

Цитата:
Сообщение от Lemming Посмотреть сообщение
Врочем так тоже можно, хотя это наверное многие знают.
X++:
ledgerTableTmp.data(LedgerTable::find("01.030"));
    ledgerTableTmp.insert();
    
    while select ledgerTableTmp
    join ledgerTrans
        where ledgerTrans.AccountNum == ledgerTableTmp.AccountNum
    {
        info(ledgerTrans.AccountNum);
    }
    return;
А вот так не работает, так декартово произведение..
Или что вы тут хотели сказать?
__________________
Zhirenkov Vitaly
Старый 14.01.2009, 17:01   #10  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от Lemming Посмотреть сообщение
А вот временную с постоянной, когда постоянная идет "вверху" запроса
X++:
while select ledgerTrans
    join ledgerTableTmp
        where ledgerTableTmp.AccountNum == ledgerTrans.AccountNum
    {
        info(ledgerTransTmp.AccountNum);
    }
    return;
приводит к известной многим ошибке : "Временные таблицы должны быть вложенными при объединении с постоянными таблицами."
Кстати говоря и вот это на указанной выше конфигурации никакой ошибки не выдаёт... Банальное декартово произведение.
__________________
Zhirenkov Vitaly
Старый 14.01.2009, 17:11   #11  
Lemming is offline
Lemming
Участник
Аватар для Lemming
 
1,144 / 343 (14) ++++++
Регистрация: 20.04.2004
Адрес: Москва, Чайнатаун в Люблино
Записей в блоге: 10
Цитата:
Сообщение от ZVV Посмотреть сообщение
А вот так не работает, так декартово произведение..
Или что вы тут хотели сказать?
У меня отработало аналогично джобу из оригинального поста. В общем, в любом раскладе, судя по такой неустойчивости к версиям и СУБД, лучше не забавляться с такими связками в реальных проектах.
Старый 14.01.2009, 17:24   #12  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от Lemming Посмотреть сообщение
У меня отработало аналогично джобу из оригинального поста. В общем, в любом раскладе, судя по такой неустойчивости к версиям и СУБД, лучше не забавляться с такими связками в реальных проектах.
Да, это точно!

Ещё прикол:
X++:
     i = 0;

    while select ledgerTableTmp
    join ledgerTrans
        where ledgerTrans.AccountNum == ledgerTableTmp.AccountNum
    {
        info('1:' + ledgerTrans.AccountNum);
        i++;

        if (transCnt && i == transCnt)
            break;
    }

    i = 0;

    while select ledgerTrans
    join ledgerTableTmp
        where ledgerTrans.AccountNum == ledgerTableTmp.AccountNum
    {
        info('2:' + ledgerTrans.AccountNum);
        i++;

        if (transCnt && i == transCnt)
            break;
    }

    i = 0;

    while select ledgerTableTmp
    join ledgerTrans
        where ledgerTrans.AccountNum == ledgerTableTmp.AccountNum
    {
        info('3:' + ledgerTrans.AccountNum);
        i++;

        if (transCnt && i == transCnt)
            break;
    }
1 и 3 - одинаковые.

При этом 1 посылает к СУБД запрос (гы ) следующего вида:
PHP код:
SELECT ...FROM LEDGERTRANS A WHERE ((SUBSTR(NLS_LOWER(DATAAREAID),1,3)=NLS_LOWER(:in1)/*'mil'*/) AND (SUBSTR(NLS_LOWER(ACCOUNTNUM),1,10)=SUBSTR(NLS_LOWER(ACCOUNTNUM),1,10))) 
(т.е. на самом деле не совсем декартово произведение, а вообще просто выборка из LedgerTrans, без учёта нашей временной таблицы)
2 - делает нормальное декартово произведение
3 - не выполняется вообще (ни запроса, ни инфо)! (именно после выполнения 2, т.к. 1 - выполняется)
15 мин. голову ломал... бред какой-то...
__________________
Zhirenkov Vitaly
Старый 14.01.2009, 17:34   #13  
Lemming is offline
Lemming
Участник
Аватар для Lemming
 
1,144 / 343 (14) ++++++
Регистрация: 20.04.2004
Адрес: Москва, Чайнатаун в Люблино
Записей в блоге: 10
Цитата:
Сообщение от ZVV Посмотреть сообщение
3 - не выполняется вообще (ни запроса, ни инфо)! (именно после выполнения 2, т.к. 1 - выполняется)
15 мин. голову ломал... бред какой-то...
Опа, точно! Я тоже наткнулся на подобное - вроде только что работало, а тут бамс и перестало. Переключил еще раз компанию, в которой у меня правильные для теста счета были(хотя в ней и был), отработало. Судя по всему, жутко неустойчивая фича.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
OZKA's DAX Journal: Многоколоночные отчеты средствами Dynamics AX. Blog bot DAX Blogs 0 27.08.2008 13:05
Table Scan через QueryRun maximka DAX: Программирование 8 05.10.2007 10:46
Заполнение DataSource из постоянной и временной таблиц m_ax DAX: Программирование 2 21.06.2007 13:08
Динамическая связь Query с временной таблицей rumpleteazer DAX: Программирование 1 30.01.2003 01:49
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

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