Пакетные запросы. Простые запросы Выполнить пакет запросов 1с

Конструктор запросов в 1С 8.3 и 8.2 — мощнейший инструмент разработки. Он позволяет составить текст запроса при помощи специальной визуальной среды. Таким образом, чтобы создать запрос 1с не обязательно знать встроенный язык запросов, достаточно ориентироваться в не сложном и интуитивно понятном интерфейсе конструктора.

Конструктор запросов представляет из себя набор вкладок, каждая из которых отвечает за свою часть запроса. Так заполняя вкладку Таблицы и поля мы выбираем таблицы из которых запрос 1с будет получать данные и поля этих таблиц необходимые для решения конкретной задачи. Заполняя в кладку Условия мы накладываем условия на выбранные таблицы, для того чтобы выбрать из них только нужные нам данные и так далее.

Описание конструктора запросов на официальном сайте 1С 8: v8.1c.ru

Таблицы и поля; ; ; ; ; ; Вложенные запросы (в разработке).

Для того чтобы вызвать конструктор запросов 1с 8 в программном коде необходимо:

  • Создать новый запрос
Запрос = Новый Запрос;
  • Задать пустую строку текста запроса
Запрос.Текст = "";
  • Поставить курсор мышки между кавычками, нажать правую кнопку мыши. В открывшемся контекстном меню выбрать пункт Конструктор запроса и ответить Да на вопрос о создании нового запроса. Если текст запроса уже записан, то необходимо щелкнуть на любом месте внутри него и вызвать конструктор;

Рассмотрим на небольших примерах с возрастающей сложностью все основные вкладки конструктора запросов. Такой подход позволит начинающему программисту 1с более эффективно изучить конструктор и все его возможности. Для примеров будем использовать конфигурацию Бухгалтерия 3.0.

Урок №1. Конструктор запросов — простейший пример использования.

Задача: написать запрос к справочнику номенклатура, выбрать всю номенклатуру справочника.

Новые вкладки: Таблицы и поля.

Новые механизмы: просмотр и редактирование текста запроса при помощи кнопки «Запрос».

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

Теоретическая часть урока №1

Вкладка Таблицы и поля состоит из трех разделов:

База данных . В данном разделе представлены все таблицы базы данных, которые можно использовать для построения запроса;

Таблицы . В данный раздел выбираются таблицы необходимые для данного запроса. Для тогда чтобы переместить их из раздела база данных нужно:

  • Либо дважды щелкнуть по таблице;
  • Либо воспользоваться кнопками «>» или «>>».

Над разделом Таблицы присутствует ряд кнопок. Про большинство из них будет подробнее рассказано в следующих уроках. А пока дам только краткие пояснения.

  • Создать вложенный запрос (красная линия). Предназначена для создания нового вложенного запроса;
  • Создать описание временной таблицы (желтая линия). Позволяет задать имя временной таблицы, которая расположена вне данного запроса, также можно использовать для передачи в запрос таблицы значений;
  • Изменить текущий элемент (зеленая линия). Позволяет перейти в выделенный вложенный запрос, временную таблицу или описание временной таблицы;
  • Удалить текущий элемент (голубая линия). Удаляет выделенную таблицу из выбранных таблиц;
  • Заменить таблицу (синяя линия). Открывает диалог замены выделенной таблицы. Полезно, если вы неверно выбрали виртуальную таблицу регистра, так как происходит позиционирование на текущей выбранной таблице в списке.
  • Параметры виртуальной таблицы (фиолетовая линия). Открывает параметры виртуальной таблицы регистра.

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

  • Либо дважды щелкнуть по полю;
  • Либо воспользоваться кнопками «>» или «>>»;
  • Также можно добавить новое поле самостоятельно, используя произвольное выражение из полей выбранных таблиц и функций языка запросов.

Над разделом Поля присутствует ряд кнопок. Про создание полей при помощи произвольных выражений будет подробнее рассказано в следующих уроках. А пока дам только краткие пояснения.

  • Добавить (зеленая линия). Предназначена для добавления нового поля при помощи редактора произвольных выражений;
  • Изменить текущий элемент (красная линия). Позволяет изменить выделенное поле при помощи редактора;
  • Удалить текущий (синяя линия). Удаляет выделенное поле из списка.

Практическая часть урока №1

Мы разобрались с теорией необходимой для выполнения задания, предусмотренного в данном уроке. Напомню как оно звучит: написать запрос к справочнику номенклатура, выбрать всю номенклатуру справочника.

Приступим к созданию запроса по номенклатуре:

  • Создадим новый запрос и откроем конструктор методом указанным в начале урока;
  • В разделе База данных , откроем ветку Справочники и найдем там справочник Номенклатура;
  • Выделим его и при помощи кнопки «>» перенесем в раздел Таблицы;
  • В разделе Таблицы раскроем справочник номенклатура при помощи значка «+»;
  • В раскрывшемся списке полей найдем поле Ссылка и перенесем его в раздел Поля при помощи кнопки «>»
  • Запрос по номенклатуре готов, нажимаем кнопку «ОК» в нижней части окна конструктора.

Простые запросы

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

На рисунке показана структура конфигурации.

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

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


Если в запросе требуется получить данные из остатков различных регистров, то значение фильтра и второй вложенный запрос будет повторяться в каждом параметре виртуальных таблиц, при этом система при каждом вложенном запросе будет обращается для получения данных к информационной базе.

Временные таблицы

С некоторого времени в запросах появилась возможность использования временных таблицх, для чего служит объект «Менеджер временных таблиц». По сути дела, менеджер временных таблиц содержит описание пространства имен временных таблиц и обеспечивает их создание и удаление из базы данных.

Временные таблицы физически сохраняются в базе, потому следует использовать их осторожно, т.к. дисковая подсистема - это самая низкопроизводительная часть техники, а скорость создания и удаления таблиц зависит непосредственно от нее.

Изменим запрос с учетом использования временных таблиц. Временные таблицы будут содержать табличную часть документа в сгруппированном виде и список продукции для фильтрации виртуальных таблиц:

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

Кроме того можно использовать инструкцию Уничтожить - при этом временная таблица удаляется, иначе временные таблицы будут уничтожен объект менеджер временных таблиц вместе с таблицами.

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

Пакетные запросы

Пакетные запросы значительно расширяют функционал временных таблиц и предоставляют новые возможности при работе с запросами.

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

Пакетные запросы в тексте запроса должны быть разделены символом «;». Пространство имен виртуальных таблиц у отдельного пакетного запроса одно. В использовании менеджера временных таблиц нет необходимости, но возможно если вам нужно передать временные таблицы в другой пакетный запрос.

Изменим процедуру с учетом пакетных запросов:

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

После исполнения запроса, переменная МассивРезультатов будет содержать 3 элемента. Два первых - это количество помещенных во временные таблицы записей ДокТЧ и СписокТоваров, в третьем будет находиться выборка с полями Док_Количество, Номенклатура и Рег_Количество.

Переменная РезультатЗапроса содержит только выборку.

Таким образом, пакетные запросы - очень удобный инструмент как для написания, так и для чтения сложных запросов.

Данная статья рассчитана на читателей, которые знакомы с языком SQL.

Язык запросов в 1С, применяющийся начиная с версии 8, сегодня стал полезным инструментом для работы с базами данных, который позволяет читать из них, но не записывать. Синтаксически язык запросов очень схож с языком SQL, но на русском языке.

Ниже представлена таблица соответствия основных операторов языка запросов и SQL:

Операторы языка запросов 1С

Оператор SQL

РАЗЛИЧНЫЕ

СОЕДИНЕНИЕ

СГРУППИРОВАТЬ ПО

ОБЪЕДИНИТЬ

УПОРЯДОЧИТЬ ПО

И это далеко не полный список. Более полную справочную информацию по доступным операторам языка запросов можно получить в конструкторе запросов, о котором будет рассказано ниже.

Выполнение запроса 1С из программного кода осуществляется при помощи объекта встроенного языка «Запрос». Пример написания запроса к базе данных с использованием встроенного языка программирования:

Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Синоним.Ссылка КАК Ссылка |ИЗ | Справочник.Справочник1 КАК Синоним"; Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл // Вставить обработку выборки ВыборкаДетальныеЗаписи КонецЦикла;

Метод «Выполнить» выполняет запрос, метод «Выбрать» возвращает значение типа «ВыборкаИзРезультатаЗапроса». Также можно использовать метод «Выгрузить», который возвращает таблицу значений.

Параметры запроса хранятся в свойстве «Параметры» (в данном случае это структура, поэтому все методы структуры тут применимы – вставить, удалить и т.д.).

Пример установки параметра «Запрос.Параметры.Вставить» («Справочник», СправочникСсылка). В запросе обратиться к параметрам можно через амперсанд «&Справочник». Ниже пример запроса с использованием параметров:

Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Пользователи.Ссылка КАК Ссылка, | Пользователи.Родитель КАК Родитель, | Пользователи.Наименование КАК Наименование |ИЗ | Справочник.Пользователи КАК Пользователи |ГДЕ | Пользователи.Ссылка = &Справочник"; Запрос.Параметры.Вставить("Справочник", СправочникСсылка); Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл // Вставить обработку выборки ВыборкаДетальныеЗаписи КонецЦикла;

Напомним, что язык запросов предназначен только для чтения данных из базы, поэтому в нем отсутствуют аналоги таких операторов SQL, как INS ERT и UPDATE. Данные можно модифицировать только через объектную модель встроенного языка программирования 1С. Также в языке запросов 1С существуют операторы, аналогов которых нет в SQL, например:

  • В ИЕРАРХИИ
  • ПОМЕСТИТЬ
  • ИНДЕКСИРОВАТЬ ПО

В ИЕРАРХИИ – позволяет выбрать все элементы иерархического справочника, которые входят в иерархию переданной ссылки. Пример запроса с использованием В ИЕРАРХИИ :

ВЫБРАТЬ Товары.Ссылка, Товары.Артикул ИЗ Справочник.Товары КАК Товары ГДЕ Товары.Ссылка В ИЕРАРХИИ(&Цитрусовые)"

В данном случае в результат вернутся все подчиненные элементы справочника номенклатуры «Цитрусовые», неважно, сколько уровней иерархии есть у данного справочника.

Также, к примеру, стоит задача найти товар с именем «Ручка». Товар должен входить в иерархию «Канц. Товаров», то есть нам не надо искать дверную ручку. Структура номенклатуры в этом случае такова:

Канцелярия

|_ Ручки перьевые |_ Ручка красная |_ Ручка синяя |_ Ручки чернильные |_ Линейки

Фурнитура

|_ Ручки дверные |_ Ручка дверная простая |_ Ручка дверная люкс

Пишем такой запрос:

ВЫБРАТЬ Товары.Ссылка, Товары.Артикул ИЗ Справочник.Товары КАК Товары ГДЕ Товары.Наименование Подобно "Ручка%" И Товары.Ссылка В ИЕРАРХИИ(&Канцелярия)"

При использовании конструкции В ИЕРАРХИИ необходимо учитывать, что если в параметр «Канцелярия» передать пустую ссылку, выполнение запроса замедлится, так как платформа будет проверять каждый элемент на принадлежность корню.

ПОМЕСТИТЬ – Данный оператор помещает результат во временную таблицу. Пример запроса:

ВЫБРАТЬ Пользователи.Ссылка КАК Ссылка, Пользователи.Родитель КАК Родитель, Пользователи.Наименование КАК Наименование ПОМЕСТИТЬ ОтобранныеПользователи ИЗ Справочник.Пользователи КАК Пользователи ГДЕ Пользователи.Ссылка = &Справочник; ВЫБРАТЬ ОтобранныеПользователи.Ссылка КАК Ссылка, ОтобранныеПользователи.Родитель КАК Родитель, ОтобранныеПользователи.Наименование КАК Наименование ИЗ ОтобранныеПользователи КАК ОтобранныеПользователи

Данный запрос на SQL будет выполнен несколькими запросами:

  • Создание временной таблицы (платформа умеет «переиспользовать» ранее созданные временные таблицы, поэтому создание происходит не всегда);
  • Помещение данных во временную таблицу;
  • Выполнение основного запроса, а именно SEL ECT из этой временной таблицы;
  • Уничтожение/очистка временной таблицы.

Временная таблица может быть уничтожена явно, через конструкцию УНИЧТОЖИТЬ , либо неявно – при закрытии менеджера временных таблиц.

У объекта «Запрос» встроенного языка программирования есть свойство «МенеджерВременныхТаблиц», которое предназначено для работы с временными таблицами. Пример кода:

МВТ = Новый МенеджерВременныхТаблиц(); Запрос = Новый Запрос; Запрос.МенеджерВременныхТаблиц = МВТ;

После выполнения запроса переменную МВТ можно использовать второй раз в другом запросе, что, несомненно, является еще одним плюсом использования временных таблиц. В данном случае временная таблица из базы будет удалена при вызове метода «Закрыть»…

МВТ.Закрыть();

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

ИНДЕКСИРОВАТЬ ПО – этот оператор применяется совместно с оператором ПОМЕСТИТЬ. При создании временной таблицы этим оператором можно проиндексировать создаваемую таблицу, что существенно ускоряет работу с ней (но только, если индекс подходит под ваш запрос).

Бесплатная консультация эксперта

Спасибо за Ваше обращение!

Специалист 1С свяжется с вами в течение 15 минут.

Особенности некоторых операторов языка запросов

ДЛЯ ИЗМЕНЕНИЯ данный оператор предназначен для блокировки определенной таблицы запроса (или всех таблиц, которые участвуют в запросе). Блокировка осуществляется наложением U блокировки на таблицу. На SQL это реализуется через hint UPDLOCK. Данная конструкция необходима для предотвращения блокировок типа deadlock. Пример запроса с конструкцией ДЛЯ ИЗМЕНЕНИЯ:

ВЫБРАТЬ Пользователи.Ссылка КАК Ссылка, Пользователи.Родитель КАК Родитель, Пользователи.Наименование КАК Наименование ИЗ Справочник.Пользователи КАК Пользователи ЛЕВОЕ СОЕДИНЕНИЕ Справочник.РФК КАК РФК ПО Пользователи.РФК = РФК.Ссылка ДЛЯ ИЗМЕНЕНИЯ Справочник.Пользователи

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



СОЕДИНЕНИЕ – запрос поддерживает соединения ЛЕВОЕ/ПРАВОЕ, ПОЛНОЕ, ВНУТРЕННЕЕ, что соответствует соединениям в SQL – LEFT/RIGHT JOIN, OUTER JOIN, INNER JOIN.

Однако при использовании конструктора запросов вы не сможете сделать ПРАВОЕ СОЕДИНЕНИЕ. Конструктор просто будет менять местами таблицы, но оператор будет всегда левый. По этой причине в 1С никогда не встретишь применения правого соединения.

Синтаксически соединение выглядит так:

ВЫБРАТЬ Таблица1.Ссылка КАК Ссылка ИЗ Справочник.Справочник1 КАК Таблица1 ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Справочник2 КАК Таблица2 ПО Таблица1.Реквизит = Таблица2.Реквизит

В языке запросов 1С отсутствует оператор для соединения декартова произведения (CROSS JOIN). Однако отсутствие оператора не означает, что язык запросов не поддерживает такого соединения. Соединить таблицы при необходимости можно таким образом:

ВЫБРАТЬ Таблица1.Ссылка КАК Ссылка ИЗ Справочник.Справочник1 КАК Таблица1 ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Справочник2 КАК Таблица2 ПО ИСТИНА

Как видно из примера, задан ключ соединения ПО ИСТИНА , то есть каждая строка одной таблицы соответствует строке другой. Тип соединения (ЛЕВОЕ, ПРАВОЕ, ПОЛНОЕ, ВНУТРЕННЕЕ) не важен, если у вас есть строки в обеих таблицах, но если в какой-то из таблиц нет строк (пуская таблица) – результат будет отличаться. Например, при использовании ВНУТРЕННЕЕ соединение результат будет пустой. При использовании ЛЕВОЕ/ПРАВОЕ соединение в результате будет или не будет данных в зависимости от того, к какой таблице мы присоединяемся – с данными или нет. При использовании ПОЛНОГО соединения данные будут всегда (естественно, только одной таблицы, так как в другой пустота), выбор типа соединения зависит от конкретной прикладной задачи.

Небольшая визуальная подсказка, как работают различные типы соединений:



ПОДОБНО. В отличие от аналогичного оператора языка SQL – LIKE, шаблон для ПОДОБНО можно задать, используя только некоторые спец символы:

  • % (процент): последовательность, содержащая любое количество произвольных символов;
  • _ (подчеркивание): один произвольный символ;
  • / - следующий символ нужно интерпретировать как обычный символ.

ИТОГИ ПО аналогом на SQL можно назвать оператор ROLLUP. Пример использования оператора ИТОГИ:

ВЫБРАТЬ Товары.Цена КАК Цена, Товары.Товар КАК Товар ИЗ Справочник.Номенклатура КАК Товары ИТОГИ СРЕДНЕЕ(Цена) ПО Товар

Результат будет такой:

Кровать

9833,333

Утюг

Ручка

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

Работа с пакетными запросами

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

ВЫБРАТЬ Пользователи.Ссылка КАК Ссылка, Пользователи.Родитель КАК Родитель, Пользователи.Наименование КАК Наименование ИЗ Справочник.Пользователи КАК Пользователи;
ВЫБРАТЬ ГрафикРаботы.Пользователь КАК Пользователь, ГрафикРаботы.Дата КАК Дата, ГрафикРаботы.РабочихЧасов КАК РабочихЧасов ИЗ РегистрСведений.ГрафикРаботы КАК ГрафикРаботы

Для получения результата всех запросов, входящих в пакет, необходимо воспользоваться методом объекта запроса «ВыполнитьПакет», вместо «Выполнить». Данный метод последовательно выполняет все запросы. Результат запроса – массив результатов для каждого запроса из пакета, а последовательность расположения в массиве такая же, как последовательность запросов в тексте пакета.

Рассматривая язык запросов, стоит упомянуть о такой особенности, как виртуальные таблицы. Виртуальные таблицы отсутствуют в базе данных, это своеобразная обертка, которая выполняется на стороне СУБД как запрос с использованием подзапросов. Пример запроса 1С с использованием виртуальных таблиц:

ВЫБРАТЬ РегистрОбязательствОбороты.Обязательство КАК Обязательство ИЗ РегистрНакопления.РегистрОбязательств.Обороты() КАК РегистрОбязательствОбороты

Такой запрос на СУБД будет выглядеть так:

SEL ECT T1.Fld25931RRef FR OM (SELECT T2._Fld25931RRef AS Fld25931RRef, CAST(SUM(T2._Fld25936) AS NUMERIC(38, 8)) AS Fld25936Turnover_, CAST(SUM(T2._Fld25937) AS NUMERIC(38, 8)) AS Fld25937Turnover_ FR OM dbo._AccumRgTn25938 T2 WH ERE ((T2._Fld949 = @P1)) AND ((T2._Fld25936 @P2 OR T2._Fld25937 @P3)) GROUP BY T2._Fld25931RRef HAVING (CAST(SUM(T2._Fld25936) AS NUMERIC(38, 8))) 0.0 OR (CAST(SUM(T2._Fld25937) AS NUMERIC(38, 8))) 0.0) T1>>>>

Видно, что не похоже на SQL, поскольку есть подзапрос, группировка. Виртуальные таблицы, по большому счету – это «синтаксический сахар», то есть созданы, в общем-то, для удобства разработки запросов, чтобы запросы были компактнее и читабельнее.

Виртуальные таблицы есть только у регистров, но какие именно виртуальные таблицы доступны у регистра, можно увидеть в конструкторе запросов.



При использовании виртуальных таблиц необходимо всегда давать условие отбора. В противном случае могут возникнуть проблемы с производительностью.



В тексте запроса это выглядит так:

РегистрНакопления.РегистрОбязательств.Обороты(, Операция = &Операция) КАК РегистрОбязательствОбороты

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



В конструкторе запросов можно увидеть полный список поддерживаемых функций и операторов языка запросов.


Конструктор запросов является очень гибким визуальным инструментом для создания запросов любой сложности. Он доступен только в режиме конфигуратора. В режиме Предприятия есть так называемая «Консоль запросов» – это внешняя обработка, поставляемая на диске ИТС. Для управляемого приложения консоль запросов можно скачать на сайте its.1c.ru.

Описание работы в конструкторе запросов выходит за рамки тематики данной статьи, поэтому подробно рассматриваться не будет.

Причины неоптимальной работы запросов

Ниже приведен список основных причин (но не всех), которые приводят к замедлению выполнения запроса.

  • Использования соединения с подзапросами

Не рекомендуется выполнять соединение с подзапросами, подзапросы необходимо заменить временными таблицами. Соединение подзапросов может приводить к значительной потере в производительности, при этом выполнение запроса на разных СУБД может значительно разниться в скорости. Скорость выполнения таких запросов также чувствительна к статистике в СУБД. Причина такого поведения в том, что оптимизатор СУБД не всегда корректно может определить оптимальный план выполнения запросов, так как оптимизатор ничего не знает о том, какое количество строк вернет подзапрос после своего выполнения.

  • Использование виртуальных таблиц в соединениях запроса

Виртуальные таблицы на уровне СУБД выполняются как подзапросы, поэтому причины такие же, как в первом пункте.

  • Использование условий в запросе, неподходящих под существующие индексы

Если в условиях запроса (в операторе ГДЕ или в условиях виртуальной таблицы) используются поля, которые не все входят в индекс, данный запрос будет выполнен с использованием SQL конструкции table scan или index scan (полностью или частично). Это скажется не только на времени выполнения запроса, но также будет наложена избыточная S блокировка на лишние строки, что в свою очередь может привести к эскалации блокировок, то есть будет заблокирована вся таблица.

  • Использование ИЛИ в условиях запроса

Использование логического оператора ИЛИ в конструкции ГДЕ может также приводить к сканированию таблицы (table scan). Это происходит из-за того, что СУБД не может корректно использовать индекс. Вместо ИЛИ можно применить конструкцию ОБЪЕДИНИТЬ ВСЕ.

  • Получение данных через точку для полей составного типа

Не рекомендуется получать значения через точку (в конструкции ВЫБРАТЬ, ГДЕ ), поскольку если реквизит объекта окажется составным типом, соединение будет происходить с каждой таблицей, входящей в этот составной тип. В результате запрос на СУБД будет значительно усложнен, это может помешать оптимизатору в выборе корректного плана выполнения запроса.

Думаю все вы согласитесь с тем, что тема запросов в системе 1С:Предприятие 8 сегодня может похвастаться своей актуальностью. Именно поэтому нашу сегодняшнюю статью мы решили посвятить теме, связанной с объединением запросов, получении последних по дате документов в 1С запросе и соединением запросов. Давайте все таки начнем.

Итак, для того, чтобы создать в системе 1С:Предприятие пакетный запрос следует использовать предложение ПОМЕСТИТЬ. Пакетный запрос подразумевают под собой сразу же несколько запросов, описанных как один большой запрос. Все они выполняются последовательно один за другим. В результате использования любого из этих запросов, их можно поместить во внутрь временной таблицы и потом обратится к ней используя для этого уже какой то другой запрос. Наверное большинство из вас спросят: в чем же плюсы этого метода?

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

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

Вот, например:
ВЫБРАТЬ
Номенклатура,

Сумма(Сумма) КАК Сумма,
ПОМЕСТИТЬ ДокПриход
ИЗ


В результате, после того, как вы выполните этот запрос выведется только то количество записей, которое было помещено в таблицу. Результаты при этом будут находится в той же самой таблице. Давайте сделаем подобный запрос для расходного документа. Для этого нам потребуется разделить эти два запроса с помощью символа ";". Именно он способен рассказать пользователю о том, что закончился один пакетный запрос и начинается другой.

ВЫБРАТЬ
Номенклатура,
Сумма(Количество) КАК Количество,
Сумма(Сумма) КАК Сумма,
ПОМЕСТИТЬ ДокПриход
ИЗ
Документ.ПоступлениеТоваровУслуг.Товары
СГРУППИРОВАТЬ ПО Номенклатура
;

ВЫБРАТЬ
Номенклатура,
Сумма(Количество) КАК Количество,
Сумма(Сумма) КАК Сумма,
ПОМЕСТИТЬ ДокРасход
ИЗ
Документ.РеализацияТоваровУслуг.Товары
СГРУППИРОВАТЬ ПО Номенклатура

;
ВЫБРАТЬ
*
ИЗ
ДокПриход КАК ДокПриход
ПОЛНОЕ СОЕДИНЕНИЕ
ДокРасход КАК ДокРасход
ПО

Из этого можно увидеть, что третий запрос соединяет данные из этих двух запросов.

Давайте теперь попытаемся привести запрос к еще более красивому виду. Для этого в результате запроса попытаемся понять какие суммы и количество у нас были приходными, а какие расходными. Для того, чтобы сделать это следует немного изменить текст третьего запроса.

ВЫБРАТЬ
ДокПриход.Номенклатура,
ДокРасход.Номенклатура,




ИЗ
ДокПриход КАК ДокПриход
ПОЛНОЕ СОЕДИНЕНИЕ
ДокРасход КАК ДокРасход
ПО
ДокПриход.Номенклатура = ДокРасход.Номенклатура

В результате мы получим данные по приходу и расходу. Но, у нас все же осталась проблема, связанная с тем, каким образом можно было бы объединить два столбца, «Номенклатура» и «Номенклатура1»? В том случае, если брать значение из столбца «Номенклатура», то мы в итоге так и не получим значение из последней строки, ну а если же брать значение из столбца «Номенклатура1», то не получим в итоге значение из третьей строки. Для этого следует воспользоватся функцией «ЕСТЬNULL».
В итоге запрос будет иметь такой вид:

ВЫБРАТЬ
КАК Номенклатура,
ДокПриход.Количество КАК КолПриход,
ДокПриход.Сумма КАК СумПриход,
ДокРасход.Количество КАК КолРасход,
ДокРасход.Сумма КАК СумРасход
ИЗ
ДокПриход КАК ДокПриход
ПОЛНОЕ СОЕДИНЕНИЕ
ДокРасход КАК ДокРасход
ПО
ДокПриход.Номенклатура = ДокРасход.Номенклатура

При этом может возникнуть еще одна проблема, связанная с тем, каким образом можно было бы заменить значения на числовое ноль? Для этого вам опять придется воспользоватся функцией «ЕСТЬNULL» и написать запрос:

ВЫБРАТЬ
ЕСТЬNULL(ДокПриход.Номенклатура,ДокРасход.Номенклатура)
КАК Номенклатура,
ЕСТЬNULL(ДокПриход.Количество,0) КАК КолПриход,
ЕСТЬNULL(ДокПриход.Сумма,0) КАК СумПриход,
ЕСТЬNULL(ДокРасход.Количество,0) КАК КолРасход,
ЕСТЬNULL(ДокРасход.Сумма,0) КАК СумРасход
ИЗ
ДокПриход КАК ДокПриход
ПОЛНОЕ СОЕДИНЕНИЕ
ДокРасход КАК ДокРасход
ПО
ДокПриход.Номенклатура = ДокРасход.Номенклатура

Пакетный запрос необходим когда запрос слишком сложен, чтобы его сформулировать и заставить работать эффективно. Для того чтобы понять, что такое пакетный запрос можно использовать схемку:

Кстати, пакетные варианты запросов стали доступны только в решении 8.1.11.67.4 – так что вы, возможно, ещё не знаете, как это работает на практике. Если рассказать примитивно, то достаточно создать ряд запросов и соединить их через символ «;». Например:

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

Почему нельзя обойтись без пакетных запросов?

Вкладываем во временную таблицу промежуточный результат, предполагаем использовать его в каких-то следующих запросах. Без наличия функционала временной таблицы, такой промежуточный запрос нужно было бы повторять ещё раз. Если нет знаний о том, как работает пакетный запрос и как им воспользоваться, то можно выполнять один за другим несколько запросов, используя данные вложенных таблиц – так было раньше, теперь не стоит тратить на это время, ведь у нас есть эффективный и простой пакетный запрос в 1С . С ним удобно, уже не надо помнить о том, где должна быть временная таблица. Для минимизации и быстродействия используйте возможности СКД. Система отберёт, отсортирует, разместит. Вот как позиционируют данное новшество сами разработчики популярного и надежного решения.

Анонс пакетных запросов от разработчиков 1С
  • Существенная оптимизация работы программы в целом;
  • Увеличение масштабируемости известного решения;
  • Эффективное быстродействие за счёт внедрения возможностей пакетного размещения;
  • Простое и понятное администрирование системы;
  • Лучшие возможности для интеграции с другими решениями.
Каковы же функциональные возможности запросов в 8.1.11?

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

Алгоритм грамотного создания пакетного запроса

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

Минусы метода

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

В результате имеем таблицу:

Теперь используем пакетный запрос, помним, что нам для этого нужен символ точка с запятой, получаем:

Обратите внимание, 3-ий запрос объединил результаты работы первых двух, смотрим, что получилось:

Теперь постараемся добавить красоты и немного изменим текст для 3-его запроса, вот так:

Теперь у нас вот что получилось:

Осталось объединить столбцы с Номенклатурой, и проставить нули в пустых клетках.