sql-server - Microsoft SQL Server,使用一个命令恢复数据库的备份

标签 sql-server sql-server-2005 tsql

当我们从生产环境复制数据库时,我们会备份数据库,将其压缩并复制备份。然后我们必须使用 SQL Server GUI 进行恢复,这涉及到几个菜单和窗口的导航。据我所知,您不能使用 SQL Server 的内置存储过程来执行此操作,因为您可能不知道数据库的逻辑文件名(这是恢复所需的)。因此,通过查询执行此操作包括以下内容:

RESTORE FILELISTONLY
FROM DISK = 'C:\backup_of_production_database.bak'
GO

上面提供了备份文件中的逻辑文件名,然后您必须在下一个查询中使用这些逻辑名称...

RESTORE DATABASE NewDevelopmentDatabase
FROM DISK = 'C:\backup_of_production_database.bak'
WITH MOVE 'YourMDFLogicalName' TO 'C:\mssql\data\DataYourMDFFile.mdf',
MOVE 'YourLDFLogicalName' TO 'C:\mssql\data\DataYourLDFFile.mdf'

正如您所看到的,这似乎效率很低,因为您必须在下一个查询中手动输入逻辑文件名。

您可以在下面找到我对此问题的解决方案。

最佳答案

这是一个无需交互即可恢复数据库的 SQL 脚本。 只需输入您的“源数据库”和“目标数据库” - 脚本将完成剩下的工作:)

SET NOCOUNT ON;

DECLARE 
    @MySourceDatabase NVarchar(1000),
    @MyDestinationDatabase NVarchar(100),
    @DeviceFrom NVarchar(1000),
    @DeviceTo NVarchar(1000),
    @LogicalName NVarchar(1000),
    @PhysicalName NVarchar(1000),
    @SQL NVarchar(MAX),
    @RowsToProcess integer,
    @CurrentRow integer,
    @Comma NVarchar(25);

--SOURCE DATABASE (DATABASE TO RESTORE)
SET @MySourceDatabase = 'D:\Backups\backup_db.bak';

--DESTINATION DATABASE (DATABASE TO RESTORE TO)
SET @MyDestinationDatabase = 'mydatabase_db';

SELECT @DeviceFrom = SUBSTRING(physical_name, 1,
CHARINDEX(@MyDestinationDatabase + '.mdf',
physical_name) - 1) 
FROM master.sys.master_files
WHERE name = @MyDestinationDatabase AND FILE_ID = 1;

SET @SQL = 'RESTORE DATABASE ' + @MyDestinationDatabase + ' FROM DISK = ''' + @MySourceDatabase + ''' WITH ';
SET @CurrentRow = 0;
SET @Comma = ',';

DECLARE @FileList TABLE (
    RowID int not null primary key identity(1,1)
    ,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 BIGINT 
    ,FilegroupId BIGINT 
    ,LogGroupGUID uniqueidentifier 
    ,DifferentialBaseLSN numeric(25) 
    ,DifferentialBaseGUID uniqueidentifier 
    ,IsReadOnly BIGINT 
    ,IsPresent BIGINT
    ,TDEThumbprint VARBINARY(32) -- Remove this line for SQL Server 2005
    );

INSERT INTO @FileList
EXEC('RESTORE FILELISTONLY FROM DISK = ''' + @MySourceDatabase + '''')
SET @RowsToProcess = @@RowCount;

WHILE @CurrentRow < @RowsToProcess
BEGIN
    SET @CurrentRow= @CurrentRow + 1;
    BEGIN
    IF @CurrentRow = @RowsToProcess
        SET @Comma = ',REPLACE';
    END
    SELECT @LogicalName = LogicalName,@PhysicalName = PhysicalName FROM @FileList WHERE RowID=@CurrentRow;
    SET @PhysicalName = Replace(@PhysicalName,@LogicalName,@MyDestinationDatabase);
    SET @SQL = @SQL + 'MOVE ''' + @LogicalName + ''' TO ''' + @PhysicalName + '''' + @Comma + '';
END

--PREVIEW THE GENERATED QUERY
SELECT @SQL;

--EXECUTE THE GENERATED QUERY
--EXEC(@SQL);

它会自动生成一个查询,例如:

RESTORE DATABASE mydatabase_db 
FROM DISK = 'D:\Backups\backup_db.bak' 
WITH 
MOVE 'backup_db' 
TO 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\mydatabase_db.mdf',
MOVE 'backup_db_log' 
TO 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\mydatabase_db.LDF',
REPLACE

关于sql-server - Microsoft SQL Server,使用一个命令恢复数据库的备份,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/962441/

相关文章:

sql - VS 2013 中是否有 localdb (mdf) 的级联删除选项

sql-server - 我可以从具有不同数据类型的键值表创建动态数据透视查询吗?

c# - 两个相似的 LINQ 查询,生成的 SQL 完全不同

sql-server - 是否可以将 View 编写为 SQL Server 中的表?

sql - 帮助 PIVOT

asp.net - 将整个数据集传递给 MSSQL 2005 中的存储过程

sql - 如何在插入期间使用标识作为列值

sql-server - 修改MS SQL存储过程的快速方法

SQL查询以获取具有子记录列表的父表的记录

sql - 如何根据另一个表中的记录数复制值