При обслуживании или обновлении конфигурации можно столкнуться с ситуацией, когда проверка или тестирование базы данных аварийно прерывается ошибкой СУБД: «Не удалось вставить значение NULL в столбец "_FldXXXX_TYPE"». При анализе таблицы выясняется, что в регистре сведений появилась поврежденная строка с пустыми полями, датой 1900 года или незаполненными служебными колонками типов. Выясним причину возникновения такой аномалии и подробно разберем по шагам все способы безопасного удаления поврежденной записи.
В платформе 1С:Предприятие для хранения составных типов данных в таблицах СУБД создается не одно поле, а группа колонок. В частности, служебная колонка с суффиксом _TYPE определяет конкретный тип значения (число, строка, ссылка на конкретный справочник или документ). На уровне базы данных на этот столбец всегда накладывается ограничение NOT NULL.
Появление значения NULL в таком поле обычно вызвано следующими факторами:
Главная сложность заключается в том, что стандартный запрос 1С ВЫБРАТЬ или вызов метода Прочитать() у набора записей падает с ошибкой несоответствия типов еще на этапе преобразования данных из СУБД. Прочитать такую запись стандартным кодом невозможно. Разберем эффективные пути решения.
Если в тексте системной ошибки указаны имена таблиц SQL (например, _InfoReg1693NG и _Fld1694_TYPE), первым делом необходимо сопоставить их с реальными метаданными конфигурации. Для этого применим встроенную функцию ПолучитьСтруктуруХраненияБазыДанных().
Посмотрим на пример кода внешней обработки, с помощью которого можно точно узнать имя поврежденного регистра:
СтруктураБД = ПолучитьСтруктуруХраненияБазыДанных();
Для Каждого СтрокаТаблицы Из СтруктураБД Цикл
Если СтрокаТаблицы.ИмяТаблицыХранения = "_InfoReg1693NG" Тогда
Сообщить("Имя регистра: " + СтрокаТаблицы.Имя);
Для Каждого Поле Из СтрокаТаблицы.Поля Цикл
Если Найти(Поле.ИмяПоляХранения, "_Fld1694") > 0 Тогда
Сообщить("Поврежденный реквизит: " + Поле.Имя);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Если регистр сведений подчинен регистратору, то в строке с аномалией часто сохраняется ссылка на документ (либо его можно определить по дате или соседним записям). Попытка прочитать набор вызовет исключение, однако платформа 1С позволяет выполнить запись пустого набора поверх существующих движений без предварительного вычитывания.
Разберем по шагам, как очистить движения поврежденного документа:
Набор = РегистрыСведений.ВашРегистр.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(СсылкаНаДокумент);
// Метод Прочитать() вызывать нельзя, чтобы не получить ошибку маршалинга
Набор.Очистить();
Набор.Записать(Истина);
При выполнении этого кода платформа сформирует прямую команду DELETE по отбору регистратора. После этого документ можно перепровести в обычном режиме. Если регистр независимый, аналогичную процедуру можно провести, установив отбор по ключевым измерениям поврежденной строки.
Если программные средства 1С завершаются ошибкой, а запись не привязана к понятному регистратору, применим прямое удаление аномальной строки через консоль SQL Server Management Studio (SSMS).
Важно: перед выполнением любых прямых запросов к таблицам СУБД обязательно создайте полную резервную копию базы данных!
NULL, либо присутствуют пустые поля в сочетании с датой 1900 года:
SELECT *
FROM dbo._InfoReg1693NG
WHERE _Fld1694_TYPE IS NULL;
DELETE FROM dbo._InfoReg1693NG
WHERE _Fld1694_TYPE IS NULL;
ragent) продолжает хранить старые кэшированные данные. Необходимо остановить службу сервера 1С, очистить каталог сеансовых данных и серверного кэша и запустить службу заново.Если прямое вмешательство в SQL Server нежелательно, воспользуемся штатным инструментом Конфигуратора. Проанализируем правильный порядок действий:
В процессе реструктуризации платформа пересоздает физические таблицы базы данных, перенося валидные строки. Записи, нарушающие целостность типов или содержащие некорректные NULL в служебных столбцах, будут удалены автоматически.