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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 02.11.2007, 15:22   #1  
kitty is offline
kitty
Участник
 
364 / 26 (1) +++
Регистрация: 24.05.2005
соединить query и временную таблицу
есть готовый query и есть временная таблица.
И идеале хотелось бы их соединить. . Поиском по форуму напшла. что соединения подобные могут плохо работать. Думала ключи таблицы сложить в одну переменную и использовать в range query(по сути врем таблица должна просто ограничивать наборб данные из нее не нужны), но где-то был пост про то, что при большой длине строки, вроде это не работает тож.
Что делать? вложенные циклы -долго будет, данных много.
Мож чо путаю?
Старый 02.11.2007, 15:33   #2  
EVGL is offline
EVGL
Banned
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
4,445 / 3001 (0) ++++++++++
Регистрация: 09.07.2002
Адрес: Parndorf, AT
Вложенный цикл в данном случае совсем не долгий, если идти от query к временной таблице. Она все равно не на SQL-сервере, и АОС всегда разбирает такое на вложенные запросы.
Старый 02.11.2007, 18:33   #3  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Проверка предельного количества Range в Query

X++:
static void Job_QueryRangeLimit(Args _args)
{
    Query       query;
    QueryRun    queryRun;

    QueryBuildDataSource    qbds;
    QueryBuildRange         qbr;

    int         nextI;
    ;

    query = new Query();
    qbds = query.addDataSource(tablenum(InventTable));

    for (nextI = 1; nextI <= 476 ; nextI++)
    {
        qbr = qbds.addRange(fieldNum(InventTable, ItemId));
        qbr.value(queryValue('1'));
    }

    queryRun = new QueryRun(query);
    queryRun.next();
}
Axapta 2.5 SP3.

476 условий - берет, а 477 - ошибка "Некоторая часть инструкции SQL имеет слишком глубокую вложенность. Перепишите запрос или разбейте его на запросы меньшего размера."

Так что, все зависит от количества ограничивающих значений. Если в пределах нескольких десятков, то можно и через Range. А вот если больше, то может быть имеет смысл сделать обратное - найти значения которые надо не исключать, а наоборот, которые допустимы.

Использование временной таблице в запросе по любому физически означает вложенный цикл. Просто, при включении таблицы в запрос этот цикл выполняется не явно.
Старый 03.11.2007, 11:31   #4  
kitty is offline
kitty
Участник
 
364 / 26 (1) +++
Регистрация: 24.05.2005
в одном месте обошлась циклами, а вот другом уже не получается, как сделать такое:
открывается форма и если при открытии отмечена галка, то должны открываться только те записи, ключи которых есть в заданном контейнере вида [[Значение1Поля1, Значение1Поля2], [Значение2Поля1, Значение2Поля2], ....]. те это пары составных ключей. Галку эту можно снимать и ставить после открытия формы, поэтому все это добро должно лежать в ExecuteQuery.
Если делать expression in query ranges и собирать значение типа ((Field11 and Field12) or (Field21 and Field22) ...), то как выше писала, можно , вроде, наткнуться на ограничение длины такого сборного range.
А если инициализировать временную таблицу, то возвращаемся к баранам join-а с ними. Как быть? Делать очищаемую постоянную таблицу, совать туда эти пары значений и потом с нею уже join-ить в ExQuery?
Старый 03.11.2007, 12:25   #5  
dns is offline
dns
Участник
 
19 / 13 (1) ++
Регистрация: 11.05.2007
Хм... А что мешает сделать join с временной таблицей? Извените, конечно, если что - то не понял? Как вариант :
queryRun.setCursor(common);
Передаём туда временную таблицу (естественно изменив перед этим Query) и... Вуаля - должно работать
Старый 06.11.2007, 11:06   #6  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Однозначного ответа нет. Тут надо пробовать разные варианты. Начать, естесственно, с временной таблицы в Query() и посмотреть насколько медленно/быстро будет работать.

Говорить "вообще" довольно затруднительно. Может, условий столько, что собственно заполнение таблицы этими условиями "съест" весь выигрыш от возможной оптимизации.

Если условий слишком много, то "может в консерватории что-то подправить?". В смысле, может с постановкой задачи что-то не то? Может, поискать другие пути решения, где условий будет не так много? Может по этим условим отфильтровать записи из какой-то другой таблицы и в Range вставать полученные значения из этой "другой" таблицы? Да мало ли...
Старый 06.11.2007, 14:38   #7  
kitty is offline
kitty
Участник
 
364 / 26 (1) +++
Регистрация: 24.05.2005
спасибо всем
правила именно в консерватории(структуру таблиц изменила), тк времени мало и возиться с врем таблицами, а потом расхлебывать совсем не хотелось
Старый 28.04.2012, 11:42   #8  
uskutus is offline
uskutus
Участник
 
28 / 10 (1) +
Регистрация: 04.04.2012
У меня такой же вопрос. Ответов я не понял.

Вот, у меня есть датасоурс, который нужно соединить с временной таблицей.
В методе executequery датасоурса

QueryBuildDataSource qbds = this.query().dataSourceTable(tablenum(Table1));
myTmpTable mytmp;
;

mytmp = this.filltmptable();

И как быть дальше? QueryBuildDataSource и xrecord разные совершенно объекты. Единственный вариант, который вижу, это сделать datasourse с временной таблицей и заполнить его заранее, но я не знаю как mytmp запихать к нему в данные.

Создать запрос для временной таблицы не получится, потому что в нее данные набиваются по определенным условиям, а альтернативы CASE WHEN ms SQL в аксапте, я так понимаю, нет.
Старый 28.04.2012, 11:46   #9  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,437 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от uskutus Посмотреть сообщение
сделать datasourse с временной таблицей и заполнить его заранее, но я не знаю как mytmp запихать к нему в данные
X++:
<>.setTmpData(mytmp)
Старый 28.04.2012, 12:00   #10  
uskutus is offline
uskutus
Участник
 
28 / 10 (1) +
Регистрация: 04.04.2012
S.Kuskov, спс
Старый 02.05.2012, 12:35   #11  
uskutus is offline
uskutus
Участник
 
28 / 10 (1) +
Регистрация: 04.04.2012
Не получается сделать join.

Делаю. В ExequteQuery датасоурса постоянной таблицы myTable.

mytmptable mytmp;
;
***
mytmptable1.setTmpData(mytmp); //mytmptable1 имя datasource с временной таблицей.

qbds = this.query().dataSourceTable(tablenum(mytmptable));
qbds = qbds.addDataSource(tablenum(myTable)); - на этой строчке компилятор ругается "QueryBuildDataSource, объект не инициализирован."

qbds.addLink(fieldnum(myTable, key), fieldnum(myTmpTable, key));
qbds.joinMode(JoinMode::InnerJoin);

Под инициализацией это имелось ввиду?

Цитата:
Сообщение от dns Посмотреть сообщение
Хм... А что мешает сделать join с временной таблицей? Извените, конечно, если что - то не понял? Как вариант :
queryRun.setCursor(common);
Передаём туда временную таблицу (естественно изменив перед этим Query) и... Вуаля - должно работать
В MSDN ни полслова не нашел, что делает эта функция.
Попробовал вставить
this.queryRun().setCursor(mytmp);

В этой строке выдается ошибка - "неправильный аргумент типа функции." Причем почему-то уже на этапе выполнения.

Последний раз редактировалось uskutus; 02.05.2012 в 12:40.
Старый 02.05.2012, 13:01   #12  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,437 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от uskutus Посмотреть сообщение
...
Делаю. В ExequteQuery датасоурса постоянной таблицы myTable.
...
mytmptable1 имя datasource с временной таблицей.
...
Сколько датасурсов у вас на форме и как они связаны? Зачем программно меняете структуру query (зачем добавляете ещё датасурс командой addDataSource)?
Старый 02.05.2012, 13:23   #13  
uskutus is offline
uskutus
Участник
 
28 / 10 (1) +
Регистрация: 04.04.2012
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Сколько датасурсов у вас на форме и как они связаны? Зачем программно меняете структуру query (зачем добавляете ещё датасурс командой addDataSource)?
Датасоурсов 6 штук. Меня интересуют только 2 - постоянная и временная таблица. Между ними связь по ключам key.

Запрос для временной таблицы такого вида:

while select mytable
{
select firstfast firstonly mytmptable
order by f1 desc, f2 desc
where mytmptable.key2 == table2.key2
&& mytmptable.key == mytable.key;
***
}

Мне для формирования нужна только 1 выделенная запись из table2, поэтому весь набор проходить вроде как ни к чему.

Программно меняю, потому что при соединении декларативно при выполнении аксапта ругается на то, что datasourse не инициализирован в местах, где совершенно не понятно, что ей не нравится.

addDataSource сделал, разбираясь в примерах, может быть и не надо было. Я подумал, что QueryBuildDataSource qbds; для формирования связи требует такого синтаксиса.

если убрать строчку qbds = qbds.addDataSource(tablenum(myTable));
Ошибка возникает на строке qbds.addLink(fieldnum(myTable, key), fieldnum(myTmpTable, key));

Да, и еще. Требуется реализовать фильтр в зависимости от состояния элемента управления, поэтому также query приходится менять программно.

Последний раз редактировалось uskutus; 02.05.2012 в 14:08.
Старый 02.05.2012, 14:08   #14  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,437 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от uskutus Посмотреть сообщение
Я подумал, что QueryBuildDataSource qbds; для формирования связи требует такого синтаксиса.
addDataSource добавляет ещё один подчинённый датасорс. Так что, если все необходимые датасурсы у вас итак заранее вынесены на форму и связанны друг с другом (прописаны свойства JoinSouce и LinkType), то необходимости в нём нет.

addLink - позволяет указать поля по которым система будет соединять связанные датасурсы.
Метод addLink нужно вызывать у подчинённого датасурса. Датасурс на этот момент должен быть инициализирован. Т.е. делать это не раньше чем отработает super() в методе init() соответствующего датасурса.
Старый 02.05.2012, 14:17   #15  
uskutus is offline
uskutus
Участник
 
28 / 10 (1) +
Регистрация: 04.04.2012
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
addDataSource добавляет ещё один подчинённый датасорс. Так что, если все необходимые датасурсы у вас итак заранее вынесены на форму и связанны друг с другом (прописаны свойства JoinSouce и LinkType), то необходимости в нём нет.

addLink - позволяет указать поля по которым система будет соединять связанные датасурсы.
Метод addLink нужно вызывать у подчинённого датасурса. Датасурс на этот момент должен быть инициализирован. Т.е. делать это не раньше чем отработает super() в методе init() соответствующего датасурса.
свойства JoinSouce и LinkType для временной таблицы не прописаны, так как выдается ошибка что датасоурс не проинициализирован. Собственно, я создаю временную таблицу в методе executequery главной таблицы, поэтому на момент Init временной, ее еще нет. Поэтому я делаю связь программно после создания временной, и опять получаю ошибку, что датасоурс не проинициализирован.

Если я правильно понял, требуется вызвать метод SetCursor, как то я неправильно его вызываю.
Старый 02.05.2012, 14:23   #16  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,437 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от uskutus Посмотреть сообщение
выдается ошибка что датасоурс не проинициализирован
в каком месте проявляется эта ошибка?

Цитата:
Сообщение от uskutus Посмотреть сообщение
Если я правильно понял, требуется вызвать метод SetCursor, как то я неправильно его вызываю.
Методы SetCursor и SetTmpData лишь меняют содержимое таблицы, но не создают её.
Связи должны работать (не выдавать ошибок) и на пустых таблицах.
Старый 02.05.2012, 14:31   #17  
uskutus is offline
uskutus
Участник
 
28 / 10 (1) +
Регистрация: 04.04.2012
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
в каком месте проявляется эта ошибка?
findOrCreateRange_W(qbds, fieldnum(myTable, key), SysQuery::valueEmptyString());

Это код в executequery, созданный уже до меня, выполняется до моего кода, с моей временной таблицей никак не связан. Похоже что x++ видит связь в свойствах, пытается ее приджойнить, а она пустая.

Если программно, то вот я писал:

qbds = qbds.addDataSource(tablenum(myTable));

если предыдущую строчку убрать, то здесь:
qbds.addLink(fieldnum(myTable, key), fieldnum(myTmpTable, key));
Старый 02.05.2012, 14:44   #18  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,437 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от uskutus Посмотреть сообщение
findOrCreateRange_W(qbds, fieldnum(myTable, key), SysQuery::valueEmptyString());
переменная qbds как инициализируется? через dataSourceNo?
При добавлении новых датасурсов нумерацию изменяется. Если дело в этом, то просто замените dataSourceNo, на dataSourceTable или dataSourceName.
За это сообщение автора поблагодарили: uskutus (1).
Старый 02.05.2012, 14:46   #19  
uskutus is offline
uskutus
Участник
 
28 / 10 (1) +
Регистрация: 04.04.2012
Тут может быть еще проблема в том, что inner join я прописывал на основной таблице, потому что если прописать на временной, будет ошибка - "временные таблицы не должны быть вложенными."

Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
переменная qbds как инициализируется? через dataSourceNo?
QueryBuildDataSource qbds = this.query().dataSourceTable(tablenum(myTable));

Последний раз редактировалось uskutus; 02.05.2012 в 14:49.
Старый 02.05.2012, 14:54   #20  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,437 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от uskutus Посмотреть сообщение
Это код в executequery, созданный уже до меня, выполняется до моего кода, с моей временной таблицей никак не связан...
Насторожило, что код этот выполняется до вашего. А в чьём executequery (т.е. в методе какого датасурса) он находится?
Теги
ax2.5

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Передать временную таблицу из формы в класс Eldar9x DAX: Программирование 26 20.06.2008 19:09
Как join'ить временную таблицу и query на форме IvanS DAX: Программирование 1 07.05.2008 09:49
Два DataSource на одну временную таблицу mou DAX: Программирование 4 22.03.2008 11:00
импорт текст.файла во временную таблицу fialka DAX: Программирование 5 07.02.2007 15:42
Как передать временную таблицу Aslan DAX: Программирование 15 23.05.2006 17:34

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

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

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