2015-04-23 35 views
0

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

假定我知道有每个备份只有两个文件(一个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' 
... 

回答

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或其他合理唯一的标识符附加到新文件名。

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; 
相关问题