При обновлении конфигурации или изменении состава счетов в плане счетов разработчики и администраторы баз данных могут столкнуться с критической ошибкой реструктуризации базы данных:
«Не удалось вставить значение NULL в столбец "_LineNo", таблицы "..._AccXX_ExtDimYYYNG"; в столбце запрещены значения NULL. Ошибка в INSERT.»
Попытка добавить новый счет вручную или повторить обновление часто приводит к тому же самому сбою. Разберем детально, почему возникает эта ошибка СУБД, как локализовать проблемный объект и устранить неполадку.
Проанализируем механику работы платформы 1С:Предприятие при реструктуризации таблиц:
NG (New Generation) создаются платформой временно в процессе реструктуризации для переноса данных в измененную структуру._AccXX_ExtDimYYY указывает на подчиненную табличную часть видов субконто определенного плана счетов (например, Хозрасчетный). Столбец _LineNo хранит номер строки этой табличной части и имеет строгое ограничение СУБД NOT NULL.INSERT INTO ... SELECT ..., соединяя данные счетов и связанного плана видов характеристик (например, ВидыСубконтоХозрасчетные)._LineNo формируется значение NULL. Это и вызывает падение процесса на уровне SQL-сервера.Такие дубли обычно появляются в результате некорректных обменов через РИБ (когда при ОбменДанными.Загрузка = Истина контроль уникальности платформы отключается), после обновления конфигураций с ручными доработками или при переносе данных между версиями платформ.
Разберем по шагам, как выявить задвоенные виды субконто. Для этого выполним поиск дубликатов по свойству ИмяПредопределенныхДанных в режиме «1С:Предприятие».
Создадим внешнюю обработку или откроем консоль запросов и выполним следующий запрос:
ВЫБРАТЬ
ВидыСубконто.ИмяПредопределенныхДанных КАК Имя,
КОЛИЧЕСТВО(ВидыСубконто.Ссылка) КАК Количество
ИЗ
ПланВидовХарактеристик.ВидыСубконтоХозрасчетные КАК ВидыСубконто
ГДЕ
ВидыСубконто.ИмяПредопределенныхДанных <> ""
СГРУППИРОВАТЬ ПО
ВидыСубконто.ИмяПредопределенныхДанных
ИМЕЮЩИЕ
КОЛИЧЕСТВО(ВидыСубконто.Ссылка) > 1
Если доступ к пользовательскому режиму заблокирован или требуется проверка непосредственно на стороне SQL-сервера, определим имя физической таблицы через функцию ПолучитьСтруктуруХраненияБазыДанных() и выполним запрос в Management Studio:
SELECT _PredefinedID, COUNT(*)
FROM dbo._ChrXXXX
WHERE _PredefinedID <> 0x00000000000000000000000000000000
GROUP BY _PredefinedID
HAVING COUNT(*) > 1;
Рассмотрим, как правильно избавиться от дубля. Стандартными средствами пометить предопределенный элемент на удаление нельзя. Нам необходимо программно снять признак предопределенности с дублирующей записи.
Разберем программный алгоритм исправления:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВидыСубконто.Ссылка КАК Ссылка
|ИЗ
| ПланВидовХарактеристик.ВидыСубконтоХозрасчетные КАК ВидыСубконто
|ГДЕ
| ВидыСубконто.ИмяПредопределенныхДанных = &ИмяДубля";
Запрос.УстановитьПараметр("ИмяДубля", "Контрагенты"); // Указываем найденное имя дубля
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Количество() > 1 Тогда
// Пропускаем первый (оригинальный) элемент, обрабатываем дубли
Выборка.Следующий();
Пока Выборка.Следующий() Цикл
ОбъектСубконто = Выборка.Ссылка.ПолучитьОбъект();
ОбъектСубконто.ИмяПредопределенныхДанных = "";
ОбъектСубконто.Записать();
КонецЦикла;
КонецЕсли;
После очистки реквизита ИмяПредопределенныхДанных дублирующий элемент превращается в обычный пользовательский элемент. Теперь с помощью стандартной обработки «Поиск и удаление дублей» перенаправим все ссылки с дубля на исходный предопределенный элемент и удалим ставший ненужным объект.
Если реструктуризация прерывается при попытке открыть базу или запустить обновление, применим обходной маневр, временно отключив механизм синхронизации предопределенных данных:
Не обновлять автоматически. Также для конкретного объекта метаданных можно использовать метод УстановитьОбновлениеПредопределенныхДанных().Автообновление и еще раз применим изменения в конфигураторе.Таким образом, устранение задвоенных записей в плане видов характеристик восстанавливает целостность связей данных и позволяет успешно завершить обновление плана счетов.