具有新文件名的SQL Server还原数据库

时间:2015-04-23 10:59:33

标签: sql-server database-restore

是否可以从备份恢复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'
...

2 个答案:

答案 0 :(得分: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或其他合理唯一的标识符。

答案 1 :(得分:0)

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

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;