Как просто скопировать базу 1С в Microsoft SQL

У клиента нужно было скопировать одну базу 1С Microsoft SQL (trade) в другую (trade_copy_for_testsa). Копировать решил средствами SQL, потому что в базе работали пользователи, да и так было бы быстрее чем через выгрузку в DT.

Задача вроде бы простая, но готового решения не нашел, пришлось пробовать самому и набивать шишки, зато получил готовый скрипт, которым можно будет воспользоваться потом:

  1. DECLARE @SrcDatabaseName AS SYSNAME
  2. DECLARE @DstDatabaseName AS SYSNAME
  3. DECLARE @SrcDatabaseNameLog AS SYSNAME
  4. DECLARE @Backup AS NVARCHAR(MAX)
  5. DECLARE @DstFileBase AS NVARCHAR(MAX)
  6. DECLARE @DstFileLog AS NVARCHAR(MAX)
  7. DECLARE @sqlquery AS NVARCHAR(MAX)
  8. SET @SrcDatabaseName = 'trade' -- Имя исходной базы
  9. SET @DstDatabaseName = 'trade_copy_for_testsa' -- Имя базы-получателя
  10. SET @Backup = 'X:\Tranzit\' + @SrcDatabaseName + '.bak' -- Куда записывать архив (файл)
  11. SET @DstFileBase = 'X:\SQLDATA\Data\' + @DstDatabaseName + '.mdf' -- Размещение файла базы-получателя
  12. SET @DstFileLog = 'C:\SQLDATA\' + @DstDatabaseName + '_log.ldf' -- Размещение файла лога-получателя
  13. SET @SrcDatabaseNameLog = @SrcDatabaseName + '_log' -- вычисляется имя файла лога базы-источника
  14. -- BACKUP DATABASE @SrcDatabaseName TO DISK = @Backup WITH INIT, FORMAT, STATS = 1, CHECKSUM, COMPRESSION
  15. SET @sqlquery = 'ALTER DATABASE [' + @DstDatabaseName + '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE'
  16. EXEC sp_executesql @sqlquery -- Переводит в режим одного пользователя
  17. RESTORE DATABASE @DstDatabaseName
  18. FROM DISK = @Backup
  19. WITH RECOVERY, REPLACE,
  20. MOVE @SrcDatabaseName TO @DstFileBase,
  21. MOVE @SrcDatabaseNameLog TO @DstFileLog
  22. SET @sqlquery = 'ALTER DATABASE [' + @DstDatabaseName + '] SET MULTI_USER'
  23. EXEC sp_executesql @sqlquery -- Переводит в режим многих пользователей

Внимание! BACKUP тут закомментирован. Для того, чтобы он прошел, уберите два дефиса в строке 18.

Скрипт не идеален. Пути к файлам базы, можно получать из самой базы, да и расчитан он только на базы из двух файлов — базы и лога транзакций. Но таких баз большинство.

Также каталог файлов должен быть одинаков у базы источника и получателя.

Пути к файлам тоже можно было бы прописать отдельно в шапке.

Если будут советы по улучшению скрипта, пишите.

Работает так:

О причине, почему использую режим Recovery при восстановлении можно почитать тут. В общем, он отсекает не завершенные транзакции, потому что иначе база оставалась в статусе «Восстанавливается».

Я пробовал лечить такое состояние кодом:

RESTORE DATABASE [earnings] WITH RECOVERY

База уходила из состояния «Восстанавливается», но в 1С при попытке открыть выдавала ошибку: «невосстановимая ошибка ошибка при выполнении запроса post к ресурсу /e1cib/login: по причине Ошибка СУБД Invalid column name ‘Partno'»:

И лечилось это только удалением базы и созданием ее заново. Так что нужно быть внимательным в опциях. Также пришлось повозиться с отключением сеансов и обратным переводом в мульти-пользовательский режим. Хотя в копии никто и не работал и регламентные задания были выключены, видимо сам сервер 1С создавал SQL-подключение.

Объем: 2 час.