2015-04-23 2 views
0

Est-il possible de restaurer la base de données SQL Server à partir d'une sauvegarde et en même temps de créer des fichiers *.mdf et *.ldf avec de nouveaux noms? Supposons que je sache qu'il n'y a que deux fichiers par sauvegarde (un mdf et un ldf), mais je ne connais pas le nom exact de ces fichiers et je ne peux malheureusement pas les déduire des noms de bases de données.Base de données de restauration SQL Server avec nouveaux noms de fichier

Le but de tout cela est de créer un fichier batch qui restaure les bases de données à partir d'un ensemble de fichiers de sauvegarde. Dans le même temps, je dois résoudre problème de nom de fichier.

Actuellement, j'ai cette commande, qui ne fonctionne pas pour chaque sauvegarde car certains fichiers de base de données sont nommés différemment de la variable% 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' 
... 

Répondre

1

Il est possible d'obtenir les détails des fichiers de données dans une sauvegarde en utilisant RESTORE FILELISTONLY.

Vous pouvez obtenir cette information dans une table que vous pouvez utiliser pour créer une instruction de restauration en l'insérant dans une table temporaire ou une variable de table. Pour intégrer dans votre code existant:

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' 

Dans un scénario avec plus de données/fichiers journaux, le code devrait être d'autant plus complexe. Une façon de résoudre le potentiel de noms de fichiers en conflit serait d'ajouter un timestamp, un GUID ou un autre identifiant raisonnablement unique aux nouveaux noms de fichiers.

0

D'après la réponse ci-dessus, j'ai créé une procédure stockée que j'exécute à partir d'un fichier batch:

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;