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