我需要以编程方式(T-SQL)还原SQL Server 2008中的数据库备份。此备份来自不同的服务器,原始数据库名称也可能不同。 (实际上,我正在将数据库从某个服务器复制到另一台服务器上的新数据库。)
显然,我必须使用RESTORE DATABASE ... WITH MOVE
,但是我需要知道应该将文件恢复到哪里以及如何命名它们。尽管搜索,我还没有找到似乎是最基本的任务:只使用默认路径和文件名,即执行SQL Server在发出CREATE DATABASE
时所做的一切 - 您不必指定该命令的路径,为什么RESTORE
需要它?
我是否忽略了一些简单的解决方案,或者我是否真的必须列出文件,以某种方式从SQL Server配置中找到数据库目录,并使用该信息构建RESTORE
命令?感谢。
(与PostgreSQL相比,使用pg_restore时,你指定一个已经创建的目标数据库;当你创建它时,你有选择 - 不是必须的 - 指定一个非默认的表空间,但如果你没有' t,你只是不关心文件的物理存储位置。)
答案 0 :(得分:9)
未来的Google员工;从 SQL Server 2012 开始 ,您可以使用:
SELECT ServerProperty(N'InstanceDefaultDataPath') AS default_file
, ServerProperty(N'InstanceDefaultLogPath') AS default_log
;
这将读取服务器属性>下显示的文件夹路径。数据库设置>数据库默认位置
答案 1 :(得分:5)
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
答案 2 :(得分:4)
我刚才写了一个函数,它为你做了这个。它支持所有版本的SQL Server,包括具有默认实例和命名实例的安装。 See here for the code and an example
要进行恢复,您将调用如下所示的函数。
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)
答案 3 :(得分:2)
您必须阅读注册表,例如
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
答案 4 :(得分:2)
我必须自己这样做,最后我结合了几个答案来创建一个恢复数据库(任何数据库)并重新映射文件的脚本。您只需知道备份文件的路径和新的数据库名称。不幸的是,这个问题似乎没有任何简洁的解决方案。
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)
注意:我知道这是一个老帖子,但它可能对前进的人有用。
答案 5 :(得分:1)
如前所述,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'
可以找到全自动脚本here
答案 6 :(得分:0)
如果您的意思是使用Management Studio的“新建数据库”选项,则会默认使用某些值。但是CREATE DATABASE的T-SQL仍然需要路径。您可以通过转到管理工作室,选择“新建数据库”,输入新名称,然后单击“脚本”按钮来查看。此按钮将为您提供SQL Server将运行的T-SQL。此过程实际上并未运行,因此您可以取消“新建数据库”向导。
还原时还有一个类似的按钮。因此,如果您已经拥有所有信息并且只需要T-SQL,请通过管理工作室进行还原,但不要单击“确定”以运行该过程,而是单击“脚本”按钮,该按钮将生成带有默认值的T-SQL值。
希望这有帮助。