[NEWSboard IBMi Forum]
Seite 1 von 3 1 2 ... Letzte
  1. #1
    Registriert seit
    May 2013
    Beiträge
    15

    SQLCODE bei Verarbeitung mehrere SQL

    Moin zusammen,

    ich bin gerade auf ein "Problem" bei nachfolgendem Code gestoßen und habe dazu mal eine Frage.

    Das Programm läuft so bis zu dem Zeitpunkt, wo innerhalb der Funktion $Update_LAGPT der sqlcode 100 auftritt, der dort als "ok" eingestuft wird.

    Da der sqlcode aber gefüllt ist, wird dann natürlich auch die innere Schleife beendet, ohne weitere fetch next und dann auch close cursor auszuführen.

    Beim nächsten Durchlauf der der äußerenSchleife scheitert dann natürlich der open cursor, da dieser ja noch offen ist.

    Gibt es eine elegante Möglichkeit, den sqlcode nicht immer explizit auf 0 setzen zu müssen, wenn mich das Ergebnis eines sql's auf eine bestimmte Datei eigentlich nicht interessiert, aber für die allgemeine Programmverarbeitung doch noch gebraucht wird?

    Beim fetch selbst hatte ich bereits daran gedacht, den sqlcode auf 0 zu setzen, jedoch weiß man ja nicht zwangsläufig, ob dieser in aufgerufenen Funktionen noch gesetzt wird und auch so bleibt.

    Im "normalen" RPG nehme ich halt %EOF(Dateiname) oder %Found(Dateiname).
    Da gibt es dann keine Problme mit Überschneidungen.

    Ich hoffe, ich habe einigermaßen verständlich ausgedrückt, worum es mir geht.

    Danke und Gruß
    Michael

    Code:
    DOW sqlcode <> 0;
    Diverse SQL bis hier
    
    
       if not $defineCursorRGZPT();
          return  false;   // Fehler (bereits behandelt => Programmende)
       endIf;
    
       doW sqlCode = 0;
    
          // Lesen nächste Rechnungszeilenpartie
          exec sql fetch rgzpt_Cursor into :sqlRecRZP;
    
          if sqlCode <> 0;
    
             if sqlCode = 100;  // = EoF
                exec sql close rgzpt_Cursor;
    
                if sqlCode = 0;  // = EoF
                   $protokolliere( '* SQL-Cursor RGZPT für Umfuhr '
                      + %char(sqlrecAK.akatnr)
                      + ' erfolgreich entfernt');
                else;
                   $protokolliere( '* SQL-Cursor RGZPT'
                      + ' konnte nicht entfernt werden');
                endif;
    
                sqlcode = 0; // sicherheitshalber wegen Hauptschleife wieder auf 0
                leave;
             endIf;
    
             // Andere Fehler
             $protokolliere('Fehler beim Fetch Next, Datei RGZPTPF. '
                  + 'SQLCode: '     + %char(SqlCode)
                  + ' - SQLState: ' + SqlState
                  + '. ' + SQLLIB_getLastSQLError()
                     );
             return false;    // => Programm abbrechen
          endIf;
    
          // Aktualisieren der Abgangsmenge bei Lagerpartie
    innerhalb der Funktion kann auch auch sqlcod <>0 entstehen, was aber ok sein kann
           if not $Update_LAGPT( sqlrecRZP.rzpfrm : sqlrecRZP.rzpartnr
               : sqlrecRZP.rzplager : sqlrecRZP.rzpptnr
               : sqlrecRZP.rzpmgeve);
      
             return false;
    
          endIf;
    
        enddo;
    
    ab hier weitere Verarbeitung nach Abarbeitung aller Sätze des fetch. 
    Diverse SQL ab hier
    
    enddo;

  2. #2
    Registriert seit
    Aug 2003
    Beiträge
    1.508
    Hi Michael,

    eleganter wäre es wenn grundsätzlich der sqlcode immer nach der jeweiligen SQL Anweisung geprüft wird und nicht erst später.
    Du kannst dir nie sicher sein wo noch überall der sqlcode geändert wird und wehe jemand ändert irgendwann mal den code und vergisst darauf.

    Besser also generell so programmieren, dass du darauf nicht acht geben musst.

    Code:
    fetch ...;
    dow sqlcode <> 0;
      //dein code
      fetch ...;
    enddo;
    Das if sqlCode = 100; kannst du dann auch hinter der Schleife verschieben.
    Ersparst dir dann auch das LEAVE.

    lg Andreas

  3. #3
    Registriert seit
    May 2013
    Beiträge
    15
    Moin Andreas,

    zunächst danke für die rasche Antwort.

    Ich glaube, über Programmierstile muss man nicht streiten *frech grins*

    Ich habe damals noch DO *Hival gelernt und das ist bei mir so sitzen geblieben. Da musste ich mich um das Handling dann auch explizit kümmern. Ich persönlich mag das Read vor dem Doxx und am Ende vor dem Enddo auch nicht wirklich.

    Nachdem ich den Post geschrieben habe, habe ich auch generell de close cursor schon hinter das enddo verschoben, da das dann auch innerhalb der Schleife etwas aufgeräumter aussieht und sowie generell passieren soll.

    Trotzdem beantwortet das nicht meine eigentlich Frage.

    Das SQL innerhalb der aufgerufenen Funktion produziert halt ggf. auch einen sqlcode 100, der mich dort aber nicht interessiert.

    Komme ich dann zurück, würde auch in Deinem Code das enddo "überlaufen", was aber nicht gewollt ist.

    Entsteht in der Funktion ein sqlcode <> 0/100 ist die Funktion auch "false" und darauf reagiere ich dann ja auch.

    Die Frage ist eigentlich "ein sqlcode" für alle sql für verschiedene Datenquellen"?

    lg
    Michael

  4. #4
    Registriert seit
    Apr 2019
    Beiträge
    43
    Komme ich dann zurück, würde auch in Deinem Code das enddo "überlaufen", was aber nicht gewollt ist.
    Naja bedingt. Du würdest ja anschließend den nächsten Satz fetchen. Das würde das SQLCOD-Ergebnis wieder überschreiben. Überlaufen würde es nicht.

    Aber zu deiner Frage -> Mir ist nicht bekannt dass sowas möglich ist (wüsste auch nicht wie die Syntax aussehen sollte, ist ja ne variable die man abfragt..).
    Du könntest dir mit Zwischenspeichern des SQLCOD in ein selbstdefiniertes SQLCOD1 (oder was auch immer) zumindestens weiterhelfen.

  5. #5
    Registriert seit
    May 2013
    Beiträge
    15
    xenofob, Du hast natürlich Recht. Da habe ich nicht zuende gedacht.

    Das würde dann für die Vorgehensweise von Andreas sprechen.

    Danke für den Hinweis

  6. #6
    Registriert seit
    Aug 2001
    Beiträge
    2.869
    Hallo Michael,

    vielleicht noch so ein einfacher Trick, um sicherzugehen, dass der Cursor auch wirklich geschlossen wurde.
    ... mach einfach ein CLOSE vor dem OPEN.
    War der Cursor noch geöffnet, dann ist er jetzt geschlossen.

    Es gibt nur einen einzigen SQLCODE.
    Dieser ist in einer globalen Datenstruktur hinterlegt und wird bei jedem SQL-Aufruf (bzw. den entsprechenden Progrmmen) erneut ausgegeben.
    Qualifizieren oder eindeutig einem Cursor zuweisen kann man nicht.

    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

  7. #7
    Registriert seit
    Apr 2019
    Beiträge
    43
    Zitat Zitat von Hawi Beitrag anzeigen
    xenofob, Du hast natürlich Recht. Da habe ich nicht zuende gedacht.

    Das würde dann für die Vorgehensweise von Andreas sprechen.

    Danke für den Hinweis
    Ja die Vorgehensweise von Andreas ist weit verbreitet. Zu recht.
    In der Schule erlernt man genau diese Art von Schleifenverarbeitung. (sogar unabhängig von RPG)

    Wenn du dich damit anfreunden könntest, ist nicht nur dir, sondern auch allen zukünftigen jungen Kollegen geholfen.
    Last edited by xenofob; 08-05-20 at 14:01. Grund: Smileys funktionieren nicht

  8. #8
    Registriert seit
    May 2013
    Beiträge
    15
    Hallo Birgitta,

    danke für den Tipp.

    Darüber nachgedacht hatte ich auch schon, da ich gleiches zum Programmende auch mache, unabhängig davon, ob ich vorher schon den close hatte.

    Und da ich den sqlcode dann ja nicht auswerten muss, läuft der "Cursor ... nicht geöfnnet" dann halt ins Leere.

    So werde ich das dann wohl machen.

    Glücklich macht mich das zwar nicht wirklich, aber an SQL kommt man ja auch nicht mehr wirklich vorbei und eigentlich ist es ja auch ganz nett und dazu nahezu plattformunabhängig.

    Aber da ich weiß, dass Du sehr viel mit SQL machst und ich auch schon auf einigen Deiner Vorträge auf der COMMON war, vieleicht magst Du mir da noch eine Frage beantworten, die mir schon länger im Kopf schwirrt, die ich aber mit niemanden wirklich ausdiskutieren kann.

    Hat Embedded-SQL in einer Anwendung, die rein aus RPG(LE) und DDS-beschriebenen Files besteht einen wirklichen Vorteil gegenüber der herkömmlichen Dateiverarbeitung?

    Über eine Antwort würde ich mich freuen. Wenn Du magst, auch gerne als pn, da es das Thema hier nicht wirklich betrifft.

    Danke und Gruß
    Michael

    P.S. ich weiß, dass ich den abschließenden close am Programmende auch vom System machen lassen kann, musste aber eh Aliasse lösche und habe es dann dort gleich mit rein gebaut

  9. #9
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Da es den DO *HIVAL nicht mehr gibt, verwende ich grundsätzlich

    exec sql open ...
    dow 1=1;
    exec sql fetch ...
    if sqlcode <> *zero;
    leave;
    endif;
    :
    enddo:
    exec sql close ...

    Somit frage ich den SQLCODE nur da ab, wo ich ihn brauche.
    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

  10. #10
    Registriert seit
    May 2013
    Beiträge
    15
    Danke Fürchau,

    das ist ja genau meine Art Code zu schreiben *smile* und würde mir in meinem konkreten Fall weiterhelfen.

    Die Frage mit den sqlcode in der globalen DS hat ja leider schon Birgitta, wie von mir befürchtet beantwortet.

    Zitat Zitat von Fuerchau Beitrag anzeigen
    Da es den DO *HIVAL nicht mehr gibt, verwende ich grundsätzlich
    Was natürlich nur dann so stimmt, wenn man nicht mehr fixed programmiert/programmieren muss

  11. #11
    Registriert seit
    Apr 2019
    Beiträge
    43
    Naja modern ist das jetzt nicht. Leave sollte man ja auch nur in absoluten Ausnahmesituationen verwenden, wenn man nach Allgemeinen Clean-Code Regeln entwickelt. (Was man ja unbedingt tun sollte, sonst kein RPG-Nachwuchs..)
    Aber die Debatte tue ich mir nicht mehr mit RPG Entwicklern an, leider eine Diskussion ohne Aussicht auf Erfolg..

  12. #12
    Registriert seit
    Aug 2001
    Beiträge
    2.869
    ... und was passiert, wenn Dein Programm fehlerhaft beendet wurde und erst gar nicht zu dem CLOSE kommt?
    Dann hast Du beim nächsten Aufruf u.U. ein Problem.

    Natürlich versucht jeder so sicher wie möglich zu programmieren, aber ich habe genügend Situationen erlebt, in denen dann "eine leere Liste" oder ein "leerer Bildschirm" zurückkam.
    ... und was noch schlimmer war, dass der Programmierer dann das Problem so gelöst hat, dass das Programm vor dem Aufruf immer neu compiliert wurde.

    Klar, man kann natürlich jetzt (seit 2 Releasen) auch den Close exklusiv im ON-EXIT machen, dann geht man ganz auf Nr. sicher.

    ... Ach und übrigens, gibt es mit dem TR2 in Release 7.1 (bzw dem entsprechenden TR in Release 7.3) die Möglichkeit auch im Free-Format eine Endlos-Schleife zu programmieren:

    Code:
    DOW *ON;
    ...
    ENDDO
    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

Similar Threads

  1. SQLCODE -805 beim Zugriff auf ein fernes System
    By mahones in forum NEWSboard Programmierung
    Antworten: 31
    Letzter Beitrag: 02-04-20, 11:21
  2. SQLCODE = -206
    By Hubert in forum NEWSboard Programmierung
    Antworten: 3
    Letzter Beitrag: 14-10-19, 14:02
  3. SQLCODE = -000000811. in einem SQLCBLLE
    By nico1964 in forum NEWSboard Programmierung
    Antworten: 4
    Letzter Beitrag: 29-06-15, 07:53
  4. IP-Verarbeitung
    By Gimli in forum IBM i Hauptforum
    Antworten: 3
    Letzter Beitrag: 06-09-02, 12:58
  5. PC-Konsole für mehrere AS/400
    By moskito in forum IBM i Hauptforum
    Antworten: 1
    Letzter Beitrag: 13-09-01, 18:40

Berechtigungen

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