Fully automated SQL Server Restore

前端 未结 10 1383
予麋鹿
予麋鹿 2020-12-07 16:58

I\'m not very fluent with SQL Server commands.

I need a script to restore a database from a .bak file and move the logical_data and logical_log files to a specific p

10条回答
  •  情话喂你
    2020-12-07 17:40

    not sure how to add comments under a particular solution but I have just implemented the solution provided by Mevdiven above...

    There is a slight problem with the drop table in my environment (Server 08 r2). I have had to modify this to use the object id in order to drop successfully.

    I also had problems due to a large number of partitions in the backup file, so I had to change the string to be nvarchar(MAX).

    I also added ability to restore the database into another directory (as our dev vs prod environments have different paths)

    CREATE PROC [dbo].[restoreDB]
        @p_strDBNameTo SYSNAME,
        @p_strDBNameFrom SYSNAME,
        @p_strBackupDirectory VARCHAR(255),
        @p_strRestoreDirectory VARCHAR(255),
        @p_strFQNBackupFileName VARCHAR(255)
    AS 
        DECLARE 
            @v_strDBFilename VARCHAR(200),
            @v_strDBLogFilename VARCHAR(200),
            @v_strDBDataFile VARCHAR(200),
            @v_strDBLogFile VARCHAR(200),
            @v_strExecSQL NVARCHAR(MAX),
            @v_strMoveSQL NVARCHAR(MAX),
            @v_strREPLACE NVARCHAR(50),
            @v_strTEMP NVARCHAR(1000),
            @v_strListSQL NVARCHAR(4000),
            @v_strServerVersion NVARCHAR(20)
    
        SET @v_strREPLACE = ''   
        IF exists (select name from sys.databases where name = @p_strDBNameTo)
            SET @v_strREPLACE = ', REPLACE'
    
        SET @v_strListSQL = ''
        SET @v_strListSQL = @v_strListSQL + 'IF OBJECT_ID(''tempdb..##FILE_LIST'') IS NOT NULL DROP TABLE ##FILE_LIST '
        SET @v_strListSQL = @v_strListSQL + 'CREATE TABLE ##FILE_LIST ('
        SET @v_strListSQL = @v_strListSQL + '   LogicalName VARCHAR(64),'
        SET @v_strListSQL = @v_strListSQL + '   PhysicalName VARCHAR(130),'
        SET @v_strListSQL = @v_strListSQL + '   [Type] VARCHAR(1),'
        SET @v_strListSQL = @v_strListSQL + '   FileGroupName VARCHAR(64),'
        SET @v_strListSQL = @v_strListSQL + '   Size DECIMAL(20, 0),'
        SET @v_strListSQL = @v_strListSQL + '   MaxSize DECIMAL(25,0),'
        SET @v_strListSQL = @v_strListSQL + '   FileID bigint,'
        SET @v_strListSQL = @v_strListSQL + '   CreateLSN DECIMAL(25,0),'
        SET @v_strListSQL = @v_strListSQL + '   DropLSN DECIMAL(25,0),'
        SET @v_strListSQL = @v_strListSQL + '   UniqueID UNIQUEIDENTIFIER,'
        SET @v_strListSQL = @v_strListSQL + '   ReadOnlyLSN DECIMAL(25,0),'
        SET @v_strListSQL = @v_strListSQL + '   ReadWriteLSN DECIMAL(25,0),'
        SET @v_strListSQL = @v_strListSQL + '   BackupSizeInBytes DECIMAL(25,0),'
        SET @v_strListSQL = @v_strListSQL + '   SourceBlockSize INT,'
        SET @v_strListSQL = @v_strListSQL + '   filegroupid INT,'
        SET @v_strListSQL = @v_strListSQL + '   loggroupguid UNIQUEIDENTIFIER,'
        SET @v_strListSQL = @v_strListSQL + '   differentialbaseLSN DECIMAL(25,0),'
        SET @v_strListSQL = @v_strListSQL + '   differentialbaseGUID UNIQUEIDENTIFIER,'
        SET @v_strListSQL = @v_strListSQL + '   isreadonly BIT,'
        SET @v_strListSQL = @v_strListSQL + '   ispresent BIT'
    
        SELECT @v_strServerVersion = CAST(SERVERPROPERTY ('PRODUCTVERSION') AS NVARCHAR)
    
        IF @v_strServerVersion LIKE '10.%' 
            BEGIN
                SET @v_strListSQL = @v_strListSQL + ', TDEThumbpr DECIMAL'
                --PRINT @v_strServerVersion
            END
    
        SET @v_strListSQL = @v_strListSQL + ')'
    
        EXEC (@v_strListSQL)
    
        INSERT INTO ##FILE_LIST EXEC ('RESTORE FILELISTONLY FROM DISK = ''' + @p_strFQNBackupFileName + '''')
    
        DECLARE curFileLIst CURSOR FOR 
            SELECT 'MOVE N''' + LogicalName + ''' TO N''' + replace(replace(PhysicalName, @p_strDBNameFrom, @p_strDBNameTo), @p_strBackupDirectory, @p_strRestoreDirectory) + ''''
              FROM ##FILE_LIST
    
        SET @v_strMoveSQL = cast('' as nvarchar(max))
    
        OPEN curFileList 
        FETCH NEXT FROM curFileList into @v_strTEMP
        WHILE @@Fetch_Status = 0
        BEGIN
            SET @v_strMoveSQL = @v_strMoveSQL + cast(@v_strTEMP as nvarchar(max)) + cast(', ' as nvarchar(max))
            FETCH NEXT FROM curFileList into @v_strTEMP
        END
    
        CLOSE curFileList
        DEALLOCATE curFileList
    
    
        PRINT 'Killing active connections to the "' + @p_strDBNameTo + '" database'
    
        -- Create the sql to kill the active database connections
        SET @v_strExecSQL = ''
        SELECT   @v_strExecSQL = @v_strExecSQL + 'kill ' + CONVERT(CHAR(10), spid) + ' '
        FROM     master.dbo.sysprocesses
        WHERE    DB_NAME(dbid) = @p_strDBNameTo AND DBID <> 0 AND spid <> @@spid
    
        EXEC (@v_strExecSQL)
    
        PRINT 'Restoring "' + @p_strDBNameTo + '" database from "' + @p_strFQNBackupFileName + '" with '
        PRINT '  data file "' + @v_strDBDataFile + '" located at "' + @v_strDBFilename + '"'
        PRINT '  log file "' + @v_strDBLogFile + '" located at "' + @v_strDBLogFilename + '"'
    
        SET @v_strExecSQL = cast('RESTORE DATABASE [' as nvarchar(max)) + cast(@p_strDBNameTo as nvarchar(max)) + cast(']' as nvarchar(max))
        SET @v_strExecSQL = @v_strExecSQL + cast(' FROM DISK = ''' as nvarchar(max)) + cast(@p_strFQNBackupFileName as nvarchar(max)) + cast('''' as nvarchar(max))
        SET @v_strExecSQL = @v_strExecSQL + cast(' WITH FILE = 1,' as nvarchar(max))
        SET @v_strExecSQL = @v_strExecSQL + @v_strMoveSQL
        SET @v_strExecSQL = @v_strExecSQL + cast(' NOREWIND, ' as nvarchar(max))
        SET @v_strExecSQL = @v_strExecSQL + cast(' NOUNLOAD ' as nvarchar(max))
        SET @v_strExecSQL = @v_strExecSQL + cast(@v_strREPLACE as nvarchar(max))
    
        --If want to print string need to do in sections due to limitation of print string length
    
        PRINT 'Exec string: ' +cast(len(@v_strExecSQL) as nvarchar(max))+ ' ***:'
        PRINT substring(@v_strExecSQL,0,3999)
        PRINT substring(@v_strExecSQL,4000,7999)
        PRINT substring(@v_strExecSQL,8000,11999)
        PRINT substring(@v_strExecSQL,12000,15999)
        PRINT substring(@v_strExecSQL,16000,19999)
        PRINT substring(@v_strExecSQL,20000,23999)
        PRINT substring(@v_strExecSQL,24000,27999)
        PRINT substring(@v_strExecSQL,28000,31999)
        PRINT substring(@v_strExecSQL,32000,35999)
    
    
        EXEC sp_executesql @v_strExecSQL
    
    GO
    

提交回复
热议问题