Как перенести справочник 1С 7.7 между базами данных на уровне SQL

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При работе с большими объемами данных в 1С:Предприятие 7.7 стандартные средства выгрузки и загрузки (через XML или текстовые файлы) могут работать крайне медленно. В таких ситуациях программисты часто прибегают к прямому переносу данных на уровне SQL-сервера. Это позволяет значительно сократить время выполнения задачи, но требует глубокого понимания структуры таблиц и механизмов работы платформы. Рассмотрим подробнее, как реализовать этот процесс, с какими трудностями можно столкнуться и как их преодолеть.

Определение имен таблиц и структуры данных

В отличие от более современных версий платформы, 1С 7.7 хранит данные в таблицах с неочевидными именами, такими как SC267 или DH104. Чтобы понять, какая таблица соответствует нужному справочнику, проанализируем файл 1cv7.dds, который находится в каталоге базы данных. Этот файл является словарем структуры данных. Открыв его обычным текстовым редактором, мы можем найти описание нужного объекта метаданных. Например, для справочника "Партии" там будет указано соответствие имени таблицы в SQL (например, SC267) и список всех его реквизитов с их внутренними именами (например, SP269, SP270).

Также существуют программные способы получения этих имен внутри самой 1С через объект Метаданные, но при работе напрямую в SQL Server Management Studio (SSMS) файл dds остается самым надежным источником информации.

Перенос данных с помощью SQL-запроса

Для переноса данных из одной базы (DB1) в другую (DB2) мы можем использовать конструкцию INSERT INTO ... SELECT. Разберем типичную ситуацию на примере справочника. Предположим, нам нужно перенести данные таблицы SC267. Посмотрим на пример запроса, который может вызвать ошибку:


INSERT INTO DB2.dbo.SC267 (ROW_ID, ID, PARENTID, CODE, DESCR, ISMARK, SP269, SP270)
SELECT ROW_ID, ID, PARENTID, CODE, DESCR, ISMARK, SP269, SP270
FROM DB1.dbo.SC267

При выполнении такого запроса SQL Server, скорее всего, выдаст ошибку: "Невозможно вставить явное значение для столбца идентификаторов в таблице, когда параметр IDENTITY_INSERT имеет значение OFF". Это происходит из-за поля ROW_ID, которое является автоматическим счетчиком в SQL (инкрементным полем).

Решение проблемы IDENTITY_INSERT

Существует два способа решения этой проблемы. Проанализируем каждый из них:

  1. Исключение столбца ROW_ID: Мы можем просто не указывать поле ROW_ID в списке полей для вставки. В этом случае SQL Server сам сгенерирует новые значения для целевой таблицы. Это безопасно, так как 1С 7.7 не использует ROW_ID для связи между объектами (связи строятся на поле ID).
    
    INSERT INTO DB2.dbo.SC267 (ID, PARENTID, CODE, DESCR, ISMARK, SP269)
    SELECT ID, PARENTID, CODE, DESCR, ISMARK, SP269
    FROM DB1.dbo.SC267
    
  2. Включение IDENTITY_INSERT: Если по какой-то причине нам важно сохранить оригинальные значения ROW_ID, мы должны разрешить прямую вставку в это поле.
    
    SET IDENTITY_INSERT DB2.dbo.SC267 ON;
    
    INSERT INTO DB2.dbo.SC267 (ROW_ID, ID, PARENTID, CODE, DESCR, ISMARK, SP269)
    SELECT ROW_ID, ID, PARENTID, CODE, DESCR, ISMARK, SP269
    FROM DB1.dbo.SC267;
    
    SET IDENTITY_INSERT DB2.dbo.SC267 OFF;
    

Обеспечение уникальности и целостности данных

Перенос строк таблицы — это только половина дела. В 1С 7.7 критически важно следить за уникальностью идентификаторов объектов (поле ID). Выясним основные правила:

Конфликты ID: Идентификаторы в 1С 7.7 — это строки из 6 или 9 символов в 36-ричной системе. Если в целевой базе уже есть данные, необходимо убедиться, что вставляемые ID не дублируются. Проверить это можно простым запросом SELECT с условием IN или EXISTS.

Обновление счетчика в _1SSYSTEM: В системной таблице _1SSYSTEM хранятся последние использованные идентификаторы для всех типов объектов. Если вы добавили записи вручную, 1С не "увидит" этого изменения автоматически. При попытке пользователя создать новый элемент в интерфейсе программа попытается использовать старый ID и выдаст ошибку "Код не уникален". После вставки записей через SQL необходимо вручную обновить соответствующее значение в _1SSYSTEM, установив там максимальное значение ID из таблицы справочника.

Работа со сложными типами данных

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

Устранение блокировок и монопольного режима

Иногда при выполнении операций или после них база данных может "зависнуть" в однопользовательском режиме (Single User Mode), и 1С перестанет запускаться. Рассмотрим, как решить эту проблему без перезагрузки всего SQL-сервера.

Выясним, какой процесс занимает базу данных, используя запрос:

SELECT spid FROM master.dbo.sysprocesses WHERE dbid = DB_ID('Имя_Вашей_Базы')

После получения spid (ID процесса), его можно завершить командой KILL [номер_процесса]. Однако более эффективным и быстрым способом перевода базы в обычный режим является следующий скрипт:

ALTER DATABASE [Имя_Вашей_Базы] SET MULTI_USER WITH ROLLBACK IMMEDIATE;

Команда ROLLBACK IMMEDIATE принудительно прерывает все активные транзакции и отключает пользователей, что позволяет мгновенно вернуть базу в многопользовательский режим.

Завершение переноса

После завершения всех операций в SQL Server крайне рекомендуется выполнить следующие действия в конфигураторе 1С:

  1. Запустите "Тестирование и исправление ИБ".
  2. Выберите пункты "Проверка логической целостности" и "Пересчет служебных таблиц".

Это позволит платформе обновить внутренние индексы и гарантирует корректную работу пользователей с новыми данными. Мы разобрали основные этапы и "подводные камни" прямого переноса данных. Помните, что любые действия с SQL-таблицами напрямую должны проводиться только после создания резервной копии базы данных.

← На главную