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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 19.02.2009, 09:31   #1  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,340 / 3558 (125) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от ZVV Посмотреть сообщение
Это вы меня "Логгером" назвали?
Извините, совсем плохим стал. Прошу великодушнейшего прощения.

Нашел тот запрос, в котором споткнулся в свое время с fetchMode. DAX 4.0 SP2 EE. Исходный запрос упростил для отображения работы именно fetchMode. Нюанс, с которым столкнулся вчера: сие не отрабатывает, если датасорса 2. Т.е. важно, чтобы датасорсов было больше двух.

Итак:
X++:
static void vsuh_testFetchMode(Args _args)
{
    CustTrans            custTrans;
    CustTable            custTable;
    Currency             currency;
    
    Query                query;
    QueryBuildDataSource qbds1, qbds2, qbds3;
    QueryRun             qr;
    
    Counter              cnt;
    ;
    query = new Query();
    qbds1 = query.addDataSource(tablenum(CustTrans));
    qbds2 = qbds1.addDataSource(tablenum(CustTable));
//    qbds2.fetchMode(QueryFetchMode::One2One);
    qbds2.relations(true);
    qbds3 = qbds1.addDataSource(tablenum(Currency));
//    qbds3.fetchMode(QueryFetchMode::One2One);
    qbds3.relations(true);
    
    qr = new QueryRun(query);
    while (qr.next() && cnt < 10)
    {
        custTrans = qr.getNo(1);
        custTable = qr.getNo(2);
        currency  = qr.getNo(3);
        
        info(strfmt("%1-%2-%3!", custTrans.Voucher, custTable.AccountNum, currency.CurrencyCode));
        cnt++;
    }
}
В этом режиме (по умолчанию, как я уже писал выше) fetchMode = QueryFetchMode::One2Many

В таблице CustTrans ваучеры уникальные - т.е. в двух записях всегда присутствуют разные ваучеры.
Итак, вариант 1 - как в джобе (fetchMode у всех QueryFetchMode::One2Many).
Название: fetchmodeOne2Many.JPG
Просмотров: 1586

Размер: 24.2 Кб
вариант 2 - включаем fetchMode One2One у датасорса №2
Название: fetchmodeOne2OneMany1.JPG
Просмотров: 1569

Размер: 24.5 Кб
вариант 3 - включаем fetchMode One2One у датасорса №3 и fetchMode One2Many у датасорса №2
Название: fetchmodeOne2OneMany2.JPG
Просмотров: 1595

Размер: 27.5 Кб
вариант 4 - включаем fetchMode One2One у датасорсов №2 и №3
Название: fetchmodeOne2One.JPG
Просмотров: 1548

Размер: 28.8 Кб
на датасорс №1 значение свойства fetchMode влияния не оказывает.

Из примера - видно - что строки выбираются всегда - а "шапки" (в моем примере они подчинены строкам) - в зависимости от параметра fetchMode
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 19.02.2009 в 10:12.
За это сообщение автора поблагодарили: ZVV (3).
Старый 19.02.2009, 11:52   #2  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
Итак:
Да, спасибо за пример, он подтвердил высказанные мною выше подозрения:
(в вашем джобе добавил
X++:
 info (qbds1.toString());
    info (qbds2.toString());
    info (qbds3.toString());
) для наглядности. Результаты:


оба One2Many:
X++:
SELECT * FROM CustTrans
SELECT * FROM CustTable WHERE CustTrans.AccountNum = CustTable.AccountNum
SELECT * FROM Currency WHERE CustTrans.CurrencyCode = Currency.CurrencyCode
 SQL: (CustTrans) SELECT ... FROM CUSTTRANS A WHERE (SUBSTR(NLS_LOWER(DATAAREAID),1,7)=NLS_LOWER(:in1)) 
ORDER BY SUBSTR(NLS_LOWER(A.DATAAREAID),1,7),SUBSTR(NLS_LOWER(A.INVOICE),1,41),SUBSTR(NLS_LOWER(A.ACCOUNTNUM),1,41)

000003_181 -  -  !
000003_181 - 000001_045 -  !
000003_181 -  - BYR !

CustTable One2One, Currency One2Many:
X++:
SELECT * FROM CustTrans JOIN * FROM CustTable WHERE CustTrans.AccountNum = CustTable.AccountNum
SELECT * FROM CustTable WHERE CustTrans.AccountNum = CustTable.AccountNum
SELECT * FROM Currency WHERE CustTrans.CurrencyCode = Currency.CurrencyCode
 SQL: (CustTrans,CustTable) SELECT ... FROM CUSTTRANS A,CUSTTABLE B 
WHERE (SUBSTR(NLS_LOWER(A.DATAAREAID),1,7)=NLS_LOWER(:in1)) AND ((SUBSTR(NLS_LOWER(B.DATAAREAID),1,7)=NLS_LOWER(:in2)) AND (SUBSTR(NLS_LOWER(A.ACCOUNTNUM),1,41)=SUBSTR(NLS_LOWER(B.ACCOUNTNUM),1,41))) 
ORDER BY SUBSTR(NLS_LOWER(A.DATAAREAID),1,7),SUBSTR(NLS_LOWER(A.ACCOUNTNUM),1,41),A.TRANSDATE,SUBSTR(NLS_LOWER(A.VOUCHER),1,41) 

000003_181 - 000001_045 -  !
000003_181 - 000001_045 - BYR !

CustTable One2Many, Currency One2One:
X++:
SELECT * FROM CustTrans JOIN * FROM Currency WHERE CustTrans.CurrencyCode = Currency.CurrencyCode
SELECT * FROM CustTable WHERE CustTrans.AccountNum = CustTable.AccountNum
SELECT * FROM Currency WHERE CustTrans.CurrencyCode = Currency.CurrencyCode
 SQL: (CustTrans,Currency) SELECT ... FROM CUSTTRANS A,CURRENCY B 
WHERE (SUBSTR(NLS_LOWER(A.DATAAREAID),1,7)=NLS_LOWER(:in1)) AND ((SUBSTR(NLS_LOWER(B.DATAAREAID),1,7)=NLS_LOWER(:in2)) AND (SUBSTR(NLS_LOWER(A.CURRENCYCODE),1,7)=SUBSTR(NLS_LOWER(B.CURRENCYCODE),1,7))) 
ORDER BY SUBSTR(NLS_LOWER(A.DATAAREAID),1,7),SUBSTR(NLS_LOWER(A.INVOICE),1,41),SUBSTR(NLS_LOWER(A.ACCOUNTNUM),1,41)0

00003_181 -  - BYR !
000003_181 - 000001_045 - BYR !

оба One2One:
X++:
SELECT * FROM CustTrans JOIN * FROM CustTable WHERE CustTrans.AccountNum = CustTable.AccountNum JOIN * FROM Currency WHERE CustTrans.CurrencyCode = Currency.CurrencyCode
SELECT * FROM CustTable WHERE CustTrans.AccountNum = CustTable.AccountNum
SELECT * FROM Currency WHERE CustTrans.CurrencyCode = Currency.CurrencyCode
 SQL: (CustTrans,CustTable,Currency) SELECT ... FROM CUSTTRANS A,CUSTTABLE B,CURRENCY C 
WHERE (SUBSTR(NLS_LOWER(A.DATAAREAID),1,7)=NLS_LOWER(:in1)) AND ((SUBSTR(NLS_LOWER(B.DATAAREAID),1,7)=NLS_LOWER(:in2)) AND (SUBSTR(NLS_LOWER(A.ACCOUNTNUM),1,41)=SUBSTR(NLS_LOWER(B.ACCOUNTNUM),1,41))) 
AND ((SUBSTR(NLS_LOWER(C.DATAAREAID),1,7)=NLS_LOWER(:in3)) AND (SUBSTR(NLS_LOWER(A.CURRENCYCODE),1,7)=SUBSTR(NLS_LOWER(C.CURRENCYCODE),1,7))) 
ORDER BY SUBSTR(NLS_LOWER(A.DATAAREAID),1,7),SUBSTR(NLS_LOWER(A.ACCOUNTNUM),1,41),A.TRANSDATE,SUBSTR(NLS_LOWER(A.VOUCHER),1,41) 

000003_181 - 000001_045 - BYR !
Как видите, запросы к БД отсылаются в этих случаях по разному, как я говорил, вероятно Аксапта "оптимизирует" таким образом сложный запрос.
Насколько я понял, данный эффект происходит только в том случае, когда идёт непоследовательное соединение датасорсов! Только в этом случае Аксапта начинает "оптимизировать" (как в примере, естественно датасорсов при этом всегда больше двух, как вы верно подметили ) и тогда нужно либо указывать fetchMode=One2One, чтоб запрос к БД был один и тогда можно пользоваться стандартным циклом по квериРун, как обычно. Либо добавлять сложные конструкции с проверкой смены "папы" последством record.Changed(). Если же порядок соединения последовательный, то fetchMode никакого влияния не оказывает, можете сами проверить поменяв местами CustTable & CustTrans и прицепив, соответсвенно, Currency ко второму DS.

Вот! Так что будьте осторожны и учитывайте данную особенность!

ЗЫ Ещё из интересных особенностей данного поведения: Аксаптовский SQL-Trace не ловит подчинённые запросы к БД при такой оптимизации. Их можно увидеть только в трэйсе на уровне БД...
__________________
Zhirenkov Vitaly
За это сообщение автора поблагодарили: sukhanchik (7).
Теги
query, queryrun, выборка, запрос (query)

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Dynamics AX: QueryRun and Query Objects - Binding operation failed to allocate buffer space Blog bot DAX Blogs 0 03.04.2009 08:05
palleagermark: Sample union query from AX 2009 Blog bot DAX Blogs 0 11.07.2008 20:05
Dynamics AX Geek: Using query() Blog bot DAX Blogs 0 28.10.2006 16:40
Установка условия ИЛИ (OR) в Query Zeratul DAX: Программирование 3 22.06.2006 14:28
Древовидная структура источников данных в Query rumpleteazer DAX: Программирование 7 03.02.2003 15:52
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

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