Как восстановить резервную копию базы данных SQL Server, не зная пути или имен файлов? - PullRequest
13 голосов
/ 22 февраля 2012

Мне нужно программно (T-SQL) восстановить резервную копию базы данных в SQL Server 2008. Эта резервная копия поступает с другого сервера, и исходное имя базы данных также может отличаться.(По сути, я копирую базу данных с одного сервера в новую базу данных на другом сервере.)

Очевидно, я должен использовать RESTORE DATABASE ... WITH MOVE, который работает, но мне нужно знать, где файлы должныбыть восстановлены и как они должны быть названы.Несмотря на поиск, я не нашел то, что казалось бы самой основной задачей: просто используйте путь и имена файлов по умолчанию, т.е. делайте то, что делает SQL Server, когда вы выдаете CREATE DATABASE - вам не нужно указыватьпуть к этой команде, так зачем он нужен для RESTORE?

Я пропустил какое-то тривиальное решение или мне действительно нужно будет перечислить файлы, каким-то образом найти каталог базы данных из конфигурации SQL Server,и использовать эту информацию для создания команды RESTORE?Спасибо.

(По сравнению с PostgreSQL, где при использовании pg_restore вы указываете целевую базу данных, которая уже создана; и при ее создании у вас была возможность - не обязательно - указывать табличное пространство не по умолчанию,но если вы этого не сделали, вам просто все равно, где физически хранятся файлы.)

Ответы [ 7 ]

9 голосов
/ 03 мая 2016

для будущих гуглов; от SQL Server 2012 и далее вы можете использовать:

SELECT ServerProperty(N'InstanceDefaultDataPath') AS default_file
     , ServerProperty(N'InstanceDefaultLogPath') AS default_log
;

Это считывает пути к папкам, которые отображаются в Свойства сервера> Настройки базы данных> Расположение базы данных по умолчанию

image Database Settings">

5 голосов
/ 27 апреля 2015

Команда CREATE DATABASE создаст базу данных с путями по умолчанию, поэтому вы можете создать базу данных, а затем восстановить ее, используя синтаксис замены (режим sqlcmd):

:setvar DatabaseName MyDatabase
declare @fileName varchar(255)
set @fileName = 'c:\backup\mybackup.bak'

if db_id('$(DatabaseName)') is null
            CREATE DATABASE [$(DatabaseName)]

RESTORE DATABASE [$(DatabaseName)]
FROM DISK = @fileName
WITH REPLACE
4 голосов
/ 22 февраля 2012

Я недавно написал функцию, которая делает это для вас. Он поддерживает все версии SQL Server, включая установки с экземплярами по умолчанию и именованными экземплярами. См. Здесь код и пример

Чтобы выполнить восстановление, вы вызовете функцию, как показано ниже.

declare @sql nvarchar(2000), 
        @data varchar(260), 
        @log varchar(260); 

select @data = dbo.fn_get_default_path(0),
       @log = dbo.fn_get_default_path(1)

SELECT @sql= 'RESTORE DATABASE DefaultLocationDB 
FROM  DISK = N''c:\backups\DemoDB.bak'' WITH  FILE = 1,  
MOVE N''demo_data_device'' TO N''' + @data + '\DemoDb.mdf'',  
MOVE N''demo_log_device'' TO N''' +  @log + '\DemoDb.ldf'',  
NOUNLOAD, REPLACE'

exec (@sql)
2 голосов
/ 23 августа 2017

Я должен был сделать это сам, и в итоге я скомбинировал несколько ответов, чтобы создать один скрипт, который восстанавливает базу данных (любую базу данных) и перераспределяет файлы. Все, что вам нужно знать, это путь к файлу резервной копии и имя новой базы данных. К сожалению, похоже, что нет кратких решений этой проблемы.

DECLARE @Source nvarchar(max) = 'C:\backup.bak'
DECLARE @RestoreDestination nvarchar(max) = 'NewDatabaseName'

--https://stackoverflow.com/a/27893494/5734516
--https://stackoverflow.com/a/4018782/5734516
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) -- remove this column if using SQL 2005
)

DECLARE @QueryCommand nvarchar(max) =
 'RESTORE FILELISTONLY FROM DISK = N''' + REPLACE(@Source, '''', '''''') + ''' WITH NOUNLOAD'

INSERT INTO @fileListTable 
EXEC(@QueryCommand)


--https://stackoverflow.com/a/2014673/5734516
DECLARE @filepath NVARCHAR(260)
EXEC master.dbo.xp_instance_regread 
        N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', 
        N'DefaultData', 
        @filepath output, 'no_output'


DECLARE @Command nvarchar(max) 
SET @Command = 'RESTORE DATABASE ' + QUOTENAME(@RestoreDestination)  + ' '
                + ' FROM DISK=N''' + REPLACE(@Source, '''', '''''') + ''' '
                + 'WITH FILE=1 '
SELECT 
    @Command = @Command + ',MOVE N''' + REPLACE(LogicalName, '''', '''''') + '''' 
    + ' TO N'''  
        + REPLACE(@filepath + '\' + @RestoreDestination + case when FileID = 1 then '.mdf' when Type = 'L' then '_' + CAST(FileID as varchar(max)) + '.ldf' else '_' + CAST(FileID as varchar(max)) + '.ndf' end, '''', '''''')
    + '''' 
FROM @fileListTable 

SELECT @Command
EXEC(@Command)

Примечание: я знаю, что это старый пост, но он может пригодиться кому-то в будущем.

2 голосов
/ 24 декабря 2016

Как уже упоминалось, CREATE DATABASE создает файлы в расположении по умолчанию. Затем вы можете найти пути к этим файлам и использовать их в RESTORE part

-- Database will be created in default location
CREATE DATABASE [MyRestoredDatabase] 

DECLARE @mdfFile VARCHAR(MAX)
DECLARE @ldfFile VARCHAR(MAX)

SELECT @mdfFile = physical_name
FROM sys.master_files
WHERE database_id = DB_ID('MyRestoredDatabase')
AND file_id = 1

SELECT @ldfFile = physical_name
FROM sys.master_files
WHERE database_id = DB_ID('MyRestoredDatabase')
AND file_id = 2

-- Overwrite known files of the new database from restore 
RESTORE DATABASE [MyRestoredDatabase] 
FROM DISK='C:\Path\To\OriginalDatabase.bak'
WITH REPLACE,
    MOVE 'OriginalDatabase' TO @mdfFile,
    MOVE 'OriginalDatabase_Log' TO @ldfFile

Если вам нужно узнать логические имена, используйте следующий SQL

RESTORE FILELISTONLY
FROM DISK='C:\Path\To\MyRestoredDatabase.bak'

Полностью автоматизированный скрипт можно найти здесь

2 голосов
/ 22 февраля 2012

Вы должны прочитать регистр, как

DECLARE @Result NVARCHAR(4000) 
EXECUTE [master].[dbo].xp_instance_regread 
N'HKEY_LOCAL_MACHINE', 
N'Software\Microsoft\MSSQLServer\MSSQLServer',N'BackupDirectory', 
@Result OUTPUT,  
'NO_OUTPUT' 
SELECT @Result
0 голосов
/ 22 февраля 2012

Если вы имеете в виду использование опции «Новая база данных» в Management Studio, то некоторые значения по умолчанию отображаются по умолчанию.Но T-SQL для CREATE DATABASE все еще требует путей.Это можно увидеть, зайдя в студию управления, выбрав «Новая база данных», введите новое имя и нажмите кнопку «Сценарий».Эта кнопка предоставит вам T-SQL, который будет работать на SQL Server.Этот процесс фактически не запускается, поэтому вы можете отменить его из мастера создания новой базы данных.

При восстановлении также имеется аналогичная кнопка.Поэтому, если у вас уже есть вся информация и вам нужен только T-SQL, пройдите через среду управления, чтобы выполнить восстановление, но вместо нажатия OK, чтобы запустить процесс, нажмите кнопку «Сценарий», которая сгенерирует вам T-SQL со значением по умолчанию.значения.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...