如果您使用 SMO 执行备份,成功完成后,我测试 SqlError 是否为 null,考虑到备份已完成且没有错误:
但是,如您所见,它实际上返回了 0 类编号 3014 的错误,表示成功。
那么问题是:
Q: How can I find out if backup completed successfully or not, and how should I handle these messages and statuses cleanly?
恐怕这里有多个“陷阱”,我不想稍后在这段代码投入生产时咬我的屁股:)
最佳答案
我同意存在多个“问题”,我个人认为 Microsoft SMO 事件实现不当,因为 ServerMessageEventArgs 包含一个属性错误,它并不总是提供有关错误的信息,而是提供有关成功操作的消息!!
举个例子: 代码为 4035 的“错误”是一条信息消息。不是错误。 代码为 3014 的“错误”是成功完成时发生的信息消息。不是错误
另请注意,信息事件并不总是在发生错误时发生。每当 SQL Server 发送一条消息,该消息可能是有关已成功完成的操作的信息时,它实际上就会发生
我还担心没有正确处理错误/成功,但是将 sqlError 检查为 Null 是一个坏主意,因为它永远不会为 null,并且它总是包含一些关于成功操作或一个错误。并且假设在出现错误时发生信息事件也是一个坏主意。
我建议通过 SqlError.Number 处理错误,并根据触发的 SMO 事件进行处理。
我编写了以下代码来创建数据库备份。它在 VB.NET 中,但在 C# 中类似。它接收必要的参数,包括调用事件的委托(delegate)(将在 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
关于c# - SQL Server SMO - 备份 - 如何确定失败/成功?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9358576/