SQL 使用新文件名的服务器还原数据库
SQL Server Restore Database with new file names
是否可以从备份恢复 SQL 服务器数据库,同时使用新名称创建 *.mdf
和 *.ldf
文件?
假设我知道每个备份只有两个文件(一个 mdf
和一个 ldf
),但我不知道这些文件的确切名称,不幸的是我不能' t 从数据库名称派生它们。
所有这一切的目的是创建批处理文件,该文件将从一组备份文件中恢复数据库。同时我必须解决文件名冲突的问题。
目前我有这个命令,它不适用于每个备份,因为一些数据库文件的命名与变量 %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'
...
可以使用RESTORE FILELISTONLY
获取备份中数据文件的详细信息。
您可以将此信息放入 table 中,您可以通过将其插入临时 table 或 table 变量来构建还原语句。要将其集成到您现有的代码中:
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'
在data/log个文件的场景下,代码需要相应地更复杂。
解决文件名冲突可能性的一种方法是将时间戳、GUID 或其他合理的唯一标识符附加到新文件名。
基于上述回答,我创建了一个存储过程,我从批处理文件中执行:
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;
是否可以从备份恢复 SQL 服务器数据库,同时使用新名称创建 *.mdf
和 *.ldf
文件?
假设我知道每个备份只有两个文件(一个 mdf
和一个 ldf
),但我不知道这些文件的确切名称,不幸的是我不能' t 从数据库名称派生它们。
所有这一切的目的是创建批处理文件,该文件将从一组备份文件中恢复数据库。同时我必须解决文件名冲突的问题。
目前我有这个命令,它不适用于每个备份,因为一些数据库文件的命名与变量 %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'
...
可以使用RESTORE FILELISTONLY
获取备份中数据文件的详细信息。
您可以将此信息放入 table 中,您可以通过将其插入临时 table 或 table 变量来构建还原语句。要将其集成到您现有的代码中:
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'
在data/log个文件的场景下,代码需要相应地更复杂。
解决文件名冲突可能性的一种方法是将时间戳、GUID 或其他合理的唯一标识符附加到新文件名。
基于上述回答,我创建了一个存储过程,我从批处理文件中执行:
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;