[NEWSboard IBMi Forum]

Hybrid View

  1. #1
    Registriert seit
    Feb 2004
    Beiträge
    18

    Angry Embedded SQL (EXEC SQL) und QMHRCVPM

    Hallo,

    ich beiß mir zur Zeit am RPG-Embedded SQL die Zähne aus... Es funktioniert soweit eigentlich alles, jedoch möchte ich gern die SQL-Meldungen (z. B. SQL0100) aus dem Joblog ins Programm holen, und ggf. dem Benutzer anzeigen. Bisher hat das immer über das API QMHRCVPM geklappt, aber die SQL-Meldungen wollen einfach nicht kommen. Das API schweigt mich an und die RCVM0200-Variable bleibt leer.

    Code:
     *** externe Prozeduren ***
    D qmhrcvpm        pr                  extpgm('QMHRCVPM')                   API-RcvMsg
    D  msgData                            like(rcvm0200)                        Nachrichten-DS
    D  msgDataLen                   10i 0 const                                   Länge
    D  format                        8    const                                 Format
    D  stack                        10    const                                 Aufrufstapel
    D  stackCounter                 10i 0 const                                   Zähler
    D  msgType                      10    const                                 Nachrichten-Art
    D  msgKey                        4    const                                 Nachrichten-Key
    D  waitTime                     10i 0 const                                 Wartezeit
    D  msgAction                    10    const                                 Nachrichten-Aktion
    D  apiError                           like(apiErr)                          Fehler
    
     *** Datenstrukturen ***
    D rcvm0200        ds                  qualified                            Nachricht
    D  bytesReturned                10i 0                                       Bytes returned
    D  bytesAvail                   10i 0                                       Bytes available
    D  severity                     10i 0                                       Severity
    D  msgId                         7                                          Identifier
    D  msgType                       2                                          Nachrichtentyp
    D  msgKey                        4                                          MSG-Key
    D  msgFile                      10                                          MSG-File
    D  msgFileLib                   10                                            Bibliothek
    D  msgFileLibU                  10                                            Bibliothek Used
    D  msgJobName                   10                                          Jobname
    D  msgUser                      10                                          Benutzer
    D  msgJobNbr                     6                                          Jobnummer
    D  msgProgramm                  12                                          Programm
    D  res1                          4
    D  sndDate                       7                                          Datum gesendet
    D  sndTime                       6                                          Zeit gesendet
    D  sndTimeMs                     6  0                                       Mikrosek. gesendet
    D  sndUser                      10                                          Benutzer gesendet
    D  res2                          1
    D  ccsidConvTxt                 10i 0                                       CCSID Conv. Text
    D  ccsidConvData                10i 0                                       CCSID Conv. Data
    D  alertOption                   9                                          Alert Option
    D  ccsidMsgHelp                 10i 0                                       CCSID Message/Help
    D  ccsidRplData                 10i 0                                       CCSID Repl. Data
    D  rplDataLenRtn                10i 0                                       Länge RPL-Data ret.
    D  rplDataLenAv                 10i 0                                       Länge RPL-Data ava.
    D  msgLenRtn                    10i 0                                       Länge MSG returned
    D  msgLenAvail                  10i 0                                       Länge MSG available
    D  helpLenRtn                   10i 0                                       Länge Hilfe ret.
    D  helpLenAvail                 10i 0                                       Länge Hilfe avail.
    D  msgRplMsgHelp              3000                                          MSG + RPLData + HLP
    
    D apierr          ds                  qualified                            API-Error
    D  bytesprov                     8b 0                                       Bytes Provided
    D  pytesavail                    8b 0                                       Bytes Available
    D  msgid                         7                                          MSG-Id
    ...
    
    /free
    ...
     exec sql fetch next from cursorSubf01 into
                    :recn, :itnr, :text_s;
    
     if sqlcod <> 100;
         qmhrcvpm(rcvm0200: %len(rcvm0200): 'RCVM0200': '*': 0: 
             '*FIRST': ' ': 0: '*SAME': apiErr);
     endif;
    /end-free

  2. #2
    Registriert seit
    Feb 2001
    Beiträge
    20.696
    Schau mal per Debugger, ob die Meldung überhaupt an deine Programmebene kommt (bei ILE meist nicht).
    Dadurch steht diese allenfalls noch im Joblog, da die Programmebene, an die die Meldung ging, schon verlassen wurde.

    Aber warum so kompliziert ?

    Alles was du brauchst steht nach jedem SQL in der SQLDA.
    SQLCOD kennst du ja schon, der Rest steht analog der MSG-Feld-Beschreibung (QSQLMSG) in SQLERM.
    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
    Aug 2001
    Beiträge
    2.928
    Aus SQL wird keine Nachricht gesendet, sondern (embedded) SQL meldet Fehler oder Warnungen über den SQLCOD/SQLCODE (< 0 = Fehler, 1-99 = Warnungen) oder den SQLSTT/SQLSTATE (Stelle 1-2 = '01' = Warnung, Stelle 1-2 = '02' = nicht gefunden, Stelle 1-2 <> '00', '01', '02' = Fehler).

    Wie Baldur sagt, kannst Du Dir die Message-Id aus dem SQLCode zusammenbasteln und den Message-Text aus der Messagefile QSQLMSG ermitteln.

    Wenn allerdings Du auf Release V5R3 or höher bist, kannst Du das Ganze viel einfacher haben:
    Über das SQL-Statement Get Diagnostics direkt auf den Message-Text zugegriffen werden:

    PHP-Code:
    C/Exec SQL 
    C
    Update ....
    C/End-Exec

    C
    /Exec SQL  
    C
    Get Diagnostics Condition 1 :MsgText MESSAGE_TEXT 
    C
    /End-Exec 
    Birgitta
    Birgitta Hauser

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

  4. #4
    Registriert seit
    May 2005
    Beiträge
    103
    Guten Morgen,

    habe diese Funktion Get Diagnostics eben mal ausprobiert, jedoch leider mit mäßigem Erfolg.

    Get Diagnostics 1 :SQLMSG = MESSAGE_TEXT; <- hier meckert bereits SEU die 1 an und behauptet, dass das Token 1 ungültig sei. Der Compiler meldet das Gleiche und wandelt nicht um.
    Wir haben hier V5R4 und erfüllen somit also die OS-Voraussetzungen.

    Weiß jemand, was ich falsch mache??

  5. #5
    Registriert seit
    Jun 2005
    Beiträge
    36
    Guten Morgen,

    versuche es mal ohne die 1.

    DB2 Universal Database

  6. #6
    Registriert seit
    May 2005
    Beiträge
    103
    Guten Morgen Jim,

    habe ich auch schon versucht, aber dann meckert SEU das Token MESSAGE_TEXT an. Hab inzwischen gemerkt, dass ich lediglich auf die Funktionen der Rubrik statement-information-item fehlerfrei zugreifen kann. Auf connection-informationen-item und condition-information-item klappt es nicht.

    Wofür steht diese ominöse 1 eigentlich??

  7. #7
    Registriert seit
    Jun 2005
    Beiträge
    36
    Hallo Tobse77,

    wofür die steht weiß ich nicht.

    Da ich zur Zeit viel mit SQL mache, habe ich das Thema mit Interesse verfolgt und den mir (unter vielen anderen) unbekannten Befehl GET DIAGNOSTICS ausprobiert. Nach einem FETCH habe ich den Befehl mit

    GET DIAGNOSTICS :rpgvar = ROW_COUNT

    ausprobiert und im Debugger gesehen, dass als Wert eine 1 in rpgvar steht - wie es nach dem Lesen EINES Satzes zu erwarten war.

    Hast Du mal die Befehlssyntax in meinem Link oben angeschaut? Ich habe hier übrigens auch V5R4.

  8. #8
    Registriert seit
    Aug 2001
    Beiträge
    2.928
    Sorry, ich hatte das Wörtchen "Condition" in meinem Beispiel vergessen. Das kommt davon wenn man irgendwas aus dem Kopf tippt ohne Zugriff auf eine Maschine.

    @JIM
    SQL ist nicht SQL (trotz Standard) und DB2 ist auch nicht DB2!
    Die DB2s für Linunx, Unix, Windows und z-Series funktionieren in einigen Bereichen anders als die DB2 UDB for i, einfach deshalb, weil die DB2 UDB for i direkt im Betriebssystem integriert ist.

    So können z.B. beim GET DIAGNOSTICS auf der AS/400 (oder wie auch immer) wesentlich mehr Informationen ausgegeben werden und für Condition-Informationen schreibt man auch CONDITION (was ich im obigen Beispiel vergessen hatte) und nicht EXCEPTION!

    Aus diesem Grund ist es besser, sich die SQL Referenz für die DB2 UDB for i zur Brust zu nehmen.
    Hier ist der Link zu GET DIAGNOSTICS auf der AS/400:
    Get Diagnostics

    Die 1 ist im embedded SQL einfach eine beliebige Zahl (oder auch Variable), die für die Syntax bei Condition Informationen erforderlich ist.
    Birgitta
    Birgitta Hauser

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

  9. #9
    Registriert seit
    May 2005
    Beiträge
    103
    Guten Morgen Birgitta,

    vielen Dank für die prompte und hilfreiche Antwort - wie gewohnt ;-)

    Die Befehlsreferenz zu GET DIAGNOSTICS habe ich mir zwar schon angeschaut, aber die richtige Syntax hat sich mir daraus nicht erschlossen.

    Mein Statement sieht nun folgendermaßen aus:
    Get current Diagnostics CONDITION 1 :SQLMSG = MESSAGE_TEXT;

    Und das Beste ist: ES FUNKTIONIERT AUCH NOCH!!! :-)

    Habe zuvor mittels API QMHRTVM den SQL-Code aus QSQLMSG ausgelesen, was gegenüber der Get Diagnostics-Funktion natürlich viel umständlicher ist und dazu auch bei z. B. SQL0100 nur die Meldung "Zeile für &1 nicht gefunden" zurückgemeldet hat. Nun bekomme ich folgerichtig "Zeile für INSERT nicht gefunden"

    Vielen Dank nochmals!!

  10. #10
    Registriert seit
    Aug 2001
    Beiträge
    2.928
    Habe zuvor mittels API QMHRTVM den SQL-Code aus QSQLMSG ausgelesen, was gegenüber der Get Diagnostics-Funktion natürlich viel umständlicher ist und dazu auch bei z. B. SQL0100 nur die Meldung "Zeile für &1 nicht gefunden" zurückgemeldet hat. Nun bekomme ich folgerichtig "Zeile für INSERT nicht gefunden"
    Mit QMHRTVM bzw. RtvMsg wäre das auch gegangen, man muss lediglich wissen, dass die variablen Message-Texte (MSGDTA) im Feld SQLERM in der SQLCA hinterlegt sind.

    Birgitta
    Birgitta Hauser

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

  11. #11
    Registriert seit
    May 2005
    Beiträge
    103
    Schon wieder was dazu gelernt... so langsam wird es wohl Zeit für den Feierabend ;-)

    Dass ich das Feld MSGDTA mit Variablen bestücken muss, habe ich aus der Bef.Ref. ersehen, jedoch nicht, woher ich die SQL-Variablen herbekomme.
    Danke für den Hinweis!!

Similar Threads

  1. Embedded SQL in VARPG
    By Squall in forum NEWSboard Programmierung
    Antworten: 23
    Letzter Beitrag: 18-10-06, 12:01
  2. Einfache Abfrage in COBOL/400 mit EXEC SQL
    By AS400-Anfänger in forum NEWSboard Programmierung
    Antworten: 6
    Letzter Beitrag: 27-06-06, 13:18
  3. RPG mit Embedded SQL, JOIN ..
    By loeweadolf in forum NEWSboard Programmierung
    Antworten: 3
    Letzter Beitrag: 18-06-06, 12:14
  4. SQL .. for update of (RPG embedded SQL)
    By loeweadolf in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 01-06-06, 09:43
  5. Character verbinden in Embedded SQL
    By e_sichert in forum NEWSboard Programmierung
    Antworten: 3
    Letzter Beitrag: 03-05-06, 10:47

Berechtigungen

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