Re: VB6 ADO DB2 - Update Problem
- From: Peter Götz <gssg_nospam@xxxxxxxxxxx>
- Date: Wed, 24 Aug 2005 13:37:59 +0200
Hallo Sascha,
> Ich möchte in einem VB6 Programm auf eine UDB DB2
> zugreifen und in bestimmten Fällen ein Update eines
> Feldes durchführen.
> Um diese Fälle zu ermitteln muss ich zwei Abfragen auf
> eine Tabelle durchführen. Jeweils ein Feld der beiden
> Abfragen (Recordsets) vergleiche ich um zu ermitteln in
> welchem Datensatz ich das Update durchführen muss.
> Bis hierhin läuft der Code auch fehlerfrei durch.
> Bei dem zuweisen des Werts aus der Variable "intNeu"
> an das Feld "Neu" des Recordsets "rsAllHauptnr" kommt
> folgende Fehlermeldung: "Das Verfahren wird von diesem
> Provider nicht unterstützt."
>
> Wenn ich die CursorLocation des rsAllHauptnr auf
> adUseClient setze, dann erscheint folgende Fehlermeldung
> beim Update: "Nicht genügend Basistabelleninformationen
> zum Aktualisieren."
Das heisst ganz einfach, dass es in Deinem Recordset kein Feld mit
eindeutigen Werten (z.B. Primärschlüssel oder wenigstens ein indiziertes
Feld mit eindeutigen Werten) gibt und ADO somit nicht weiss, welcher
Datensatz tatsächlich zu verarbeiten ist.
> Dies erkläre ich dadurch, dass bei
> adUseClient die Daten auf dem DB2 Server nicht aktualisiert
> werden können.
Was veranlasst Dich zu der Annahme, dass Daten eines Recordsets mit
clientseitigem Cursor in der DB nicht aktualisiert werden könnnen? Natürlich
können sie das. Je nach LockType (adLockOptimistic oder
adLockBatchOptimistic):
RS.Update
bzw.
RS.UpdateBatch
> Die zu aktualisierende Tabelle hat einen Key.
Die Fehlermeldung sagt aber was anderes.
> Wie kann ich das Update durchführen?
>
> Um meine Frage zu erklären, hier der Codeausschnitt:
>
>
> Set g_Connection = New adodb.Connection
> strName = "IBMDADB2.1"
> g_strUser = "MyUser"
> g_strPWD = "MyPWD"
> g_strDSN_Name = "Einkauf"
> strConnection = "PROVIDER=" & strName & ";" & " " & "DSN=" &
> g_strDSN_Name & ";" & "uid=" & g_strUser & ";" & "pwd=" & g_strPWD &
> ";" & "database=" & g_strDSN_Name
Solche Connectionstrings verursachen mir immer eine Gänsehaut.
Man kann eine Connection auch ohne ein solches Ungetüm öffnen, indem man
ganz einfach die Werte für die einzelnen Eigenschaften der Connection direkt
zuweist. Das hat neben der deutlich besseren Lesbarkeit auch noch den
Vorteil, dass man beim Debugging schon per Intellisense autom. alle
tatsächlichen Werte dieser Eigenschaften gezeigt bekommt.
Beispiele gibt es unter
www.gssg.de -> Visual Basic -> VBclassic -> Datenbank
> g_Connection.Open strConnection
>
> 'Dadurch ist also die Connection hergestellt.
Wenn kein Fehler aufgetreten ist, ja.
> strSelectAllHartnr = "SELECT TEST.ARTNR, TEST.HARTNR, TEST.NEU" & _
> " FROM EK_USER.TEST AS TEST"
> Set rsAllHartnr = New adodb.Recordset
> With rsAllHartnr
> '.CursorLocation = adUseClient
> .CursorLocation = adUseServer
Warum serverseitiger Cursor?
Das ist reine Ressourcenverschwendung.
Arbeite bevorzugt mit clientseitigem Cursor, das entlastet das LAN und den
DB-Server. Es gibt wirklich nur sehr wenige Fälle in denen einen
serverseitiger Cursor wirklich sinnvoll und notwendig wäre. Mit Blick auf
einen späteren Umstieg auf ADO.net solltest Du Dich ohnehin auf
verbindungsloses Arbeiten einstellen.
> .CursorType = adOpenDynamic
Bewirkt das mögliche Maximum an Ressourcenverbrauch.
Bei clientseitigem Cursor ist adOpenDynamic ohnehin nicht möglich, es ist
dann nur adOpenStatic sinnvoll.
.LockType = adLockOptimistic
.Open strSelectAllHartnr, g_Connection
Auch eine solche mit allen möglichen und unmöglichen Parametern vollgepackte
Open-Anweisung erleichtert späteres Debugging nicht gerade. Man kann den
entsprechenden RS-Eigenschaften die Werte auch direkt vor dem Open zuweisen
und hat dann wieder den Vorteil, dass Intellisense beim Debugging sofort die
tatsächlichen Werte zeigt.
> End With
> 'Ermitteln aller 1. Angebotsnummern aller Hauptnummern
> strSelectHartnr_Group = "SELECT TEST.SAISKZ, MIN(TEST.ARTNR)
> AS ARTNR, TEST.HARTNR, TEST.NEU" & _
" FROM EK_USER.TEST AS TEST" & _
" GROUP BY TEST.SAISKZ, TEST.HARTNR, TEST.NEU"
>
>
> Set rsHartnr_Group = New adodb.Recordset
> With rsHartnr_Group
> .Open strSelectHartnr_Group, g_Connection, adOpenDynamic,
> adLockOptimistic
> End With
>
> rsAllHartnr.MoveFirst
> rsHartnr_Group.MoveFirst
>
>
> intNeu = 1
>
>
> Do Until rsHartnr_Group.EOF = True
> If rsHartnr_Group![ARTNR] = rsAllHartnr![ARTNR] Then
> rsAllHartnr.Fields![NEU] = intNeu
> rsAllHartnr.Update
> End If
> Loop
Wenn rsHartnr_Group.EOF nicht schon bei Eintritt in diese Do...Loop-Schleife
den Wert True hat, dann wird diese Schleife bis in alle Ewigkeit ausgeführt
werden, da es darin keinen Code gibt, der jemals ein .EOF = True bewirken
und somit ein Kriterium zum Verlassen der Schleife liefern könnte.
Gruß aus St.Georgen
Peter Götz
www.gssg.de (mit VB-Tips u. Beispielprogrammen)
.
- References:
- VB6 ADO DB2 - Update Problem
- From: Sascha
- VB6 ADO DB2 - Update Problem
- Prev by Date: Re: Wie erkennen, dass Con.Execute fertig ist?
- Next by Date: Re: MS Data Bound Grid Control 5.0 (SP3)
- Previous by thread: VB6 ADO DB2 - Update Problem
- Next by thread: sort bei memo feldern
- Index(es):
Relevant Pages
|
|