02.11.2007, 15:22 | #1 |
Участник
|
соединить query и временную таблицу
есть готовый query и есть временная таблица.
И идеале хотелось бы их соединить. . Поиском по форуму напшла. что соединения подобные могут плохо работать. Думала ключи таблицы сложить в одну переменную и использовать в range query(по сути врем таблица должна просто ограничивать наборб данные из нее не нужны), но где-то был пост про то, что при большой длине строки, вроде это не работает тож. Что делать? вложенные циклы -долго будет, данных много. Мож чо путаю? |
|
02.11.2007, 15:33 | #2 |
Banned
|
Вложенный цикл в данном случае совсем не долгий, если идти от query к временной таблице. Она все равно не на SQL-сервере, и АОС всегда разбирает такое на вложенные запросы.
|
|
02.11.2007, 18:33 | #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(); } 476 условий - берет, а 477 - ошибка "Некоторая часть инструкции SQL имеет слишком глубокую вложенность. Перепишите запрос или разбейте его на запросы меньшего размера." Так что, все зависит от количества ограничивающих значений. Если в пределах нескольких десятков, то можно и через Range. А вот если больше, то может быть имеет смысл сделать обратное - найти значения которые надо не исключать, а наоборот, которые допустимы. Использование временной таблице в запросе по любому физически означает вложенный цикл. Просто, при включении таблицы в запрос этот цикл выполняется не явно. |
|
03.11.2007, 11:31 | #4 |
Участник
|
в одном месте обошлась циклами, а вот другом уже не получается, как сделать такое:
открывается форма и если при открытии отмечена галка, то должны открываться только те записи, ключи которых есть в заданном контейнере вида [[Значение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 |
Участник
|
Хм... А что мешает сделать join с временной таблицей? Извените, конечно, если что - то не понял? Как вариант :
queryRun.setCursor(common); Передаём туда временную таблицу (естественно изменив перед этим Query) и... Вуаля - должно работать |
|
06.11.2007, 11:06 | #6 |
Участник
|
Однозначного ответа нет. Тут надо пробовать разные варианты. Начать, естесственно, с временной таблицы в Query() и посмотреть насколько медленно/быстро будет работать.
Говорить "вообще" довольно затруднительно. Может, условий столько, что собственно заполнение таблицы этими условиями "съест" весь выигрыш от возможной оптимизации. Если условий слишком много, то "может в консерватории что-то подправить?". В смысле, может с постановкой задачи что-то не то? Может, поискать другие пути решения, где условий будет не так много? Может по этим условим отфильтровать записи из какой-то другой таблицы и в Range вставать полученные значения из этой "другой" таблицы? Да мало ли... |
|
06.11.2007, 14:38 | #7 |
Участник
|
спасибо всем
правила именно в консерватории(структуру таблиц изменила), тк времени мало и возиться с врем таблицами, а потом расхлебывать совсем не хотелось |
|
28.04.2012, 11:42 | #8 |
Участник
|
У меня такой же вопрос. Ответов я не понял.
Вот, у меня есть датасоурс, который нужно соединить с временной таблицей. В методе 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 |
Участник
|
|
|
28.04.2012, 12:00 | #10 |
Участник
|
S.Kuskov, спс
|
|
02.05.2012, 12:35 | #11 |
Участник
|
Не получается сделать 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); Под инициализацией это имелось ввиду? Цитата:
Попробовал вставить this.queryRun().setCursor(mytmp); В этой строке выдается ошибка - "неправильный аргумент типа функции." Причем почему-то уже на этапе выполнения. Последний раз редактировалось uskutus; 02.05.2012 в 12:40. |
|
02.05.2012, 13:01 | #12 |
Участник
|
Сколько датасурсов у вас на форме и как они связаны? Зачем программно меняете структуру query (зачем добавляете ещё датасурс командой addDataSource)?
|
|
02.05.2012, 13:23 | #13 |
Участник
|
Цитата:
Запрос для временной таблицы такого вида: 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 |
Участник
|
Цитата:
addLink - позволяет указать поля по которым система будет соединять связанные датасурсы. Метод addLink нужно вызывать у подчинённого датасурса. Датасурс на этот момент должен быть инициализирован. Т.е. делать это не раньше чем отработает super() в методе init() соответствующего датасурса. |
|
02.05.2012, 14:17 | #15 |
Участник
|
Цитата:
Сообщение от S.Kuskov
addDataSource добавляет ещё один подчинённый датасорс. Так что, если все необходимые датасурсы у вас итак заранее вынесены на форму и связанны друг с другом (прописаны свойства JoinSouce и LinkType), то необходимости в нём нет.
addLink - позволяет указать поля по которым система будет соединять связанные датасурсы. Метод addLink нужно вызывать у подчинённого датасурса. Датасурс на этот момент должен быть инициализирован. Т.е. делать это не раньше чем отработает super() в методе init() соответствующего датасурса. Если я правильно понял, требуется вызвать метод SetCursor, как то я неправильно его вызываю. |
|
02.05.2012, 14:23 | #16 |
Участник
|
в каком месте проявляется эта ошибка?
Цитата:
Связи должны работать (не выдавать ошибок) и на пустых таблицах. |
|
02.05.2012, 14:31 | #17 |
Участник
|
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 |
Участник
|
Цитата:
При добавлении новых датасурсов нумерацию изменяется. Если дело в этом, то просто замените dataSourceNo, на dataSourceTable или dataSourceName. |
|
|
За это сообщение автора поблагодарили: uskutus (1). |
02.05.2012, 14:46 | #19 |
Участник
|
Тут может быть еще проблема в том, что inner join я прописывал на основной таблице, потому что если прописать на временной, будет ошибка - "временные таблицы не должны быть вложенными."
QueryBuildDataSource qbds = this.query().dataSourceTable(tablenum(myTable)); Последний раз редактировалось uskutus; 02.05.2012 в 14:49. |
|
02.05.2012, 14:54 | #20 |
Участник
|
|
|
Теги |
ax2.5 |
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|