Как исправить ошибку SQL при добавлении реквизита в регистр накопления 1С?

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

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

Ошибка SQL: Запись значения NULL в поле, не допускающее NULL '_FLD..._TYPE'

Разберем природу возникновения этой ошибки на уровне платформы и СУБД, а также пошагово рассмотрим способы ее устранения.

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

Проанализируем внутреннее устройство хранения данных платформы 1С:

  1. Хранение составных типов данных: Если реквизит или измерение имеет составной тип (например, ссылка на несколько видов документов или справочников), платформа на уровне SQL создает группу колонок. Среди них обязательной является колонка с суффиксом _TYPE (бинарный дескриптор типа данных), а также поля для конкретных типов (_RTRef, _RRRef, _N, _T и др.). Поле _TYPE имеет ограничение NOT NULL.
  2. Механизм реструктуризации: При добавлении нового поля платформа выполняет реструктуризацию таблицы: создается новая временная таблица и переносятся данные из старой посредством SQL-запроса INSERT INTO ... SELECT ....
  3. Причина сбоя: Если в исходной таблице регистра уже содержалась запись с нарушенной целостностью (где колонка _TYPE для какого-то существующего поля оказалась равной NULL) или при добавлении нового реквизита был случайно включен составной тип, операция массовой вставки завершается ошибкой СУБД.

Шаг 1. Определение проблемного объекта и поля

Выясним, к какому именно реквизиту относится поле, указанное в тексте ошибки (например, _FLD7470). Для этого воспользуемся функцией платформы или SQL-запросом.

В среде 1С для сопоставления полей метаданных и физических таблиц СУБД применим метод ПолучитьСтруктуруХраненияБазыДанных():


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

Также определить проблемную таблицу можно напрямую в Microsoft SQL Server Management Studio:


SELECT TABLE_NAME, COLUMN_NAME 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE COLUMN_NAME LIKE '%_FLD7470%';

Шаг 2. Проверка и исправление некорректных данных

После выявления проблемной таблицы и поля проанализируем строки, вызвавшие ошибку:


SELECT * 
FROM _AccumRg12345 
WHERE _FLD7470_TYPE IS NULL;

Если запрос вернул строки с NULL, необходимо восстановить корректное значение дескриптора типа (например, обновив значение через UPDATE на эталонное бинарное значение дескриптора) либо удалить битые записи, предварительно сделав полную резервную копию базы данных.

Шаг 3. Проверка типов в конфигураторе

Проверим свойства добавляемого реквизита в дереве конфигурации:

  1. Откроем свойства добавленного реквизита (например, ДатаРазмещения).
  2. Убедимся, что для поля выбран строго примитивный тип Дата, а не составной тип с пустыми или лишними флажками.

Шаг 4. Обход через файловый режим

Если прямое исправление данных в SQL затруднено, воспользуемся обходным путем через файловую информационную базу:

  1. Создадим резервную копию и выгрузим информационную базу в файл с расширением .dt.
  2. Загрузим .dt в локальную файловую информационную базу. Встроенная СУБД файлового формата менее жестко обрабатывает ограничения NOT NULL при реструктуризации.
  3. Выполним добавление нужного реквизита в регистр накопления и применим изменения конфигурации (F7).
  4. Запустим процедуру «Тестирование и исправление информационной базы» в режиме «Реструктуризация таблиц информационной базы» и «Проверка логической целостности».
  5. Выгрузим обновленную базу снова в .dt и загрузим обратно на SQL-сервер.

Альтернативное архитектурное решение

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

← На главную