При сбое во время обновления платформы, неудачной реструктуризации или аварийном завершении работы службы сервера СУБД в базе данных на SQL Server может очиститься системная таблица _Consts. В архитектуре 1С:Предприятие таблица _Consts хранит значения неколлекционных констант и должна содержать ровно одну служебную строку. Если эта строка исчезает, платформа 1С при запуске системы не может прочитать константы и выдает ошибку, делая дальнейшую работу с базой невозможной.
Рассмотрим причинно-следственные связи этой проблемы и разберем по шагам несколько эффективных способов восстановления структуры и данных таблицы констант.
Выясним, почему база данных теряет единственную строку в таблице констант:
_Consts остаётся созданной, но незаполненной.Так как в таблице _Consts все колонки имеют свойство NOT NULL, попытка ручного создания строки через стандартный запрос INSERT INTO в SQL Management Studio требует заполнения десятков или сотен полей (типа _Fld19032, _Fld19033 и т.д.) корректными значениями по умолчанию. Рассмотрим варианты восстановления базы от простых и безопасных к низкоуровневым.
Если Конфигуратор 1С открывается, наименее трудоемким и самым надежным решением является полная пересборка структуры базы с помощью механизма выгрузки и загрузки файла .dt.
Разберем процесс по шагам:
.dt. Механизм выгрузки извлекает данные объектов и метаданные, не опираясь на наличие строки в таблице _Consts.При загрузке платформой будет автоматически сгенерирована корректная SQL-структура таблиц и инициализирована единственная строка таблицы _Consts со значениями по умолчанию для всех констант.
Если создавать новую базу не требуется, можно заставить платформу 1С воссоздать структуру таблицы констант прямо в существующей базе данных.
Выполним следующие шаги:
.bak).В процессе реструктуризации платформа 1С полностью пересоздаст служебные таблицы бд, сформирует недостающую строку в _Consts и заполнит ее пустыми значениями соответствующих типов.
ПолучитьСтруктуруХраненияБазыДанныхВ ситуациях, когда стандартные механизмы выгрузки сбоят, а в SQL нужно вставить запись с точным соответствием полей, применим комбинированный метод с использованием кода 1С.
Проанализируем этот алгоритм:
.cf) развернем новую пустую базу на SQL Server. В ней сформируется таблица констант с аналоговой структурой полей.ПолучитьСтруктуруХраненияБазыДанных() получим соответствие имен констант и полей SQL в обеих базах данных.Рассмотрим пример кода 1С для выгрузки структуры таблицы констант в массив:
МассивИмен = Новый Массив;
МассивИмен.Добавить("ТаблицаКонстанты");
СтруктураХранения = ПолучитьСтруктуруХраненияБазыДанных(МассивИмен, Истина);
Для Каждого СтрокаТаблицы Из СтруктураХранения Цикл
ПечатьИмениТаблицы = СтрокаТаблицы.ИмяТаблицыХранения;
Для Каждого ПолеИзТаблицы Из СтрокаТаблицы.Поля Цикл
Сообщить("Константа: " + ПолеИзТаблицы.ИмяМетаданных + " -> Поле SQL: " + ПолеИзТаблицы.ИмяПоляХранения);
КонецЦикла;
КонецЦикла;
С помощью полученных данных можно сопоставить имена полей в поврежденной базе и сгенерировать корректный запрос переноса данных из пустой базы в рабочую.
Если в таблице _Consts поврежденной базы отсутствуют записи, но сама структура колонок SQL известна, сформируем строку через T-SQL скрипт в SQL Server Management Studio (SSMS). Скрипт анализирует системные представления sys.columns и подставляет дефолтные значения для всех типов данных:
nvarchar, ntext) — пустая строка ''.numeric, int) — 0.tinyint, binary(1)) — 0 или 0x00.datetime, datetime2) — пустая дата 1С ('2000-01-01').binary(16)) — 0x00000000000000000000000000000000.Рассмотрим пример генерации такого T-SQL скрипта:
DECLARE @TableName NVARCHAR(128) = '_Consts';
DECLARE @Columns NVARCHAR(MAX) = '';
DECLARE @Values NVARCHAR(MAX) = '';
DECLARE @SQL NVARCHAR(MAX);
SELECT
@Columns = @Columns + '[' + c.name + '], ',
@Values = @Values +
CASE
WHEN t.name IN ('nvarchar', 'nchar', 'varchar', 'char', 'text', 'ntext') THEN ''''''
WHEN t.name IN ('int', 'bigint', 'smallint', 'tinyint', 'numeric', 'decimal', 'float', 'real') THEN '0'
WHEN t.name IN ('binary', 'varbinary') THEN
CASE WHEN c.max_length = 16 THEN '0x00000000000000000000000000000000' ELSE '0x00' END
WHEN t.name IN ('datetime', 'datetime2', 'smalldatetime') THEN '''2000-01-01'''
ELSE '0'
END + ', '
FROM sys.columns c
JOIN sys.types t ON c.user_type_id = t.user_type_id
WHERE c.object_id = OBJECT_ID(@TableName);
SET @Columns = LEFT(@Columns, LEN(@Columns) - 1);
SET @Values = LEFT(@Values, LEN(@Values) - 1);
SET @SQL = 'INSERT INTO [dbo].[' + @TableName + '] (' + @Columns + ') VALUES (' + @Values + ')';
EXEC sp_executesql @SQL;
Выполнение данного скрипта создаст необходимую пустую строчку со всеми заполненными NOT NULL полями, что позволит платформе 1С нормально инициализировать базу данных при старте.
Потеря строки в _Consts часто свидетельствует о возможных сопутствующих повреждениях других системных таблиц (например, _Config или таблиц настроек пользователей). После успешного запуска базы данных обязательно проверим ссылочную и логическую целостность в Конфигураторе, а также выполним тестирование целостности базы через утилиту chdbfl.exe (в случае файловых копий) или средствами СУБД DBCC CHECKDB на SQL Server.