Цитата:
Сообщение от
Blog bot
Такие операции существенно уменьшают число запросов к базе данных и позволяют улучшить производительность операций.
Такие операции МОГУТ уменьшить число запросов и МОГУТ улучшить производительность, если:
1. в обрабатываемой таблице нет переопределенных методов insert, update, delete соответственно
2. обрабатываемая таблица не включена в RLS
3. обрабатываемая таблица не содержит deleteAction (для удаления)
Да, можно отключить эти факторы при помощи skip-методов.
Но отключение переопределенных методов чревато тем, что логическая целостность базы нарушится.
Подробнее см хелп, ключевая фраза "What prevents fast SQL operations?"
Кроме того, подобные операции может быть и повышают производительность, но гарантировано уменьшают наглядность и юзабилити.
Обычно при длительной обработке данных показывают прогресс-бар, который показывает сколько процентов осталось.
Групповые операции ничего не показывают. Если групповая операция выполняется несколько минут, то вы не знаете: повисла она, заблокирована или таки выполняется.
И кроме того, групповые операции блокируют ВСЕ обрабатываемые записи за один раз. А обработка каждой записи, при правильном написании, блокирует только обрабатываемую запись. См.
aEremenko: Ресурс заблокирован, ждите...
Ну, и напоследок, групповые операции не позволяют работать с критериями из query. Что напрочь лишает их полезность, если пользователь может задавать критерии со спец-символами
http://axapta.mazzy.ru/lib/search/
В общем, групповые операции дело хорошее.
Но у них тоже есть минусы.
Цитата:
Сообщение от
Blog bot
Например, возьмем код:
X++:
while select * from custCollectionLetterTrans
where custCollectionLetterTrans.CollectionLetterNum == this.CollectionLetterNum
&& custCollectionLetterTrans.AccountNum == this.AccountNum
&& custCollectionLetterTrans.CollectionLetterIssued
{
custTrans = CustTrans::find(custCollectionLetterTrans.CustTransId, true);
custTrans.CollectionLetterCode = custCollectionLetterTrans.CollectionLetterCode;
custTrans.update();
}
Это отвратительный код, за который надо штрафовать программиста и снижать его зарплату. Надеюсь, что этот код упрощен только для демонстрационных целей
Более правильный код:
X++:
SysProgressOperation progress;
;
select count(recid) from custCollectionLetterTrans
where custCollectionLetterTrans.CollectionLetterNum == this.CollectionLetterNum
&& custCollectionLetterTrans.AccountNum == this.AccountNum
&& custCollectionLetterTrans.CollectionLetterIssued;
progress = SysProgressOperation::newGeneral('','',custCollectionLetterTrans.recid);
while select * from custCollectionLetterTrans
where custCollectionLetterTrans.CollectionLetterNum == this.CollectionLetterNum
&& custCollectionLetterTrans.AccountNum == this.AccountNum
&& custCollectionLetterTrans.CollectionLetterIssued
{
ttsbegin;
custTrans = CustTrans::find(custCollectionLetterTrans.CustTransId, true);
custTrans.CollectionLetterCode = custCollectionLetterTrans.CollectionLetterCode;
custTrans.update();
ttscommit;
progress.inccount();
}
Еще более правильным было бы создание запроса для таблицы и код:
X++:
SysProgressOperation progress;
Query q;
QueryBuildDataSource = qbds;
QueryRun qr;
;
q = new Query(queryStr(mySupercustCollectionLetterTransQuery));
qbds = q.datasourcetable(tablenum(custCollectionLetterTrans));
SysQuery::findOrCreateRange(qbds,fieldnum(custCollectionLetterTrans,CollectionLetterNum ).value(this.CollectionLetterNum);
SysQuery::findOrCreateRange(qbds,fieldnum(custCollectionLetterTrans,AccountNum).value(this.AccountNum );
SysQuery::findOrCreateRange(qbds,fieldnum(custCollectionLetterTrans,CollectionLetterIssued).value(SysQuery::notEmptyString());
qr = new QueryRun(q);
progress = SysProgressOperation::newGeneral('','',SysQuery::CountTotal(qr));
while( qr.next() )
{
custCollectionLetterTrans = qr.getTable(tablenum(custCollectionLetterTrans));
ttsbegin;
custTrans = CustTrans::find(custCollectionLetterTrans.CustTransId, true);
custTrans.CollectionLetterCode = custCollectionLetterTrans.CollectionLetterCode;
custTrans.update();
ttscommit;
progress.inccount();
}
Этот код позволяет:
1. отделить запрос и процесс его оптимизации от программирования.
2. позволяет работать с пользовательскими критериями
3. полностью совместим со всей функциональностью форм и отчетов
4. полностью совместим с пакетной обработкой
5. информирует пользователя о ходе выполнения.
Поэтому... Если уж начали двигаться в сторону групповых операций... Если это возможно.... Нужен не update_recordset, а дополнительный режим групповой обработки для Query.