[NEWSboard IBMi Forum]
  1. #1
    Registriert seit
    Jul 2003
    Beiträge
    4

    dyn. SQL im RPG IV

    hallo,

    bin noch etwas unerfahren mit embedded sql.

    Ich möchte ein dynamisches sql mehrfach verarbeiten - es geht um ein Übersichtspgm (Subfile) mit div. Selektionen/Sortierungen.
    Ich def. also eine Abfrage, öffne sie & lese, am Ende close cursor - alles ok.
    Ausgabe auf BS - jetzt eine andere Selektion - Wenn ich dann die Abfrage ändere, wieder öffne & lesen will bekomme ich den SQL-Code -501 (cursor not open)

    - wie kann ich das verhindern?

  2. #2
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Parametrierte Abfragen werden so definiert:

    /exec sql
    +declare cursor mycursor for
    +Select field1, field2, ....
    +from myfile
    +where key1=:mykey1 and key2=:mykey2 ...
    /end-exec

    Um die Abfrage dann auszuführen muss die Abfrage natürlich immer neu geöffnet werden:

    /exec sql open mycursor
    /end-exec

    do *hival
    /exec sql
    +fetch mycursor into :myfield1, :myfield2, ...
    /end-exec

    if sqlcod < *zero
    or sqlcode = 100
    leave
    endif

    :
    write MySubfile
    :

    enddo

    /exec-sql close mycursor
    /end-exec
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  3. #3
    Registriert seit
    Jul 2003
    Beiträge
    4
    danke,
    leider hilft mir das nicht weiter - ich will es mal als Beispiel bringen:


    eval abfrage = 'select * from myfile where feld1 = sel1 and
    feld2 = sel2 order by key1'

    /exec sql prepare s1 from :abfrage
    /end-exec

    /exec sql declare c1 cursor for s1
    /end-exec


    /exec sql open c1
    /end-exec


    dow sqlcod <> 100

    /exec sql fetch c1 into :myfile
    /end-exec

    if sqlcod = 100
    /exec sql close c1
    /end-exec
    leavesr
    endif

    write subfile

    ....


    exfmt sfcontrol

    wenn neue Selektion:

    eval abfrage = 'select * from myfile where feld2 = sel2 and
    feld4 = sel4 order by key2, key4'

    danach schicke ich das Pgm wieder zum "prepare s1"
    und lasse es da weiter laufen (ist in meinem Pgm. eine Subroutine)

  4. #4
    Registriert seit
    Aug 2001
    Beiträge
    2.873

    Dynamisches SQL

    Hallo,

    nur so eine Vermutung:
    Ist die Reihenfolge in Deiner Quelle genau so wie angegeben (unabhängig von der Ausführung von Subroutinen)?

    Wenn nein, versuche Deinen Code so zu stricken:

    1. Füllen Command
    2. Declare
    3. Close (mache ich immer nochmals zur Sicherheit)
    4. Open
    5. Fetch

    Wir hatten diesbezüglich Probleme, als wir beim statischen SQL das Declare-Statement in die *INZSR gelegt haben.
    (allerdings war das noch unter RPGIII).

    Sonst sieht der Code in Ordnung aus.

    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  5. #5
    Registriert seit
    Jul 2003
    Beiträge
    4
    danke,

    ich habe den close vor dem open eingebaut, aber das war's leider auch nicht. Die Reihenfolge ist genau, wie Du es beschrieben hast, wenn sie nicht stimmt gibt's einen Abbruch bei der Umwandlung - ich denke, daß der SQL-Precompiler von oben nach unten geht & die Abfolge von Subroutinen nicht beachtet.

  6. #6
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    Die Reihenfolge von CLOSE / OPEN in der Quelle spielt keine Rolle. Einzig der DECLARE CURSOR muss in der Quelle vor der ersten Nutzung mit OPEN / FETCH / CLOSE liegen.
    Auch der PREPARE kann in der Quelle liegen wo er will.

    Prüfe jedoch mal, ob der PREPARE nicht bereits einen SQLCOD <> 0 liefert, ich glaube hier liegt ggf. das Problem.
    Der CLOSE schließt ggf. den CURSOR nicht tatsächlich (SQL-Optimizer), so dass der PREPARE fehlschlägt.

    Wenn Du vor Aufruf des Programmes mittels "STRDBG UPDPROD(*YES)" den Debugmodus startest, kannst du im Joblog detailierte Meldungen sehen.

    Mit ENDDBG beendest du den Modus.

    Achte bei der Umwandlung mal darauf wie die Option CLOSQLCSR gesetzt ist.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

  7. #7
    Registriert seit
    Aug 2001
    Beiträge
    2.873

    B.Hauser

    Die Reihenfolge Close/Open spielt tatsächlich eine Rolle.
    Wenn z.B. folgendes Szenario stattfindet.

    Cursor wurde geöffnet
    Alle Sätze oder einige Sätze wurden mit Fetch in einer Schleife gelesen.
    Es wurde kein Close gesetzt. (z.B. Schleife wurde nicht mit SQL-Code 100 verlassen)
    Ein erneuter OPEN ist jetzt wirkungslos. (im Gegensatz zu einem SETLL im RPG)

    CLOSQLCSR bewirkt nicht unbedingt, dass der Cursor geschlossen wird.
    Sondern nur, ob der bereits gefundene Zugriffs-Weg beim nächsten Aufruf wieder verwendet wird.

    Bei obigem Beispiel könnte es sogar sein, dass beim erneuten Programm-Aufruf keine Sätze mehr angezeigt werden, da der Cursor nicht geschlossen wurde, und alle Sätze verarbeitet wurden.

    Birgitta
    Birgitta Hauser

    Anwendungsmodernisierung, Beratung, Schulungen, Programmierung im Bereich RPG, SQL und Datenbank
    IBM Champion seit 2020 - 4. Jahr in Folge
    Birgitta Hauser - Modernization - Education - Consulting on IBM i

  8. #8
    Registriert seit
    Jan 2001
    Beiträge
    833
    Hallo

    vielleicht noch ein Tipp :

    Wenn Du das Programm mit STRDBG durchgehst dann
    schau Dir mal nach den einzelnen SQL Aktionen
    den SQLCODE an.

    Zusätzlich könnte das JOBLOG noch einen Fehler hergeben.


    Gruss Michael

  9. #9
    Registriert seit
    Jul 2003
    Beiträge
    4

    Smile

    hallo & vielen Dank für die Tips,

    der Tip mit der Umwandlung war der Hit:

    mit commit *none, closqlcsr *endmod & dlyprp *yes

    hat's geklappt


    also danke nochmal

    gruß

    lisa

  10. #10
    Registriert seit
    Feb 2001
    Beiträge
    20.241
    @Birgitta

    Ich meinte ja nicht die Reihenfolge der Durchführung von OPEN/CLOSE sondern nur der Ort in der Quelle.

    Das Hauptproblem mit dynamischen SQL's sind die Resourcen, die intern verwendet werden.
    Da der DECLARE CURSOR nicht dynamisch ist sondern zur Compilezeit bestimmt wird, wird auf die Resource Statement konstant verwiesen.

    Erst wenn der Cursor also tatsächlich geschlossen ist, wird auch die Resource Statement wieder freigegeben.

    Ein erneutes PREPARE kann somit nicht erfolgreich sein.

    Durch die Option CLOSQLCSR(*ENDMOD) wird der Cursor durch verlassen des Moduls gelöscht und das Statement wieder freigegeben. Der Defaultwert ist ansonsten *ENDACTGRP, was die Resourcen über die gesamte Programmlaufzeit belegt.

    Cursor werden auch durch COMMIT gelöscht, wenn nicht explizit im DECLARE CURSOR ... WITH HOLD definiert wurde.
    Also auch ein Commit würde die Resource Statement in diesem Fall freigeben.
    Dienstleistungen? Die gibt es hier: http://www.fuerchau.de
    Das Excel-AddIn: https://www.ftsolutions.de/index.php/downloads
    BI? Da war doch noch was: http://www.ftsolutions.de

Similar Threads

  1. ILE RPG / SQL Füllen einer Feldgruppe
    By homue in forum NEWSboard Programmierung
    Antworten: 5
    Letzter Beitrag: 18-07-07, 16:47
  2. Bibliotheksliste in RPG IV abfragen
    By timeless in forum IBM i Hauptforum
    Antworten: 5
    Letzter Beitrag: 11-01-07, 12:04
  3. embedded SQL in RPG
    By muadeep in forum IBM i Hauptforum
    Antworten: 5
    Letzter Beitrag: 03-08-06, 13:25
  4. SQL .. for update of (RPG embedded SQL)
    By loeweadolf in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 01-06-06, 09:43

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • You may not post attachments
  • You may not edit your posts
  •