Как удалить аномальную запись со значением NULL из регистра сведений 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При обслуживании или обновлении конфигурации можно столкнуться с ситуацией, когда проверка или тестирование базы данных аварийно прерывается ошибкой СУБД: «Не удалось вставить значение NULL в столбец "_FldXXXX_TYPE"». При анализе таблицы выясняется, что в регистре сведений появилась поврежденная строка с пустыми полями, датой 1900 года или незаполненными служебными колонками типов. Выясним причину возникновения такой аномалии и подробно разберем по шагам все способы безопасного удаления поврежденной записи.

Почему возникает ошибка со столбцом _TYPE

В платформе 1С:Предприятие для хранения составных типов данных в таблицах СУБД создается не одно поле, а группа колонок. В частности, служебная колонка с суффиксом _TYPE определяет конкретный тип значения (число, строка, ссылка на конкретный справочник или документ). На уровне базы данных на этот столбец всегда накладывается ограничение NOT NULL.

Появление значения NULL в таком поле обычно вызвано следующими факторами:

  1. Аварийное прерывание реструктуризации: если при изменении состава типов реквизита процесс обновления прервался (отключение электропитания, аварийная остановка службы сервера 1С или СУБД), часть записей успевает модифицироваться с нарушением структуры.
  2. Сбои транзакций на уровне СУБД: некорректное завершение фоновых заданий или аварийный перезапуск сервера во время записи набора.
  3. Некорректная интеграция: прямое внесение изменений в таблицы базы сторонними скриптами в обход платформенного объектного API.

Главная сложность заключается в том, что стандартный запрос 1С ВЫБРАТЬ или вызов метода Прочитать() у набора записей падает с ошибкой несоответствия типов еще на этапе преобразования данных из СУБД. Прочитать такую запись стандартным кодом невозможно. Разберем эффективные пути решения.

Способ 1. Определение метаданных через встроенный язык

Если в тексте системной ошибки указаны имена таблиц SQL (например, _InfoReg1693NG и _Fld1694_TYPE), первым делом необходимо сопоставить их с реальными метаданными конфигурации. Для этого применим встроенную функцию ПолучитьСтруктуруХраненияБазыДанных().

Посмотрим на пример кода внешней обработки, с помощью которого можно точно узнать имя поврежденного регистра:


СтруктураБД = ПолучитьСтруктуруХраненияБазыДанных();
Для Каждого СтрокаТаблицы Из СтруктураБД Цикл
    Если СтрокаТаблицы.ИмяТаблицыХранения = "_InfoReg1693NG" Тогда
        Сообщить("Имя регистра: " + СтрокаТаблицы.Имя);
        Для Каждого Поле Из СтрокаТаблицы.Поля Цикл
            Если Найти(Поле.ИмяПоляХранения, "_Fld1694") > 0 Тогда
                Сообщить("Поврежденный реквизит: " + Поле.Имя);
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
КонецЦикла;

Способ 2. Перезапись через пустой набор записей (без чтения)

Если регистр сведений подчинен регистратору, то в строке с аномалией часто сохраняется ссылка на документ (либо его можно определить по дате или соседним записям). Попытка прочитать набор вызовет исключение, однако платформа 1С позволяет выполнить запись пустого набора поверх существующих движений без предварительного вычитывания.

Разберем по шагам, как очистить движения поврежденного документа:


Набор = РегистрыСведений.ВашРегистр.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(СсылкаНаДокумент);
// Метод Прочитать() вызывать нельзя, чтобы не получить ошибку маршалинга
Набор.Очистить();
Набор.Записать(Истина);

При выполнении этого кода платформа сформирует прямую команду DELETE по отбору регистратора. После этого документ можно перепровести в обычном режиме. Если регистр независимый, аналогичную процедуру можно провести, установив отбор по ключевым измерениям поврежденной строки.

Способ 3. Прямое удаление записи средствами Microsoft SQL Server

Если программные средства 1С завершаются ошибкой, а запись не привязана к понятному регистратору, применим прямое удаление аномальной строки через консоль SQL Server Management Studio (SSMS).

Важно: перед выполнением любых прямых запросов к таблицам СУБД обязательно создайте полную резервную копию базы данных!

  1. Открываем Management Studio и создаем новый запрос к нужной базе данных.
  2. Находим поврежденную запись, в которой колонка типа содержит NULL, либо присутствуют пустые поля в сочетании с датой 1900 года:

SELECT * 
FROM dbo._InfoReg1693NG 
WHERE _Fld1694_TYPE IS NULL;
  1. Убедившись, что запрос возвращает исключительно дефектную строку, выполняем ее удаление:

DELETE FROM dbo._InfoReg1693NG 
WHERE _Fld1694_TYPE IS NULL;
  1. Очищаем кэш сервера 1С: после прямого вмешательства в базу данных СУБД служба сервера 1С:Предприятия (ragent) продолжает хранить старые кэшированные данные. Необходимо остановить службу сервера 1С, очистить каталог сеансовых данных и серверного кэша и запустить службу заново.

Способ 4. Тестирование и исправление информационной базы

Если прямое вмешательство в SQL Server нежелательно, воспользуемся штатным инструментом Конфигуратора. Проанализируем правильный порядок действий:

  1. Запустим 1С в режиме Конфигуратор монопольно (предварительно завершив все сеансы пользователей).
  2. Откроем пункт меню Администрирование > Тестирование и исправление...
  3. Установим флажки напротив пунктов «Проверка логической целостности» и «Реструктуризация таблиц информационной базы».
  4. В переключателях обработки ссылочной целостности укажем «Очищать ссылки», а при частичной потере данных — «Удалять записи».
  5. Запустим выполнение процедуры.

В процессе реструктуризации платформа пересоздает физические таблицы базы данных, перенося валидные строки. Записи, нарушающие целостность типов или содержащие некорректные NULL в служебных столбцах, будут удалены автоматически.

← На главную