В этой статье разберем ситуацию, когда при работе со стандартной обработкой "Обеспечение потребностей" в "1С:Управление торговлей" система внезапно начинает выдавать невосстановимую ошибку СУБД. Проанализируем причины ее появления и по шагам рассмотрим, как это исправить.
Часто проблема проявляется после обновления конфигурации или незначительных изменений в настройках, сделанных пользователем. Система сообщает об ошибке при выполнении запроса POST, указывая на проблему со стороны MS SQL Server:
Ошибка СУБД:
Microsoft OLE DB Driver for SQL Server: Не удалось привязать составной идентификатор "T3._Fld3555_TYPE".
HRESULT=80040E14, SQLSrvr: SQLSTATE=42S22, native=4104
Эта ошибка означает, что оптимизатор запросов MS SQL Server не смог сопоставить поле из запроса (`T3._Fld3555_TYPE`) ни с одной из таблиц. Давайте выясним, почему платформа 1С генерирует такой "непонятный" для SQL Server запрос и как это исправить.
Корень проблемы, как выяснилось в ходе обсуждения, кроется в использовании одного и того же дополнительного реквизита для нескольких типов документов, особенно когда этот реквизит используется в отборах в сложных отчетах или обработках, построенных на Системе Компоновки Данных (СКД). Обработка "Обеспечение потребностей" — яркий тому пример.
Рассмотрим ситуацию: пользователь создал дополнительный реквизит, например, "Своя дата доставки", и назначил его документу "Заказ клиента". Все работало хорошо. Позже, для унификации, этот же допреквизит был добавлен к другому типу документа, например, "Заявка на возврат товаров от клиента". Как только пользователь попытался использовать отбор по этому "общему" реквизиту в обработке, система сломалась.
Происходит следующее:
LEFT JOIN) с таблицами дополнительных реквизитов каждого типа документа, которому назначен этот реквизит.T1, T2, T3 и т.д.), оптимизатор MS SQL Server "теряет контекст" и не может понять, к какой из таблиц относится то или иное поле. Это и приводит к ошибке "Не удалось привязать составной идентификатор".В ходе отладки был получен упрощенный фрагмент запроса, который вызывал ошибку. Обратите внимание на его структуру:
ВЫБРАТЬ РАЗРЕШЕННЫЕ
null как поле
ИЗ
(ВЫБРАТЬ
0 КАК Поле1) КАК ВложенныйЗапрос
ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаявкаНаВозвратТоваровОтКлиента.ДополнительныеРеквизиты КАК ЗаявкаНаВозвратТоваровОтКлиентаДополнительныеРеквизиты
ПО (ЗаявкаНаВозвратТоваровОтКлиентаДополнительныеРеквизиты.Ссылка = ВЫРАЗИТЬ(NULL КАК Справочник.Назначения).Заказ)
И (ЗаявкаНаВозвратТоваровОтКлиентаДополнительныеРеквизиты.Свойство = &П),
(ВЫБРАТЬ
0 КАК Поле1) КАК ВложенныйЗапрос1
ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказКлиента.ДополнительныеРеквизиты КАК ЗаказКлиентаДополнительныеРеквизиты
ПО (ЗаказКлиентаДополнительныеРеквизиты.Ссылка = ВЫРАЗИТЬ(NULL КАК Справочник.Назначения).Заказ)
И (ЗаказКлиентаДополнительныеРеквизиты.Свойство = &П)
Конструкция ВЫРАЗИТЬ(NULL КАК Справочник.Назначения).Заказ — это пример того, как платформа 1С пытается создать синтаксически корректный, но логически запутанный запрос для унификации условий. Именно эта сложность и вводит в заблуждение оптимизатор SQL Server.
Главное правило: избегайте использования общих дополнительных реквизитов в отборах сложных отчетов и обработок. Даже если реквизиты имеют одинаковый логический смысл, на уровне метаданных они должны быть разными.
Разберем решение по шагам:
НСИ и администрирование -> Общие настройки -> Дополнительные реквизиты и сведения). Найдите ваш реквизит и уберите его назначение для того типа документа, который был добавлен последним и вызвал ошибку. Например, если реквизит изначально был для "Заказа клиента", а потом его добавили к "Заявке на возврат", то у "Заявки на возврат" это назначение нужно убрать.
Этот подход не только решает проблему с ошибкой, но и положительно сказывается на производительности системы, так как генерируемые запросы становятся значительно проще и быстрее выполняются на стороне СУБД.
Таким образом, решением проблемы является не изменение кода конфигурации, а корректировка пользовательских настроек — разделение одного общего дополнительного реквизита на несколько уникальных для каждого типа документа.