【问题标题】:SMO : Restore failed for Server '.'SMO:服务器“。”的还原失败
【发布时间】:2012-10-14 19:59:42
【问题描述】:

我正在使用以下 SMO 代码尝试恢复 SQL Server 数据库:

Server _server;
ServerConnection _conn;

public void Restore(string destinationPath)
{
   Restore res = new Restore();
   _conn = new ServerConnection { ServerInstance = "." };
   _server = new Server(_conn);

   try
   {
       string fileName = destinationPath;
       const string databaseName = "RelationAtOffice";

       res.Database = databaseName;
       res.Action = RestoreActionType.Database;
       res.Devices.AddDevice(fileName, DeviceType.File);

       res.PercentCompleteNotification = 10;
       res.ReplaceDatabase = true;
       res.PercentComplete += new PercentCompleteEventHandler(ProgressEventHandler);
       res.SqlRestore(_server);

       System.Windows.Forms.MessageBox.Show("Restore of " + databaseName + " Complete!", "Restore", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    catch (SmoException exSMO)
    {
       System.Windows.Forms.MessageBox.Show(exSMO.ToString());
    }
    catch (Exception ex)
    {
        System.Windows.Forms.MessageBox.Show(ex.ToString());
    }
}

为什么将下面的代码链接到正确答案。但是我的代码不起作用? 代码喜欢在一起。我使用了 wpf 和以下链接用户 winapp

Link

SMO 错误:

Microsoft.SqlServer.Management.Smo.FailedOperationException:恢复 服务器“MORTEZA”失败。
---> Microsoft.SqlServer.Management.Smo.SmoException:
System.Data.SqlClient.SqlError:无法获得独占访问 因为数据库正在使用中。
在 Microsoft.SqlServer.Management.Smo.ExecutionManager.ExecuteNonQueryWithMessage(StringCollection 查询,ServerMessageEventHandler dbccMessageHandler,布尔值 错误消息)
在 Microsoft.SqlServer.Management.Smo.BackupRestoreBase.ExecuteSql(服务器 服务器,StringCollection 查询)
在 Microsoft.SqlServer.Management.Smo.Restore.SqlRestore(Server srv)
在 RelationAtOfficeApp.Admin.AdministratorMainPage.Restore(字符串 目的地路径)在 E:\prozhe\RelationAtOfficeApp\RelationAtOfficeApp\RelationAtOfficeApp\Admin\AdministratorMainPage.xaml.cs:268 行

【问题讨论】:

  • 你能复制准确的错误信息吗?
  • 错误信息:服务器“King”恢复失败
  • 您正在尝试恢复到现有数据库,但有人仍在其中。该“某人”可以是您自己的会话之一,因此请确保它们都没有持久存在该数据库中。

标签: wpf sql-server c#-4.0 restore smo


【解决方案1】:

最可能的原因是:

  • 您已从服务器备份 - 将 Data.mdfData_Log.ldf 备份到 Backup.bak 文件中

  • 在同一台(服务器)机器上,您现在正尝试恢复同一个数据库

在这种情况下,.mdf.ldf 应该被覆盖——但这不会发生,因为 SQL Server 仍然控制着那个数据库——所以恢复失败,因为数据和日志文件不能被覆盖。

有两种方法可以解决这个问题:

  1. 定义“文件重定位”,例如在恢复时定义一个新的数据和日志文件名。这样,您的数据库现在已恢复,并且文件以新名称放置在 SQL Server 数据目录中。

    这需要类似他的代码:

    ....  
    res.Devices.AddDevice(fileName, DeviceType.File);
    
    // define "file relocation" - for all "logical" files in a SQL Server database,
    // define a new physical location where the file will end up at          
    RelocateFile relocateDataFile = new RelocateFile("Data", @"(your data dir)\RestoredData.mdf");
    RelocateFile relocateLogFile = new RelocateFile("Log", @"(your log dir)\Data\RestoredData_log.ldf");
    
    res.RelocateFiles.Add(relocateDataFile);
    res.RelocateFiles.Add(relocateLogFile);
    
  2. 如果您不想创建新文件,您应该能够通过以下设置向 SMO Restore 指定要使用恢复操作替换现有数据库:

    res.ReplaceDatabase = true;
    

    打电话之前

    res.SqlRestore(_server);
    

更新:我在示例中使用的逻辑文件名当然只是示例 - 在您的情况下,您的备份文件很可能包含 其他逻辑文件名 ,并且您需要在代码中使用这些文件名。

您可以通过以下两种方式找出您的数据库包含哪些逻辑文件名:

  1. 正如错误消息明确指出的那样 - 您可以在 SQL Server Management Studio 中的 RESTORE 命令上使用 FILELISTONLY 选项,从而在恢复之前检查 .bak 文件。试试这样的:

    RESTORE FILELISTONLY
    FROM DISK = N'path-and-full-file-name-of-your-bak-file-here.bak'
    

    这将为您提供一个小网格,其中包含您的 .bak 文件中包含的逻辑和物理文件名。

  2. 如果数据库仍然连接到服务器,可以使用 SQL Server Management Studio 中的Object Explorer 找出数据库的逻辑文件名是什么;右键单击您选择的数据库,然后您将看到此对话框,在 Files 部分中,您将获得所需的信息:

【讨论】:

  • 我正在使用:res.ReplaceDatabase = true; res.SqlRestore(_server);但这是错误:Microsoft.SqlServer.Management.Smo.FailedOperationException:服务器“MORTEZA”的恢复失败。 ---> Microsoft.SqlServer.Management.Smo.SmoException:System.Data.SqlClient.SqlError:无法获得独占访问,因为数据库正在使用中。在
  • @MMDMNC:我在回复中展示了 两个解决方案 - 尝试解决方案 #1!在Restore 上使用RelocateFiles 属性 ....
  • 错误尝试解决方案#1:smo:Microsoft.SqlServer.Management.Smo.FailedOperationException:服务器“MORTEZA”恢复失败。 ---> Microsoft.SqlServer.Management.Smo.SmoException:System.Data.SqlClient.SqlError:逻辑文件“数据”不是数据库“RelationAtOffice”的一部分。使用 RESTORE FILELISTONLY 列出逻辑文件名。在 Microsoft.SqlServer.Management.Smo.ExecutionManager.ExecuteNonQueryWithMessage(StringCollection 查询,ServerMessageEventHandler dbccMessageHandler,布尔错误AsMessages)......
  • @MMDMNC:好吧,在这种情况下,您的文件具有不同的逻辑文件名 - 您需要找出这些文件名是什么(使用该命令 - RESTORE FILELISTONLY),然后使用正确的逻辑文件名SMO 应用中的文件名!
【解决方案2】:

除了marc-s 的回答,您还可以在.SqlRestore() 之前添加一行代码来解决“正在使用的数据库”错误:

_server.KillAllPrecesses("MyDatabaseName");
res.SqlRestore(_server);

这模拟了与 Sql Server Management Studio 还原完全相同的行为:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-25
    • 1970-01-01
    相关资源
    最近更新 更多