16.09.2010, 22:28 | #1 |
Участник
|
Длина строки range - 250, 1000 или больше
Добрый день всем.
При написании модификаций обратил внимание на странную особенность работы querybuildRange - при задании фильтра из формы SysQueryForm длина строки критерия ограничена 250 символами, что в общем понятно, так как длина соответствующего поля RangeValue во временной табличке TmpSysQuery как раз 250 символов. Но если задавать критерий из X++ то можно задать строки большей длины, например 1000 символов. Правда если потом открыть редактирование этого Query формой SysQueryForm, то критерий усекается до 250 символов, что неприятно. Есть какие-нить ограничения в языке X++ на длину критерия ? Или магическая цифра 250 символов выбрана неспроста... |
|
16.09.2010, 22:30 | #2 |
Участник
|
|
|
17.09.2010, 08:48 | #3 |
Ищущий знания...
|
Вроде бы в X++ ограничений на количество символов нет, но учтите что сколько бы вы не передали символов из кода, в запросе в итоге будут участвовать только первые 250 сам наступал на эти грабли
Лучше разбивать на несколько range (но это не всегда возможно из-за определения какое условие подставлять И или ИЛИ. если писать в одном range, тогда в запросе будет условие И, а если в нескольких, то ИЛИ. и на эти грабли наступал ).
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
|
За это сообщение автора поблагодарили: mazzy (2). |
17.09.2010, 09:04 | #4 |
Ищущий знания...
|
Цитата:
вот джобик для наглядности: X++: Query query; QueryBuildDataSource qbds; QueryBuildRange qbr; InventTable inventTable; str filter; int i; ; // вариант №1 создаем один range и в него через запятую записываем условие --> query = new Query(); qbds = query.addDataSource(tableNum(InventTable)); qbr = qbds.addRange(fieldNum(InventTable, ItemId)); while select inventTable { i++; if (filter != '') filter += ', '; filter += '!' + inventTable.ItemId; if (i == 3) break; } qbr.value(filter); info('1-ый вариант -->'); info(query.dataSourceTable(tableNum(InventTable)).toString()); info('1-ый вариант <--'); // <-------------------------------------------------------------------------- i = 0; // вариант №2 для каждой номенклатуры добавляем range --> query = new Query(); qbds = query.addDataSource(tableNum(InventTable)); while select inventTable { i++; qbds.addRange(fieldNum(InventTable, ItemId)).value(SysQuery::valueNot(inventTable.ItemId)); if (i == 3) break; } info('2-ой вариант -->'); info(query.dataSourceTable(tableNum(InventTable)).toString()); info('2-ой вариант <--'); // <-----------------------------------------------------
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
|
За это сообщение автора поблагодарили: Logger (3). |
17.09.2010, 09:25 | #5 |
Ищущий знания...
|
Цитата:
При формировании запроса в X++ в условие range можно добавлять сколько угодно символов, и запрос нормально отработает. Но, соответственно, если это условие добавить потом, например, в фильтр на форме (диалоге), то оно обрежется до 250 сомволов (потому как там используется TmpSysQuery ).
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
17.09.2010, 09:42 | #6 |
Участник
|
Уточню вопрос. Строка фильтра обрезается до 250 символов, потому что, соответствующее поле во временной табличке, которая используется для отображения критериев на форме SysQueryForm, имеет как раз 250 символов. Если увеличить длину поля, то можно сделать и 1000 символов, что по-моему удобнее в использовании, но неясно будут ли какие либо побочные эффекты.
|
|
17.09.2010, 09:47 | #7 |
Ищущий знания...
|
Не думаю, что возникнут какие то проблемы.
Если из кода запрос с условием более 250-ти символов отрабатывает нормально, то и на формах (диалогах) он должен отрабатывать нормально.
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
17.09.2010, 10:23 | #8 |
Участник
|
Нет, ничего ужасного в увеличении длины нету.
Но, учтите, что рано или поздно вы наткнетесь на максимальную длину значения в where выражении SQL Server (она равно около 2000 символов на какой-то из версий, если мне память не изменяет). То есть, если вам нужен фильтр по 300 символов, то да, все ОК. Но если вы собираетесь генерировать очень длинные фильтры - возможно exist join подойдет больше. На форуме обсуждалась эта проблема, к слову, поэтому можете попробывать поискать конкретные детали. |
|
|
За это сообщение автора поблагодарили: Logger (3), aidsua (2). |
17.09.2010, 10:52 | #9 |
----------------
|
как и говорил Иван, вот такой джобик через некоторое время валится с ошибкой SQL (слишком длинный запрос)
X++: static void JobRangeLength(Args _args) { InventTable inventTable, inventTableQr; int i; Query q = new Query(); QueryRun qr; QueryBuildDataSource qbDS; QueryBuildRange qRange; ; qbDS = q.addDataSource(tableNum(InventTable)); qbDS.fields().clearFieldList(); qbDS.addSelectionField(fieldNum(InventTable, ItemId)); qbDS.addSortField(fieldNum(InventTable, ItemId), SortOrder::Descending); qRange = qbDS.addRange(fieldNum(InventTable, ItemId)); qRange.value("null"); qr = new QueryRun(q); while select ItemId from inventTable order by ItemId ASC { i++; qRange.value(qRange.value() + ',' + inventTable.ItemId); qr.query(q); qr.reset(); qr.next(); inventTableQr = qr.getNo(1); if(inventTable.ItemId != inventTableQr.ItemId) { info(strFmt("%1 %2 %3", i, inventTable.ItemId, strLen(qRange.value()))); warning(qRange.value()); break; } } } |
|
|
За это сообщение автора поблагодарили: Logger (3), aidsua (2). |
17.09.2010, 10:52 | #10 |
MCT
|
2Logger
Паш, я когда давно крутил эту проблему, и решил, что луше создавать временную табличку с критериями и джойнить, как Иван предложил. Как то на мой взгляд это выглядит посимпотнее.
__________________
Axapta book for developer |
|
|
За это сообщение автора поблагодарили: Logger (3). |
17.09.2010, 11:10 | #11 |
Участник
|
есть еще магическая константа 475 - максимальный уровень вложенности в WHERE. Что может быть критично, поскольку Axapta каждое условие добавляемое по ИЛИ оборачивает в новый уровень (это если добавлять много Range).
У нас бывают запросы с размером WHERE больше 10000 символов - проходит, если бы не такая вложенность (Ax4, SQL2005). Вышеприведенный джоб валится как раз на значении счетчика 476, при этом длина запроса 12500 символов. Последний раз редактировалось vanokh; 17.09.2010 в 11:17. |
|
|
За это сообщение автора поблагодарили: sukhanchik (3), Logger (3), lev (3), aidsua (2), gl00mie (2). |
17.09.2010, 12:43 | #12 |
Роман Долгополов (RDOL)
|
В продолжение темы
Выборка произвольных записей одним запросом |
|
19.09.2010, 01:31 | #13 |
Гость
|
ребята вы кажется неправильно используете аксапту
почему я, программируя уже лет 8, ни разу не сталкивался с такими проблемами? |
|
19.09.2010, 14:36 | #14 |
Участник
|
Цитата:
|
|