如果使用SMO执行备份,则在成功完成后,我将SqlError测试为null,考虑到备份已完成且没有错误:
但是,正如您所看到的,它实际上返回了0级数字3014的错误,这意味着成功。
所以问题是:
问:如何确定备份是否成功完成,以及如何干净地处理这些消息和状态?
我担心这里有多个“陷阱”,我不想在这段代码生产后我在屁股上咬我:)
答案 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 被定义为备份成功时发送的消息。
我不确定你关注的其他“陷阱”,因为你没有记录它们。