[NEWSboard IBMi Forum]

Thema: SQLRPG

  1. #1
    Registriert seit
    Aug 2001
    Beiträge
    13

    Question SQLRPG

    Wer kann mir einen hilfreichen Tipp geben ??

    Situation : Ich baue in einem RPG IV Programm anhand verschiedener Bedingungen ein SQL-Statement in einer Charakter-Variablen über den CAT-Befehl zusammen. Wie kann ich dieses SQL-Statement aus dem RPG-Programm heraus ausführen lassen ??

    Vielen Dank für Eure Hilfe.

    Ursus

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

    Smile

    Hallo Ursus,

    hier ein Beispiel für dynamisches SQL mit Cursor:
    $SCLCMD ist der zusammengesetzte Befehl (Select .....)

    Sql-Command aufbereiten
    C/EXEC SQL
    C+ Prepare SQLBP From :$SQCMD
    C/END-EXEC
    *
    * Cursor Definieren
    C/EXEC SQL
    C+ Declare $SQLC1 Cursor For SQLBP
    C/END-EXEC
    *
    * Cursor öffnen
    *----------------------*
    C/EXEC SQL
    C+ Open $SQLC1
    C/END-EXEC
    *
    * Verarbeiten SQL-Command in Schleife
    *--------------------------------------*
    C Do *Hival
    *
    C/EXEC SQL
    C+ Fetch $SQLC1
    C+ INTO :$SQLAB, :$SQZZ, :$SQXX, :$SQYY
    C/END-EXEC
    *
    * Ende-Bedingungen
    C IF SQLCOD = 100
    C leave
    C endif
    *
    * Nächster Satz (Fehler)
    C if SQLCOD < 0
    C iter
    C endif
    *
    * Verarbeitung
    * Was auch immer
    C enddo
    *
    * Schliessen Cursor
    *-------------------*
    C/EXEC SQL
    C+ Close $SQLC1
    C/END-EXEC
    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

  3. #3
    Registriert seit
    Aug 2001
    Beiträge
    13

    Post

    Hallo Frau Hauser,

    vielen Dank für Ihre Antwort, ich habe Ihre Idee in mein Programm wie folgt in mein Programm eingebaut :
    **
    D SQLSTRG S 512A
    **
    ** In SQLSTRG steht zum Ze***unkt der
    ** Ausführung folgendes Statemnet :
    ** SELECT COUNT(*) INTO :#ANZ FROM biliothek/
    ** dateiname WHERE bedingungen
    **
    C/EXEC SQL
    C+ PREPARE SQLBP FROM :SQLSTRG
    C/END SQL
    **
    C/EXEC SQL
    C+ DECLARE C1 CURSOR FOR SQLBP
    C/END-EXEC
    **
    C/EXEC SQL
    C+ OPEN C1
    C/END-EXEC
    **
    C/EXEC SQL
    C+ FETCH C1
    C/END-EXEC
    C EVAL O8ANZ = #ANZ
    **

    Nach der Ausführung des Prepare Statements kommt es zu dem Fehler :
    SQL0312 CQLCODE -312 "Host Variable nicht definiert oder nicht benutzbar"
    Ist meine Variable zu lang, oder habe ich sie falsch definiert ??

    Vielen Dank für Ihre Mühe,

    Marc


    [Dieser Beitrag wurde von Ursus am 09. August 2001 editiert.]

  4. #4
    Registriert seit
    Feb 2001
    Beiträge
    20.241

    Post

    Bei einer Prepared-Select-Anweisung kann kein INTO verwendet werden !!!!
    Bei der Fehlermeldung ist die Variable #ANZ gemeint. Diese kann nur der RPG-Kompiler kennen und nicht der SQL-Analyser, der das Prepare durchführt. Schließlich wird die Variable #ANZ vom RPG-Compiler bereits in eine Adressse umgesetzt, so dass die Variable so nicht mehr bekannt ist.

    Nehmen Sie das obige Beispiel also wörtlich, definieren Sie den Select OHNE INTO und verwenden Sie anschließend OPEN, FETCH ... :INTO und CLOSE.
    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

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

    Post

    Hallo

    Das Beispiel für das Dynamische SQL stammt aus einem Programm, das in dieser Form im Einsatz ist. Fetch-Anweisungen mit INTO sind durchaus möglich!

    Allerdings war die Länge des Commands unter RPGIII auf 256 Stellen begrenzt! Unter RPGIV habe ich noch kein dynamisches SQL verwendet, bei dem der Command länger als 256 Stellen war

    Vermutlich besteht diese Grenze noch
    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

  6. #6
    Registriert seit
    Aug 2001
    Beiträge
    13

    Post

    Vielen Dank für Ihre Tipps !

    Ich habe jetzt nur noch ein Problem :
    Wird der komplette String als "einzeiliges SQL-Statement" verarbeitet oder wird wie im Debugger angezeigt, ein Zeilenumbruch nach 60 Zeichen vorgenommen ??
    Die Abfrage läuft, wenn das SQL-Statement maximal 60 Zeichen enthält, wenn ich mehr als 60 Zeichen verwenden will, bekomme ich bei dem PREPARE-Statement die Fehlermeldung SQLCODE -206 (Spalte nicht in angegebener Tabelle definiert) obwohl das gleiche Statement im interaktiven SQL läuft.

    Muß ich irgendwelche Trennzeichen beachten oder wo liegt jetzt der Fehler ??

    Vielen Dank, Marc

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

    Post

    Hallo Marc,

    ich habe gestern Mittag den Select-Befehl nicht genau gelesen.

    Bei dem angegebenen SELECT-Befehl handelt es sich um eine Verarbeitung ohne Cursor.
    Diese Verarbeitung ist möglich, wenn genau ein Ergebnis-Satz erwartet wird. Die INTO-Angabe erfolgt in der SELECT-Anweisung.
    In diesem Fall darf nur FETCH angegeben werden.

    Werden mehrere Sätze, die einzeln verarbeitet werden sollen erwartet, darf die INTO-Anweisung nicht im SELECT erfolgen. Die Verarbeitung erfolgt in einer DO-Schleife bei der die einzelnen Sätze durch FETCH INTO verarbeitet werden.
    Diese Art der Verarbeitung funktionniert natürlich auch, wenn nur ein Ergebnis-Satz erwartet wird.

    Was die Länge des Strings angeht, habe ich bis zu 256-Zeichen noch nie Probleme gehabt.
    Wie wurde der String aufgebaut? Vielleicht liegt der Fehler dort

    B. Hauser
    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
    Aug 2001
    Beiträge
    13

    Post

    Hallo Birgitta,

    ich habe auf folgende Weise das SQL-Statement aufgebaut :

    D #SQLCMD S 1024A

    D CSQL 'SELECT COUNT(*) FROM SWDAT-
    D /MDBF00 WHERE BFFIRM = ''000'''

    D ASQLCMD S 1 DIM(1024)

    MOVEA CSQL ASQLCMD(1)

    IF I1PROG <> *BLANKS
    EVAL #SQL2 = ' AND BFPROG = I1PROG'
    MOVEA #SQL2 ASQLCMD(56)
    ENDIF

    IF I1SAB <> '*'
    EVAL #SQL2 = 'AND BFSAB = I1SAB'
    MOVEA #SQL2 ASQLCMD(75)
    ENDIF

    MOVEA ASQLCMD #SQLCMD

    C/EXEC SQL
    C+ PREPARE SQLBP FROM :#SQLCMD
    C/END-EXEC

    Im Debugger sieht das Statement vor dem Prepare folgendermaßen aus :

    ....5...10...15...20...25...30...35...40...45...50 ...55...60
    'SELECT COUNT(*) FROM SWDAT/MDBF00 WHERE BFFIRM = '000' '
    'AND BFPROG = I1PROG'

    Zuerst habe ich das Statement über den CAT-Befehl zusammengebaut, als dabei Fehlermeldungen kamen, habe ich eine Datenstruktur erstellt und diese wie oben beschrieben gefüllt. Beide Wege funktionieren, wenn ich nur maximal 60 Stellen fülle, bei mehr als 60 Stellen ergeben beide Wege die beschriebene Fehlermeldung.

    Ich habe die Variablen auch schon auf 100 gekürzt um zu testen, ob es dann fehelrfrei läuft, aber auch das bringt die gleiche Fehlermeldung.

    Was habe ich falsch gemacht ? Was habe ich noch für Möglichkeiten ?

  9. #9
    Registriert seit
    Aug 2001
    Beiträge
    13

    Post

    Hallo Birgitta,

    ich habe auf folgende Weise das SQL-Statement aufgebaut :

    D #SQLCMD S 1024A

    D CSQL 'SELECT COUNT(*) FROM SWDAT-
    D /MDBF00 WHERE BFFIRM = ''000'''

    D ASQLCMD S 1 DIM(1024)

    MOVEA CSQL ASQLCMD(1)

    IF I1PROG <> *BLANKS
    EVAL #SQL2 = ' AND BFPROG = I1PROG'
    MOVEA #SQL2 ASQLCMD(56)
    ENDIF

    IF I1SAB <> '*'
    EVAL #SQL2 = 'AND BFSAB = I1SAB'
    MOVEA #SQL2 ASQLCMD(75)
    ENDIF

    MOVEA ASQLCMD #SQLCMD

    C/EXEC SQL
    C+ PREPARE SQLBP FROM :#SQLCMD
    C/END-EXEC

    Im Debugger sieht das Statement vor dem Prepare folgendermaßen aus :

    ....5...10...15...20...25...30...35...40...45...50 ...55...60
    'SELECT COUNT(*) FROM SWDAT/MDBF00 WHERE BFFIRM = '000' '
    'AND BFPROG = I1PROG'

    Zuerst habe ich das Statement über den CAT-Befehl zusammengebaut, als dabei Fehlermeldungen kamen, habe ich eine Datenstruktur erstellt und diese wie oben beschrieben gefüllt. Beide Wege funktionieren, wenn ich nur maximal 60 Stellen fülle, bei mehr als 60 Stellen ergeben beide Wege die beschriebene Fehlermeldung.

    Ich habe die Variablen auch schon auf 100 gekürzt um zu testen, ob es dann fehelrfrei läuft, aber auch das bringt die gleiche Fehlermeldung.

    Was habe ich falsch gemacht ? Was habe ich noch für Möglichkeiten ?

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

    Post

    SQL Sucht die variablen I1PROG und I1SAB in der Datei !
    Sie möchten aber den Inhalt !

    LÖsung:

    D BED1 100A INZ
    D BED2 100A INZ

    IF I1PROG <> *BLANKS
    EVAL BED1 = ' AND BFPROG = '''' + I1PROG + ''''
    ENDIF

    IF I1SAB <> '*'
    EVAL BED2 = ' AND BFSAB = '''' + I1SAB + ''''
    ENDIF

    EVAL #SQLCMD = 'SELECT COUNT(*) ... ' + BED1 + BED2

    ACHTUNG:

    Beachten Sie dass die Prepareanweisung nur 1 Mal funktioniert solange das Programm aktiv bleibt. Das SQL-Statement SQLBP wird erst nach Trennung der Verbindung zur Datenbank wieder gelöscht.
    Ihre Lösung ist daher nicht performant !

    Definieren Sie lieber die benötigten Varianten für ihren SELECT direkt und führen die entsprechende Anweisung zur Laufzeit aus.
    Vorteil: Das Prepare erfolgt bereits zur Compile-Zeit !

    select
    when I1PROG = *BLANK and I1SAB=*BLANK
    /EXEC-SQL
    +SELECT ... (Variante 1)
    /END-EXEC
    when I1PROG <>*BLANK and I1SAB=*BLANK
    /EXEC-SQL
    +SELECT ... WHERE BFPROG=:I1PROG (Variante 2)
    /END-EXEC

    when ...
    :
    :
    endsl

    Die Bibliothek muss auch nicht angegeben werden, da diese über die Librarylist automatisch ermittelt wird.
    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

  11. #11
    Registriert seit
    Aug 2001
    Beiträge
    13

    Post

    Vielen Dank für Ihre Mühen !

    Ich habe Ihre Vorschläge umgesetzt und jetzt läuft meine Abfrage endlich.

    Nochmals, vielen Dank.

    Marc

Similar Threads

  1. SQLRPG Debug
    By olbe in forum NEWSboard Programmierung
    Antworten: 5
    Letzter Beitrag: 24-07-07, 14:48
  2. SQLRPG
    By muadeep in forum IBM i Hauptforum
    Antworten: 3
    Letzter Beitrag: 28-06-05, 13:17
  3. SQLRPG Angabe LIB als Paramater
    By procher in forum IBM i Hauptforum
    Antworten: 3
    Letzter Beitrag: 24-01-03, 16:59
  4. SQLRPG R510
    By TARASIK in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 19-12-02, 12:18
  5. Dateifreigabe bei SQLRPG
    By Wiezorek in forum IBM i Hauptforum
    Antworten: 4
    Letzter Beitrag: 16-10-01, 12:03

Berechtigungen

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