2013-09-02 3 views
2

현재 CMS의 기본 설치가 있습니다.이 CMS에는 사용자, 제품, 컨텐츠 등에 대한 완벽한 작업 데이터 세트가 포함되어 있습니다. 설치 시간이 늘어날 것으로 예상됩니다. 현재 SQL Server 2012로 이동하여 새 DB를 만든 다음 기존 기본 설치 db에서 데이터베이스를 복원해야합니다.원본을 그대로 둔 채 복제 할 SQL 스크립트

설치하는 데 최대 10-15 분이 걸릴 수 있습니다.

또한 기본 데이터베이스에 구축 할 사이트의 모든 요구 사항이 있는지 확인하십시오.

문제는 다음과 같습니다.

  1. 스크립트는
  2. 후 자신의 MDF와 신선한 새 데이터베이스로이 재현이 .BAK 파일을 가지고 새로운 .BAK 파일에이 데이터베이스의 복제를 만드는 신선한 새로운 빈 데이터베이스
  3. 을 만들 수 있습니다 및 LDF 파일을 각각 찾습니다.

데이터베이스가 동일한 서버에 있으므로이 컴퓨터를 다른 컴퓨터 나 인스턴스로 마이그레이션 할 필요가 없습니다.

우리의 코드는 우리가이 코드를 실행하지만 매번, 우리는 오류 메시지 다음 얻을, 우리는 모든 것이 신선하고 깨끗하지만 여전히 모든 데이터가 포함되어 있는지 확인하려면

CREATE database my_test 

BACKUP DATABASE test_db TO DISK = 'C:\my_test\my_test.bak' WITH INIT; 
EXEC internal_lab_test.dbo.sp_helpfile; 

RESTORE FILELISTONLY 
    FROM DISK = 'C:\my_test\my_test.bak' 

RESTORE DATABASE my_test 
    FROM DISK = 'C:\my_test\my_test.bak' 
    WITH MOVE 'my_test' TO 'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\test_db.mdf', 
    MOVE 'my_test_log' TO 'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\test_db_log.ldf' 

이하

우리는 또한 원래 데이터베이스의 MDF와 LDF 파일이 재치에 남아 있으며

Msg 3154, Level 16, State 4, Line 10 
The backup set holds a backup of a database other than the existing 'my_test' database. 
Msg 3013, Level 16, State 1, Line 10 
RESTORE DATABASE is terminating abnormally. 

답변

4

내가이 오래 알고 새 데이터베이스에 사용이 arent 있는지 확인하려면, 그러나 그것은이었다 완성도를 위해 Google의 2 번째 항목.

데이터베이스가 이미 존재하기 때문입니다. 따라서 데이터베이스를 삭제하거나 바꾸기로 추가하십시오.

또한 my_test 및 my_test_log 이름은 restore filelistonly 명령의 논리 이름이어야합니다. 날이에 의해 wroted

RESTORE DATABASE my_test 
    FROM DISK = 'C:\my_test\my_test.bak' 
    WITH Replace, 
    MOVE 'my_test' TO 'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\test_db.mdf', 
    MOVE 'my_test_log' TO 'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\test_db_log.ldf' 
1

Compleate 스크립트 ('템플릿'에서 복제 dB 증가 스크립트, 다음 복제 drop하여 DB를 적용) 일반적인 개발 작업에 대한 충분한 융통성이 있습니다. 참고 : 절차 adv.cloneDatabase이 실행되기 전에 DB 'read_only, single_user'를 만들어야하며, xp_cmdshell을 실행할 권한이 필요하면 원본 상태를 반환해야합니다.

CREATE PROCEDURE adv.alterateFileNames(
     @mdfFileName nvarchar(256), 
     @ldfFileName nvarchar(256), 
     @newMdfFileName nvarchar(256) OUTPUT, 
     @newLdfFileName nvarchar(256) OUTPUT 
) 
AS 
BEGIN 
    DECLARE @path_data nvarchar(256) 
    DECLARE @ext_data nvarchar(4) 
    DECLARE @path_log nvarchar(256) 
    DECLARE @ext_log nvarchar(4) 

    -- respect file extensions 
    if (RIGHT(@mdfFileName , 4)='.mdf') 
    BEGIN 
     SET @path_data = SUBSTRING(@mdfFileName,0,LEN(@mdfFileName)-3) 
     SET @ext_data = '.mdf' 
    END 
    ELSE 
    BEGIN 
     SET @path_data = @mdfFileName 
     SET @ext_data = '' 
    END 


    if (RIGHT(@ldfFileName , 4)='.ldf') 
    BEGIN 
     SET @path_log = SUBSTRING(@ldfFileName,0,LEN(@ldfFileName)-3) 
     SET @ext_log = '.ldf' 
    END 
    ELSE 
    BEGIN 
     SET @path_log = @ldfFileName 
     SET @ext_log = '' 
    END 

    -- respect suffix counters like dbname_2 (that means add value to them) 
    DECLARE @iData int 

    DECLARE @data_suffix_index int = len(@path_data) - charindex('_', reverse(@path_data)) 
    IF (@data_suffix_index < len(@path_data)-1 AND @data_suffix_index > 0) 
    BEGIN 
     DECLARE @data_suffix nvarchar(128) = substring(@path_data, @data_suffix_index+2, len(@path_data)[email protected]_suffix_index-1) 
     IF @data_suffix NOT LIKE '%[^0-9]%' 
     BEGIN 
      SET @path_data = SUBSTRING(@path_data,0,@data_suffix_index+1) 
      SET @iData = CAST(@data_suffix as int); 
     END 
    END 
    IF (@iData is null) 
    BEGIN 
      SET @path_data = @path_data 
      SET @iData = 0 
    END 

    DECLARE @iLog int 

    DECLARE @log_suffix_index int = len(@path_log) - charindex('_', reverse(@path_log)) 
    IF (@log_suffix_index < len(@path_log)-1 AND @log_suffix_index > 0) 
    BEGIN 
     DECLARE @log_suffix nvarchar(128) = substring(@path_log, @log_suffix_index+2, len(@path_log) - @log_suffix_index-1) 
     IF @log_suffix NOT LIKE '%[^0-9]%' 
     BEGIN 
      SET @path_log = SUBSTRING(@path_log,0,@log_suffix_index+1) 
      SET @iLog = CAST(@log_suffix as int); 
     END 
    END 
    IF (@iLog is null) 
    BEGIN 
      SET @path_log = @path_log 
      SET @iLog = 0 
    END 

    WHILE 1=1 
    BEGIN 
     IF EXISTS(SELECT * FROM sys.master_files WHERE [email protected]_data+'_'+CAST(@iData AS varchar(6))[email protected]_data) 
      SET @[email protected]+1 
     ELSE 
     BEGIN 
      SET @path_data= @path_data+'_'+CAST(@iData AS varchar(6))[email protected]_data 
      BREAK 
     END 
    END 

    WHILE 1=1 
    BEGIN 
     IF EXISTS(SELECT * FROM sys.master_files WHERE [email protected]_log+'_'+CAST(@iLog AS varchar(6))[email protected]_log) 
      SET @[email protected]+1 
     ELSE 
     BEGIN 
      SET @path_log= @path_log+'_'+CAST(@iLog AS varchar(6))[email protected]_log 
      BREAK 
     END 
    END 
    SET @newMdfFileName = @path_data 
    SET @newLdfFileName = @path_log 
END 
GO 
CREATE PROCEDURE adv.cloneDatabase 
( 
    @databaseName sysname, 
    @newDatabaseName sysname 
) 
AS 
BEGIN 
    SET NOCOUNT ON 

    IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = @databaseName) 
     THROW 50000, 'Database doesn''t exist', 1; 
    IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = @databaseName AND owner_sid<>0x01) 
     THROW 50000, 'Clonning of system database is not supported', 1; 
    IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = @databaseName AND is_read_only=1) 
     THROW 50000, 'Clonning of not readonly database is not supported', 1; 
    IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = @databaseName AND user_access=1 /*single user*/) 
     THROW 50000, 'Clonning of nor single_user database is not supported', 1; 

    -- collect file info 
    DECLARE @Files TABLE 
    (
     [type] int, /*0,1,2,3,4*/ 
     type_desc nvarchar(60), /*ROWS,LOG,FILESTREAM,FULLTEXT*/ 
     name sysname, 
     physical_name nvarchar(260) 
    ) 

    INSERT INTO @Files ([type], type_desc, name, physical_name) 
    SELECT [type], type_desc, f.name, physical_name 
    FROM sys.master_files f INNER JOIN sys.databases d ON f.database_id=d.database_id 
    WHERE [email protected] 

    -- test files 
    DECLARE @filesCount int 
    SELECT @filesCount = count(*) from @Files 
    IF (@filesCount<>2) 
     THROW 50000, 'The procedure doesn''t support complex file structures', 1; 

    DECLARE @mdfFileName nvarchar(260), @ldfFileName nvarchar(260) 
    SELECT @mdfFileName = physical_name FROM @Files WHERE type_desc='ROWS' 
    SELECT @ldfFileName = physical_name FROM @Files WHERE type_desc='LOG' 

    DECLARE @newMdfFileName nvarchar(260), @newLdfFileName nvarchar(260) 
    exec adv.alterateFileNames @mdfFileName, @ldfFileName, @[email protected] OUTPUT, @[email protected] OUTPUT 

    DECLARE @cmd1 nvarchar(4000)= 'copy /Y "@mdfFileName" "@newMdfFileName"' 
    DECLARE @cmd2 nvarchar(4000)= 'copy "@ldfFileName" "@newLdfFileName"' 
    SET @cmd1=replace(@cmd1,'@mdfFileName',@mdfFileName) 
    SET @cmd1=replace(@cmd1,'@newMdfFileName',@newMdfFileName) 
    SET @cmd2=replace(@cmd2,'@ldfFileName',@ldfFileName) 
    SET @cmd2=replace(@cmd2,'@newLdfFileName',@newLdfFileName) 

    DECLARE @OUTPUT TABLE (line text) 
    DECLARE @result INT 

    BEGIN TRY 
     INSERT INTO @OUTPUT (line) VALUES ('> '[email protected]) 
     INSERT INTO @OUTPUT 
     exec @result =xp_cmdshell @cmd1 
     INSERT INTO @OUTPUT (line) VALUES ('> '[email protected]) 
     IF (@result <> 0) 
      THROW 50000, 'Error copying mdf file',1 

     INSERT INTO @OUTPUT 
     exec @result =xp_cmdshell @cmd2 
     IF (@result <> 0) 
      THROW 50000, 'Error copying ldf file',1 
    END TRY 
    BEGIN CATCH 
     SELECT * FROM @OUTPUT WHERE line is not null; 
     THROW 
    END CATCH 
    DECLARE @createDatabaseSql nvarchar(max) 
    SET @createDatabaseSql = ' 
    CREATE DATABASE '[email protected]+' 
     ON (FILENAME = '''[email protected]+'''), 
     (FILENAME = '''[email protected]+''') 
    FOR ATTACH;' 
    exec sp_executesql @stmt = @createDatabaseSql 

END 
GO