[NEWSboard IBMi Forum]
Seite 2 von 2 Erste 1 2
  1. #13
    Registriert seit
    Aug 2014
    Beiträge
    179
    Hallo liebes Forum,

    ich schätze die Beiträge sehr und trage auch selbst gerne zu Lösungen bei. Und doch wünsche ich mir mehr sachliche Diskussion und keine Diskussion in dem Stil: meine Lösung ist besser als deine. Für jede Aufgabenstellung gibt es mehrere Lösungen und die Leser des Forums sind gestandene IT-Fachleute, denen ich es zutraue, sich ein eigenes Urteil zu bilden, was die Vielfalt und Anwendbarkeit der Lösungen betrifft.

    In diesem Sinne stelle ich meine Idee mit der SQL-Function Split() vor. Die Function kam mit 7.3 TR 6 auf die Maschine. Der Sourcecode der Function kann mit dem Navigator eingesehen werden, damit ist es möglich, diese Function auf einem älteren Release zu implementieren.

    Unter dem Pfad /home/import/csv/adressen.csv sind folgende Daten gespeichert. Am Ende jedes Datensatzes ist ein Linefeed

    PHP-Code:
    10001,Leisha Leysner,80689,München,Amarellenweg
    10002
    ,Darion Willimczik,81669,München,Schleibingerstraße
    10003
    ,Helvi Holzwardt,81673,München,Dornbergstraße
    10004
    ,Theofánis Arndgen,80997,München,Reinoltstraße
    10005
    ,Tybi Klimczok,80999,München,Frühaufstraße
    10006
    ,Lieschen Bredenkötter,80804,München,Max-von-Gruber-Straße
    10007
    ,Andree Flächsenhaar,81369,München,Adunistraße
    10008
    ,Heber Uschkerat,80937,München,Karlsteinstraße
    10009
    ,Olyvia Füchtling,80331,München,Neuturmstraße
    10010
    ,Art Berendes,80999,München,Grünwedelstraße 
    Folgendes Statement liest die Datei und splittet sie in die einzelnen Datensätze

    Carriage Return = chr(13)
    Linefeed = chr(10)

    Code:
    select Ordinal_Position as Pos, Element
      from TABLE (SYSTOOLS.SPLIT(get_clob_from_file('/home/import/csv/adressen.csv'), chr(10)));
    Das Ergebnis

    PHP-Code:
    Pos Element
    -----------------------------------------------------------------------
    1    10001,Leisha Leysner,80689,München,Amarellenweg
    2    10002
    ,Darion Willimczik,81669,München,Schleibingerstraße
    3    10003
    ,Helvi Holzwardt,81673,München,Dornbergstraße
    4    10004
    ,Theofánis Arndgen,80997,München,Reinoltstraße
    5    10005
    ,Tybi Klimczok,80999,München,Frühaufstraße
    6    10006
    ,Lieschen Bredenkötter,80804,München,Max-von-Gruber-Straße
    7    10007
    ,Andree Flächsenhaar,81369,München,Adunistraße
    8    10008
    ,Heber Uschkerat,80937,München,Karlsteinstraße
    9    10009
    ,Olyvia Füchtling,80331,München,Neuturmstraße
    10   10010
    ,Art Berendes,80999,München,Grünwedelstraße 
    Das RPG-Programm sieht es so aus
    Code:
             ctl-opt dftactgrp(*no) main(main);
          //------------------------------------------------------------------//
          //                                                                  //
          // Einlesen einer CSV-Datei und Verarbeiten mit Split()             //
          //                                                                  //
          //-----------------                                                 //
          // R.Ross 01.2020 *                                                 //
          //------------------------------------------------------------------//
          // SQL-Options                                                      //
          //------------------------------------------------------------------//
    
             exec sql set option datfmt=*iso, timfmt=*iso, commit=*chg,
                                 closqlcsr=*endactgrp;
    
          //------------------------------------------------------------------//
          // Array Records - wird mit SQL gefüllt                             //
          //------------------------------------------------------------------//
    
             dcl-ds  DsRecords   qualified dim(10000) inz;
                      Id         int(10);
                      Text       varchar(256);
             end-ds;
    
          //------------------------------------------------------------------//
          // Main                                                             //
          //------------------------------------------------------------------//
             dcl-proc main;
    
             dcl-s   LocFile     varchar(256);
             dcl-s   LocCounter  uns(10);
    
               LocFile = '/home/import/csv/adressen.csv';
    
               exec sql declare cursor01 cursor for
                select Ordinal_Position, Element
                  from table (
                       systools.split(get_clob_from_file(:LocFile), chr(10)));
    
               exec sql open cursor01;
    
               exec sql fetch cursor01 for 10000 rows  // Fetch into Array
                         into :DsRecords;
    
               if sqlcode >= *zero;
                  exec sql GET DIAGNOSTICS :LocCounter = ROW_COUNT;
               endif;
    
               exec sql close cursor01;
    
             end-proc;
          //------------------------------------------------------------------//
    mit einem weiteren Split() auf den Datensatz werden die einzelnen Felder ausgelesen

    Code:
    select Ordinal_Position as Pos, Element
      from TABLE (SYSTOOLS.SPLIT('10001,Leisha Leysner,80689,München,Amarellenweg', ','));
    Das liefert folgendes Ergebnis

    PHP-Code:
    Pos Element
    ------------------
    1    10001
    2    Leisha Leysner
    3    80689
    4    München
    5    Amarellenweg 
    Herzliche Grüße
    Rainer Ross

    Ab und zu entwickle ich auch mal Spiele für die IBM i
    http://www.myhofi.com/tms/HTML/SlotMachine.html
    http://www.myhofi.com/chess/index.html

    aber normalerweise Webanwendungen so schnell wie Greenscreen
    http://www.myhofi.com/tms/HTML/Myapp.html

    hier ist der Kurs dazu
    https://www.toolmaker.de/schulungen/...ibm-i-kompakt/

  2. #14
    Registriert seit
    May 2002
    Beiträge
    1.121
    Die Function kam mit 7.3 TR 6 auf die Maschine. Der Sourcecode der Function kann mit dem Navigator eingesehen werden, damit ist es möglich, diese Function auf einem älteren Release zu implementieren.
    Allerdings müsste man dann einen Zugang zu einer Maschine haben, welche mindestens auf 7.3 TR6 läuft....

    Aber wir sollen ja dieses Jahr eine neue Maschiene bekommen. Freun mich dann schon es probieren zu können.

    Und ich finde alle Lösungen okay. Immer wieder schön zu sehen, dass viele Weg nach Rom führen ;-)

    Liebe Grüße
    Ronald

  3. #15
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Ich bekomme auch gerne Dateien mit mehr als 10000 Zeilen;-).
    Da würde ich dir eher eine Table-Function nach Birgittas Methode mit einzelnem Satz-Return empfehlen.
    Nach deiner Methode scheiterst du an der 16MB-Grenze;-).
    Auch die Split-Funktion wird da eine wohl eine ähnliche Grenze haben.

    Nach dem Fetch steht die Anzahl der Zeilen bereits in der SQLCA SQLER3;-).
    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. #16
    Registriert seit
    Dec 2003
    Beiträge
    53
    Hallo zusammen und vielen Dank für die Antworten.
    Ich war die letzten Tage unterwegs und konnte daher erst heute antworten.
    Bei der *.csv stehen in der 1. Zeile immer Feldnamen und in Zeile 2-n die zugehörigen Daten. Anzahl/Reihenfolge der Felder ist variabel, ob die Daten korrekt sind muss vor Übernahme ins ERP-System geprüft werden. Die Datei wird maschinell oder manuell erstellt und die Anzahl der Sätze hängt vom Prozess/User ab, das können z.B. 5 Sätze mit 1000 Feldern, 20.000 Sätze mit 5 Feldern aber theoretisch auch 50.000 Sätze mit 1000 Feldern sein.
    Eine bestehende Lösung gibt es bereits, sie basiert auf einem CPYFRMIMPF und einem tab-getrennten *.txt-File. Für den CPYFRMIMPF wird eine PF mit 150 Feldern (80A) benutzt, da unklar ist, ob z.B. in der 1. Spalte eine Beschreibung(80A) oder ein Wert(13,5) oder etwas Anderes steht. Nach dem CPYFRMIMPF wird der erste Satz mit den Feldnamen aus der PF gelesen und für die einzelnen Feldnamen die Definition(Feldart/Feldlänge) aus den bereits bestehenden ERP-Dateien ermittelt und alles in eine Tabelle geschrieben.
    Anschließend werden die Sätze 2-n verarbeitet und inhaltlich gegen die Tabelle geprüft, so dass z.B. in einem mit 5S2 definierten Feld keine Buchstaben, 6 Vorkomma- oder 4 Nachkomma-Stellen stehen. Bei ungültigen Feldnamen wird das komplette File, bei ungültigen Daten der falsche Datensatz mit Fehlerprotokoll abgelehnt. Später folgen dann noch weitere Prüfungen aufgrund der vorhandenen Business-Logik.
    Mittlerweile reichen die 150 Felder der alten Lösung nicht mehr aus, da es bereits Artikel gibt mit mehr als 1.000 Feldern bzw. zusätzlichen Artikel-Angaben.
    Da ich beim CPYFRMIMPF eine PF mit 1000 Feldern(80A) bräuchte, die sich aber wegen der DS-Größe nicht kompilieren lässt, werde ich mein Glück mal mit SPLIT(), GET_CLOB_FROM_FILE und "CLOB"-Variablen versuchen. Ein Kurz-Test mit interaktivem SQL sah vielversprechend aus…

  5. #17
    Registriert seit
    Feb 2001
    Beiträge
    20.207
    Tut mir Leid, das ist aber der falsche Ansatz.
    Wenn du den obigen SQL ebenso pauschalisierst, wirst du ebenso an der 32-KB-Grenze scheitern.
    Dies ist aber nicht Sinn und Zweck eines CPYFRMIMPF.
    Für jeden Typ einer CSV-Datei lege ich mir eine individuelle Importtabelle an, deren Feldtypen genau dem erwarteten entsprechen. Da gibt es das 32-KB-Probelm überhaupt nicht.
    Desweiteren erfolgt beim Import bereits die Typprüfung, Fehler lassen sich in einer Protokolldatei ausgeben.
    Jeder Import sollte individualisiert werden, damit die nachfolgende Verarbeitung erheblich vereinfacht werden kann.

    https://www.ibm.com/support/knowledg...cpyfrmimpf.htm
    RMVCOLNAM entfernt automatisch die Kopfzeile.
    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

  6. #18
    Registriert seit
    Aug 2001
    Beiträge
    2.644
    Zitat Zitat von malzusrex Beitrag anzeigen
    Allerdings müsste man dann einen Zugang zu einer Maschine haben, welche mindestens auf 7.3 TR6 läuft....
    zum Testen wüsste ich da ja was ;-)

    Und ansonsten gilt wie immer: der GF auf die Füsse treten, daß auch die IT am Ball bleibt. Wir kennen alle die Diskussionen, aber erstaunlicherweise ist leider gerade unser Markt da sehr hartnäckig, Altblech zu betreiben.
    (Und das schreibe ich als jemand, der zwangsweise für einen Kunden eine CISC-Maschine betreibt...)
    www.RZKH.de
    IBM Champion 2022, 2023, 2024
    IBM i Community Advocate https://www.youracclaim.com/badges/6...c-7ad4ba147af6
    Common / CEAC
    http://pub400.com

Similar Threads

  1. Größe einer Collection begrenzen
    By M Scheid in forum IBM i Hauptforum
    Antworten: 2
    Letzter Beitrag: 03-12-14, 18:52
  2. CPI Größe
    By jojoschluckfirma in forum NEWSboard Programmierung
    Antworten: 2
    Letzter Beitrag: 03-12-14, 14:51
  3. Antworten: 3
    Letzter Beitrag: 20-12-13, 10:27
  4. Größe IFS
    By kuddel in forum IBM i Hauptforum
    Antworten: 3
    Letzter Beitrag: 05-02-03, 08:19
  5. Größe des IFS, wie ermitteln?
    By Spirou in forum IBM i Hauptforum
    Antworten: 6
    Letzter Beitrag: 17-04-02, 10:54

Berechtigungen

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