Как восстановить резервную копию базы данных SQL Server, не зная пути назначения или имен файлов?

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

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

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

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


person user1224797    schedule 22.02.2012    source источник


Ответы (7)


Для будущих сотрудников Google; начиная с SQL Server 2012 и далее вы можете использовать:

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

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

«Свойства

person gvee    schedule 03.05.2016

Недавно я написал функцию, которая делает это за вас. Он поддерживает все версии 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)
person Filip De Vos    schedule 22.02.2012

Команда 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
person David Martin    schedule 27.04.2015
comment
затем я пробую это в sqlcmd или SQL Query, я получаю: File 'MyDBnameHere' cannot be restored to 'M:\myOLDserverPath\MyDBnameHere.mdf'. Use WITH MOVE to identify a valid location for the file. - person Tilo; 06.08.2016

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

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
person Artineer    schedule 22.02.2012
comment
Добро пожаловать в StackOverflow: если вы публикуете образцы кода, XML или данных, пожалуйста, выделите эти строки в текстовом редакторе и нажмите кнопку образцов кода ( { } ) на панели инструментов редактора, чтобы красиво отформатировать и выделить синтаксис. ! - person marc_s; 22.02.2012

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

-- 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'

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

person Ondrej    schedule 23.12.2016

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

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)

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

person webwake    schedule 23.08.2017
comment
Для SQL Server 2019 добавьте [SnapshotURL] nvarchar(360) к определению таблицы @fileListTable. - person ScottBurfieldMills; 04.06.2020

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

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

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

person Douglas    schedule 22.02.2012