Fully automated SQL Server Restore

前端 未结 10 1391
予麋鹿
予麋鹿 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:28

    Yet another modification/implementations. Here's my 2 cents. I have modified Mevdiven's script above, so that it will restore the file to the current database data directory. I have a problem in that I do not want to use the location defined in the back up file.

    I grab the data directory used by the first master file

    SELECT top(1) @v_strRestorePath =  physical_name FROM sys.master_files
    

    And use that as my destination data path.

    I also found that the ##FILE_LIST table was hanging around, so I drop it near the end.

    The extra --' are just so the SQL looks nice on Stack overflow

    USE [master]
    GO
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    IF OBJECT_ID('[dbo].[restoreDB]') IS NOT NULL
    DROP PROC [dbo].[restoreDB]
    GO
    
    CREATE PROC [dbo].[restoreDB]
        @p_strDBNameTo SYSNAME,
        @p_strDBNameFrom SYSNAME,
        @p_strFQNRestoreFileName VARCHAR(255)
    
    AS 
    DECLARE 
        @v_strDBFilename VARCHAR(100),
        @v_strDBLogFilename VARCHAR(100),
        @v_strDBDataFile VARCHAR(100),
        @v_strDBLogFile VARCHAR(100),
        @v_strExecSQL NVARCHAR(1000),
        @v_strExecSQL1 NVARCHAR(1000),
        @v_strMoveSQL NVARCHAR(4000),
        @v_strREPLACE NVARCHAR(50),
        @v_strTEMP NVARCHAR(1000),
        @v_strListSQL NVARCHAR(4000),
        @v_strServerVersion NVARCHAR(20),
        @v_strRestorePath varchar(500)
    
    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 (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = ''##FILE_LIST''))'
    SET @v_strListSQL = @v_strListSQL + 'BEGIN'
    SET @v_strListSQL = @v_strListSQL + '   DROP TABLE ##FILE_LIST '
    SET @v_strListSQL = @v_strListSQL + 'END '
    
    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)
    
    -- We want to get the current data path from this server as the backup file paths may not be the same on the server
    -- especially wehen switching between Express/Standard instances
    SELECT top(1) @v_strRestorePath =  physical_name FROM sys.master_files;
    set  @v_strRestorePath = REPLACE(@v_strRestorePath, RIGHT(@v_strRestorePath, CHARINDEX('\', REVERSE(@v_strRestorePath))-1),'')
    --print @v_strRestorePath --'
    
    INSERT INTO ##FILE_LIST EXEC ('RESTORE FILELISTONLY FROM DISK = ''' + @p_strFQNRestoreFileName + '''')
    
    -- want to see whats in the fillist?
    --SELECT * FROM  ##FILE_LIST
    
    DECLARE curFileLIst CURSOR FOR 
        -- Here we restore each file to the current server restore path. Right(...) grabs the file name from the back up
        SELECT 'MOVE N''' + LogicalName + ''' TO N''' + @v_strRestorePath + Replace(RIGHT(PhysicalName, CHARINDEX('\', REVERSE(PhysicalName))-1),@p_strDBNameFrom, @p_strDBNameTo) + ''''  --'
          FROM ##FILE_LIST
    
    SET @v_strMoveSQL = ''
    
    OPEN curFileList 
    FETCH NEXT FROM curFileList into @v_strTEMP
    WHILE @@Fetch_Status = 0
    BEGIN
        SET @v_strMoveSQL = @v_strMoveSQL + @v_strTEMP + ', '
        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_strFQNRestoreFileName + '" with '
    PRINT '  data file "' + @v_strDBDataFile + '" located at "' + @v_strDBFilename + '"'
    PRINT '  log file "' + @v_strDBLogFile + '" located at "' + @v_strDBLogFilename + '"'
    
    SET @v_strExecSQL = 'RESTORE DATABASE [' + @p_strDBNameTo + ']'
    SET @v_strExecSQL = @v_strExecSQL + ' FROM DISK = ''' + @p_strFQNRestoreFileName + ''''
    SET @v_strExecSQL = @v_strExecSQL + ' WITH FILE = 1,'
    SET @v_strExecSQL = @v_strExecSQL + @v_strMoveSQL
    SET @v_strExecSQL = @v_strExecSQL + ' NOREWIND, '
    SET @v_strExecSQL = @v_strExecSQL + ' NOUNLOAD '
    SET @v_strExecSQL = @v_strExecSQL + @v_strREPLACE
    
    
    --PRINT '---------------------------'
    --PRINT @v_strExecSQL
    --PRINT '---------------------------'
    
    --For Some reason the file list hangs when I was debugging remove it.
    IF (EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '##FILE_LIST'))
    BEGIN
        DROP TABLE ##FILE_LIST
    END
    
    EXEC sp_executesql @v_strExecSQLter 
    

    Hope this helps some one too!

提交回复
热议问题