Fully automated SQL Server Restore

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

    I have created a new version based on the answers found here. It should work with the latest versions of SQL Server.

    Provided with a back-up location, it restores the DB and moves the MDF and LDF files to a specified location.

    declare @databaseName nvarchar(max);
    declare @backUpDiskLocation nvarchar(max);
    declare @physicalMDFLocation nvarchar(max);
    declare @physicalLDFLocation nvarchar(max);
    
    set @databaseName = '[<DB_Name>]';
    set @backUpDiskLocation = 'C:\SQL-BACKUP\<backUP-Name>.bak';
    set @physicalMDFLocation = 'C:\SQL\SQLData\<MDF-Name>.mdf';
    set @physicalLDFLocation = 'C:\SQL\SQL-LOG\<LDF-Name_log>.LDF'
    
    if (DB_ID(@databaseName)) is not null
    Begin
    DECLARE @kill varchar(8000); SET @kill = ''; 
    SELECT @kill = @kill + 'kill ' + CONVERT(varchar(5), spid) + ';' 
    FROM master..sysprocesses 
    WHERE dbid = DB_ID(@databaseName)
    EXEC(@kill);
     DECLARE @Alter nvarchar(max); SET @Alter = 'ALTER DATABASE ' + @databaseName +' SET offline  WITH Rollback Immediate'
     EXEC (@Alter)
    END
    
    declare @sql nvarchar(max)
    set @sql = N'restore filelistonly from disk=''' + @backUpDiskLocation +'''';
    
    select @sql
    create table #filelist (LogicalName nvarchar(128), PhysicalName nvarchar(260), Type char(1), FilegroupName varchar(10), size bigint, MaxSize bigint, field int, createlsn bit, droplsn bit, uniqueid uniqueidentifier, readonlylsn bit, readwritelsn bit, backupsizeinbytes bigint, sourceblocksize int, filegroupid int, loggroupguid uniqueidentifier, differentialbaselsn bit, differentialbaseguid uniqueidentifier, isreadonly bit, ispresent bit, tdethumbprint varchar(5), SnapshotUrl nvarchar(128));
    insert into #filelist exec sp_executesql @sql;
    ALTER TABLE #filelist add id int identity(1,1)
    update #filelist set PhysicalName = @physicalMDFLocation where [id]= 1
    update #filelist set PhysicalName = @physicalLDFLocation where [id]= 2
    select * from #filelist
    
    set @sql = N'RESTORE database '+ @databaseName +' from disk = '''+ @backUpDiskLocation +''' with replace, ';
    select @sql
    select @sql = @sql + N' move ''' + LogicalName + N''' to ''' + PhysicalName + N''',' from #filelist;
    
    set @sql = substring(@sql, 1, len(@sql)-1); -- remove last ','
    
    select @sql
    exec sp_executesql @sql;
    
    drop table #filelist
    
    0 讨论(0)
  • 2020-12-07 17:19

    Here's the fully automated restore T-SQL stored proc. Accepts three(3) parameters.

    1. Target Database
    2. Source Database
    3. Fully Qualified backup file name location
      (\\yourserver\yourshare\backupfile.bak or simply c:\backup.bak)


    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)
    
        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)
    
    
        INSERT INTO ##FILE_LIST EXEC ('RESTORE FILELISTONLY FROM DISK = ''' + @p_strFQNRestoreFileName + '''')
    
        DECLARE curFileLIst CURSOR FOR 
            SELECT 'MOVE N''' + LogicalName + ''' TO N''' + replace(PhysicalName, @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 '---------------------------'
    
    
        EXEC sp_executesql @v_strExecSQL
    
    0 讨论(0)
  • 2020-12-07 17:22

    None of the versions include SQL 2000. This will work on all of them:

    use master
    
    --
    -- check SQL Server version
    DECLARE @sql_ver int;
    CREATE TABLE #tmp_sql_ver
    (
        [Index] int,
        [Name]  nvarchar(100),
        [iVal]  int,
        [cVal]  nvarchar(100)
    )
    INSERT INTO #tmp_sql_ver EXEC('xp_msver ProductVersion');
    IF (SELECT cast(cVal as char(2)) FROM #tmp_sql_ver) = '8.'
        SET @sql_ver = 8;
    ELSE
        SET @sql_ver = 9;
    DROP TABLE #tmp_sql_ver;
    
    --
    -- get mdf/ldf names
    DECLARE @mdf_name varchar(50)
    DECLARE @ldf_name varchar(50)
    DECLARE @RestoreFileListOnly_columns varchar(2000)
    
    IF (@sql_ver = 8)
    BEGIN
        SET @RestoreFileListOnly_columns = '
            LogicalName     nvarchar(128),
            PhysicalName    nvarchar(260),
            [Type]  char(1),
            FileGroupName   nvarchar(128),
            [Size]  numeric(20,0),
            [MaxSize]   numeric(20,0),
        '
    END
    ELSE
    BEGIN
        SET @RestoreFileListOnly_columns = '
            LogicalName     nvarchar(128),
            PhysicalName    nvarchar(260),
            [Type]  char(1),
            FileGroupName   nvarchar(128),
            [Size]  numeric(20,0),
            [MaxSize]   numeric(20,0),
    
            FileID  bigint,
            CreateLSN   numeric(25,0),
            DropLSN     numeric(25,0) NULL,
            UniqueID    uniqueidentifier,
            ReadOnlyLSN     numeric(25,0) NULL,
            ReadWriteLSN    numeric(25,0) NULL,
            BackupSizeInBytes   bigint,
            SourceBlockSize     int,
            FileGroupID     int,
            LogGroupGUID    uniqueidentifier NULL,
            DifferentialBaseLSN     numeric(25,0) NULL,
            DifferentialBaseGUID    uniqueidentifier,
            IsReadOnly  bit,
            IsPresent   bit
        '
        DECLARE @tmp_ver NVARCHAR(20)
        SELECT @tmp_ver = CAST(SERVERPROPERTY ('PRODUCTVERSION') AS NVARCHAR)
        IF @tmp_ver LIKE '1[01].%' 
            BEGIN
                SET @RestoreFileListOnly_columns = @RestoreFileListOnly_columns + ', TDEThumbpr DECIMAL'
            END
    END
    IF EXISTS (SELECT [table_name] FROM information_schema.tables WHERE [table_name] = 'tmp_RestoreFileListOnly')
    BEGIN
        DROP TABLE [tmp_RestoreFileListOnly];
    END
    EXEC ('CREATE TABLE tmp_RestoreFileListOnly ('+@RestoreFileListOnly_columns+');');
    
    INSERT INTO tmp_RestoreFileListOnly EXEC('RESTORE FILELISTONLY FROM DISK = ''' + @bkpfile + '''')
    PRINT 'RESTORE FILELISTONLY FROM DISK = ''' + @bkpfile + ''''
    --IF @@ROWCOUNT <> 2 RETURN
    SELECT @mdf_name = LogicalName FROM tmp_RestoreFileListOnly WHERE Type = 'D'
    SELECT @ldf_name = LogicalName FROM tmp_RestoreFileListOnly WHERE Type = 'L'
    DROP TABLE tmp_RestoreFileListOnly
    
    0 讨论(0)
  • 2020-12-07 17:22

    this might help. I wanted to create a script for a client with the minimum variables required to be set for multiple database backups restored from a single location. I tried to avoid using dynamic SQL because I think it all gets a little messy.

    -- Use VARCHAR as the restore statement doesn't like NVARCHAR
    DECLARE @data_file_path VARCHAR(512), @log_file_path VARCHAR(512), @backup_path VARCHAR(512),
            @backup_extension VARCHAR(4), @mdf_extension VARCHAR(4), @ldf_extension VARCHAR(4)
    
    -- ** VARIABLES THAT MUST BE SET **--
    SET @data_file_path = 'E:\DataPath\'
    SET @log_file_path  = 'F:\LogPath'
    SET @backup_path =    'B:\BackUpPath'
    -- **----------------------------**--
    
    SET @backup_extension = '.bak'
    SET @mdf_extension = '.mdf'
    SET @ldf_extension = '.ldf'
    
    DECLARE @DATABASES_TO_RESTORE TABLE (rownum int IDENTITY (1, 1) PRIMARY KEY NOT NULL, backup_name VARCHAR(64), restore_as VARCHAR(64))
    
    -- ** Declare the Databases to be Restored ** --
    INSERT INTO @DATABASES_TO_RESTORE
        SELECT 'Intranet', 'Intranet_Test'
        UNION
        SELECT 'TestAudit', 'TestAudit_Test'
    -- ** -------------------------------------** --
    
    DECLARE @max_rows INT, @row_count INT
    SET @row_count = 1
    SELECT @max_rows=count(*) FROM @DATABASES_TO_RESTORE
    
    WHILE @row_count <= @max_rows
    BEGIN
        DECLARE @backup_name VARCHAR(32), @restore_as VARCHAR(32), @logical_data_name VARCHAR(64), @logical_log_name VARCHAR(64),
                @data_file_full_path VARCHAR(512), @log_file_full_path VARCHAR(512), @full_backup_path VARCHAR(MAX)
    
        SELECT @backup_name = backup_name, @restore_as = restore_as FROM @DATABASES_TO_RESTORE WHERE rownum = @row_count    
        SET @full_backup_path = @backup_path + @backup_name + @backup_extension
    
        DECLARE @filelist TABLE (LogicalName NVARCHAR(128) NOT NULL, PhysicalName NVARCHAR(260) NOT NULL, [Type] CHAR(1) NOT NULL, FileGroupName NVARCHAR(120) NULL, Size NUMERIC(20, 0) NOT NULL, MaxSize NUMERIC(20, 0) NOT NULL, FileID BIGINT NULL, CreateLSN NUMERIC(25,0) NULL, DropLSN NUMERIC(25,0) NULL, UniqueID UNIQUEIDENTIFIER NULL, ReadOnlyLSN NUMERIC(25,0) NULL , ReadWriteLSN NUMERIC(25,0) NULL, BackupSizeInBytes BIGINT NULL, SourceBlockSize INT NULL, FileGroupID INT NULL, LogGroupGUID UNIQUEIDENTIFIER NULL, DfferentialBaseLSN NUMERIC(25,0)NULL, DifferentialBaseGUID UNIQUEIDENTIFIER NULL, IsReadOnly BIT NULL, IsPresent BIT NULL, TDEThumbprint VARBINARY(32) NULL)
    
        INSERT into @filelist
            EXEC ('RESTORE FilelistOnly FROM DISK = ''' + @full_backup_path + '''')
    
        IF @@ROWCOUNT = 2
        BEGIN
            SELECT @logical_data_name = LogicalName FROM @filelist WHERE [Type] = 'D'
            SELECT @logical_log_name  = LogicalName FROM @filelist WHERE [Type] = 'L'
    
            SET @data_file_full_path = @data_file_path + @restore_as + @mdf_extension
            SET @log_file_full_path = @log_file_path + @restore_as + @ldf_extension
    
            RESTORE DATABASE @restore_as
            FROM DISK = @full_backup_path
            WITH
            FILE = 1, 
            MOVE @logical_data_name 
            TO @data_file_full_path,
            MOVE @logical_log_name 
            TO @log_file_full_path
        END
        ELSE
            PRINT 'CANNOT RESTORE DATABASE ' + @restore_as + ' THE BACKUP CONTAINS MORE THAN 1 BACKUP SET'
    
        SELECT @row_count = @row_count + 1
    END
    
    0 讨论(0)
  • 2020-12-07 17:28

    RESTORE FILELISTONLY produces a result set that is documented in the MSDN. You then need to iterate this result set and build an appropriate RESTORE ... MOVE... How you capture and iterate the result set depends on your environment. In a C# application you would use a SqlDataReader. In pure T-SQL you would use INSERT ... EXEC.

    The skeleton of a pure SQL solution would be:

    declare @filelist table (LogicalName nvarchar(128), PhysicalName nvarchar(260), Type char(1), FilegroupName varchar(10), size int, MaxSize bigint, field int, createlsn bit, droplsn bit, uniqueid uniqueidentifier, readonlylsn bit, readwritelsn bit, backupsizeinbytes bigint, sourceblocksize int, filegroupid int, loggroupguid uniqueidentifier, differentialbaselsn bit, differentialbaseguid uniqueidentifier, isreadonly bit, ispresent bit, tdethumbprint varchar(5));
    insert into @filelist exec sp_executesql N'restore filelistonly from disk=''D:\backups\my_backup.bak''';
    
    set @sql = N'RESTORE database my_database from disk ''D:\backups\my_backup.bak'' with ';
    select @sql = @sql + N' move ' + LogicalName + N' to ' udf_localFilePath(PhysicalName) + N','
    from @filelist;
    
    set @sql = substring(@sql, 1, len(@sql)-1); -- remove last ','
    exec sp_executesql @sql;
    

    This is not actual working code, but just to get you the idea. You can also use a cursor instead of the non-standard assignment-inside-query construction of @sql

    Be aware that the list of columns in the result set of RESTORE FILELISTONLY differs between SQL Server versions. Refer to the target version specifications for the correct list.

    0 讨论(0)
  • 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!

    0 讨论(0)
提交回复
热议问题