22.12.2008, 15:55 | #21 |
Боец
|
2 ZVV: можно взглянуть на код?
Проверил сам - получилось не более 476 критериев. + Проверил, тема обсуждалась (Поиск на форуме по "476" или "477") + см. вложение |
|
22.12.2008, 16:51 | #22 |
MCITP
|
Цитата:
Цитата:
Сообщение от DSPIC
Может прозвучит нелогично, но помнится, когда я с этим экспериментировал, получалось ограничение именно на количество рэнджей, а не на длину в 250 символов. При этом было не важно, сколько самих рэнджей на одно поле наложить:
(2x125 или 1x250) - если в сумме получалась магическая цифра немногим больше 250 то запрос не проходил... А обсуждаемая магическая цифра 476 (например тут соединить query и временную таблицу) - это уже ограничение несколько другого рода. И не на кол-во ренджей, как могло бы показаться, а на размер SQL-оператора, насколько я понимаю. Очевидно, ваш пример проверялся на сиквеле, где, помнится размер оператора максимальный 32К (могу ошибаться)? Ну вот оно где-то так и выходит, по моим прикидкам. На оракле это ограничение выше - 64К (для 9-ой версии, например). (Причём из документации по 10-ке и 11-ке данное ограничение вообще исчезло почему-то) Соответсвенно данный пример может отрабатывать с гораздо большим значением У меня например успешно отрабатывает такой джоб на оракле: 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 <= 1200 ; nextI++) { qbr = qbds.addRange(fieldNum(InventTable, ItemId)); qbr.value(queryValue(int2str(nextI))); } queryRun = new QueryRun(query); queryRun.next(); } Цитата:
ORA-00600: internal error code, arguments: [733], [36332372], [pga heap], [], [], [], [], []
Кстати, даже в этом случае (1200), размер SQL-оператора уходящего в БД превышает задекларированные 64к, но работает. Тестировал на 3.0сп3кр3 + Оракл 9208Вин
__________________
Zhirenkov Vitaly |
|
02.02.2011, 09:34 | #23 |
Участник
|
Подскажите, плз, как приведенные на первой странице примеры кода заставить работать не в отчете, а просто как код?
Очень криво, наверное, написал, поясню: 1. Я сделал на форме MenuItemButton. В свойствах указал нужный datasource. Тип менюайтема выбрал Action (из тех соображений, что там будет запускаться "голый" код, а не отчет и не форма). 2. Сделал соответствующий MenuItem, запускающий класс. 3. Сделал класс. В классе сделал метод main. Скопировал в него код из этой темы (разные коды пробовал). И вот после всего у меня при выполнении (нажатии на эту кнопку) система ругается либо на отсутствие метода main, либо на "отсутствие поля в таблице" в строке fr = this.args().caller(); (Подозреваю, надо правильно ставить тип main и правильно определять classDeclaration созданного класса...) Подскажите, плз, как надо правильно. |
|
02.02.2011, 09:43 | #24 |
Участник
|
ClassDeclaration:
X++: public class ClassTest extends RunBase { } X++: public static void main(Args _args) { FormRun fr; ; if(!_args) throw error("Класс должен быть вызван с параметрами!"); else { fr = _args.caller(); info(fr.name()); } }
__________________
С уважением, Александр. Последний раз редактировалось samolalex; 02.02.2011 в 10:03. |
|
|
За это сообщение автора поблагодарили: Geo (1). |
02.02.2011, 09:52 | #25 |
Участник
|
К слову, для создания метода main есть стандартный шаблон. В контекстном меню редактора пункт Scripts/template/method/main
|
|
03.02.2011, 16:15 | #26 |
Участник
|
Спасибо!
|
|
11.02.2011, 02:11 | #27 |
Участник
|
Ниччего не получается
Хочу сделать так, чтобы у отмеченных записей инвертировалось логическое поле Archives. Сделал метод вот такой: X++: public static void main(Args _args) { FormRun fr; FormDatasource fds; PurchReqTable purchReqTableLocal; ; if(!_args) throw error("Класс должен быть вызван с параметрами!"); else { fr = _args.caller(); //info(fr.name()); if (fr) { fds = fr.dataSource(); ttsbegin; for (purchReqTableLocal = fds.getFirst(true) ? fds.getFirst(true) : fds.cursor(); purchReqTableLocal; purchReqTableLocal = fds.getNext()) { purchReqTableLocal.Archives = !purchReqTableLocal.Archives; purchReqTableLocal.doUpdate(); } ttscommit; // делаем проверку, изменилось ли содержимое: for (purchReqTableLocal = fds.getFirst(true) ? fds.getFirst(true) : fds.cursor(); purchReqTableLocal; purchReqTableLocal = fds.getNext()) { info(strfmt("%1, %2", purchReqTableLocal.PurchReqId, purchReqTableLocal.Archives)); } } } } Не работает! "Проверка" проходит нормально, отображаются правильные ключи отмеченных записей с правильным (как бы новым) значением изменяемого поля. Но записи реально не изменяются (убедился через журнал базы данных). При этом, если не отмечать несколько записей, а запускать для просто текущей - оно работает. Пробовал ttsbegin и ttscommit помещать внутрь цикла - не помогло. Помогите, пожалуйста. |
|
11.02.2011, 08:53 | #28 |
Участник
|
Cтранно что этот код вообще работает. Вы же НЕ блокируете курсор для обновления. Попробуйте перед изменением курсора перевыбрать его.
А ещё для того чтобы изменения отображались на форме нужно обновить(refresh) источник данных X++: for (purchReqTableLocal = fds.getFirst(true) ? fds.getFirst(true) : fds.cursor(); purchReqTableLocal; purchReqTableLocal = fds.getNext()) { ttsbegin; purchReqTableLocal.selectForUpdate(true); purchReqTableLocal.reread() purchReqTableLocal.Archives = !purchReqTableLocal.Archives; purchReqTableLocal.doUpdate(); ttscommit; fds.reread(); fds.refresh(); } P.S.: Если вы работает не просто с табличным курсором, а с источником данных, то у вас также есть возможность использовать метод fds.write(), который сам управляет транзакциями и отображением изменений. |
|
|
За это сообщение автора поблагодарили: Geo (1). |
11.02.2011, 11:54 | #29 |
Участник
|
Огромное спасибо! Работает!
И не говорите. Тыкаюсь, как слепой котенок... Пора, наверное, уже отойти от попыток освоения АХ методом медитирования над непонятным кодом, и что-нибудь почитать. Цитата:
А он (журнал баз данных) настроен на протоколирование изменений Archives таблицы PurchReqTable?
... Можно еще вопрос, вдогонку? С Вашим кодом, после отработки, в форме обновляется только одна запись (текущая), а не все выделенные. Чтобы все обновились, надо куда-нибудь нажать, при этом сбрасывается выделение. Но если поставить в конце вызов info("1"), например - то сразу все обновляются, и без сброса выделения. Как можно добиться этого без окошка инфолога? Я пробовал повесить *_ds.reread() и *_ds.refresh() на метод clicked() контрола - не помогло. |
|
11.02.2011, 12:21 | #30 |
Участник
|
Цитата:
Методы _ds.reread() и _ds.refresh() в принципе обновляют только активную запись. Была попытка обновить каждую запись вызывая эти методы из цикла, но вот в чём дело: метод fds.getNext() хоть и возвращает курсор связанный со следующей записью, но активной её не делает. Не уверен, но попробуйте вместо fds.refresh(); сделать X++: purchReqTableLocal.dataSource().reread() purchReqTableLocal.dataSource().refresh() X++: fds.refreshEx(purchReqTableLocal) |
|
11.02.2011, 12:42 | #31 |
Участник
|
Помогло так:
X++: fds.reread(); fds.refresh(); fds.refreshEx(); |
|
11.02.2011, 13:07 | #32 |
Участник
|
Интересно, значит refreshEx() без параметров обновляет все записи кроме текущей. Нужно будет запомнить. А вы к стати вызывали его внутри цикла или один раз после? И вызов fds.reread() тогда наверное должен быть лишним.
А ошибку с параметром он выдал, видимо, потому что в качестве параметра он ждёт номер позиции (ds.getPosition), а не сам курсор. Последний раз редактировалось S.Kuskov; 11.02.2011 в 13:11. |
|
12.02.2011, 20:12 | #33 |
Участник
|
|
|
|
|