15.12.2008, 20:49 | #1 |
Участник
|
Запрос по таблице параметров.
Всем привет!
Помогите с запросиком плиз. Имеем две таблицы: Table1 поля: num, type Table2 поля: num, param, value Связь по num, в Table2 может быть набор записей привязаных к одной записи в Table1. Необходим запрос, в котором можно бы было задать тип(типы) и параметр(параметры) с соответствующим значением для поиска, причем значение параметра можно было бы задавать в виде "*ала*", ну т.е. что-то типа: Код: while select table1 table1.where type=="стол" join table2 where table2.num==table1.num && ( (table2.param=="цвет" && table2.value=="красный") || (table2.param=="ножек" && table2.value=="2..4") || (table2.param=="название" && table2.value like "тол")) Спасибо! |
|
15.12.2008, 21:46 | #2 |
Участник
|
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. |
|
16.12.2008, 07:16 | #3 |
Участник
|
Да так и делаю и все вроде работает, но видимо:
"Using wildcards and comma-separated range values Again, the previous example here was using standard syntax, not the special syntax using expressions. It's not possible to modify the above examples to work with wildcards. The above statement applies to AX versions < 5.0 AX 5.0 introduced solution to wildcards - while you still cannot directly use wildcards in ranges, now it supports the 'LIKE' keyword. (AccountNum LIKE "*AA*" || Name LIKE "*AA*")" Забыл указать Ах3.0 Мой сумбур на данный момент выглядит так: Код: ... QueryBuildDataSource qbdsTable1; QueryBuildDataSource qbdsTable2; QueryBuildRange qbrTable1; QueryBuildRange qbrTable2; FreeTxt qValueTable1; FreeTxt qValueTable2; ; qbdsTable1 = this.query().dataSourceTable(tablenum(Table1)); qbdsTable2 = this.query().dataSourceTable(tablenum(Table2)); qbdsTable2.addLink(fieldnum(Table2, num), fieldnum(Table1, num)); qbdsTable2.joinMode(JoinMode::ExistsJoin); qbrTable1 = qbdsTable1.addRange(fieldnum(Table1, RecId)); qbrTable2 = qbdsTable2.addRange(fieldnum(Table2, RecId)); while select Table3 { if(qValueTable1) qValueable1 += '||'; qValueTable1 += strFmt('(%1.Type=="%2")', qbdsTable1.name(), Table3.Type); } while select Table4 { if(qValueTable2) qValueTable2 += '||'; qValueTable2 += strFmt('(%1.Param=="%2")&&(%1.Value=="%3")', qbdsTable2.name(), Table4.Param, Table4.Values); } qbrTable2.value(qValueTable2); qbrTable1.value(qValueTable1); ... Последний раз редактировалось uchenik; 16.12.2008 в 07:29. |
|
16.12.2008, 13:30 | #4 |
MCITP
|
Не понял, так что не работает то? Что у вас самое главное, которого не можете добиться? like?
С ним нормально можно работать и в тройке (пример на 3.0 SP3): X++: static void ZVVTestJobQuery(Args _args) { QueryBuildDataSource qbdsIJT; QueryBuildRange qbrIJT; Query query = New Query(); QueryRun queryRun; FreeText rangeValue; inventJournalTable inventJournalTable; ; qbdsIJT = query.addDataSource(tablenum(inventJournalTable)); qbdsIJT.addSelectionField(FieldNum(inventJournalTable, JournalNameId)); qbdsIJT.orderMode(OrderMode::GroupBy); qbdsIJT.addSortField(FieldNum(inventJournalTable, JournalNameId)); qbrIJT = qbdsIJT.addRange(fieldnum(inventJournalTable, RecId)); rangeValue = strFmt('(%1.%2 like "%3")&&(%1.%4==%5)' ,qbdsIJT.name() ,FieldStr(inventJournalTable, JournalNameId) ,strFmt("%1%2", "Перенос", '*') ,FieldStr(inventJournalTable, JournalType) ,any2int(InventJournalType::Transfer)); qbrIJT.value(rangeValue); info(qbdsIJT.toString()); queryRun = New QueryRun(query); while (queryRun.next()) { inventJournalTable = queryRun.get(tablenum(inventJournalTable)); info(inventJournalTable.JournalNameId); } } PHP код:
__________________
Zhirenkov Vitaly |
|
16.12.2008, 15:20 | #5 |
Участник
|
Есть две описанные ДВЕ таблицы, собственно для примера в них есть такие данные:
таблица1 num type 1 пользователь 2 пользователь 3 системный блок таблица2 num param value 1 Фамилия Иванов 2 Фамилия Иванова |
|
16.12.2008, 18:20 | #6 |
MCITP
|
Мне без разницы сколько у вас таблиц... я не вижу тут никакой проблемы.
Вы ответьтьте на поставленный вопрос, тогда может будет о чём-то поговорить... А то пишете какой-то сумбур Цитата:
Да так и делаю и все вроде работает...
Цитата:
Самого главного добиться не знаю как.
__________________
Zhirenkov Vitaly |
|
16.12.2008, 20:19 | #7 |
Участник
|
На SP2 не работает "Ошибка расширенного диапазона запроса: Ожидается правая круглая скобка рядом с 42", возможно и мое поэтому же не работает.
Пришлось "раздувать" запрос, предварительно перелопачивая возможные варианты путем select с like. Последний раз редактировалось uchenik; 16.12.2008 в 21:10. |
|
16.12.2008, 21:17 | #8 |
Программатор
|
Поиск по форуму Вам в руки. Про ожидаемую скопку рядом с 42, 43, 4**** уже обсуждалось. С синтаксисом у Вас проблемы.
|
|
16.12.2008, 21:35 | #9 |
Участник
|
Sada, т.е. у ZVV все ок, а у меня нет? (copy/past применял)
Смена like на == все меняет и скобка уже не нужна. Ну не работает like в нужном разрезе Последний раз редактировалось uchenik; 16.12.2008 в 21:53. |
|
17.12.2008, 10:11 | #10 |
MCITP
|
Цитата:
Проверил на KR2 & KR3 - работает. У вас вероятно KR1 или вообще нет?
__________________
Zhirenkov Vitaly |
|
04.03.2009, 15:52 | #11 |
Участник
|
На 4.0 SP2 в похожей ситуации такая же ошибка! Кто-нибудь нашёл выход?
|
|
16.03.2009, 16:26 | #12 |
Участник
|
Аналогичная проблема. Написан простенький джоб, но с == работает, а с LIKE не работает.
Может кто-нибудь решил проблему? X++: static void my_Job35(Args _args) { Query q; QueryBuildDataSource qbds; QueryBuildRange qbr; str s; QueryRun qr; InventDim inventDim; ; q = new Query(); qbds = q.addDataSource(TableNum(InventDim)); qbr = qbds.addRange(fieldNum(InventDim, DataAreaId)); s = strFmt('(InventLocationId LIKE "%1")', 'Новый'); qbr.value(s); info(q.dataSourceNo(1).toString()); qr = new QueryRun(q); while (qr.next()) { inventDim = qr.getNo(1); info(inventDim.inventLocationId); break; } } |
|
16.03.2009, 17:07 | #13 |
Участник
|
Была проблема с like. Решил её так:
X++: QueryBuildDataSource qbdsIJT; QueryBuildRange qbrIJT; Query query = New Query(); QueryRun queryRun; FreeText rangeValue; Dimensions dimensions; ; qbdsIJT = query.addDataSource(TableNum(Dimensions)); qbdsIJT.addSelectionField(FieldNum(Dimensions, Description)); qbdsIJT.addSortField(FieldNum(Dimensions, Description)); qbrIJT = qbdsIJT.addRange(FieldNum(Dimensions, Description)); [B]rangeValue = strFmt("*АХО*, *Складская логистика (РЦ)*");[/B] qbrIJT.value(rangeValue); info(qbdsIJT.toString()); queryRun = New QueryRun(query); while (queryRun.next()) { dimensions = queryRun.get(tablenum(Dimensions)); info(dimensions.Description); } |
|
16.03.2009, 17:07 | #14 |
Участник
|
Extended Range не поддерживает wildcards и соответствующие keywords
поэтому ничего удивительного |
|
16.03.2009, 18:06 | #15 |
MCTS
|
Цитата:
но с == работает, а с LIKE не работает.
X++: qbr = qbds.addRange(fieldNum(InventDim, [B]DataAreaId[/B])); X++: static void Job9(Args _args) { Query q; QueryBuildDataSource qbds; QueryBuildRange qbr; QueryRun qr; InventDim inventDim; ; q = new Query(); qbds = q.addDataSource(TableNum(InventDim)); // можно еще так //global::findOrCreateRange_W(qbds,fieldNum(InventDim, InventLocationId), "Глав*"); qbr = qbds.addRange(fieldnum(InventDim, InventLocationId)); qbr.value("Глав*"); info(q.dataSourceNo(1).toString()); qr = new QueryRun(q); while (qr.next()) { inventDim = qr.get(TableNum(InventDim)); info(inventDim.inventLocationId); break; } } |
|
16.03.2009, 19:07 | #16 |
Участник
|
Еще литералы могут влиять. а с учетом того что для тяжелых запросов ядро в зависимости от настроек конфигурационной утилиты может их само втыкать - очень весело получается.
|
|
17.03.2009, 08:28 | #17 |
Участник
|
Согласна, что вариант с наложением фильтра на само поле отработает как LIKE.
X++: qbr = qbds.addRange(fieldnum(InventDim, InventLocationId)); qbr.value("Глав*"); InventLocationId Пример Код: select InventDim where InventDim.InventLocationId LIKE 'Склад1' && InventDim.InventLocationId LIKE 'Склад2' |
|
17.03.2009, 08:47 | #18 |
MCTS
|
X++: global::findOrCreateRange_W(qbds,fieldNum(Table1, Field2), "Глав*"); global::findOrCreateRange_W(qbds,fieldNum(Table1, Field3), "Д_*"); А вот запрос: X++: select InventDim where InventDim.InventLocationId LIKE 'Склад1' && InventDim.InventLocationId LIKE 'Склад2' И у меня есть подозрение, что на DataAreaId не выйдет наложить фильтр. Записи уже фильтрованы по текущей компании. Тогдв два выхода, переносить таблицу в холдинг, что не есть хорошо. Или использовать changecompany, заполняя временную таблицу и вытягивая данные уже по нее. Последний раз редактировалось Eldar9x; 17.03.2009 в 08:52. |
|
17.03.2009, 09:22 | #19 |
Участник
|
Что-то я не очень понял о чем спор. По-моему вот правильный ответ:
Здесь ключевые слова "расширенный фильтр" и "like". Расширенный фильтр like не поддерживает, по крайне мере в 3.0 точно. |
|
17.03.2009, 09:31 | #20 |
Участник
|
TO Eldar9x
Range как раз и накладывается на любое поле в таблице, чтобы воспользоваться механизмом фильтров через StrFmt. X++: // Add our range queryBuildRange = dsInventTable.addRange(fieldNum(InventTable, DataAreaId)); queryBuildRange.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 Но это отдельная тема. TO Lucky13 и kashperuk Спасибо Жаль только что не получится так написать... |
|