Как просто скопировать базу 1С в Microsoft SQL
У клиента нужно было скопировать одну базу 1С Microsoft SQL (trade) в другую (trade_copy_for_testsa). Копировать решил средствами SQL, потому что в базе работали пользователи, да и так было бы быстрее чем через выгрузку в DT.
Задача вроде бы простая, но готового решения не нашел, пришлось пробовать самому и набивать шишки, зато получил готовый скрипт, которым можно будет воспользоваться потом:
- DECLARE @SrcDatabaseName AS SYSNAME
- DECLARE @DstDatabaseName AS SYSNAME
- DECLARE @SrcDatabaseNameLog AS SYSNAME
- DECLARE @Backup AS NVARCHAR(MAX)
- DECLARE @DstFileBase AS NVARCHAR(MAX)
- DECLARE @DstFileLog AS NVARCHAR(MAX)
- DECLARE @sqlquery AS NVARCHAR(MAX)
- SET @SrcDatabaseName = 'trade' -- Имя исходной базы
- SET @DstDatabaseName = 'trade_copy_for_testsa' -- Имя базы-получателя
- SET @Backup = 'X:\Tranzit\' + @SrcDatabaseName + '.bak' -- Куда записывать архив (файл)
- SET @DstFileBase = 'X:\SQLDATA\Data\' + @DstDatabaseName + '.mdf' -- Размещение файла базы-получателя
- SET @DstFileLog = 'C:\SQLDATA\' + @DstDatabaseName + '_log.ldf' -- Размещение файла лога-получателя
- SET @SrcDatabaseNameLog = @SrcDatabaseName + '_log' -- вычисляется имя файла лога базы-источника
- -- BACKUP DATABASE @SrcDatabaseName TO DISK = @Backup WITH INIT, FORMAT, STATS = 1, CHECKSUM, COMPRESSION
- SET @sqlquery = 'ALTER DATABASE [' + @DstDatabaseName + '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE'
- EXEC sp_executesql @sqlquery -- Переводит в режим одного пользователя
- RESTORE DATABASE @DstDatabaseName
- FROM DISK = @Backup
- WITH RECOVERY, REPLACE,
- MOVE @SrcDatabaseName TO @DstFileBase,
- MOVE @SrcDatabaseNameLog TO @DstFileLog
- SET @sqlquery = 'ALTER DATABASE [' + @DstDatabaseName + '] SET MULTI_USER'
- EXEC sp_executesql @sqlquery -- Переводит в режим многих пользователей
Внимание! BACKUP тут закомментирован. Для того, чтобы он прошел, уберите два дефиса в строке 18.
Скрипт не идеален. Пути к файлам базы, можно получать из самой базы, да и расчитан он только на базы из двух файлов — базы и лога транзакций. Но таких баз большинство.
Также каталог файлов должен быть одинаков у базы источника и получателя.
Пути к файлам тоже можно было бы прописать отдельно в шапке.
Если будут советы по улучшению скрипта, пишите.
Работает так:
О причине, почему использую режим Recovery при восстановлении можно почитать тут. В общем, он отсекает не завершенные транзакции, потому что иначе база оставалась в статусе «Восстанавливается».
Я пробовал лечить такое состояние кодом:
RESTORE DATABASE [earnings] WITH RECOVERY
База уходила из состояния «Восстанавливается», но в 1С при попытке открыть выдавала ошибку: «невосстановимая ошибка ошибка при выполнении запроса post к ресурсу /e1cib/login: по причине Ошибка СУБД Invalid column name ‘Partno'»:
И лечилось это только удалением базы и созданием ее заново. Так что нужно быть внимательным в опциях. Также пришлось повозиться с отключением сеансов и обратным переводом в мульти-пользовательский режим. Хотя в копии никто и не работал и регламентные задания были выключены, видимо сам сервер 1С создавал SQL-подключение.
Объем: 2 час.
Это все, конечно, круто, но прям не верится, что ты это сделал всего за 2 часа, особенно если не пишешь постоянно скрипты в Microsoft SQL. Чтобы за 2 часа и разобраться в синтаксисе MS SQL и скрипт написать, и протестировать, и там еще возникала ошибка, что база уходила в состояние «Восстанавливается», с которой приходилось разбираться, и потом с рабочей базой это всё проделать, что тоже занимает время. В общем не верю в то, что ты это сделал за 2 часа и клиенту выставил всего 2 часа. Откуда ты такое маленькое время берешь, с потолка? Чтобы новых клиентов завлечь или потешить свое самолюбие перед другими?
постоянно не пишу, но за свою жизнь скриптов 300 написал под MS SQL. Все же 20 лет в 1С.
Это всё хорошо, но ты же постоянно нереальные сроки пишешь, в данном случае 2 часа. Невозможно разобраться с синтаксисом MS SQL, написать скрипт, протестировать всё это, при этом сталкнувшись с ошибкой, что база восстанавливается, исправлением этой ошибки и т.д. Зачем пишешь такие неправдоподобные сроки с потолка? Чтобы завлечь новых клиентов или порадовать своё самолюбие?
я пишу фактические сроки. Я немного затупил, потому заняло 2 часа. Так то уже копирую базы скриптами не в первый раз.
Поэтому решил себе наконец уже записать рабочий скрипт, чтобы в следующий раз его можно было повторно использовать.