PDA

View Full Version : ODBC-Probleme



RainerGschwendtner
29-01-03, 14:51
Hallo zusammen.

Ich habe ein Problem mit dem CA/ODBC-Treiber.
Ich Programmiere in VisualBasic und nutze seit kurzem den ClientAccess-ODBC-Treiber.
Ich kann aus meinem Programm zwar sehr einfach die Daten der iSeries abrufen (SELECT * FROM tabelle WHERE spalte = 1).
D. h. ich bekomme ein gültiges Recordset. Wenn ich jetzt jedoch die Daten ändere und zurückschreiben will bekomme ich die Meldung:


SQL0204-"wetst" der Art *File in QS36F nicht gefunden.

Das kann aber nicht sein, da ich oben die Daten ja gerade erste gelesen habe.

Fuerchau
29-01-03, 15:25
ODBC mit AS/400 ist nun mal leider etwas schwierig.
Wenn du mit DAO arbeitest ist es wichtig, dass du das Recordset mit dbOpenDynaset eröffnest.
In der Eigenschaft recordset.Updatable erfährst du, ob das geklappt hat.
Das Problem des ODBC ist auch, ob du mit ODBC-Direct oder über JET die Datei eröffnest.
Wenn über JET gearbeitet wird, stellt JET automatisch fest, über welchen eindeutigen Schlüssel ein Update möglich ist. Auch dies funktioniert ausschließlich mit dbOpenTable.

Dies ist aber halt alles nicht unbedingt SQL-like und der CA-ODBC unterstützt halt ausschließlich native SQL.

Ansonsten gilt halt:
update file set f1=?, f2=?, ...
where k1=? and k2=? ...

Das kannst du als Query-Objekt erstellen.
Jedes ? als Paramtermarker ergibt ein Parameter-Objekt in der Parmeters-Auflistung.
Die einzelnen Parameter kannst du dann so füllen und den update dann durchführen:

myqry(0) = Wert1
myqry(1) = Wert2
:
myqry(n) = recordset!Key1
myqry(n+1) = recordset!Key2
:
:
myqry.execute

RainerGschwendtner
30-01-03, 07:01
Hallo, ich arbeite nicht mit DAO sondern mit ADO.


Dass es mit "native SQL" klappt habe ich letzt Nacht auch festgestellt. Allerdings habe ich dort noch ein Problem. Wie kann ich hier einen neuen Satz anlegen? (Blöde Frage, aber ich bekomms nicht hin .-((


Das mit den Query-Objekten ist mir neu. Kannst du mir das ganze event. noch etwas genauer erklären?
Vorteile? Wie geht das genau?

Fuerchau
30-01-03, 09:55
Wenn du mit ADO arbeitest, um so besser.
Du solltest dabei aber nicht mehr ODBC verwenden sondern den OLEDB-Provider IBMDA400. Hierzu solltest du auch am besten CA V5R1 einsetzen, auch wenn die AS/400 noch V4 verwendet.
Bei den Verbindungseigenschaften kannst du die Bibliotheksliste (Registerkarte Erweitert) einstellen, so dass du den Datenexplorer verwenden kannst.
Anm.: ODBC geht zwar auch, ist aber langsamer und unterliegt ein paar Einschränkungen.

Für den Update erstellst du ein Command-Objekt und gibst den SQL-Befehl

"UPDATE myfile set F1=?, F2=? .... where K1=? and K2=? ..."

direkt ein.
Die Argumente kannst du dann mittels
updcmd(0) = myarg1
:
updcmd(n) = myargn
übergeben und anschliessend per

(dim RecAffected as long )
updcmd.execute RecAffected, , adExecuteNoRecords

ausführen.
Da der Update kein Recordset zurückgibt, ist die Option "adExecuteNoRecords" wichtig, da sonst die Information "RecAffected" nicht korrekt zurückgegeben wird und ein Recordset-Objekt auch nicht benötigt wird (es ist ja leer und muss eh wieder zerstört werden).
"RecAffected" sollte auch ausgewertet werden, wenn der Inhalt nähmlich nicht 1 ist, stimmt ggf. der Schlüssel (Where-Klausel) nicht, der Satz ist vielleicht nicht mehr da oder von einer anderen Anwendung gesperrt.
Du kannst zur Überprüfung auch das Error-Ereignis verwenden.

Nun zum Einfügen. Der SQL-befehl lautet "Insert" und kann ähnlich wie der Update per Command-Objekt durchgeführt werden.

"Insert into myfile (F1, F2, F3, ...) values (?, ?, ?, ...)"

Die Verwendung per Execute-Methode ist identisch zum Update incl. "RecAffected", "adExecuteNoRecords" und Error-Ereignis.
Beim Insert kann natürlich ein Fehler passieren, z.B. doppelter Schlüssel oder ggf. kein Default-Wert bei nicht verwendetem Feld, usw.

Anmerkung zu Datumsfeldern:
Wenn du mit ODBC arbeitest, verlangt CA/400 ein CDate()-Format.
Wenn du mit OLEDB arbeitest, verlangt CA/400 einen String im ISO-Format (Timestamp: YYYY-MM-DD-HH.MM.SS.MMMMMM).
Mit der Format$-Anweisung kannst du dies problemlos erreichen.

RainerGschwendtner
31-01-03, 06:44
OK,
ich glaube jetzt hab ich’s langsam begriffen.

Vielen Dank für die ausführliche Antwort.

Das Problem lag wohl darin, dass mein alter ODBC-Treiber (HIT-Software) auf meiner alten iSeries (V4R4) folgendes kommentarlos verarbeitete:

rec.addNew
rec.fields(„FeldName“).Value = „NeuerWert“
rec.update


Auf meiner neuen iSeries (V5R2) funktionierte der HIT-ODBC-Treiber allerdings nicht mehr richtig. Also habe ich den CA/-Treiber installiert und der kommt mit obigen Konstruktionen nicht klar.

Zu allem Überfluss verhält sich der CA-Treiber auch noch anders. Bisher bekam ich bei einem Leerstring „“ zurück, jetzt „ „. Was natürlich nicht gerade toll ist wenn ich auf „“ abfrage.

Aber das Leben wäre ja zu einfach wenn immer alles funktionieren würde.