← вся теориятеория к собесу · Язык запросов 1С

Результат запроса 1С: Выбрать и Выгрузить

разбор писал Даниил, автор Сеньорчика

Зачем это спрашивают

Запрос вернул результат, и с ним можно работать по-разному: обойти выборкой, выгрузить в таблицу, проверить на пустоту. Выбор влияет на память сервера и на то, что можно передать на клиент. На собесе спрашивают, когда что брать.

// Так спрашивают: «Чем Выбрать() отличается от Выгрузить()?» «Как проверить, что запрос что-то вернул?» «Как обойти результат с ИТОГИ?» «Можно ли передать результат запроса на клиент?»

Выборка и таблица

Выбрать() даёт выборку: курсор, который идёт по строкам по одной. Выгрузить() строит таблицу значений целиком в памяти. Выборка подходит для обхода миллионов строк, таблица нужна, когда по результату ищут, сортируют или передают его дальше.

Пустой() проверяет результат, не выгружая строк. Поля выборки читают только после Следующий(): до первого вызова выборка не стоит ни на одной записи.

Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
    Возврат;
КонецЕсли;
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
    Итог = Итог + Выборка.Сумма;
КонецЦикла;

Что выбрать

Выгрузить() на миллионе строк положит в память сервера таблицу со всеми колонками, и рабочий процесс может упереться в лимит памяти. Для обхода больших результатов берут выборку.

ИТОГИ и клиент

Для запроса с ИТОГИ выборку открывают с обходом по группировкам: Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам), и у каждой строки группы можно взять вложенную выборку её детальных записей. Так код строит отчёт-дерево без отдельных запросов на каждую группу.

Результат, выборка и таблица значений живут только на сервере. На клиент отдают массив структур, данные формы или значение в реквизите формы. Поле, ради которого в цикле по выборке получают объект, выбирают в самом запросе: обращение к объекту на каждой строке превращает один запрос в тысячу.

Как отвечать: «Когда используешь Выбрать, а когда Выгрузить?»

Выбрать даёт курсор и не держит строки в памяти, его беру для обхода больших результатов: посчитать, сформировать движения, выгрузить в файл. Выгрузить строит таблицу значений целиком, она нужна, когда по результату ищу, сортирую, сворачиваю или передаю в другой запрос параметром. Если нужно только узнать, есть ли строки, хватает Пустой. Ни то ни другое на клиент не передаётся, туда отдаю массив структур или данные формы.

Кандидат выбирает метод по задаче и называет цену памяти, плюс помнит про Пустой и границу клиент-сервер. Это разговор о практике, а не о синтаксисе.

На чём валят

  • −Читают поле выборки без Следующий(). Выборка не стоит на записи. Сначала Следующий(), потом поля.
  • −Выгружают миллион строк ради обхода. Таблица целиком в памяти сервера. Обходят выборкой.
  • −Получают объект ради одного поля в цикле по выборке. Тысяча строк дают тысячу обращений. Поле выбирают в запросе.
  • −Пытаются передать результат запроса на клиент. Он живёт только на сервере. Отдают массив структур или данные формы.

Проверь себя

Пять вопросов из банка по этой подтеме. Всего их 12, остальные разбираются в тренажёре.

  1. #oc_q_result1 / 5
    Как быстрее всего проверить, что запрос вернул хотя бы одну строку?
    A)Результат.Выбрать().Количество()
    B)Результат.Выгрузить().Количество() > 0
    C)Результат.Пустой()
    D)Результат <> Неопределено
    показать ответ и разбор
    +C)`Результат.Пустой()`

    // разбор: Пустой() проверяет результат без выгрузки всех строк в память. Выгрузка ради подсчёта создаёт таблицу целиком. Выполнить() всегда возвращает объект результата, поэтому сравнение с Неопределено ничего не скажет. Если важен сам факт, в запрос ещё и добавляют ПЕРВЫЕ 1.

  2. #oc_q_result2 / 5
    Что вернёт Результат.Выгрузить()?
    A)Массив структур по строкам
    B)ТаблицаЗначений со всеми строками
    C)Выборку для обхода порциями
    D)Строку XML с результатом
    показать ответ и разбор
    +B)ТаблицаЗначений со всеми строками

    // разбор: Выгрузить() создаёт таблицу значений с типизированными колонками по полям запроса. Удобно для небольших результатов и передачи дальше в код. На миллионах строк выгрузка съедает память рабочего процесса — такие результаты обходят выборкой.

  3. #oc_q_result3 / 5
    Как получить массив ссылок из результата запроса одной колонки?
    A)Результат.Выгрузить().ВыгрузитьКолонку("Ссылка")
    B)Результат.Колонки.Ссылка
    C)Результат.Выбрать().ВМассив()
    D)Результат.ВыгрузитьМассив()
    показать ответ и разбор
    +A)`Результат.Выгрузить().ВыгрузитьКолонку("Ссылка")`

    // разбор: Таблица значений умеет выгрузить колонку в массив одним вызовом. Такой массив передают параметром в другой запрос или функцию. У выборки и самого результата методов получения массива нет.

  4. #oc_q_result4 / 5
    Запрос с ИТОГИ ПО Контрагент. Как обойти результат по группировкам?
    A)Обход ПоГруппировкам и вложенные выборки
    B)Результат.Выгрузить() и сортировка по уровням
    C)Выбрать() без параметров — итоги придут первыми строками
    D)Итоги доступны только в СКД
    показать ответ и разбор
    +A)Обход `ПоГруппировкам` и вложенные выборки

    // разбор: Обход ПоГруппировкам возвращает выборку верхнего уровня (контрагенты с итогами), а для каждой её строки Выбрать() даёт вложенную выборку детальных записей. Обход Прямой выдаст строки итогов и детальные подряд, и их придётся различать по типу записи.

  5. #oc_q_result5 / 5
    Результат запроса на 2 млн строк. Выгрузить() или Выбрать()?
    A)Выгрузить() в цикле по 1000 строк
    B)Выгрузить(): одним вызовом быстрее
    C)Без разницы, память выделит СУБД
    D)Выбрать(): строки читаются порциями
    показать ответ и разбор
    +D)Выбрать(): строки читаются порциями

    // разбор: Выгрузить() создаёт таблицу в памяти рабочего процесса целиком: два миллиона строк легко превращаются в гигабайты. Выборка читает данные порциями и держит в памяти немного. Если нужна вся таблица — сначала проверяют, нельзя ли свернуть данные запросом.

дальше

Теорию прочитал. Навык ставится повторением

В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, бесплатная часть практики — одна сессия дня в сутки.