【问题标题】:SQL Server Restore Database with new file namesSQL Server 使用新文件名还原数据库
【发布时间】:2015-04-23 10:59:33
【问题描述】:

是否可以从备份中恢复 SQL Server 数据库,同时使用新名称创建 *.mdf*.ldf 文件?

假设我知道每个备份只有两个文件(一个 mdf 和一个 ldf),但我不知道这些文件的确切名称,不幸的是我无法从数据库名称中导出它们.

所有这些的目的是创建批处理文件,该批处理文件将从一组备份文件中恢复数据库。同时我必须解决文件名冲突的问题。

目前我有这个命令,它不适用于每个备份,因为某些数据库文件的命名与变量 %DATABASENAME% 不同:

...
RESTORE DATABASE [%NewDB%] 
FROM DISK = N'%BACKUPFILENAME%' 
WITH RECOVERY,  
MOVE N'%DATABASENAME%' TO N'C:\%NewDB%.mdf',  
MOVE N'%DATABASENAME%_Log' TO N'C:\%NewDB%_Log.ldf'
...

【问题讨论】:

    标签: sql-server database-restore


    【解决方案1】:

    可以使用RESTORE FILELISTONLY 获取备份中数据文件的详细信息。

    您可以通过将这些信息插入到临时表或表变量中来将此信息放入可用于构建恢复语句的表中。要将其集成到您现有的代码中:

    DECLARE @fileListTable TABLE
    (
        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),
        UniqueID             UNIQUEIDENTIFIER,
        ReadOnlyLSN          NUMERIC(25,0),
        ReadWriteLSN         NUMERIC(25,0),
        BackupSizeInBytes    BIGINT,
        SourceBlockSize      INT,
        FileGroupID          INT,
        LogGroupGUID         UNIQUEIDENTIFIER,
        DifferentialBaseLSN  NUMERIC(25,0),
        DifferentialBaseGUID UNIQUEIDENTIFIER,
        IsReadOnly           BIT,
        IsPresent            BIT,
        TDEThumbprint        VARBINARY(32)
    )
    
    --This schema works from SQL 2008 to SQL 2014. 
    --SQL 2005 didn't have the TDEThumbprint column, but is otherwise the same.
    
    INSERT INTO @fileListTable EXEC('restore filelistonly 
    FROM DISK = N''%BACKUPFILENAME%''')
    
    DECLARE @datafile NVARCHAR(128), @logfile NVARCHAR(128)
    
    SELECT @datafile = LogicalName FROM @fileListTable WHERE Type = 'D'
    
    SELECT @logfile = LogicalName FROM @fileListTable WHERE Type = 'L'
    
    RESTORE DATABASE [%NewDB%] 
    FROM DISK = N'%BACKUPFILENAME%' 
    WITH RECOVERY,  
    MOVE @datafile TO N'C:\%NewDB%.mdf',  
    MOVE @logfile TO N'C:\%NewDB%_Log.ldf'
    

    在具有更多数据/日志文件的场景中,代码需要相应地更复杂。

    解决文件名冲突的一种方法是将时间戳、GUID 或其他合理唯一的标识符附加到新文件名。

    【讨论】:

      【解决方案2】:

      根据上面的答案,我创建了一个存储过程,我从批处理文件中执行:

      Create Procedure restoreDB
          @filepath nvarchar(700),
          @dbname nvarchar(200)
      
          as
      
          declare @dbfile nvarchar(300)
          declare @dblogfile nvarchar(300)
      
          declare @newdbfile nvarchar(300)
          declare @newdblogfile nvarchar(300)
      
          select @dbname = ltrim(@dbname)
          set @newdbfile = 'c:\' + @dbname + '.mdf'
          set @newdblogfile = 'c:\' + @dbname + '.ldf'
      
      
          DECLARE @Filenames TABLE (
              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),
              UniqueID             uniqueidentifier,
              ReadOnlyLSN          numeric(25,0),
              ReadWriteLSN         numeric(25,0),
              BackupSizeInBytes    bigint,
              SourceBlockSize      int,
              FileGroupID          int,
              LogGroupGUID         uniqueidentifier,
              DifferentialBaseLSN  numeric(25,0),
              DifferentialBaseGUID uniqueidentifier,
              IsReadOnl            bit,
              IsPresent            bit,
              TDEThumbprint        varbinary(32)
          )
      
          INSERT INTO @Filenames
          EXEC('restore filelistonly from disk=''' + @filepath + '''');
      
          select @dbfile = (select top 1 LogicalName from @Filenames where [Type] = 'd');
          select @dblogfile = (select top 1 LogicalName from @Filenames where [Type]='l');
      
          RESTORE DATABASE @dbname FROM  DISK = @filepath WITH  RECOVERY,  MOVE @dbfile TO @newdbfile,  MOVE @dblogfile TO @newdblogfile;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-22
        • 1970-01-01
        • 1970-01-01
        • 2010-12-17
        • 1970-01-01
        • 2019-05-28
        相关资源
        最近更新 更多