При работе с большими объемами данных в 1С:Предприятие 7.7 стандартные средства выгрузки и загрузки (через XML или текстовые файлы) могут работать крайне медленно. В таких ситуациях программисты часто прибегают к прямому переносу данных на уровне SQL-сервера. Это позволяет значительно сократить время выполнения задачи, но требует глубокого понимания структуры таблиц и механизмов работы платформы. Рассмотрим подробнее, как реализовать этот процесс, с какими трудностями можно столкнуться и как их преодолеть.
В отличие от более современных версий платформы, 1С 7.7 хранит данные в таблицах с неочевидными именами, такими как SC267 или DH104. Чтобы понять, какая таблица соответствует нужному справочнику, проанализируем файл 1cv7.dds, который находится в каталоге базы данных. Этот файл является словарем структуры данных. Открыв его обычным текстовым редактором, мы можем найти описание нужного объекта метаданных. Например, для справочника "Партии" там будет указано соответствие имени таблицы в SQL (например, SC267) и список всех его реквизитов с их внутренними именами (например, SP269, SP270).
Также существуют программные способы получения этих имен внутри самой 1С через объект Метаданные, но при работе напрямую в SQL Server Management Studio (SSMS) файл dds остается самым надежным источником информации.
Для переноса данных из одной базы (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 (инкрементным полем).
Существует два способа решения этой проблемы. Проанализируем каждый из них:
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
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 из таблицы справочника.
Если справочник содержит специфические реквизиты, проанализируем дополнительные таблицы, которые также потребуется перенести:
1SCONST. Чтобы их перенести, нужно отобрать записи, где OBJID соответствует идентификаторам переносимых элементов справочника.1SBLOB. В основной таблице справочника в соответствующем поле хранится лишь ссылка. Если не перенести данные из блоб-таблицы, тексты в новой базе окажутся пустыми.Иногда при выполнении операций или после них база данных может "зависнуть" в однопользовательском режиме (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С:
Это позволит платформе обновить внутренние индексы и гарантирует корректную работу пользователей с новыми данными. Мы разобрали основные этапы и "подводные камни" прямого переноса данных. Помните, что любые действия с SQL-таблицами напрямую должны проводиться только после создания резервной копии базы данных.