17.09.2010, 12:42 | #1 |
Роман Долгополов (RDOL)
|
Выборка произвольных записей одним запросом
Для выборок произвольных записей одним запросом есть класс RecordRefrenceList_RU. Появился, кажется, в RU3. Никаких особеннойстей новых
версий не использует и все это можно вполне "даунгрейтить" до 3.0. Под произвольными имеется в виду то, что у выбираемых записей нет ничего общего - это просто список их кодов. Типичный пример - пользователь наставил в некоторой форме отбора сотню галок и хочет отмеченные записи как то обработать Класс реализует универсальный join с постоянно/временной (постоянной в терминах БД, временной по сути) таблицей. RecId желаемых записей надо засунуть в этот класс, а затем использовать его в Query или select. Соответственно чтобы все работало нормально на фильтруемой таблице должен быть индекс по RecId Для того чтобы работало с select надо метод getParmId() изменить на с private на public Пример X++: static void refList_Tutorial(Args _args) { RecordReferenceList_RU refList = RecordReferenceList_RU::construct(); RecordReference_RU ref; InventTable inventTable; int i; Query query; QueryBuildDataSource qbds; QueryRun queryRun; ; setprefix("RecordReferenceList_RU"); while select inventTable { refList.addRecord(inventTable); i++; if (i > 10) { break; } } refList.flush(); info("Query"); query = new Query(); qbds = query.addDataSource(tablenum(InventTable)); refList.join(qbds); queryRun = new QueryRun(query); while (queryRun.next()) { info(queryRun.get(tablenum(InventTable)).caption()); } info("Select"); while select inventTable join ref where ref.RefRecId == inventTable.RecId && ref.ParmId == refList.getParmId() { info(inventTable.caption()); } refList.cleanup(); } транзакции, есть периодическая операция RecordReferenceCleanUp_RU (Основное/Пер операции/Очистка/Очистка ссылок на записи) Достоинства и недостатки данного метода очевидны + Произвольные фильтры без ограничений на к-во выбранных записей + Нормальный join средствами сервера БД. Даже с учетом того что тут что то куда записывается работает (в общем случае - таблички с парой сотен записей не в счет) быстрее чем join с временной таблицей - Доп накладные расходы на запись/очистку. Понятно что не стоит такое использовать если алгоритм, задействующий данный функционал, выполняется 100 раз в минуту или надо отобрать пару-тройку записей В остальных случаях вполне годится Еще раз - это тема про выборку одним запросом. Выборка в вызовом find() или select в цикле это то же вариант решения той же задачи, но здесь речь не о нем |
|
|
За это сообщение автора поблагодарили: mazzy (2), AlGol (2), Maximin (1), vvk (1), pavelt (1), sukhanchik (5), Logger (3), TasmanianDevil (5), ziva (2), Weez (1), alex55 (3), vanokh (1), klimova_m (1), kornix (1), pedrozzz (2), Pandasama (1), syl (1). |
Теги |
multiselect, маркировка, полезное |
|
|