При анализе готовых отчетов, динамических списков или типовых конфигураций разработчики часто сталкиваются с конструкциями запросов, заключенными в фигурные скобки {...}. Попытка скопировать такой запрос в консоль запросов или выполнить его обычным объектом Запрос нередко вызывает вопросы: откуда берутся эти скобки, какую роль они играют и как их правильно убрать или настроить через конструктор запроса. Разберем детально назначение этого синтаксиса и особенности его поведения.
Символы фигурных скобок {...} представляют собой синтаксис расширения языка запросов платформы 1С:Предприятие. Данный механизм используется такими подсистемами и объектами платформы, как:
Когда фигурные скобки обрамляют предложение соединения, например:
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций.СрезПоследних(...) КАК РаботникиОрганизации
ПО ШтатноеРасписаниеОрганизаций.Должность = РаботникиОрганизации.Должность
И ШтатноеРасписаниеОрганизаций.ПодразделениеОрганизации = РаботникиОрганизации.ПодразделениеОрганизации}
это указывает платформе, что таблица РаботникиОрганизации является необязательной. Если в настройках отчета или списка пользователь не выбирает ни одного поля из этой таблицы, не накладывает по ней отбор и не сортирует по ней данные, платформа исключает всю секцию соединения из итогового SQL-запроса, отправляемого в СУБД. Это ускоряет выполнение запроса и снижает нагрузку на сервер баз данных.
Кроме того, данный механизм используется для управления правами доступа на уровне записей и метаданных (RLS): если у пользователя нет прав на чтение необязательной таблицы, но поля из нее не выводятся в отчет, отчет выполнится без ошибки нарушения прав.
Проанализируем практические способы управления фигурными скобками в запросе в зависимости от стоящей задачи.
Если текст запроса редактируется в конфигураторе или в конструкторе запроса СКД, управлять скобками можно интерактивно:
РаботникиОрганизации).ЛЕВОЕ СОЕДИНЕНИЕ.Если запрос переносится в модуль для выполнения через объект Запрос и динамическая оптимизация СКД не требуется, фигурные скобки вокруг соединения можно удалить вручную в текстовом редакторе. Соединение останется частью запроса и будет выполняться безусловно:
// Было:
// {ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций.СрезПоследних(...) КАК РаботникиОрганизации ПО ...}
// Стало:
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций.СрезПоследних(КОНЕЦПЕРИОДА(КОНЕЦПЕРИОДА(&Период, МЕСЯЦ), МЕСЯЦ), ) КАК РаботникиОрганизации
ПО ШтатноеРасписаниеОрганизаций.Должность = РаботникиОрганизации.Должность
И ШтатноеРасписаниеОрганизаций.ПодразделениеОрганизации = РаботникиОрганизации.ПодразделениеОрганизации
Посмотрим, что происходит, если выполнить запрос с фигурными скобками через стандартный Запрос во встроенном языке без предварительного удаления скобок:
{ЛЕВОЕ СОЕДИНЕНИЕ ...} парсером стандартного запроса воспринимается как обычное соединение. Платформа просто игнорирует фигурные скобки и выполняет всё, что находится внутри них, как обязательную часть запроса.{ВЫБРАТЬ ...}, {ГДЕ ...}, {УПОРЯДОЧИТЬ ПО ...} и {ХАРАКТЕРИСТИКИ ...} объектом Запрос игнорируются вместе со всем их содержимым. Если условие или параметр были объявлены исключительно внутри {ГДЕ ...}, в обычном запросе они учитываться не будут.Разберем типичную ошибку проектирования запроса, встречающуюся на практике. Посмотрим на фрагмент исходного запроса:
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций.СрезПоследних(...) КАК РаботникиОрганизации
ПО ШтатноеРасписаниеОрганизаций.Должность = РаботникиОрганизации.Должность}
ГДЕ
НЕ РаботникиОрганизации.Сотрудник ЕСТЬ NULL
В данном случае соединение заключено в фигурные скобки как необязательное, однако в блоке ГДЕ присутствует жесткое условие на поле РаботникиОрганизации.Сотрудник без обрамления в фигурные скобки. В результате:
НЕ ... ЕСТЬ NULL в секции ГДЕ фактически превращает левое соединение во внутреннее (ВНУТРЕННЕЕ СОЕДИНЕНИЕ), отсекая все записи первой таблицы, не нашедшие соответствия во второй.Для сохранения корректной логики СКД условие на поле необязательной таблицы также должно помещаться в фигурные скобки: {ГДЕ (НЕ РаботникиОрганизации.Сотрудник ЕСТЬ NULL)}, либо условие должно переноситься в секцию ПО самого соединения.
При работе с несколькими связанными необязательными таблицами обратим внимание на свойство Номер группы на вкладке «Компоновка данных» в конструкторе запроса:
Если необходимо получить чистый результирующий текст запроса, сформированный схемой компоновки для СУБД с учетом примененных настроек пользователя, выполним штатную процедуру компоновки макета через объекты встроенного языка:
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиКомпоновкиДанных,,, Тип("ГенераторМакетаКомпоновкиДанных"));
Для Каждого НаборДанных Из МакетКомпоновки.НаборыДанных Цикл
Если ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Тогда
ТекстЧистогоЗапроса = НаборДанных.Запрос;
КонецЕсли;
КонецЦикла;
В полученном значении ТекстЧистогоЗапроса фигурные скобки будут полностью раскрыты платформой: неиспользуемые соединения и условия отброшены, а нужные поля подставлены в тело запроса.