При работе в клиент-серверном варианте 1С:Предприятия под управлением Microsoft SQL Server пользователи и разработчики могут столкнуться с аварийным завершением операции и системным сообщением: «Microsoft SQL Native Client: Символьные или двоичные данные могут быть усечены. HRESULT=80040E57, SQLSrvr: SQLSTATE=22001, native=8152». Чаще всего подобный сбой происходит при формировании печатных форм (например, Заявки на кассовый расход в БГУ), проведении документов или формировании сложных отчетов. Разберем подробно механику возникновения этой ошибки, способы ее локализации и варианты устранения.
Выясним причину такого поведения СУБД. Ошибка SQLSTATE=22001 (native=8152) (в англоязычной версии — «String or binary data would be truncated») означает, что сервер баз данных пытается записать строковое или двоичное значение в поле таблицы, максимальная длина которого меньше фактического размера записываемых данных.
В контексте платформы 1С:Предприятие это чаще всего происходит в следующих сценариях:
tempdb). Если в первой ветке конструкции ОБЪЕДИНИТЬ ВСЕ длина строкового поля оказалась короткой или сформировалась пустая строка, СУБД жестко фиксирует тип колонки как VARCHAR(N) с малой длиной. При попытке поместить данные из последующих веток, где текст длиннее, сервер выдает исключение.ВЫРАЗИТЬ(Поле КАК СТРОКА(N)), платформа может передать в SQL-сервер некорректную декларацию типа временной таблицы.Проанализируем выполнение кода с помощью отладчика платформы 1С:Предприятие. Для этого выполним следующие действия:
Печать() или СформироватьПечатнуюФорму()).Запрос.УстановитьПараметр(), чтобы выявить проблемное поле.По умолчанию MS SQL Server при ошибке 8152 не сообщает, какое именно поле вызвало сбой. Однако в СУБД можно включить расширенную диагностику.
Если используется MS SQL Server 2016 SP2 CU6, MS SQL Server 2017 CU12 или более новые версии, выполним в SQL Server Management Studio (SSMS) команду включения флага трассировки:
DBCC TRACEON(460, -1);
После включения этого флага (или на MS SQL Server 2019 по умолчанию) сервер будет возвращать ошибку с кодом 2628, в тексте которой прямо указывается имя базы данных, целевая таблица (или временная таблица #tt...), имя проблемной колонки и значение строки, которое было усечено.
Если ошибка возникает только на одном конкретном документе (а другие документы того же вида печатаются без сбоев), причина кроется в пользовательских данных. Разберем по шагам, как найти проблемное значение:
Если ошибка вызвана недоработкой типового алгоритма печати во временную таблицу, исправим текст проблемного запроса. Рассмотрим пример, где объединяются две таблицы, и в первой ветке строка не имеет явного ограничения длины:
ВЫБРАТЬ
Документ.Ссылка КАК Ссылка,
ВЫРАЗИТЬ(Документ.НазначениеПлатежа КАК СТРОКА(1000)) КАК НазначениеПлатежа,
Документ.Сумма КАК Сумма
ПОМЕСТИТЬ ВТ_ДанныеПечати
ИЗ
Документ.ЗаявкаНаКассовыйРасход КАК Документ
ГДЕ
Документ.Ссылка = &Ссылка
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
Документ.Ссылка,
ВЫРАЗИТЬ(Документ.СодержаниеОперации КАК СТРОКА(1000)),
Документ.Сумма
ИЗ
Документ.ЗаявкаНаКассовыйРасход.Расшифровка КАК Документ
ГДЕ
Документ.Ссылка = &Ссылка
Обратим внимание: явное указание конструкции ВЫРАЗИТЬ(Поле КАК СТРОКА(N)) гарантирует, что СУБД выделит в структуре временной таблицы достаточное количество байт для хранения длинного текста во всех объединяемых выборках.
Если ошибка имеет системный характер после некорректного обновления или сбоя метаданных:
%LocalAppData%\1C\1cv8\ и %AppData%\1C\1cv8\) либо переподключим информационную базу в списке запуска.