我经常需要从我的SQL服务器上的备份文件中恢复数据库,并且我有一个可配置的脚本来处理这个问题。基本上,脚本使用RESTORE命令,并且全部都有变量来替换数据库名称,bak文件夹等。但是,我面临的一个问题是恢复一个数据库,该数据库被分成多个文件,有时数量会增加到100。 / p>
所以我的问题是如何使脚本动态化,以便我可以指定文件计数,脚本将遍历所有文件并恢复它。据我所知,RESTORE命令不允许这种灵活性。
我现在看到的一个选项是动态生成整个RESTORE命令然后执行它,但我只想将它作为最后一个选项使用。
还有其他选择吗?
谢谢,
答案 0 :(得分:1)
我不确定我是否理解“指定文件计数”,但我使用某种脚本为自己实现测试环境。我希望它对你有所帮助。随意问我
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,
IsReadOnl bit,
IsPresent bit,
TDEThumbprint varbinary(32)
)
insert into @fileListTable exec('restore filelistonly from disk = ''C:\Share\BackUp\Reporting\Prod23.bak''') -- hear I get all files from backup
select * from @fileListTable
declare @sctript nvarchar(max)
select
@sctript = 'restore database Prod from disk = ''C:\Share\BackUp\Reporting\Prod23.bak'' WITH FILE = 1,' +
STUFF( (SELECT results.MoveTo + ' , '
from
(
select
'MOVE ''' + LogicalName+ ''' TO ''E:\MobiledbnkDB_Report\' + LogicalName +
case [Type]
when 'D' then '.mdf'
when 'L' then '.ldf'
end + ''' ' as MoveTo
FROM @fileListTable -- hear I mode files to another folder
) as results
FOR XML PATH('')),
1, 0, '')
+ ' NOUNLOAD, STATS = 5'
use master
if exists(SELECT * FROM sys.databases d WITH(NOLOCK) where d.name = 'Prod')
begin
alter database Prod set restricted_user with rollback immediate
drop database Prod
end
print @sctript
exec (@sctript)
答案 1 :(得分:0)
我认为您正在寻找的是我提出的用于恢复未压缩的LiteSpeed文件的解决方案。由于文件数量根据备份时litespeed可用的线程数而有所不同,因此我们永远不知道要还原到报告环境需要包含多少文件。我使用了Vladimir使用stuff函数和另一个脚本来执行以下操作。将FILELOCATION替换为您的文件夹并更新您的数据库,数据和日志文件名。
Declare @BackupFolder nvarchar(100) = N'FILELOCATION'
DECLARE @BackupDirectory SYSNAME = @BackupFolder
IF OBJECT_ID('tempdb..#DirTree') IS NOT NULL
DROP TABLE #DirTree
CREATE TABLE #DirTree (
Id int identity(1,1),
SubDirectory nvarchar(255),
Depth smallint,
FileFlag bit,
ParentDirectoryID int
)
INSERT INTO #DirTree (SubDirectory, Depth, FileFlag)
EXEC master..xp_dirtree @BackupDirectory, 10, 1
UPDATE #DirTree
SET ParentDirectoryID = (
SELECT MAX(Id) FROM #DirTree d2
WHERE Depth = d.Depth - 1 AND d2.Id < d.Id
)
FROM #DirTree d
DECLARE
@ID INT,
@BackupFile VARCHAR(MAX),
@Depth TINYINT,
@FileFlag BIT,
@ParentDirectoryID INT,
@wkSubParentDirectoryID INT,
@wkSubDirectory VARCHAR(MAX)
DECLARE @BackupFiles TABLE
(
FileNamePath VARCHAR(MAX),
TransLogFlag BIT,
BackupFile VARCHAR(MAX),
DatabaseName VARCHAR(MAX)
)
DECLARE FileCursor CURSOR LOCAL FORWARD_ONLY FOR
SELECT * FROM #DirTree WHERE FileFlag = 1
OPEN FileCursor
FETCH NEXT FROM FileCursor INTO
@ID,
@BackupFile,
@Depth,
@FileFlag,
@ParentDirectoryID
SET @wkSubParentDirectoryID = @ParentDirectoryID
WHILE @@FETCH_STATUS = 0
BEGIN
--loop to generate path in reverse, starting with backup file then prefixing subfolders in a loop
WHILE @wkSubParentDirectoryID IS NOT NULL
BEGIN
SELECT @wkSubDirectory = SubDirectory, @wkSubParentDirectoryID = ParentDirectoryID
FROM #DirTree
WHERE ID = @wkSubParentDirectoryID
SELECT @BackupFile = @wkSubDirectory + '\' + @BackupFile
END
SELECT @BackupFile = @BackupDirectory + @BackupFile
INSERT INTO @BackupFiles (FileNamePath) VALUES(@BackupFile)
FETCH NEXT FROM FileCursor INTO
@ID,
@BackupFile,
@Depth,
@FileFlag,
@ParentDirectoryID
SET @wkSubParentDirectoryID = @ParentDirectoryID
END
CLOSE FileCursor
DEALLOCATE FileCursor
SELECT @BackupFolder + '\' + SubDirectory from #DirTree
Declare @filecount int = (select count(*) from #DirTree)
declare @sctript nvarchar(max)
select
@sctript = 'RESTORE DATABASE rrrealty FROM ' +
STUFF( (SELECT +',' + results.MoveTo
from
(
select 'DISK = N''' + 'FILELOCATION' + SubDirectory + '''' as MoveTo
FROM #DirTree -- hear I mode files to another folder
) as results
FOR XML PATH('')),
1, 1, '') + ' WITH FILE = 1
MOVE N''file'' TO N''file.mdf'',
MOVE N''file_Log'' TO N''L:\filelog.ldf'',
NOUNLOAD, REPLACE, STATS = 5'
Exec (@sctript)