View Full Version : Kann ein SQL Cursor übertragen werden?
Hallo zusammen,
ist es möglich einen SQL Cursor als Ein- Ausgabe einer Prozedur zu nutzen?
Ich versuche momentan in einem Serviceprogramm per SQL einen Satz zu lesen,
diesen dann zurück zu geben und beim nächsten Aufruf der Prozedur des Serviceprogramms an eben dieser Stelle (dafür die Übergabe des Cursors)
weiter zu lesen.
Leider scheiter ich schon, sobald ich den Cursor außerhalb des Exec SQLs ansprechen möchte.
Ist das überhaupt möglich und wenn ja, wie muss entsprechende RPGLE Variable deklariert
werden?
Du kannst keinen Cursor übergeben, Du kannst ggf. über LIMIT und OFFSET genau den Datensatz lesen, den Du verarbeiten möchtest.
Allerdings einzelne Sätze mit SQL zu lesen bringt nichts. SQL wird erst dann schnell, wenn ein Block von Daten gelesen und verarbeitet werden kann.
Birgitta
Alles klar,
dankeschön - aber schade.
Bleibt mir der Cursor denn erhalten,
wenn ich diese "externe" Prozedur mehrfach aus dem Selben Programm aufrufe?
... wieso willst Du da einen cursor übergeben?. Du brauchst doch nur eine exportierte procedure getNextRecord(), die einen kompletten Datensatz zurückgibt. Das ist doch Basisgeschäft von Data Access Modulen. Und was die Performance angeht, die Unterschiede liegen unterhalb der Messbarkeit und bei entsprechender Programmierung (caching und Blockfetch) ist das schneller akls Rekord Löffel.
D*B
Genau das versuche ich zu basteln.
Allerdings möchte ich kein setll/read verwenden, da ich nach verschiedenen alten logischen Dateien lesen möchte. Momentan war mein Ansatz den Namen der logischen Datei zu übergeben, dann per dspfd den key zu lesen und diesen in das Order by des SQL zu geben.
So weit so gut. Der erste Satz wird in die DS geschrieben und die Prozedur verlassen.
Jetzt besteht mein Problem darin Satz zwei zu lesen.
Da zäumst du dein Pferd von hinten auf.
Dieser Ansatz ist für SQL grundfalsch.
Befreie dich von der LF-Denke und kümmere dich ausschließlich um den SQL.
Für jede Sortierung legst du halt 2 Funktionen an:
- declare und Open des Cursors
- Fetch next des Cursors und Close am Ende
Dies führt zu statischen SQL's die erheblich performanter sind.
Benötigst du eine neue Sortierung, gibts 2 neue Funktionen.
Fehlt dazu ein Index, dann wird er halt angelegt.
Dein Ansatz führt zu a) dynamischem SQL und b) zu keiner Garantie dass der Index (LF) auch verwendet wird.
... von Pferden kann man offenkundig unterschiedliche Meinungen haben...
für Deinen Ablauf würde ich dem Serviceprogramm eine procedure setOrderBy geben und eine openCursor. Im Serviceprogramm muss man dann drauf achten, dass das beim CRTSQLMOD kein CLOSSQLCSR(*ENDMOD) drinsteht, damit einem der Cursor nicht geschlossen wird.
Dynamic SQL ist von der Performance keinerlei Problem, Programm technisch auch nicht, letzte Woche habe ich das wieder mal in einem Workshop mit totalen ILE Newbies in den Übungen implementieren lassen.
D*B
PS: lass dich nicht ins Boxhorn jagen, wg. dynamic SQL und so - auf anderen Büchsen greift man immer auf diese Art und Weise mit Zugriffsmodulen auf SQL Datenbanken zu.
Dankeschön euch!
Unabhängig von der Lösung habe ich jetzt das Problem, dass mein "declare" scheinbar
keinerlei Beachtung vom Compiler findet.
Vor dem declare kann ich sqlcode beliebig setzen (mit ev im debug).
dann kommt mein Codestück:
exec sql declare fieldcursor cursor for
select apkeyf, apkseq
from tmprcdfmt
order by apkeyn asc;
if sqlcode <> 0;
ind_fehler = *on;
return ind_fehler;
endif;
und mein sqlcode hat danach immernoch den selben Wert, als hätte er nicht
einmal versucht den Cursor zu setzen.
exec sql open xy oder close xy dagegen finden Beachtung.
Habt ihr da eine Idee?
Das Modul erstelle ich so:
CRTSQLRPGI
OBJ(TESTLIB/SQLTEST)
SRCFILE(TESTLIB/QRPGSRC)
SRCMBR(SQLTEST)
OBJTYPE(*MODULE)
REPLACE(*YES)
DBGVIEW(*SOURCE)
Declare ist nur die Beschreibung, wie auf die Daten zugegriffen werden soll.
Eine Aktion erfolgt erst beim Open und bei diesem kann der SQLCODE dann geprüft werden.
Birgitta
Das erklärt einiges!
Dann darf ich da den SQLCode einfach noch nicht abfragen.
Perfekt.
Dankeschön!