|
04.07.2006, 16:36 | #1 |
MCTS
|
Расширенный AddRange и OuterJoin
Итак, в продолжении темы Расширенный AddRange
http://www.axforum.info/forums/showt...693#post108693 Чтобы не быть голословным происследуем поведение таблиц заказов SalesTable & SalesLine. Связываем таблицы по InnerJoin и пытаемся наложить ограничение по SalesId так, как описано в статье http://www.axaptapedia.com/index.php...ultiple_tables Допустим, нас интересуют первые несколько заказов. PHP код:
Просю обратить внимание на строку q.dataSourceNo(2).addRange(fieldNum(SalesLine, DataAreaId)).value( ......... SalesTable.SalesId <= первые несколько заказов Что-за чертовщина? Налаживаем ограничение по SalesTable, а "цепляемся" к SalesLine. Дело в том, что в предыдущем посте стояла задача наложения ограничения одновременно по нескольким таблицам. Следовательно, ничто нам не мешает проделать такой вот финт. Кроме того, есть пара моментов, не обозначенных(или обозначенных, но вскользь) в вышеприведённой статье. Во-первых, в примере: queryBuildRange2.value(strFmt('((%1.%2 == %3) || ((%1.%2 == %4) && (%1.%5 == %6)))', query.dataSourceTable(tableNum(InventTable)).name(), // InventTable %1 fieldStr(InventTable, ItemType), // ItemType %2 any2int(ItemType::Service), // %3 any2int(ItemType::Item), // %4 fieldStr(InventTable, ItemId), // ItemId %5 fieldStr(InventItemBarCode, ItemId))); // %6 ограничение накладывается на второй источник данных. И неспроста. Дело в том, что если подобная конструкция будет цепляться не на последний источник данных, то Аксапта не сможет "переварить" составленный запрос, она просто "вылетит". Всё потому, что в составленном запросе налагаемое условие по некоему полю может встретится раньше, чем декларация самой таблицы. Что-то вроде select * from Table1 where table2.Field1 == bla_bla join Table2 Это первый момент. Второй момент более печальный. Свяжем таблицы по InnerJoin. Наше условие "подцепляется" ко второму источнику данных. В этом случае, всё отработается как надо. Как надо будет работать и в случае "подключения" к первому источнику данных. А вот OuterJoin (как впрочем, я подозреваю и другие виды связи отличные от InnerJoin) поведёт себя неожиданно. Итак, устанавливаем q.dataSourceNo(2).joinMode(JOINMODE::OuterJoin); и q.dataSourceNo(1).addRange(fieldNum(SalesLine, DataAreaId)).value( Всё работает как и надо, а вот q.dataSourceNo(2).joinMode(JOINMODE::OuterJoin); и q.dataSourceNo(2).addRange(fieldNum(SalesLine, DataAreaId)).value( // наш "финт" выводит чёрти что. Смотрим запрос в отладчике и видим LEFT OUTER JOIN SALESLINE B ON ((B.DATAAREAID='bmd') AND ((A.SALESID<=' 10') AND (A.SALESID=B.SALESID)))} WHERE (A.DATAAREAID='bmd') ORDER BY A.DATAAREAID,A.SALESID OPTION(FAST 4) условие SALESID<=10 расположено до WHERE А что же было в случае q.dataSourceNo(2).joinMode(JOINMODE::OuterJoin); и q.dataSourceNo(1).addRange(fieldNum(SalesLine, DataAreaId)).value( ? А вот что LEFT OUTER JOIN SALESLINE B ON ((B.DATAAREAID='bmd') AND (A.SALESID=B.SALESID))} WHERE ((A.DATAAREAID='bmd') AND (A.SALESID<=' 10')) ORDER BY A.DATAAREAID,A.SALESID OPTION(FAST 4) Какие выводы можно сделать? Вывод первый Используя механизм наложения ограничений по нескольким таблицам необходимо "цепляться" за последний источник данных Вывод второй Механизм наложения ограничений по нескольким таблицам корректно отрабатывает с InnerJoin. С другими видами связи он, увы, работает некорректно. И как это побороть на ум ничто и не приходит.
__________________
В глухомани, в лесу Несмотря на красу Дни проводит Лиса Патрикевна. Я никак не пойму Отчего, почему Не пускают куму На деревню |
|