2014-10-15 3 views
0

Мне часто нужно восстановить базу данных из файлов резервных копий на моем SQL-сервере, и у меня есть настраиваемый скрипт, который позаботится об этом. В основном сценарий использует команду RESTORE и имеет переменные во всем, чтобы заменить имя базы данных, папку с файлом bak и т. Д. Однако одна проблема, с которой я сталкиваюсь, заключается в восстановлении базы данных, разбитой на несколько файлов, время от времени увеличивается до 100.Восстановление резервной копии базы данных, состоящей из нескольких файлов по сценарию

Итак, мой вопрос заключается в том, как создать динамический сценарий, чтобы я мог просто указать количество файлов, и скрипт будет перебирать все файлы и восстанавливать их. Насколько я понимаю, команда RESTORE не допускает такой гибкости.

Один из вариантов, который я вижу сейчас, состоит в том, чтобы динамически генерировать всю команду RESTORE, а затем выполнять ее, но я хочу использовать ее только в качестве последней опции.

Есть ли другие варианты?

Спасибо,

ответ

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) 
0

Я думаю, что вы ищете это решение, которое я придумал, чтобы восстановить несжатые файлы LiteSpeed. Поскольку количество файлов различается в зависимости от того, сколько потоков litespeed было доступно во время резервного копирования, мы никогда не знаем, сколько файлов потребуется включить для восстановления в нашей среде отчетов. Я использовал использование Владимиром функции материала и еще один скрипт, чтобы сделать следующее. Замените 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)