При работе с крупными конфигурациями (например, 1С:Управление производственным предприятием) пользователи и разработчики могут столкнуться со следующей технической ошибкой при формировании отчетов:
«Ошибка выполнения запроса. Построенный запрос к СУБД использует слишком много таблиц. Допустимо не более 256. Microsoft SQL Native Client: Too many table names in the query. The maximum allowable is 256.»
Интересной особенностью данной проблемы является то, что отчет может успешно работать долгое время, а затем внезапно перестать формироваться без каких-либо изменений в конфигурации или правах доступа. Проанализируем технические причины такого поведения и разберем практические варианты решения задачи.
Рассмотрим детально, из-за чего формируемый платформой SQL-запрос превышает допустимый лимит СУБД в 256 таблиц:
ДокументРасчетовСКонтрагентом), и происходит разворачивание его реквизита через точку (ДокументРасчетовСКонтрагентом.Подразделение), платформа 1С строит левые соединения (LEFT JOIN) со всеми физическими таблицами документов, входящих в данный составной тип и имеющих указанный реквизит. Если составной тип включает в себя десятки видов документов, количество соединений в итоговом SQL-запросе стремительно растет.SELECT составляет 256. При превышении этого порога драйвер взаимодействия генерирует исключение.Ключевым множителем количества таблиц в запросе выступает механизм RLS (Record Level Security). Рассмотрим, как он влияет на итоговый SQL-скрипт:
Если для текущего пользователя включено ограничение прав на уровне записей (например, по подразделениям, организациям или контрагентам), платформа 1С добавляет дополнительные подзапросы и соединения с таблицами прав к каждой подсоединенной таблице из составного типа.
Таким образом, если тип ДокументРасчетовСКонтрагентом состоит из 30 разных видов документов, а условие RLS требует присоединить по 5-8 служебных таблиц прав к каждому документу, итоговое количество таблиц в транслируемом SQL-запросе легко превышает порог в 256 штук.
Разберем по шагам, какими способами можно устранить данную проблему в зависимости от имеющегося доступа к конфигурации и типа отчета.
Самый быстрый способ восстановить работоспособность отчета на стороне пользователя — избавить построитель отчета от необходимости разворачивать составной тип:
ДокументРасчетовСКонтрагентом.Подразделение.Подразделение присутствует непосредственно в регистре накопления взаиморасчетов).Если вы разрабатываете собственный отчет или дорабатываете запрос в конфигураторе, всегда явно приводите составной тип к конкретному источнику с помощью функции ВЫРАЗИТЬ. Это исключает присоединение лишних таблиц СУБД.
Рассмотрим пример кода:
// Неправильно: обращение через точку к составному типу присоединяет десятки таблиц
Запрос.Текст = "
|ВЫБРАТЬ
| Взаиморасчеты.ДокументРасчетов.Подразделение КАК Подразделение,
| Взаиморасчеты.СуммаОстаток КАК Сумма
|ИЗ
| РегистрНакопления.ВзаиморасчетыСКонтрагентами.Остатки КАК Взаиморасчеты";
// Правильно: явное ограничение типа выбираемого документа
Запрос.Текст = "
|ВЫБРАТЬ
| ВЫРАЗИТЬ(Взаиморасчеты.ДокументРасчетов КАК Документ.РеализацияТоваровУслуг).Подразделение КАК Подразделение,
| Взаиморасчеты.СуммаОстаток КАК Сумма
|ИЗ
| РегистрНакопления.ВзаиморасчетыСКонтрагентами.Остатки КАК Взаиморасчеты";
Для сложных отчетов эффективным решением является разбиение одного крупного запроса на несколько этапов с применением временных таблиц:
Посмотрим на пример использования временной таблицы:
Запрос.Текст = "
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| Взаиморасчеты.ДокументРасчетов КАК ДокументРасчетов
|ПОМЕСТИТЬ ВТ_Документы
|ИЗ
| РегистрНакопления.ВзаиморасчетыСКонтрагентами КАК Взаиморасчеты
|;
|
|ВЫБРАТЬ
| ВТ.ДокументРасчетов КАК ДокументРасчетов,
| Реализация.Подразделение КАК Подразделение
|ИЗ
| ВТ_Документы КАК ВТ
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК Реализация
| ПО ВТ.ДокументРасчетов = Реализация.Ссылка";
Старые отчеты, построенные на объекте ПостроительОтчета (например, Универсальный отчет в УПП 1.3), генерируют менее оптимальные SQL-запросы при работе с составными полями. Перевод отчета на Систему компоновки данных (СКД) позволяет оптимизатору 1С более интеллектуально управлять соединениями и автоматически отсекать неиспользуемые таблицы метаданных при формировании итогового отчета.