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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 22.02.2012, 17:11   #1  
yahenz is offline
yahenz
Участник
 
12 / 10 (1) +
Регистрация: 27.12.2011
Адрес: Челябинск
? Join временной таблицы в запросе
Всем привет!

Пересмотрел несколько похожих тем, но к сожалению, из-за нехватки опыта, понимания так и не пришло.
Задача такова: На форме (не важно какой, у формы 1 источник данных) нужно организовать фильтр по полю ItemId. Т.к. область значений может быть достаточна велика, то я решил использовать временную таблицу, заполнить ее нужными значениями (ItemId) и сдлеать join к постоянной таблице, являющейся источником данных на форме.

Я пытаюсь в executeQuery() сформировать запрос и присвоить его datasource формы.

Вот примерный код:
X++:
public void executeQuery()
{
    Query                           query;
    QueryBuildDataSource            qbdsRetailPriceBuffer, qbdsTmpTable;

    TmpTable tmpTable = TmpTable::InitOnServer();
    ;

    query = new Query();
    qbdsRetailPriceBuffer = query.addDataSource(tablenum(RetailPriceBuffer));

    if(InventLocationFilter.valueStr() && CustomSectionFilter.valueStr())
    {
        tmpTable.data(GetCustomSectionFilterResult(InventLocationFilter.valueStr(), CustomSectionFilter.valueStr()));
        qbdsTmpTable = qbdsRetailPriceBuffer.addDataSource(tablenum(TmpTable));
        qbdsTmpTable.addLink(fieldnum(RetailPriceBuffer, ItemId), fieldnum(TmpTable, ItemId));
        qbdsTmpTable.joinMode(JoinMode::ExistsJoin);
        qbdsTmpTable.fetchMode(false);
    }  

    this.query(query);
    super();
}
В методе TmpTable::InitOnServer() возвращается курсор временной таблицы созданной на сервере:
X++:
public static server TmpTable InitOnServer()
{
    TmpTable tmpTable;
    select firstonly tmpTable;
    return tmpTable;
}
В методе GetCustomSectionFilterResult(), заполняется и возвращается табл. переменная временной таблицы:
X++:
public static server TmpTable GetCustomSectionFilterResult(InventLocationId _inventLocationId, CustomSectionId _customSectionId)
{
    TmpTable    tmpTable = TmpTable::InitOnServer();
    ;

    //Заполнение tmpTable...

    return tmpTable;
}
Когда выполняется super(), выдает: "Временные таблицы должны быть вложенными (inner), когда вы объединяете их оператором join с постоянными таблицами".
Что же я делаю не так?

Помогите пожалуйста, если кто сталкивался.

С уважением, Евгений.
Старый 22.02.2012, 17:31   #2  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1293 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Но мой взгляд, объединение постоянной таблицы с временной не самая удачная идея.
Я бы сделал так:
таблицу бы сделал не временной а нормальной.
  • Одно из полей использовал бы в качестве какого-либо идентификатора сессии (непосредственно номера сессии или Guid)
  • В форме бы сделал соединение основной таблицы с этой псевдовременной.
  • Вызывал заполнение этой таблицы и устанавливал бы фильтр по полю-сессии.
  • Ну и при закрытии очищал бы эту псевдовременную таблицу.
В свое время так пришлось делать в российских запросах по ГК (те, что похожи на стандартные 1С-овские типа ОСВ), так как счетов было порядка 1000 и в ранж запихнуть условия не получалось.
За это сообщение автора поблагодарили: yahenz (1).
Старый 22.02.2012, 17:38   #3  
lev is offline
lev
Ищущий знания...
Аватар для lev
Oracle
MCBMSS
Axapta Retail User
 
1,723 / 491 (20) +++++++
Регистрация: 18.01.2005
Адрес: Москва
если честно, не до конца понял что за монстро-фильтр надо организовать, который нельзя было бы наложить с помощью расширенного фильтра...

попробую предположить решение вашей проблемы...
необходимо добавить курсор временной таблицы в QueryRun вашей формы, а именно написать в методе ExecuteQuery до супера (по идее все равно где именно) следующий код:
X++:
this.queryRun().setCursor(myTmpTable);
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с)
С Уважением,
Елизаров Артем
Старый 22.02.2012, 18:04   #4  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
sumitax: Temporary Table and Join Query issue
Старый 22.02.2012, 18:10   #5  
Pustik is offline
Pustik
Участник
 
807 / 372 (14) ++++++
Регистрация: 04.06.2004
Цитата:
Сообщение от yahenz Посмотреть сообщение
Когда выполняется super(), выдает: "Временные таблицы должны быть вложенными (inner), когда вы объединяете их оператором join с постоянными таблицами".
Что же я делаю не так?

Помогите пожалуйста, если кто сталкивался.

С уважением, Евгений.
Насколько я помню, временная таблица должна всегда быть в "верху" запроса. Т.е. линкуйте постоянные таблицы к временной, а не наоборот.
__________________
-Ты в гномиков веришь?
-Нет.
-А они в тебя верят, смотри, не подведи их.

Последний раз редактировалось Pustik; 22.02.2012 в 18:13.
Старый 22.02.2012, 18:50   #6  
yahenz is offline
yahenz
Участник
 
12 / 10 (1) +
Регистрация: 27.12.2011
Адрес: Челябинск
Цитата:
Сообщение от Raven Melancholic Посмотреть сообщение
Но мой взгляд, объединение постоянной таблицы с временной не самая удачная идея.
Я бы сделал так:
таблицу бы сделал не временной а нормальной.
  • Одно из полей использовал бы в качестве какого-либо идентификатора сессии (непосредственно номера сессии или Guid)
  • В форме бы сделал соединение основной таблицы с этой псевдовременной.
  • Вызывал заполнение этой таблицы и устанавливал бы фильтр по полю-сессии.
  • Ну и при закрытии очищал бы эту псевдовременную таблицу.
В свое время так пришлось делать в российских запросах по ГК (те, что похожи на стандартные 1С-овские типа ОСВ), так как счетов было порядка 1000 и в ранж запихнуть условия не получалось.
В начале я так и делал - простую таблицу и предполагал очищать ее каждый раз при использовании, но меня отговорили от этой затеи, вроде как есть временные, ими и надо пользоваться. В любом случае спасибо, буду иметь ввиду как вариант.

Цитата:
Сообщение от lev Посмотреть сообщение
если честно, не до конца понял что за монстро-фильтр надо организовать, который нельзя было бы наложить с помощью расширенного фильтра...

попробую предположить решение вашей проблемы...
необходимо добавить курсор временной таблицы в QueryRun вашей формы, а именно написать в методе ExecuteQuery до супера (по идее все равно где именно) следующий код:
X++:
this.queryRun().setCursor(myTmpTable);
Ммм, фильтр сам по себе простой - отобразить на форме только те номенклатуры, которые подходят под условие. Но простым addRange(...).value(...), как я понимаю решить не получится, т.к. длинна критерия в value(...) ограничена 250 символами. А у меня список номенклатур отбора может быть очень большим. Поэтому и хочу просто "схлопнуть" datasource формы связав его по номенклатурам во временной таблице.

Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Благодарю, буду разбираться.

Цитата:
Сообщение от Pustik Посмотреть сообщение
Насколько я помню, временная таблица должна всегда быть в "верху" запроса. Т.е. линкуйте постоянные таблицы к временной, а не наоборот.
Как окажусь на работе, попробую, спс.
Старый 22.02.2012, 19:04   #7  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
не надо джоинить постоянные и временные таблицы.
Цитата:
длинна критерия в value(...) ограничена 250 символами
сделайте еще один addRange по тому же полю и еще один.. и еще.. и т.д.
За это сообщение автора поблагодарили: Pustik (7), yahenz (1).
Старый 22.02.2012, 21:51   #8  
yahenz is offline
yahenz
Участник
 
12 / 10 (1) +
Регистрация: 27.12.2011
Адрес: Челябинск
Цитата:
Сообщение от Wamr Посмотреть сообщение
не надо джоинить постоянные и временные таблицы.

сделайте еще один addRange по тому же полю и еще один.. и еще.. и т.д.
Я правильно понял, если у меня будет 5000 номенклатур, то это 5000 addRange'й? Или необходимо создавать следующий рендж, только когда в первом "закончилось место"?
Старый 22.02.2012, 22:45   #9  
db is offline
db
Роман Долгополов (RDOL)
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
 
393 / 692 (24) +++++++
Регистрация: 01.04.2004
Адрес: Москва
ну думаю не будет большим свинством процитировать себя Выборка произвольных записей одним запросом
За это сообщение автора поблагодарили: fed (3), lev (3), yahenz (1).
Старый 24.04.2012, 11:59   #10  
klimova_m is offline
klimova_m
Участник
 
43 / 18 (1) ++
Регистрация: 17.11.2008
Адрес: С.Петербург
Проверено: если Range становится очень много (в моем случае их 833 набралось), то Ax ругается так "Трассировка стека: При выполнении операции привязки не удалось распределить пространство буфера."
__________________
Ты лучше голодай, чем что попало есть,
И лучше будь один, чем вместе с кем попало.
Старый 24.04.2012, 14:10   #11  
kornix is offline
kornix
MCP
MCBMSS
Злыдни
Ex AND Project
 
414 / 146 (5) +++++
Регистрация: 24.02.2009
Адрес: Санкт-Петербург
Цитата:
Сообщение от klimova_m Посмотреть сообщение
Проверено: если Range становится очень много (в моем случае их 833 набралось), то Ax ругается так "Трассировка стека: При выполнении операции привязки не удалось распределить пространство буфера."
Range ограничен 250 символами. Возможно, имеет смысл попробовать накладывать ограничения как-то по-другому. Довольно странно выглядит запрос к таблице, в котором в условии WHERE безумное количество ограничений.

длина Range
Старый 24.04.2012, 14:33   #12  
oip is offline
oip
Axapta
Лучший по профессии 2014
 
2,564 / 1416 (53) ++++++++
Регистрация: 28.11.2005
Записей в блоге: 1
Цитата:
Сообщение от kornix Посмотреть сообщение
Range ограничен 250 символами.
Нет у range в X++ ограничения в 250 символов. Ограничение в 250 символов есть только у EDT Range, который стандартно используется на формах для указания критериев запросов. Но и его длину можно увеличить.

А вот больше скольких-то сотен условий по ИЛИ добавить не получится, есть ограничение на уровень вложенности WHERE.

Аксапта для ИЛИ построит что-то типа такого и в некоторый момент загнется:
X++:
((((((((((((((((((((((((((((((((((((((((((((((((ITEMID=?) OR (ITEMID=?)) OR (ITEMID=?)) OR (ITEMID=?)) OR (ITEMID=?))...

Последний раз редактировалось oip; 24.04.2012 в 15:07. Причина: добавил про вложенность
За это сообщение автора поблагодарили: klimova_m (1), kornix (1).
Старый 24.04.2012, 14:59   #13  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,907 / 5717 (196) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Цитата:
Сообщение от oip Посмотреть сообщение
Нет у range в X++ ограничения в 250 символов. Ограничение в 250 символов есть только у EDT Range, который стандартно используется на формах для указания критериев запросов. Но и его длину можно увеличить.

А вот больше скольких-то сотен условий по ИЛИ добавить не получится, есть ограничение на уровень вложенности WHERE.
Я бы еще добавил, что при большом количестве условий по OR в where, увеличивается вероятность того, что сиквельный оптимизатор переглючит и он уйдет в full scan (Точнее конечно же - в поиск по индексу, но только по условию dataareaId==key).
Я, поэтому, всегда пользуюсь техникой, которую участник db описал. Хотя я ее предпочитаю даже не столько с точки зрения производительности, сколько с точки зрения наглядности...
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
JOIN подчиненной таблицы в отчете Ислан DAX: Программирование 14 24.10.2011 17:42
Display метод временной таблицы выполняется в компании DAT S.Kuskov DAX: Программирование 4 15.04.2011 20:11
Можно ли вообще сделать JOIN временной таблицы и InventDim??? Maxim Gorbunov DAX: Программирование 9 05.03.2005 10:39
SQL-запрос с участием временной таблицы Atani DAX: Программирование 1 07.10.2003 19:55
Временные таблицы в запросе Dron AKA andy DAX: Программирование 4 06.09.2002 12:14

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

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

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