2015-04-23 33 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; 
相關問題