|
12.09.2011, 11:45 | #1 |
Участник
|
Цитата:
В принципе, общая идея, заключающаяся в том, что нужно наложить еще один Range по этому полю - правильная. Проблема только в том, что этот Range должен подкючаться по "И", а если уже есть Range по этому же полю, скажем, настроенный пользователем, то подключение произойдет по "ИЛИ" Именно для данного конкретного случая можно сделать "хитрый трюк". Дело в том, что определение того факта, что Range добавляется по уже существующему полю выполняется по Id поля. При этом, как правило, используется FieldId. Однако Axapta может идентифицировать поле как по FieldId, так и по ExtendedFieldId. Т.е. идентифицировать поле, как первый элемент массива. Естесственно, что FieldId и ExtendedFieldId - это разные значения. Как следствие, построитель запросов интепретирует их как разные Range и выполняет объединение по "И". Получается, примерно следующее X++: static void Job_Test(QueryRun queryRun) { Query queryFind; QueryRun queryRunFind; QueryBuildDataSource qbds; QueryBuildRange qbr; ; queryFind = new Query(queryRun.query().pack()); qbds = queryFind.dataSourceTable(tablenum(CustTable)); // Вот этот трюк qbr = qbds.findRange(fieldnum(CustTable, accountNum)); if (qbr) { // Если Range уже есть, то создаю новый Range по ExdendendFieldId qbr = qbds.addRange(fieldId2ext(fieldnum(CustTable, accountNum),1)); } qbr.value('КлиентАБВ'); queryRunFind = new QueryRun(queryFind); if (queryRunFind.next()) { info("Есть такая запись"); } } Естесственно, этот трюк работает только для полей, которые массивами не являются. Для полей-массивов можно сделать подобное только для первого элемента массива. |
|
|
За это сообщение автора поблагодарили: coolibin (1), S.Kuskov (1), propeller (1). |
12.09.2011, 12:41 | #2 |
Участник
|
Цитата:
Если выбирать из предложенных вариантов, то мне больше нравится мой про использование http://www.axaptapedia.com/Expressions_in_query_ranges P.S.: propeller, вот уж действительно "простейшая задача" Последний раз редактировалось S.Kuskov; 12.09.2011 в 13:32. |
|
13.09.2011, 11:21 | #3 |
Участник
|
Цитата:
Цитата:
Сообщение от Владимир Максимов
К сожалению, это ничего не гарантирует. Если исходный запрос относительно сложен и имеет несколько таблиц-источников с "не линейной" схемой объединения, то подключение еще одного источника по Exists Join может привести к тому, что запросу "снесет крышу". Результат может оказаться парадоксальным.
X++: boolean findSuperCust(Query _srcQuery, CustAccount _custAccount = "КлиентАБВ") { Query q; QueryRun qr; QueryBuildDataSource qbds,qbds2; ; q = new Query(_srcQuery); qbds = q.dataSourceTable(tablenum(custTable)); qbds2 = qbds.addDataSource(tablenum(custTable)); qbds2.fields().addField(fieldNum(custTable, AccountNum)); qbds2.fetchMode(JoinMode::INNERJOIN); qbds2.relations(true); qbds2.addRange(fieldNum(custTable, AccountNum)).value(_custAccount); qr = new QueryRun(q); return qr.next(); } |
|
|
За это сообщение автора поблагодарили: S.Kuskov (1). |
13.09.2011, 11:38 | #4 |
Участник
|
Вы, наверное, с JoinMode() перепутали?
Но FetchMode() тоже надо будет настраивать, если есть другие датасорсы, подключенные к CustTable. А основная проблема с этим запросом - не может Аксапта обрабатывать большое количество вложенных подзапросов. Особенно, если они находятся на одном уровне вложенности
__________________
Axapta v.3.0 sp5 kr2 |
|
|
За это сообщение автора поблагодарили: dn (1), Aquarius (1). |
13.09.2011, 11:55 | #5 |
Участник
|
Цитата:
qbds2.joinMode(JoinMode::innerJoin); qbds2.fetchMode(QueryFetchMode::One2One); Возможно. Но на практике, когда не проходил ExistJoin, вариант с InnerJoin проходил. Хотя согласен, что в общем случае это видимо не всегда будет работать. |
|
13.09.2011, 12:37 | #6 |
Участник
|
Цитата:
только в случае нескольких вложенных таблиц Аксапта возвращает записи ПОСЛЕДОВАТЕЛЬНО. я уже ссылку давал Цитата:
Сообщение от mazzy
вариант S.Kuskov: приджойнить exist join тоже не подойдет. поскольку в запросе уже может быть join. http://msdn.microsoft.com/en-us/libr...36(AX.10).aspx
|
|
13.09.2011, 13:07 | #7 |
Участник
|
|
|
13.09.2011, 13:36 | #8 |
Участник
|
хорошо соотносится.
проверьте. |
|
13.09.2011, 14:14 | #9 |
Участник
|
Цитата:
Цитата:
Проблема с "exists join" связана с тем, что если такой exists будет вставлен между двумя таблицами уже соеденёнными при помощи "inner join", то результирующий запрос получится не всегда ожиданным. Например, такой гипотетический код: Код: select Table1 exists join Table3 where Table3.id == Table1.id inner join Table2 where Table2.id == Table1.id Код: table1 where exists (select Table3 join table2) |
|
|
За это сообщение автора поблагодарили: dn (1). |
13.09.2011, 16:27 | #10 |
Участник
|
Такое поведение как раз задается fetchmode 1:n
Последний раз редактировалось dn; 13.09.2011 в 16:32. |
|
13.09.2011, 11:45 | #11 |
Участник
|
Ну это легко проверить простым дополнительным запросом.
Цитата:
X++: void init() { super(); selectRangeRecords = this.query().dataSourceNo(1).addRange(fieldnum(TmpSysQuery, RangeStatus)); selectRangeRecords.value('!' + enum2str(RangeStatus::Hidden)); selectRangeRecords.status(RangeStatus::Locked); // <<-- } О! Здравая идея. А для оптимизации тогда ещё можно задать addSelectionField со значением SelectionField:atabase по какому-нибудь полю индекса |
|
Теги |
query, как правильно |
|
Похожие темы | ||||
Тема | Ответов | |||
Очередной вопрос про Query | 45 | |||
Вопрос по query? | 1 | |||
Вопрос по query и join | 2 | |||
Вопрос по запросу (query) | 2 | |||
Вопрос знатокам QBE и Query в AXAPTA | 6 |
|