我有一周前的Database1备份。在调度程序中每周进行备份,我得到一个.bak文件。现在我想要处理一些数据,所以我需要将其恢复到另一个数据库- Database2。

我看到过这个问题:在同一台pc上使用不同的名称恢复SQL Server数据库,建议步骤是重命名原始db,但我不在这个选项中,因为我在生产服务器中,我不能真正做到这一点。

是否有其他方法将其恢复到Database2,或者至少如何浏览该.bak文件的数据?

谢谢。

Ps:上面链接的第二个答案看起来很有希望,但它总是以错误告终:

恢复文件列表异常终止


当前回答

当我使用旧数据库恢复新数据库时,遇到了与本主题相同的错误。(使用.bak也会出现同样的错误) 我用新数据库的名称更改了旧数据库的名称(与此图相同)。它工作。

其他回答

以下是我从各种文章中拼凑出来的内容,使用备份和恢复来复制数据库,并使用move来修复物理位置,使用额外的sql来修复逻辑名称。

/**
 * Creates (or resets) a Database to a copy of the template database using backup and restore.
 *
 * Usage: Update the @NewDatabase value to the database name to create or reset.
 */

DECLARE @NewDatabase SYSNAME = 'new_db';

-- Set up
USE tempdb;

DECLARE @TemplateBackups SYSNAME = 'TemplateBackups';
DECLARE @TemplateDatabase SYSNAME = 'template_db';
DECLARE @TemplateDatabaseLog SYSNAME = @TemplateDatabase + '_log';

-- Create a backup of the template database
BACKUP DATABASE @TemplateDatabase TO DISK = @TemplateBackups WITH CHECKSUM, COPY_ONLY, FORMAT, INIT, STATS = 100;

-- Get the backup file list as a table variable
DECLARE @BackupFiles TABLE(LogicalName nvarchar(128),PhysicalName nvarchar(260),Type char(1),FileGroupName nvarchar(128),Size numeric(20,0),MaxSize numeric(20,0),FileId tinyint,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));
INSERT @BackupFiles EXEC('RESTORE FILELISTONLY FROM DISK = ''' + @TemplateBackups + '''');

-- Create  the backup file list as a table variable
DECLARE @NewDatabaseData VARCHAR(MAX);
DECLARE @NewDatabaseLog VARCHAR(MAX);

SELECT @NewDatabaseData = PhysicalName FROM @BackupFiles WHERE Type = 'D';
SELECT @NewDatabaseLog = PhysicalName FROM @BackupFiles WHERE Type = 'L';

SET @NewDatabaseData = REPLACE(@NewDatabaseData, @TemplateDatabase, @NewDatabase);
SET @NewDatabaseLog = REPLACE(@NewDatabaseLog, @TemplateDatabase, @NewDatabase);

RESTORE DATABASE @NewDatabase FROM DISK = @TemplateBackups WITH CHECKSUM, RECOVERY, REPLACE, STATS = 100,
   MOVE @TemplateDatabase TO @NewDatabaseData,
   MOVE @TemplateDatabaseLog TO @NewDatabaseLog;

-- Change Logical File Name
DECLARE @SQL_SCRIPT VARCHAR(MAX)='
    ALTER DATABASE [{NewDatabase}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    ALTER DATABASE [{NewDatabase}] MODIFY FILE (NAME=N''{TemplateDatabase}'', NEWNAME=N''{NewDatabase}'');
    ALTER DATABASE [{NewDatabase}] MODIFY FILE (NAME=N''{TemplateDatabase}_log'', NEWNAME=N''{NewDatabase}_log'');
    ALTER DATABASE [{NewDatabase}] SET MULTI_USER WITH ROLLBACK IMMEDIATE;
    SELECT name AS logical_name, physical_name FROM SYS.MASTER_FILES WHERE database_id = DB_ID(N''{NewDatabase}'');
';
SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{TemplateDatabase}', @TemplateDatabase);
SET @SQL_SCRIPT = REPLACE(@SQL_SCRIPT, '{NewDatabase}', @NewDatabase);
EXECUTE (@SQL_SCRIPT);

下面介绍如何将备份恢复为具有唯一db名称的附加db。

对于SQL 2005,这工作得非常快。我相信更新的版本也会有同样的效果。

首先,您不必让原始db脱机。但为了安全起见,我还是想。在我的例子中,我将挂载我的“账单”数据库的克隆,它将被命名为“billingclone”。

1)做好计费数据库的备份

2)为了安全起见,我将原件下线如下:

3)打开一个新的查询窗口

* *重要!保持这个查询窗口打开,直到全部完成!你需要从这个窗口恢复数据库!

现在输入以下代码:

-- 1) free up all USER databases
USE master;
GO
-- 2) kick all other users out:
ALTER DATABASE billing SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
-- 3) prevent sessions from re-establishing connection:
ALTER DATABASE billing SET OFFLINE;

3)接下来,在管理工作室,在对象资源管理器中单击数据库,选择“恢复数据库”

4)在“To Database”字段中输入新的名称。即billingclone

5)在“Source for Restore”中,点击“From Device”,点击…导航按钮

6)单击Add并导航到您的备份

7)在“恢复”旁打勾(选择要恢复的备份集)

8)接下来选择上方LH角的OPTIONS页面

9)现在在RESTORE AS中编辑数据库文件名。对db和日志都这样做。即billingclone。MDF和billingclone_log.ldf

10)现在点击OK,等待任务完成。

11)在对象资源管理器中点击刷新,你将看到你的新db

12)现在你可以把你的账单数据库重新上线了。使用脱机计费时使用的相同查询窗口。使用该命令:

-- 1) free up all USER databases
USE master; GO
-- 2) restore access to all users:
ALTER DATABASE billing SET MULTI_USER WITH ROLLBACK IMMEDIATE;GO
-- 3) put the db back online:
ALTER DATABASE billing SET ONLINE;

完成了!

如果不存在数据库,我使用以下代码:

ALTER PROCEDURE [dbo].[RestoreBackupToNewDB]    
         @pathToBackup  varchar(500),--where to take backup from
         @pathToRestoreFolder  varchar(500), -- where to put the restored db files 
         @newDBName varchar(100)
    AS
    BEGIN

            SET NOCOUNT ON
            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
            )
            INSERT INTO @fileListTable EXEC('RESTORE FILELISTONLY FROM DISK ='''+ @pathToBackup+'''')
            DECLARE @restoreDatabaseFilePath NVARCHAR(500)
            DECLARE @restoreLogFilePath NVARCHAR(500)
            DECLARE @databaseLogicName NVARCHAR(500)
            DECLARE @logLogicName NVARCHAR(500)
            DECLARE @pathSalt uniqueidentifier = NEWID()

            SET @databaseLogicName = (SELECT LogicalName FROM @fileListTable WHERE [Type]='D') 
            SET @logLogicName = (SELECT LogicalName FROM @fileListTable WHERE [Type]='L')           
            SET @restoreDatabaseFilePath= @pathToRestoreFolder + @databaseLogicName + convert(nvarchar(50), @pathSalt) + '.mdf'
            SET @restoreLogFilePath= @pathToRestoreFolder + @logLogicName + convert(nvarchar(50), @pathSalt) + '.ldf'

            RESTORE DATABASE @newDBName FROM DISK=@pathToBackup     
            WITH 
               MOVE @databaseLogicName TO @restoreDatabaseFilePath,
               MOVE @logLogicName TO @restoreLogFilePath

            SET NOCOUNT OFF
    END

SQL Server 2008 R2:

对于您希望“从不同数据库的备份恢复:”的现有数据库,请执行以下步骤:

From the toolbar, click the Activity Monitor button. Click processes. Filter by the database you want to restore. Kill all running processes by right clicking on each process and selecting "kill process". Right click on the database you wish to restore, and select Tasks-->Restore-->From Database. Select the "From Device:" radio button. Select ... and choose the backup file of the other database you wish to restore from. Select the backup set you wish to restore from by selecting the check box to the left of the backup set. Select "Options". Select Overwrite the existing database (WITH REPLACE) Important: Change the "Restore As" Rows Data file name to the file name of the existing database you wish to overwrite or just give it a new name. Do the same with the log file file name. Verify from the Activity Monitor Screen that no new processes were spawned. If they were, kill them. Click OK.

用“复制数据库”选项从数据库中复制一个不同的名称 备份新复制的数据库 恢复它!