Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Wenn Sie sich mit Ihrem Recordset im unmittelbaren Modus befassen, besteht viel weniger Wahrscheinlichkeit, dass Parallelitätsprobleme auftreten. Wenn Ihre Anwendung dagegen die Batchmodusaktualisierung verwendet, besteht möglicherweise die Möglichkeit, dass ein Benutzer einen Datensatz ändert, bevor änderungen, die von einem anderen Benutzer vorgenommen wurden, der denselben Datensatz bearbeitet hat, gespeichert werden. In einem solchen Fall möchten Sie, dass Ihre Anwendung den Konflikt ordnungsgemäß behandelt. Es kann Ihr Wunsch sein, dass die letzte Person, die ein Update an den Server sendet, "gewinnt". Oder Sie möchten den letzten Benutzer entscheiden lassen, welche Aktualisierung Vorrang haben soll, indem Sie ihm eine Auswahl zwischen den beiden widersprüchlichen Werten zur Verfügung stellen.
Unabhängig vom Fall stellt ADO die UnderlyingValue- und OriginalValue-Eigenschaften des Field-Objekts bereit, um diese Arten von Konflikten zu behandeln. Verwenden Sie diese Eigenschaften in Kombination mit der Resync-Methode und der Filter-Eigenschaft des Recordset.
Bemerkungen
Wenn ADO während einer Batchaktualisierung einen Konflikt findet, wird der Errors-Auflistung eine Warnung hinzugefügt. Daher sollten Sie immer sofort nach dem Aufrufen von BatchUpdate auf Fehler überprüfen, und wenn Sie sie finden, sollten Sie mit dem Testen der Annahme beginnen, dass ein Konflikt aufgetreten ist. Der erste Schritt besteht darin, die Filter-Eigenschaft für das Recordset auf "adFilterConflictingRecords" festzulegen. Dadurch wird die Ansicht auf Ihr Recordset auf nur die Datensätze beschränkt, die in Konflikt stehen. Wenn die RecordCount-Eigenschaft nach diesem Schritt gleich Null ist, wissen Sie, dass der Fehler durch einen anderen Konflikt ausgelöst wurde.
Wenn Sie BatchUpdate aufrufen, generieren ADO und der Anbieter SQL-Anweisungen, um Aktualisierungen für die Datenquelle auszuführen. Beachten Sie, dass bestimmte Datenquellen Einschränkungen haben, welche Spaltentypen in einer WHERE-Klausel verwendet werden können.
Rufen Sie als Nächstes die Resync-Methode für das Recordset auf, indem Sie das Argument "AffectRecords" auf "adAffectGroup" und das Argument "ResyncValues" auf "adResyncUnderlyingValues" setzen. Die Resync-Methode aktualisiert die Daten im aktuellen Recordset-Objekt aus der zugrunde liegenden Datenbank. Mithilfe von adAffectGroup stellen Sie sicher, dass nur die Datensätze, die mit der aktuellen Filtereinstellung sichtbar sind, d. h. nur die widersprüchlichen Datensätze, mit der Datenbank neu synchronisiert werden. Dies kann zu einem erheblichen Leistungsunterschied führen, wenn Sie mit einem großen Recordset umgehen. Durch Festlegen des Arguments "ResyncValues" auf "adResyncUnderlyingValues" beim Aufrufen von Resync stellen Sie sicher, dass die UnderlyingValue-Eigenschaft den (widersprüchlichen) Wert aus der Datenbank enthält, dass die Value-Eigenschaft den vom Benutzer eingegebenen Wert verwaltet und dass die OriginalValue-Eigenschaft den ursprünglichen Wert für das Feld enthält (der Wert, den sie vor dem letzten erfolgreichen UpdateBatch-Aufruf hatte). Anschließend können Sie diese Werte verwenden, um den Konflikt programmgesteuert zu lösen, oder der Benutzer muss den verwendeten Wert auswählen.
Diese Technik wird im folgenden Codebeispiel gezeigt. Das Beispiel erstellt künstlich einen Konflikt, indem ein separates Recordset verwendet wird, um einen Wert in der zugrunde liegenden Tabelle zu ändern, bevor UpdateBatch aufgerufen wird.
'BeginConflicts
strConn = "Provider=SQLOLEDB;Initial Catalog=Northwind;" & _
"Data Source=MySQLServer;Integrated Security=SSPI;"
strSQL = "SELECT * FROM Shippers WHERE ShipperID = 2"
'Open Rs and change a value
Set objRs1 = New ADODB.Recordset
Set objRs2 = New ADODB.Recordset
objRs1.CursorLocation = adUseClient
objRs1.Open strSQL, strConn, adOpenStatic, adLockBatchOptimistic, adCmdText
objRs1("Phone") = "(111) 555-1111"
'Introduce a conflict at the db...
objRs2.Open strSQL, strConn, adOpenKeyset, adLockOptimistic, adCmdText
objRs2("Phone") = "(999) 555-9999"
objRs2.Update
objRs2.Close
Set objRs2 = Nothing
On Error Resume Next
objRs1.UpdateBatch
If objRs1.ActiveConnection.Errors.Count <> 0 Then
Dim intConflicts As Integer
intConflicts = 0
objRs1.Filter = adFilterConflictingRecords
intConflicts = objRs1.RecordCount
'Resync so we can see the UnderlyingValue and offer user a choice.
'This sample only displays all three values and resets to original.
objRs1.Resync adAffectGroup, adResyncUnderlyingValues
If intConflicts > 0 Then
strMsg = "A conflict occurred with updates for " & intConflicts & _
" record(s)." & vbCrLf & "The values will be restored" & _
" to their original values." & vbCrLf & vbCrLf
objRs1.MoveFirst
While Not objRs1.EOF
strMsg = strMsg & "SHIPPER = " & objRs1("CompanyName") & vbCrLf
strMsg = strMsg & "Value = " & objRs1("Phone").Value & vbCrLf
strMsg = strMsg & "UnderlyingValue = " & _
objRs1("Phone").UnderlyingValue & vbCrLf
strMsg = strMsg & "OriginalValue = " & _
objRs1("Phone").OriginalValue & vbCrLf
strMsg = strMsg & vbCrLf & "Original value has been restored."
MsgBox strMsg, vbOKOnly, _
"Conflict " & objRs1.AbsolutePosition & _
" of " & intConflicts
objRs1("Phone").Value = objRs1("Phone").OriginalValue
objRs1.MoveNext
Wend
objRs1.UpdateBatch adAffectGroup
Else
'Other error occurred. Minimal handling in this example.
strMsg = "Errors occurred during the update. " & _
objRs1.ActiveConnection.Errors(0).Number & " " & _
objRs1.ActiveConnection.Errors(0).Description
End If
On Error GoTo 0
End If
objRs1.MoveFirst
objRs1.Close
Set objRs1 = Nothing
'EndConflicts
Sie können die Status-Eigenschaft des aktuellen Datensatzes oder eines bestimmten Felds verwenden, um zu bestimmen, welche Art eines Konflikts aufgetreten ist.
Ausführliche Informationen zur Fehlerbehandlung finden Sie unter Fehlerbehandlung.