[NEWSboard IBMi Forum]
Seite 1 von 5 1 2 ... Letzte
  1. #1
    Registriert seit
    May 2004
    Beiträge
    444

    65k Dateifeld oder wie lese ich eine Datei direkt aus dem IFS ein.

    Hallo zusammen,

    wir haben folgendes Problem.
    Bisher wurden Daten in einer physischen Datei (Feld hatte 32k Länge) zur Verfügung gestellt. Jetzt reicht diese Länge nicht mehr aus. Daher wollte ein Kollege dies über ein CLOB Feld machen.
    Kann mir jemand sagen wie ich die Daten aus dem IFS in das Feld rein bekomme.
    Wenn ich die XML Datei direkt lesen kann wäre das auch gut, so dass ich im RPG alles in einem String erhalte.

    Ich habe sowas ähnliches schon mal gemacht mit

    PHP-Code:
    select a.*from XMLTABLE('etd/header'passing XMLParse(Document Get_xml_file(lib.GblXMLFile))
    Columns H_AR varchar(250Path 'AR',        
    H_AW varchar(250Path 'AW',        
    H_CT varchar(250Path 'CT',        
    H_CU varchar(250Path 'CU',        
    H_CZ varchar(250Path 'CZ',        
    H_BU varchar(250Path 'BU',        
    H_CH varchar(250Path 'CH',        
    H_CK varchar(250Path 'CK',        
    H_CL varchar(250Path 'CL',        
    H_CW varchar(250Path 'CW',        
    H_CX varchar(250Path 'CX',        
    H_CF varchar(250Path 'CF',        
    H_DV varchar(250Path 'DV'a
    Allerdings löst er an dieser Stelle schon die einzelnen TAGs auf. Ich bräuchte aber einfach den kompletten Datenstrom als 1 String. Die 64k was ein RPG Feld groß sein darf würde fürs erste reichen.

    Ich hoffe ihr könnt mir helfen.

    Viele Grüße Harald

  2. #2
    Registriert seit
    Aug 2001
    Beiträge
    2.869
    Das geht mit SQL und zwar mit einer der Funktionen GET_CLOB_FROM_FILE, GET_DBCLOB_FROM_FILE und GET_BLOB_FROM_FILE ... oder falls Du ein XML-Dokument übernehemen wills GET_XML_FILE.

    Die Datei muss allerdings mit SQL definiert sein. In DDS-Dateien bekommst Du keine LOB-Spalten.

    Beispiel:
    Code:
      Declare global temporary table MyXMLTBL
             (MyXML XML)
      With Replace;
    
      Insert into MyXMLTbl
             Values(Get_xml_file('/home/Dir1/Dir2/YourXML.xml'));
    
    Declare Global Temporary Table TestCLOB
    (Id       Integer Not NULL Default 0,
     YourCLOB CLOB(65535) Not NULL Default '')
    With Replace;
     
    Insert into testCLOB
    Values(1, Get_CLOB_From_FILE('/home/Dir1/Dir2/YourTest.txt'));
    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

  3. #3
    Registriert seit
    May 2004
    Beiträge
    444
    Vielen Dank Birgitta.

    Das mit GET_CLOB_FROM_FILE hat mit meinem Benutzer funktioniert. Allerdings beim Kollegen und bei einem anderen Benutzer von mir nicht. Fehler war folgendes:

    Insert into leasd/www_in3
    Values(Get_CLOB_from_file('/leasing/tmpxml/test/lskopie.xml'))
    Fehler von Auslöserprogramm oder externer Routine erkannt.

    SQL0443 ist die Nachrichten-ID

    Im Joblog kommt Fehler bei benutzerdefinierter Funktion in Teildatei QSQPTABL

    Und Detail ist:
    Ursache . . . . : Beim Aufrufen der benutzerdefinierten Funktion
    GET_CLOB_FROM_FILE in Bibliothek QSYS2 ist ein Fehler aufgetreten. Der
    Fehler trat beim Aufrufen des zugeordneten externen Programms oder
    Serviceprogramms QDBSSUDF2 in Bibliothek QSYS, Programmeingangspunkt bzw.
    externem Namen QSQGTCF, spezieller Name GET_CLOB_FROM_FILE_1, auf. Der
    Fehler trat bei Teildatei QSQPTABL Datei QSQPTABL in Bibliothek QSYS2 auf.
    Der Fehlercode ist 1. Fehlercodes und ihre Bedeutung:
    1 -- Das externe Programm oder Serviceprogramm hat SQLSTATE 42926
    zurückgegeben. Die vom Programm zurückgegebene Textnachricht ist: LOB- und
    XML-Lokatoren sind mit COMMIT(*NONE) nicht zulässig. .

  4. #4
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Achte auf letzteres. Mit Commit *none kann mit den intern verwendeten LOB-Locators nicht gearbeitet werden. Das lesen aus dem IFS mit dieser Funktion geht nicht ohne Commitsteuerung.
    Was aber klappt, ist das lesen und schreiben per CLOB_FILE:
    https://www.ibm.com/support/knowledg...lobfileref.htm

    Per "exec sql set : MyVar = : MyClobFile;" kann gelesen und per "exec sql : MyClobFile = : MyVar;" kann geschrieben werden.
    Die Größe ist allerdings auf 16MBytes beschränkt, bei Unicode eben 8M Zeichen.
    Allerdings klappt auch ein SUBSTR auf den CLOB_FILE.

    CLOB_FILE kann i.Ü. auch mit einer CCSID ergänzt werden um z.B. UTF8 in UCS2 beim Lesen umzwandeln.

    Das gibts i.Ü. bereits seit mindestens V5R4.
    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.869
    Die Größe ist allerdings auf 16MBytes beschränkt, bei Unicode eben 8M Zeichen.
    Wenn man mit LOB-File-Referenz-Variablen arbeitet können IFS-Files mit bis zu 2GB verarbeitet werden, zumindest solange man die LOB-File mit SQL-Funktionen bearbeitet.
    Versucht man die LOB-File in eine RPG-Variable zu laden und mit RPG-Funktionen zu verarbeiten, ist die Maximal-Größe auf 16MB beschränkt (und das ist nicht das Problem von SQL sondern das ist das RPG Limit!).

    LOB-FILE Variablen gibt es i.Ü. schon seit Release V5R1M0!

    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

  6. #6
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Ich wollte aber LOB-Locator vermeiden, da diese ja wieder Commitsteuerung erfordern.
    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.869
    Nochmal zum Mitschreiben!

    Wenn man im embedded SQL LOB-File-Referenz-Variablen (z.B. SQLTYPE(CLOB_FILE)) verwendet und nur mit SQL darauf zugreift kann man bis zu 2 GB große IFS-Dateien verarbeiten und braucht KEINE Commit-Steuerung!

    Code:
    DCL-S MyCLOBFile SQLType(CLOB_File);                                 
      DCL-S MyText     Char(50);                                           
     //********************************************************************
      Exec SQL   Set Option  Commit=*NONE, DatFmt=*ISO, TimFmt=*ISO,       
                             Naming=*SYS,  CloSQLCsr=*EndActGrp;           
                                                                           
        MyCLOBFile_Name = '/home/Dir1/Dir2/YourIFSFile.txt';               
        MyCLOBFile_NL   = %Len(%Trim(MyCLOBFile_Name));                    
        MyCLOBFile_FO   = SQFRD;                            //Read Only    
                                                                           
        Exec SQL Set :MyText = Substr(:MyCLOBFILE, 1, 50);       
        //Check SQLCODE or SQLSTATE
    
        Dsply MyText;      
        *InLR       = *On;
    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
    Feb 2001
    Beiträge
    20.207
    Ich habe ja auch nichts gegenteiliges beschrieben:
    Mit CLOB_FILE benötige ich keinen Commit, wenn ich keinen LOB verwende.
    Lese ich CLOB_FILE in einen LOB ein, geht das wieder nur mit Commit.
    Will ich mehr als 16MB in ILERPG lesen, klappt dies per SUBSTR(: MyClobFile, 8000000, 8000000).
    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

  9. #9
    Registriert seit
    May 2004
    Beiträge
    444
    Ich habe folgenden SQL Befehl ausgeführt

    Insert into leasd/www_in3
    Values(Get_CLOB_from_file('/leasing/tmpxml/test/lskopie.xml'))
    1 Zeilen in WWW_IN3 in LEASD eingefügt.

    Hat funktioniert.

    Den gleichen Befehl mit meinem anderen Benutzerprofil und er bringt den Fehler den ich oben beschrieben habe.

    Weiß jemand an was das Problem liegt, den es funktioniert ja, zumindest mit meinem ersten Benutzer

    WICHTIG!
    Natürlich löst das für uns erst mal nur das Problem bis 65k. Denn es gibt ja heute schon viele Programme die einen RPG-Parser verwenden und diesen wollten wir im ersten Schritt nicht austauschen. Der Verarbeitet ja nur einen String. Mit den SQL-XML-Anweisungen die Frau Hauser mir gezeigt hat, habe ich ein Programm bereits umgestellt was auch läuft, allerdings etwas Performance-Probleme hat. Aber es funktioniert. Wenn aber jetzt riesige Dateien kommen. Was für Lösungsvorschläge hätten sie dann? Wie oben beschrieben die einzelnen Blöcke einlesen oder so wie ich in einem bereits existierenden Programm, direkt aus dem IFS mit den SQL-XML-Anweisungen die Daten einlesen (also mit View der die Daten aufbereitet und ich lese im RPG den View).
    Was machen Sie bei riesigen XML-Dateien?

    Vielen Dank für die Hilfe.

    Viele Grüße Harald

  10. #10
    Registriert seit
    Jan 2021
    Beiträge
    26
    Hallo, ich bin der Kollege , der mit diesem Problem betraut ist .
    Nochmals zur Problemstellung . Wir haben einen Prozess , der XML-files aus einem Verzeichnis lädt und weiterverarbeitet . Die Programme verarbeiten bisher eine max. Feldlänge von 30000 Stellen. diese wird seit neustem überschritten , die Datenmenge wurde größer , so dass heute mit einer Feldlänge von über 30000 mit bis zu 48000 Stellen zu rechnen ist . um die Struktur und Logik der Programme nicht zu ändern , möchten wir die Parmlänge auf 65535 erweitern und intern , im ILE , mit der maximalen Feldlänge arbeiten . Dazu benötigen wir diese CLOB-funktion , die es uns ermöglicht über die maxmimale Feldlänge von Feldern zu arbeiten.
    Die idee war und ist , in der Datenbibliothek eine neue File mit einem CLOB-Feld zu erstellen, dessen länge auf 65535 zu limitieren und mit SQL in einem SQLRPG-Programm , embedded , die XML-file zu laden , den Datenteil zu speichern und an ein RPG-Programm mit ParmLänge 65535 weiterzureichen , für die weiterverarbeitung . Leider scheitern wir daran , dass der insert in die CLOB-File nicht funktioniert, das weiterreichen an das RPG nicht möglich ist . wir erhalten die Meldung , wie oben beschrieben .

    habt ihr eine Idee woran dies liegen kann ?
    wir benötigen die Daten einfach nur im RPG in 65535..

  11. #11
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Die maximale Feldlänge im ILERPG beträgt 16MB! Solange also diese Länge nicht überschritten wird, gibt es kein Problem mit XML-INTO.
    Außerdem löst der LOB das Problem der Verarbeitung ja immer noch nicht, da größere Dateien als 16MB immer nur per SUBSTR verarbeitet werden können.

    XML-INTO erlaubt aber auch das teilweise Verarbeiten mit XPath.
    Mit der Option "path=...." kannst du dir Teile aus einer XML extrahieren, so dass die 16MB-Grenze nicht gesprengt wird.

    Was den Insert in die Datei angeht, so muss es dazu Fehler im Joblog geben. Stelle das Programm mal unter STRDBG, dann gibts ggf. erweiterte Diagnose.
    Du kannst mit Embedded SQL auch "Get Diagnostic" zum SQLSTATE erweiterte Fehlermeldungen auslesen.
    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 2021
    Beiträge
    26
    wir haben dies direkt im SQL getestet .. ohne Commit ..
    die 16 MB sollten nicht überschritten werden ...

    Habt ihr ein Beispiel , in dem ich die XML lade und deren Daten an ein RPG - Programm als einen String weiterreichen kann ? würde ein direktes laden , mit SQL in ein im RPG definiertes Feld mit der Länge 65535 auch funktionieren ?

Similar Threads

  1. Mit dem Bagger durch die Eifel oder wie debugge ich eine SQL Prozedur
    By KingofKning in forum NEWSboard Programmierung
    Antworten: 8
    Letzter Beitrag: 04-11-19, 08:59
  2. mehrere Spoolfiles in eine Datei
    By programmer400 in forum NEWSboard Drucker
    Antworten: 7
    Letzter Beitrag: 26-07-17, 11:58
  3. Antworten: 10
    Letzter Beitrag: 14-12-16, 16:45
  4. verschiedene Jobs gleiche Datei, schreib / lese konflikt?
    By dibe in forum NEWSboard Programmierung
    Antworten: 20
    Letzter Beitrag: 25-02-16, 16:33
  5. Antworten: 3
    Letzter Beitrag: 20-12-13, 10:27

Berechtigungen

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