[NEWSboard IBMi Forum]
Seite 1 von 2 1 2 Letzte
  1. #1
    Registriert seit
    Jan 2012
    Beiträge
    1.102

    JSON_TABLE in dynamischem SQL verwenden

    Hallo,

    ich glaube nicht, dass es geht, aber ich frage hier einfach mal:

    Ich möchte die JSON_TABLE Funktion "variabler" nutzen. Ich würde gerne den path Parameter als Variable übergeben. Das scheint nicht zu klappen. Im meiner interaktiven SQL Oberfläche (dbVisualizer) will die Funktion unbedingt ein Literal dafür ('lax $.userprf') haben:
    Code:
    drop variable jsontest;
    create variable jsontest varchar(1000);
    set jsontest = '{ "userprf" : "TESTUSER",  "ID"  : 1000001234567 }';
    
    select userprf from JSON_TABLE(jsontest, 'lax $'
            columns( userprf varchar(10) path 'lax $.userprf')
            ) as json;
    Alternativ habe ich versucht, die Funktion mit dynamischem SQL zu nutzen. Dabei ist mir aber ein Limit im Wege: Im embedded SQL kann ein SQL-Statement anscheinend nur 32K groß werden. Wenn ich mit Unicode arbeite, ist das nicht sehr viel.

    Dieter

  2. #2
    Registriert seit
    Aug 2003
    Beiträge
    1.508
    Hallo Dieter,

    Ab 7.2 und den entsprechenden PTFs kannst du das in RPG mit DATA-INTO machen.
    Ist in manchen Fällen besser geeignet als SQL.
    https://www.common.org/scotts-iland-...son-data-into/

    lg Andreas

  3. #3
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Also 32K (Unicode-SQL ist das nur 16K) ist schon sehr viel für einen SQL-String.
    Hostvariablen sind davon nämlich ausgenommen!
    Auch dynamische SQL's reichen da vollkommen aus. Man muss nur seine Variableninhalte nicht einbetten sondern mit "?" und beim Execute/Open dann ein "Using : Hostvar1, : Hostvar2, .." verwenden.
    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

  4. #4
    Registriert seit
    Jan 2012
    Beiträge
    1.102
    Hallo Andreas,
    vielen Dank. Das mit dem DATA-INTO habe ich nicht gewusst. Ich dachte, das geht nur für XML.

    Ich schaue mir das auf jeden Fall mal an.

  5. #5
    Registriert seit
    Jan 2012
    Beiträge
    1.102
    Zitat Zitat von Fuerchau Beitrag anzeigen
    Also 32K (Unicode-SQL ist das nur 16K) ist schon sehr viel für einen SQL-String.
    Hostvariablen sind davon nämlich ausgenommen!
    Auch dynamische SQL's reichen da vollkommen aus. Man muss nur seine Variableninhalte nicht einbetten sondern mit "?" und beim Execute/Open dann ein "Using : Hostvar1, : Hostvar2, .." verwenden.
    Hallo Baldur,
    vielen Dank.

    Das mit den Hostvariablen bei dynamischem SQL ist eigentlich genau, was ich gesucht habe. Das muss ich mir näher ansehen.

  6. #6
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Also ganz simpel:
    Überall, wo du variable Werte benötigst, gibst du ein "?" als sog. Parametermarker ein.
    Dann machst du deinen Prepare und beim Execute (oder auch execute immediate ohne Prepare) führst du dann deine Hostvariablen an.

    Stmt = "insert into mytable (F1, F2, F3) values(?, ?, ?)"
    prepare InsertMyTable from : Stmt;
    execute InsertMyTable using : F1, : F2, : F3;

    Stmt = "Select f1, f2, f3 from mytable where F1=? and F2=? and F3=?"
    prepare SelectMyTable from : Stmt;
    declare GetMyTable cursor for SelectMyTable;
    open GetMyTable using : F1, : F2, : F3;
    fetch GetMyTable into : DS.F1, : DS.F2, : DS.F3;

    Alles kein Hexenwerk.
    - volle Unicodeunterstützung der Variablen
    - Typanpassung falls erforderlich
    - NULL-Anzeiger wie immer ": V1 : N1"
    - Fetch dann in benannte Variablen (mittels using SQLDA geht es auch absolut flexibel)
    - keine Hochkomma-Probleme!
    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
    Jan 2012
    Beiträge
    1.102
    Super,

    herzlichen Dank für die Info!

  8. #8
    Registriert seit
    Aug 2003
    Beiträge
    1.508
    Zitat Zitat von Fuerchau Beitrag anzeigen
    Also 32K (Unicode-SQL ist das nur 16K) ist schon sehr viel für einen SQL-String.
    Hostvariablen sind davon nämlich ausgenommen!
    Auch dynamische SQL's reichen da vollkommen aus. Man muss nur seine Variableninhalte nicht einbetten sondern mit "?" und beim Execute/Open dann ein "Using : Hostvar1, : Hostvar2, .." verwenden.
    Nur den PATH kann man leider nicht mit Hostvariablen abbilden :-(

  9. #9
    Registriert seit
    Jan 2012
    Beiträge
    1.102
    Zitat Zitat von andreaspr@aon.at Beitrag anzeigen
    Nur den PATH kann man leider nicht mit Hostvariablen abbilden :-(
    Ja das ist schade. Aber es klappt trotzdem grundsätzlich. Der Pfad wird im dynamischen SQL-String angefügt. Mein Problem war dabei das Clob für den JSON-String. Das funktioniert ganz gut mit den Host-Variablen.

    Allerdings habe ich leider immer noch ein Problem mit den Zeichensätzen. Ich habe den SQL-String als varucs2 deklariert. Das Parser normaler Zeichenketten klappt sehr gut. Aber sobald ich ein echtes Unicode Zeichen im JSON-String drinhabe, wird nichts mehr geparst. Irgendwie haut das mit den Clobs und Unicode noch nicht so hin.

    Die Deklaration dcl-s clobDS sqltype(clob:200000) ccsid(1200); wird vom Compiler nicht akzeptiert. Ich musste den Clob ohne ccsid deklarieren. Ich fürchte, dass da irgendwo das Problem liegt.

    Hier mal das ganze Programm, falls es jemanden interessiert:
    Code:
    //==========================================================================================
    // Funktion:
    //
    // Syntax zum Parsen von JSON mit der JSON_TABLE Funktion:
    //    $ – Start with the current object
    //    . – Look inside an object
    //    [ ] – Look inside an array
    //    – Reference the value associated with a key
    //
    //==========================================================================================
    dcl-proc um_JSON_getString export;
       dcl-pi *n varucs2(200000);
          json_in varucs2(200000) const;
          path varucs2(1000) const;
       end-pi;
    
    
    dcl-s anw varucs2(16000);
    dcl-s json_clobDS sqltype(clob:200000);
    dcl-s clobDS sqltype(clob:200000);
    
    
    json_clobDS_data = %trim(json_in);
    json_clobDS_len = %len(%trimr(json_in));
    
    
    //Jetzt das SQL-Statement zusammenbauen:
    anw = 'select inhalt from JSON_TABLE(?, ' + um_hkUni('lax $')
        + ' columns( inhalt clob(200000) path ' + um_hkUni('lax $.' + path) + ')) as json';
    
    
    exec sql prepare cmd from :anw;
    exec sql declare csr1 cursor for cmd;
    
    
    exec sql open csr1 using :json_clobDS;
    UM_JoblogSQL(sqlcod:##PGMNAME:'open');
    
    
    if sqlcod = 0;
       exec sql fetch next from csr1 into :clobDS;
       if sqlcod <> 0;
          clear clobDS;
          UM_JoblogSQL(sqlcod:##PGMNAME:'fetch');
       endif;
    endif;
    
    
    exec sql close csr1;
    
    
    return %ucs2(%trimr(%subst(clobDS_data:1:clobDS_len)));
    
    
    end-proc;

  10. #10
    Registriert seit
    Jan 2012
    Beiträge
    1.102
    Ich bin eben darauf gestoßen, dass es außer dem sqltype(clob) noch den sqltype(dbclob) also "Double Byte" Clob gibt. Bei diesem Typ kann man auch eine ccsid(1200) angeben. Ich probiere damit mal ein bisschen rum.

  11. #11
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Solange dein CLOB < 8 mb ist, kannst du ggf. auch eine Hostvariable vom Typ Unicode bis 8MB definieren. Einen CLOB brauchst du da noch nicht.

    Ansonsten gibt es da noch den DBCLOB, der nun tatsächlich als Unicode 1200 definiert ist (max. 8 M).
    Du kannst also von deinem HTTP-Request den CLOB in DBCLOB aus dem CLOB mit CCSID 1208 casten.
    Der Typ der generierten Variablen ist GRAPH und die CCSID dafür bestimmst du in der H-Zeile (Default 1200, früher 13488).

    PS:
    Da warst du wirklich schneller. Aber eine CCSID kannst du auch hier nicht angeben, da der Default bereits 1200 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

  12. #12
    Registriert seit
    Jan 2012
    Beiträge
    1.102
    Vielen Dank. Wenn 1200 der Default Wert ist, werde ich ccsid(1200) weglassen. Macht den Code kürzer.

Similar Threads

  1. PGU - mehrere Datenbanken verwenden
    By -Totti in forum IBM i Hauptforum
    Antworten: 5
    Letzter Beitrag: 25-05-18, 20:21
  2. SQL-UDTF mit dynamischem SQL
    By dschroeder in forum NEWSboard Programmierung
    Antworten: 20
    Letzter Beitrag: 05-12-17, 13:38
  3. DSPSIZ Beide Formate verwenden
    By tarkusch in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 05-05-14, 08:57
  4. BINCHAR - wie kann ich das Feld verwenden?
    By harbir in forum NEWSboard Programmierung
    Antworten: 1
    Letzter Beitrag: 31-10-13, 19:10
  5. WinWord für AS/400 verwenden
    By CMueller@must.de in forum NEWSboard Windows
    Antworten: 0
    Letzter Beitrag: 01-10-01, 10:00

Berechtigungen

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