PDA

View Full Version : IFS Datei im RPG auslesen



harkne
26-06-24, 14:08
Hallo zusammen,

kann mir jemand sagen was ich hier falsch mache.
in PiDirFile steht das richtige Verzeichnis und Dateiname aber er bekommt sofort 100 im SQLCOD


exec sql declare crs1sql cursor for
select cast (line as char(1000)) as txtline
from table(QSYS2.IFS_READ(:PiDirFile));exec sql open crs1sql;
dow *on;

exec sql fetch next from crs1sql into :wLine;

if SqlCode < *zero or SqlCod = 100;
leave;
endif;

...

enddo;


führe ich das SQL direkt aus dann funktioniert es

select cast(line as char(1000)) as txtline from
table(QSYS2.IFS_READ('/spareparts/sql/xxx_poi103c1.sql'
))

Andreas_Prouza
26-06-24, 14:33
Wie ist PiDirFile definiert? Char oder Varchar?
Die Blanks werden hier leider berücksichtigt.
Ansonsten kannst du einfach ein QSYS2.IFS_READ(trim(:PiDirFile)) machen.

lg Andreas

harkne
26-06-24, 14:39
Ja, habe es gerade gemerkt.

select cast (line as char(1000)) as txtline
from table(QSYS2.IFS_READ(trim(:PiDirFile)));exec sql open crs1sql;

so funktioniert es. Danke

harkne
26-06-24, 14:49
Aber vielleicht habe ihr eine Antwort. Momentan lese ich die Datei Zeile für Zeile aus und füge sie in einer Variablen zusammen, gibt es eine Möglichkeit die Datei komplett in eine Variable auszulesen?

Andreas_Prouza
26-06-24, 15:20
Dafür kannst du die SQL-Funktion get_clob_from_file(pfad) verwenden.

Fuerchau
26-06-24, 16:29
Und es gibt noch die Alternative:

https://www.ibm.com/docs/de/i/7.5?topic=dlhviiratus-lob-file-reference-variables-in-ile-rpg-applications-that-use-sql

https://www.ibm.com/docs/en/i/7.5?topic=dlhviiratus-lob-host-variables-in-ile-rpg-applications-that-use-sql

Ich lese dann mit values( :clobfile) into : dbclob_Feld;

Da DBCLOB bis 1GB groß sein darf, reicht das i.d.R.
Mit einer Overlay-Definition kann man das dann als varucs2(nn) im RPG native verarbeiten.

B.Hauser
26-06-24, 16:30
Dafür kannst du die SQL-Funktion get_clob_from_file(pfad) verwenden.

... aber bedenke

GET_CLOB_FROM_FILE muss unter Commitment Control ausfrührt werden.
GET_CLOB_FROM_FILE liefert einen Large Object Locator zurück und dieser muss in RPG entsprechend mit SQLTYPE definiert werden, also DCL-S MyClobLoc SQLType(Clob_Locator);
Ein LOB Locator kann mit SQL-Funktionen (z.B. LOCATE oder SUBSTR) wie ein normales alphanumerisches Feld behandelt werden. Eine direkte Bearbeitung mit RPG-Funktionen ist hingegen nicht möglich.


Ansonsten kannst Du auch mit IFS_READ-Funktionen die ganze IFS-Datei in einem Schwung lesen und ausgeben ... dafür musst Du das Programm NICHT (unbedingt) unter Commitment Control ausführen.

Select Line
from Table(QSYS2.IFS_READ_UTF8(Path_Name => '/home/YourDir1/YourDir2/YourIFSFile.txt',
End_Of_Line => 'NONE')) a;


Außerdem kannst Du auch die IFS-Datei direkt mit (embedded) SQL direkt als LOB_FILE lesen. Du musst lediglich die CLOB-File definieren und die vom Precompiler erstellten Daten-Struktur-Unterfelder füllen.
Für die LOB_Files gilt das gleiche wie für die LOB Locators. Sie können mit SQL-Funktionen wie alphanumerische Strings berarbeitet werden, aber nicht mit normalen RPG-Variablen und Funktionen.

Etwa so:

DCL-S MyClobFile SQLType(CLOB_File);
DCL-S MyText Char(50);

DCL-S Start Int(10);
DCL-S RowLen Int(5) inz(120);
DCL-S Index Uns(3);

DCL-S MyIFSFile VarChar(256) inz('/home/YourDir/YourIFSFile.txt');
//************************************************** *****************
Exec SQL Set Option Commit=*NONE, DatFmt=*ISO, TimFmt=*ISO,
Naming=*SYS, CloSQLCsr=*EndActGrp;

MyCLOBFile_Name = %Trim(MyIFSFile);
MyCLOBFile_NL = %Len(%Trim(MyCLOBFile_Name));
MyCLOBFile_FO = SQFRD; //Read Only

For Index = 1 to 15;
Start = (Index-1) * RowLen + 1;
Exec SQL Set :MyText = Substr(:MyCLOBFile, :Start, :RowLen);
Dsply MyText;
If SQLCODE = 100 or SQLCODE < *Zeros
or %Len(%Trim(MyText)) = *Zeros;
Leave;
EndIf;
EndFor;

*InLR = *On;


Birgitta

Fuerchau
26-06-24, 18:04
Wie gesagt, du kannst den SQLTYPE( DBCLOB : 1M) per based Pointer mit VARUCS2 redefinieren und dann ganz normal als RPG-Variable verwenden.
Das ist auch äußerst praktisch für die IFS-Ausgabe per CLOB_FILE.

B.Hauser
26-06-24, 18:22
Wie gesagt, du kannst den SQLTYPE( DBCLOB : 1M) per based Pointer mit VARUCS2 redefinieren und dann ganz normal als RPG-Variable verwenden.
Das ist auch äußerst praktisch für die IFS-Ausgabe per CLOB_FILE.

Und warum sollte ich mir das antun?
Ich kann das Ganze gleich so wie ich es brauche mit SQL aufbereiten und das Ergebnis dann nach RPG übertragen.
i.Ü. sind RPG-Variablen auf 16MB beschränkt, IFS-Dateien dagegen auf 2GB

Fuerchau
26-06-24, 21:13
Weil es schneller ist und funktioniert. Ich habe das schon gebaut, bevor es die anderen IFS-Zugriffe überhaupt gab. Damit lese ich z.B. EDI-Dateiformate aus und erstelle EDI-Dateien.