【问题标题】:How to restore to a different database in SQL Server?如何在 SQL Server 中恢复到不同的数据库?
【发布时间】:2011-09-10 04:05:00
【问题描述】:

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

我看到了这个问题:Restore SQL Server database in same pc with different name,建议的步骤是重命名原始数据库,但我没有那个选项,因为我在生产服务器中,我真的做不到。

有没有其他方法可以将它恢复到Database2,或者至少,我如何浏览那个 .bak 文件的数据?

谢谢。

ps:上面链接的第二个答案看起来很有希望,但它一直以错误终止:

恢复文件列表异常终止

【问题讨论】:

    标签: sql-server-2008 backup restore


    【解决方案1】:

    实际上比恢复到同一个服务器要简单一些。基本上,您只需浏览“还原数据库”选项。这是给你的教程:

    http://www.techrepublic.com/blog/window-on-windows/how-do-i-restore-a-sql-server-database-to-a-new-server/454

    特别是因为这是一个非生产恢复,您可以放心地尝试一下,而不必过多担心细节。只需将您的 SQL 文件放在新服务器上您想要的位置,并为其命名您想要的任何名称,您就可以开始了。

    【讨论】:

    • 您好,我需要还原到同一台服务器,不同的数据库...(还原数据库的名称不同)
    • 对不起,我误读了这个问题。相同的基本原则适用,您只需要确保新名称和文件名(mdf、ldf 等)不同。
    【解决方案2】:

    您可以创建一个新数据库,然后使用“恢复向导”启用覆盖选项或:

    查看备份文件的内容:

    RESTORE FILELISTONLY FROM DISK='c:\your.bak'
    

    从结果中记下 .mdf & .ldf 的逻辑名称,然后:

    RESTORE DATABASE MyTempCopy FROM DISK='c:\your.bak'
    WITH 
       MOVE 'LogicalNameForTheMDF' TO 'c:\MyTempCopy.mdf',
       MOVE 'LogicalNameForTheLDF' TO 'c:\MyTempCopy_log.ldf'
    

    这将使用your.bak 的内容创建数据库MyTempCopy

    (不要创建 MyTempCopy,它是在还原期间创建的)


    示例(将名为“creditline”的数据库的备份恢复到“MyTempCopy”):

    RESTORE FILELISTONLY FROM DISK='e:\mssql\backup\creditline.bak'
    
    >LogicalName
    >--------------
    >CreditLine
    >CreditLine_log
    
    RESTORE DATABASE MyTempCopy FROM DISK='e:\mssql\backup\creditline.bak'
    WITH 
       MOVE 'CreditLine' TO 'e:\mssql\MyTempCopy.mdf',
       MOVE 'CreditLine_log' TO 'e:\mssql\MyTempCopy_log.ldf'
    
    >RESTORE DATABASE successfully processed 186 pages in 0.010 seconds (144.970 MB/sec).
    

    【讨论】:

    • 嗨,我似乎遗漏了一些东西,它不断抛出错误backkup set holds a backup of a database other than existing "tmp" database,我明白了。 to 短语应该是 MyTempCopy 的实际物理路径吗?
    • 奇怪,to 是新数据库的数据库和日志位置,更新上面的示例
    • 对于其他尝试此操作的人,请勿创建 MyTempCopy,它是在还原期间创建的。
    • 在我的情况下(SQL2012)cr 仅适用于 REPLACE、RECOVERY、选项。 dba.stackexchange.com/questions/51489/…
    • 应该使用 REPLACE, RECOVERY 来解决这个问题。所以这将是:RESTORE DATABASE MyTempCopy FROM DISK='e:\mssql\backup\creditline.bak' WITH REPLACE, RECOVERY, MOVE 'CreditLine' TO 'e:\mssql\MyTempCopy.mdf', MOVE 'CreditLine_log' TO 'e:\mssql\MyTempCopy_log.ldf'
    【解决方案3】:

    SQL Server 2008 R2:

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

    1. 在工具栏中,单击“活动监视器”按钮。
    2. 单击进程。按要还原的数据库过滤。通过右键单击每个进程并选择“终止进程”来终止所有正在运行的进程。
    3. 右键单击要恢复的数据库,然后选择任务-->恢复-->从数据库。
    4. 选择“来自设备:”单选按钮。
    5. 选择 ... 并选择要从中恢复的其他数据库的备份文件。
    6. 选中备份集左侧的复选框,选择要从中还原的备份集。
    7. 选择“选项”。
    8. 选择覆盖现有数据库(替换)
    9. 重要提示:将“恢复为”行数据文件名更改为您希望覆盖的现有数据库的文件名,或者只是给它一个新名称。
    10. 对日志文件文件名执行相同操作。
    11. 从活动监视器屏幕验证没有产生新进程。如果是,就杀了他们。
    12. 点击确定。

    【讨论】:

    • 尽管是程序员,我还是更愿意使用这个向导。更简单、更清洁。
    • 对我来说关键步骤是#8。谢谢丹尼尔。
    • Sql 2014.. 步骤 6a:将目标数据库更改为您希望还原到的数据库。第 9 步和第 10 步:这应该通过更改目标数据库为您解决。但是通过转到文件并检查原始步骤 9 和 10 中所述的文件名来仔细检查。
    【解决方案4】:

    对于 SQL Server 2012,使用 Sql Server Management Studio,我发现 Microsoft 页面中的这些步骤对于还原到不同的数据库文件和名称很有用:(参考:http://technet.microsoft.com/en-us/library/ms175510.aspx

    注意 第 4 步和第 7 步的设置很重要,以免覆盖现有数据库。


    将数据库恢复到新位置,并可选择重命名数据库

    1. 连接到适当的 SQL Server 数据库引擎实例,然后在对象资源管理器中,单击服务器名称以展开 服务器树。
    2. 右键单击数据库,然后单击恢复数据库恢复数据库对话框打开。
    3. 常规页面上,使用来源部分指定要恢复的备份集的来源和位置。选择其中之一 以下选项:

      • 数据库

        • 从下拉列表中选择要恢复的数据库。该列表仅包含已根据 msdb 备份历史记录。

          注意如果备份来自不同的服务器,目标服务器将没有备份历史信息 对于指定的数据库。在这种情况下,选择设备手动 指定要恢复的文件或设备。

      • 设备

        • 单击浏览 (...) 按钮打开 选择备份设备 对话框。在备份媒体类型框中,选择以下之一 列出的设备类型。选择一台或多台设备 备份媒体框,点击添加。将您想要的设备添加到 备份媒体 列表框后,单击 确定 返回到 常规页面。在来源:设备:数据库列表框中,选择要恢复的数据库的名称。

          注意 此列表仅在选择设备时可用。只有在所选设备上有备份的数据库才会 可用。

    4. Destination 部分中,Database 框会自动填充要恢复的数据库的名称。 要更改数据库的名称,请在 数据库框。
    5. 恢复到框中,将默认设置保留为到最后一次备份或点击时间线访问备份 时间轴对话框手动选择一个时间点来停止 恢复行动。
    6. 在要恢复的备份集网格中,选择要恢复的备份。此网格显示可用于指定的备份 地点。默认情况下,建议使用恢复计划。覆盖 建议的恢复计划,您可以更改网格中的选择。 依赖于较早备份恢复的备份是 取消选择较早的备份时自动取消选择。
    7. 要指定数据库文件的新位置,请选择文件页面,然后单击将所有文件重新定位到文件夹。为 数据文件夹日志文件提供新位置 文件夹。或者,您可以保留相同的文件夹,只需重命名数据库和日志文件名。

    【讨论】:

    • 此外,我必须转到“选项”选项卡并选中“覆盖现有数据库(用替换)”...然后它起作用了。
    • @JohnKurtz 如果您要恢复到新数据库,则不需要这样做。
    • 我已经创建了一个空数据库来恢复。那一定是区别。
    • 听起来像。
    • 确认如果您在步骤 4 中输入一个不存在的数据库的名称,它会按照描述工作。确认如果您选择另一个已经存在的数据库,您必须检查“覆盖现有的'选项'选项卡上的数据库(替换)'。感谢您的耐心等待!
    【解决方案5】:

    实际上,没有必要用原生 SQL Server 术语来恢复数据库,因为您“想摆弄一些数据”和“浏览那个 .bak 文件的数据”

    您可以使用 ApexSQL Restore - 一个 SQL Server 工具,将本地和本地压缩的 SQL 数据库备份和事务日志备份附加为实时数据库,可通过 SQL Server 访问Management Studio、Visual Studio 或任何其他第三方工具。它允许附加单个或多个完整、差异和事务日志备份

    此外,我认为您可以在该工具处于全功能试用模式(14 天)时完成这项工作

    免责声明:我在 ApexSQL 担任产品支持工程师

    【讨论】:

      【解决方案6】:

      这是我从各种帖子中拼凑起来的内容,用于使用备份和还原复制数据库,并使用 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);
      

      【讨论】:

      • 您好 NateN,我想将我的 .bak(存在于我的本地机器 d:驱动器路径)文件恢复到另一个数据库。我尝试使用此代码进行单元测试,但它给出了错误..“独家无法获得访问权限,因为数据库正在使用中。“无法恢复数据库..你能帮我怎么办..?
      • 您要恢复到的数据库不能被其他进程使用。我不确定如何编写脚本杀死所有访问数据库的进程。
      • 你好 NateN,它现在工作正常,我使用你的示例代码,然后我对该代码进行了一些小改动,然后工作正常......再次感谢您提供示例代码...
      • 对于 sql2014 及更高版本,DECLARE @BackupFiles... 行需要一个额外的列:SnapshotURL nvarchar(360)
      【解决方案7】:
      • 当我使用旧数据库恢复新数据库时,我遇到了与此主题相同的错误。 (使用 .bak 会出现同样的错误)

      • 我将旧数据库的名称更改为新数据库的名称(与此图相同)。有效。

      【讨论】:

      • 下次请把银行名擦掉
      【解决方案8】:

      以下是如何将备份还原为具有唯一数据库名称的附加数据库。

      对于 SQL 2005,这非常有效。我相信新版本也能正常工作。

      首先,您不必使原始数据库脱机。但是为了安全起见,我喜欢。在我的示例中,我将挂载我的“计费”数据库的克隆,并将其命名为“计费克隆”。

      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) 接下来,在 Management Studio 中,在 Object Explorer 中点击 Databases,选择“Restore Database”

      4) 在“至数据库”字段中输入新名称。 IE。计费克隆

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

      6) 点击添加并导航到您的备份

      7) 在还原旁边打勾(选择要还原的备份集)

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

      9) 现在在 RESTORE AS 中编辑数据库文件名。对数据库和日志执行此操作。 IE。 billingclone.mdf 和 billingclone_log.ldf

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

      11) 在您的对象资源管理器中点击刷新,您将看到您的新数据库

      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;
      

      完成!

      【讨论】:

        【解决方案9】:

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

        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
        

        【讨论】:

          【解决方案10】:
          1. 使用不同名称的“复制数据库”选项从您的数据库中复制一份
          2. 备份新复制的数据库
          3. 恢复它!

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-10-14
            • 1970-01-01
            • 2013-11-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多