Re: VB6 ADO DB2 - Update Problem



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)

.



Relevant Pages

  • Re: Huge memory comsumption of ADODB Connection object
    ... Why I said the Connection ... to nothing, the memory used by my app doesn't decrease, only when I close the ... I take the same opinion as you do, if the cursor doesn't return ... resultset to client, no impact will be imposed to client. ...
    (microsoft.public.data.ado)
  • Re: VB-ADO-SQL Server : SQL Server performs logins after some queries
    ... It should not open new connection, ... > All recordsets in all procedure refer to this specific DB connection ... > Meanwhile I've found the origin of all my SQL Server errors that I faced: ... > not used to open one or more connection objects for different recordsets ...
    (microsoft.public.vb.database.ado)
  • Re: ADODB
    ... In general, use datasets (the .NET equivalent of recordsets), and bind ... I make a connection to a SQL2005 database when my app loads using the ... LogonUsers = 0 ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Timeout
    ... Dim Rst as ADODB.Recordset ... rst.Open sql, cn, adOpenKeyset, adLockReadOnly <- hier kommt der timeout ... Eigenschaften Deines Recordsets schon vor dem .Open mit den richtigen Werten ... Set .Active Connection = Cnn ...
    (microsoft.public.de.vb.datenbank)
  • Re: psycopg, transactions and multiple cursors
    ... >> opening a connection thus the app doesn't suffer so much. ... first time a change is made to the database. ... >> what you want is a nested and not a new cursor. ... B e careful that you don;t confuse the DB API curosrs with the cursors ...
    (comp.lang.python)