В процессе администрирования или восстановления баз данных 1С:Предприятие 7.7 возникают ситуации, когда необходимо сравнить физическую структуру таблиц в двух разных SQL-базах. Это особенно актуально, если отсутствуют файлы конфигурации .md и словаря данных .dds, а базы имеют расхождения в длине реквизитов или составе полей. Разберем детально, как с помощью SQL-запросов выявить все отличия в структурах таблиц.
Самый быстрый и универсальный способ получить информацию о колонках таблицы — это обращение к стандартизированному системному представлению INFORMATION_SCHEMA.COLUMNS. Оно содержит данные о именах полей, типах данных, их максимальной длине и точности. Рассмотрим ситуацию на примере таблицы справочника SC172.
Для начала проанализируем структуру в каждой базе по отдельности, выполнив простой запрос:
SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'SC172'
ORDER BY COLUMN_NAME;
Однако ручное сравнение результатов двух запросов неудобно и чревато ошибками. Чтобы автоматизировать процесс и увидеть только различия, воспользуемся объединением таблиц из разных баз данных (при условии, что они находятся на одном сервере или связаны через Linked Server).
Проанализируем ситуацию, когда нам нужно найти расхождения: где поле есть в одной базе, но нет в другой, или где отличаются типы и размеры данных. Для этого идеально подходит тип соединения FULL OUTER JOIN. Выполним следующий запрос, заменив Base1 и Base2 на актуальные имена ваших баз данных:
SELECT
ISNULL(t1.COLUMN_NAME, t2.COLUMN_NAME) AS [Имя поля],
t1.DATA_TYPE AS [Тип База1],
t2.DATA_TYPE AS [Тип База2],
t1.CHARACTER_MAXIMUM_LENGTH AS [Длина База1],
t2.CHARACTER_MAXIMUM_LENGTH AS [Длина База2],
t1.NUMERIC_PRECISION AS [Точность База1],
t2.NUMERIC_PRECISION AS [Точность База2]
FROM Base1.INFORMATION_SCHEMA.COLUMNS AS t1
FULL OUTER JOIN Base2.INFORMATION_SCHEMA.COLUMNS AS t2
ON t1.TABLE_NAME = t2.TABLE_NAME
AND t1.COLUMN_NAME = t2.COLUMN_NAME
WHERE (t1.TABLE_NAME = 'SC172' OR t2.TABLE_NAME = 'SC172')
AND (
t1.DATA_TYPE <> t2.DATA_TYPE
OR t1.CHARACTER_MAXIMUM_LENGTH <> t2.CHARACTER_MAXIMUM_LENGTH
OR t1.NUMERIC_PRECISION <> t2.NUMERIC_PRECISION
OR t1.COLUMN_NAME IS NULL
OR t2.COLUMN_NAME IS NULL
);
Разберем, что делает этот код. Мы выбираем данные из первой базы и пытаемся сопоставить их с данными из второй по имени таблицы и имени колонки. Если в одной из баз поле отсутствует или имеет другие характеристики (длина, тип), запрос выведет эту строку. Условие IS NULL в блоке WHERE позволяет увидеть поля, которые существуют только в одной из баз.
Хотя INFORMATION_SCHEMA удобна, она не всегда отображает специфические для MS SQL Server параметры, такие как признак is_nullable или детальные свойства пользовательских типов данных. В 1С 7.7 это критично, так как движок программы жестко завязан на определенные параметры SQL. Рассмотрим более продвинутый вариант запроса:
SELECT
o1.name AS TableName,
c1.name AS ColumnName,
typ1.name AS DataType_B1,
c1.max_length AS MaxLen_B1,
c1.precision AS Prec_B1,
typ2.name AS DataType_B2,
c2.max_length AS MaxLen_B2,
c2.precision AS Prec_B2
FROM Base1.sys.columns c1
JOIN Base1.sys.objects o1 ON c1.object_id = o1.object_id
JOIN Base1.sys.types typ1 ON c1.user_type_id = typ1.user_type_id
FULL OUTER JOIN (
SELECT c2.name, o2.name AS table_name, typ2.name AS type_name, c2.max_length, c2.precision
FROM Base2.sys.columns c2
JOIN Base2.sys.objects o2 ON c2.object_id = o2.object_id
JOIN Base2.sys.types typ2 ON c2.user_type_id = typ2.user_type_id
) AS t2 ON o1.name = t2.table_name AND c1.name = t2.name
WHERE o1.name = 'SC172'
AND (c1.max_length <> t2.max_length OR c1.precision <> t2.precision OR t2.name IS NULL);
Важный момент для 1С 7.7: Обратите внимание на поля типа CHAR. В 1С идентификаторы объектов (ID) имеют длину 9 или 13 символов. Если при сравнении вы обнаружите разницу даже в один символ (например, CHAR(9) против CHAR(10)), база не сможет корректно работать с типовым исполняемым файлом 1С, так как он ожидает строго определенную структуру.
Для восстановления работоспособности базы недостаточно просто иметь одинаковый набор полей. 1С 7.7 активно использует индексы для поиска и сортировки. Если состав индексов различается, система может выдавать ошибки при проведении документов или работать крайне медленно. Проверить индексы можно следующим образом:
sys.indexes.sys.index_columns.Выясним причину расхождений: часто индексы пропадают при некорректном прерывании процесса «Тестирования и исправления» или при ручных манипуляциях с базой в SQL Server Management Studio.
Если ваша конечная цель — восстановление файла .md, то после приведения SQL-структуры в соответствие с «эталонной» базой, выполните следующие шаги:
.md файл (например, от той же версии типовой конфигурации)..dds.Помните, что любые изменения структуры таблиц напрямую через SQL (команды ALTER TABLE) следует проводить только после создания полной резервной копии базы данных. Совместное использование SQL-запросов и штатных средств 1С позволяет восстановить работоспособность системы даже в самых сложных случаях потери метаданных.