SQL Server SMO - 备份 - 如何确定失败/成功?

时间:2012-02-20 09:14:09

标签: c# .net sql-server backup smo

如果使用SMO执行备份,则在成功完成后,我将SqlError测试为null,考虑到备份已完成且没有错误:

enter image description here

但是,正如您所看到的,它实际上返回了0级数字3014的错误,这意味着成功。

所以问题是:

  

问:如何确定备份是否成功完成,以及如何干净地处理这些消息和状态?

我担心这里有多个“陷阱”,我不想在这段代码生产后我在屁股上咬我:)

2 个答案:

答案 0 :(得分:2)

我同意有多个"陷阱"我个人认为Microsoft SMO事件的实现很差,因为ServerMessageEventArgs包含一个属性错误,它并不总是提供有关错误的信息,而是有关成功操作的消息!!

举个例子: "错误"代码4035是一条信息消息。不是错误。 "错误"代码3014是成功完成时发生的信息消息。不是错误

另请注意,发生错误时并不总是会发生信息事件。只要SQL Server发送的消息可能是有关已成功完成的操作的信息,就会发生这种情况

我也担心没有正确处理错误/成功,但检查sqlError为Null是个坏主意,因为它不会是null并且它将始终包含有关成功操作的消息或一个错误。并且假设在出现错误时发生信息事件也是一个坏主意

我建议通过SqlError.Number处理错误,并根据SMO事件触发它。

我已经制作了以下代码来创建数据库备份。它在VB.NET中,但在C#中会是类似的。它接收必要的参数,包括委托调用事件的委托(在GUI处理),根据触发的事件报告百分比和错误处理的进度以及提到的SqlError.Number

Public Sub BackupDatabase(databaseName As String, backupFileFullPath As String, optionsBackup As OptionsBackupDatabase, operationProgress As IProgress(Of Integer),
                          operationResult As Action(Of OperationResult)) Implements IDatabaseManager.BackupDatabase
    Dim sqlBackup As New Smo.Backup()
    sqlBackup.Action = Smo.BackupActionType.Database
    sqlBackup.BackupSetName = databaseName & " Backup"
    sqlBackup.BackupSetDescription = "Full Backup of " & databaseName
    sqlBackup.Database = databaseName
    Dim bkDevice As New Smo.BackupDeviceItem(backupFileFullPath, Smo.DeviceType.File)
    sqlBackup.Devices.Add(bkDevice)
    sqlBackup.Initialize = optionsBackup.Overwrite
    sqlBackup.Initialize = True
    sqlBackup.PercentCompleteNotification = 5

    AddHandler sqlBackup.PercentComplete, Sub(sender As Object, e As PercentCompleteEventArgs)
                                              operationProgress.Report(e.Percent)
                                          End Sub
    AddHandler sqlBackup.Complete, Sub(sender As Object, e As ServerMessageEventArgs)
                                       Dim sqlMessage As SqlClient.SqlError = e.Error
                                       Dim opResult As New OperationResult()
                                       Select Case sqlMessage.Number
                                           Case 3014
                                               opResult.operationResultType = OperationResultType.SmoSuccess
                                               opResult.message = "Backup successfully created at " & backupFileFullPath & ". " & sqlMessage.Number & ": " & sqlMessage.Message
                                           Case Else
                                               opResult.operationResultType = OperationResultType.SmoError
                                               opResult.message = "ERROR CODE " & sqlMessage.Number & ": " & sqlMessage.Message
                                       End Select
                                       operationResult.Invoke(opResult)
                                   End Sub

    AddHandler sqlBackup.NextMedia, Sub(sender As Object, e As ServerMessageEventArgs)
                                        Dim sqlMessage As SqlClient.SqlError = e.Error
                                        Dim opResult As New OperationResult()
                                        opResult.operationResultType = OperationResultType.SmoError
                                        opResult.message = "ERROR CODE:  " & sqlMessage.Number & ": " & sqlMessage.Message
                                        operationResult.Invoke(opResult)
                                    End Sub

    AddHandler sqlBackup.Information, Sub(sender As Object, e As ServerMessageEventArgs)
                                          Dim sqlMessage As SqlClient.SqlError = e.Error
                                          Dim opResult As New OperationResult()
                                          Select Case sqlMessage.Number
                                              Case 4035
                                                  opResult.operationResultType = OperationResultType.SmoInformation
                                                  opResult.message = sqlMessage.Number & ": " & sqlMessage.Message
                                              Case Else
                                                  opResult.operationResultType = OperationResultType.SmoError
                                                  opResult.message = "ERROR CODE " & sqlMessage.Number & ": " & sqlMessage.Message
                                          End Select
                                          operationResult.Invoke(opResult)
                                      End Sub
    Try
        sqlBackup.SqlBackupAsync(smoServer)
    Catch ex As Exception
        Throw New BackupManagerException("Error backing up database " & databaseName, ex)
    End Try
End Sub

答案 1 :(得分:1)

我可能错了,但我相信Complete事件触发是备份成功的主要指标 - 错误将通过Information事件报告。

由于错误的类是0(或任何低于10的值),它表示它是一条信息性消息,而不是实际错误(Error有些错误名称)。并且3014 被定义为备份成功时发送的消息。

我不确定你关注的其他“陷阱”,因为你没有记录它们。