Fuerchau
19-04-11, 18:33
Hallo Leute,
nur so zur Info bezgl. des manchmal seltsamen Verhaltens bei ODBC-Zugriffen.
Da ich mit FTSolutions ein BI-Software entwickle und vertreibe muss ich mich ja intensiv mit dem ODBC beschäftigen (ja ja ich weiß, mit Java wäre ja alles kein Problem, aber wer weiß ...).
Aus bekannten Gründen soll man ja bei SQL's mit Parametermarkern "?" arbeiten.
Dies habe ich auch intensiv genutzt. Bei verschiedenen Kundensystemen liefen diese SQL's aber sporadisch auf Fehler!
"PWS0043 - Parameterwert nicht verwendbar"
"Anzahl Parameter falsch"
Oder sogar keine Daten obwohl Daten da sind!
Das macht einen schon wahnsinnig wenn die SQL's mal laufen und mal nicht. Eine Regel gibts da überhaupt nicht.
Ein SQL-Trace (ODBC-Manager) oder Jobolog (Debug-Modus) brachte überhaupt keinen Hinweis, was denn da so falsch läuft.
Im Joblog stand nur lapidar:
... Cursor geöffnet (also war der SQL ja OK)
... Cursor geschlossen (ohne Datenabruf)
Nun bin ich zu meinem Lieblingsthema gekommen und habe mal CCSID's geprüft. Und sieh da, der Systemwert QCCSID bei den betroffenen Systemen steht auf 65535, *HEX.
Normalerweise ist das wohl kein Problem, da der QZDASOINIT-Job trotzdem auf eine korrekte CCSID gestellt wurde.
Aber was mach der ODBC-Treiber oder der Serverjob (wer ist letztlich egal).
Für Optimierungen und Wiedererkennung von SQL's werden nämlich sämtliche Konstanten selbstständig in Parametermarker überführt und dann ins SQLPKG gestellt, bzw. gesucht, ggf. gefunden usw.
Enthält nun ein SQL sowohl Konstanten als auch gleichzeitig Parametermarker scheint diese Mimik ab und zu nämlich daneben zu gehen.
Hier half ein wenig Googeln (ich weiß nicht mehr wo das war), da wird nämlich bezogen auf eine andere CCSID geschrieben, dass bei dieser Art der Übersetzung Probleme auftauchen können, wenn die ClientCCSID (hier die Codepage) zur AS/400 (hier *HEX) abweicht.
Dazu gab es nur eine Lösung:
Entweder alle Konstanten als Parameter ersetzen oder eben ungedreht.
Da ich eine zentrale Routine für Execute-Aufrufe hatte, war letzteres die schnellste Lösung.
Kurzerhand ein neues CMD-Objekt aus dem alten erstellt und sukzessive (unter Berücksichtigung des Feldtyps) jedes "?" durch seinen Inhalt ersetzt.
Und siehe da:
Alle SQL's laufen problemlos auch auf diesen problematischen Systemen!!!
Zu guter letzt hatte ich allerdings noch ein weiteres Problem:
Spradisch blieb mein Progrämmchen einfach stehen und wollte nichts mehr tun.
Der QZDA-Job stand auf "recv", im Joblog gabs keine Hinweise und ich konnte nur noch den Taskmanager zum Killen verwenden.
Da ich mitunter sehr viele Einzel-Selects auf die AS/400 loslasse habe ich nun festgestellt, dass nach ca. 7.350 Queries der ODBC-Treiber oder der QZDA-Job nicht mehr wollen!!!
Ich hatte also nun die Anzahl Queries gezählt und nach 5000 dann die Verbindung geschlossen und wieder aufgemacht. Allerdings schlagen hier 2 Funktionen zu:
a) Connection-Pool
b) Wiederverwendung eines QZDA-Jobs
So war dann halt nach 2530 weiteren Queries wieder Schluss.
Also habe ich meine offene Verbbindung in ein Collection-Objekt geschoben und eine neue verbindung aufgemacht.
Und so habe ich nun auch diese unverständliche Grenze umgangen.
Falls der wiederverwendete Job noch ein Problem darstellen wird, kann ich noch einen ENDJOB per QCMDEXC hinterherjagen.
So gebe ich nun alle Verbindungen erst bei Programmende frei.
Das wars mal so aus dem Nähkästchen.
Vielleicht hat ja der eine oder andere auch so unerklärliche Probleme und kann hieruas vielleicht eine Lösung ziehen.
nur so zur Info bezgl. des manchmal seltsamen Verhaltens bei ODBC-Zugriffen.
Da ich mit FTSolutions ein BI-Software entwickle und vertreibe muss ich mich ja intensiv mit dem ODBC beschäftigen (ja ja ich weiß, mit Java wäre ja alles kein Problem, aber wer weiß ...).
Aus bekannten Gründen soll man ja bei SQL's mit Parametermarkern "?" arbeiten.
Dies habe ich auch intensiv genutzt. Bei verschiedenen Kundensystemen liefen diese SQL's aber sporadisch auf Fehler!
"PWS0043 - Parameterwert nicht verwendbar"
"Anzahl Parameter falsch"
Oder sogar keine Daten obwohl Daten da sind!
Das macht einen schon wahnsinnig wenn die SQL's mal laufen und mal nicht. Eine Regel gibts da überhaupt nicht.
Ein SQL-Trace (ODBC-Manager) oder Jobolog (Debug-Modus) brachte überhaupt keinen Hinweis, was denn da so falsch läuft.
Im Joblog stand nur lapidar:
... Cursor geöffnet (also war der SQL ja OK)
... Cursor geschlossen (ohne Datenabruf)
Nun bin ich zu meinem Lieblingsthema gekommen und habe mal CCSID's geprüft. Und sieh da, der Systemwert QCCSID bei den betroffenen Systemen steht auf 65535, *HEX.
Normalerweise ist das wohl kein Problem, da der QZDASOINIT-Job trotzdem auf eine korrekte CCSID gestellt wurde.
Aber was mach der ODBC-Treiber oder der Serverjob (wer ist letztlich egal).
Für Optimierungen und Wiedererkennung von SQL's werden nämlich sämtliche Konstanten selbstständig in Parametermarker überführt und dann ins SQLPKG gestellt, bzw. gesucht, ggf. gefunden usw.
Enthält nun ein SQL sowohl Konstanten als auch gleichzeitig Parametermarker scheint diese Mimik ab und zu nämlich daneben zu gehen.
Hier half ein wenig Googeln (ich weiß nicht mehr wo das war), da wird nämlich bezogen auf eine andere CCSID geschrieben, dass bei dieser Art der Übersetzung Probleme auftauchen können, wenn die ClientCCSID (hier die Codepage) zur AS/400 (hier *HEX) abweicht.
Dazu gab es nur eine Lösung:
Entweder alle Konstanten als Parameter ersetzen oder eben ungedreht.
Da ich eine zentrale Routine für Execute-Aufrufe hatte, war letzteres die schnellste Lösung.
Kurzerhand ein neues CMD-Objekt aus dem alten erstellt und sukzessive (unter Berücksichtigung des Feldtyps) jedes "?" durch seinen Inhalt ersetzt.
Und siehe da:
Alle SQL's laufen problemlos auch auf diesen problematischen Systemen!!!
Zu guter letzt hatte ich allerdings noch ein weiteres Problem:
Spradisch blieb mein Progrämmchen einfach stehen und wollte nichts mehr tun.
Der QZDA-Job stand auf "recv", im Joblog gabs keine Hinweise und ich konnte nur noch den Taskmanager zum Killen verwenden.
Da ich mitunter sehr viele Einzel-Selects auf die AS/400 loslasse habe ich nun festgestellt, dass nach ca. 7.350 Queries der ODBC-Treiber oder der QZDA-Job nicht mehr wollen!!!
Ich hatte also nun die Anzahl Queries gezählt und nach 5000 dann die Verbindung geschlossen und wieder aufgemacht. Allerdings schlagen hier 2 Funktionen zu:
a) Connection-Pool
b) Wiederverwendung eines QZDA-Jobs
So war dann halt nach 2530 weiteren Queries wieder Schluss.
Also habe ich meine offene Verbbindung in ein Collection-Objekt geschoben und eine neue verbindung aufgemacht.
Und so habe ich nun auch diese unverständliche Grenze umgangen.
Falls der wiederverwendete Job noch ein Problem darstellen wird, kann ich noch einen ENDJOB per QCMDEXC hinterherjagen.
So gebe ich nun alle Verbindungen erst bei Programmende frei.
Das wars mal so aus dem Nähkästchen.
Vielleicht hat ja der eine oder andere auch so unerklärliche Probleme und kann hieruas vielleicht eine Lösung ziehen.