Im letzten Artikel zu diesem Thema wurde mit Hilfe von verschiedenen CL- und SQL-Techniken der Einstieg in ein variables CL-Programm entwickelt. Im aktuellen Artikel werden einige Subroutinen exemplarisch dargestellt und mögliche Erweiterungen aufgezeigt.
Die Aufgabe
Ausgangspunkt für diese Artikelserie war die Anfrage eines Kunden, wie man eine Db2-Datei von der IBM i als CSV-Datei ins IFS übertragen und dabei beliebige Spaltenüberschriften wählen kann. Die Übertragung einer kompletten Datei als CSV-Datei ins IFS kann mit dem CL-Befehl CPYTOIMPF erfolgen. Als Überschrift für die einzelnen Spalten kann entweder *SYS oder *SQL ausgewählt werden. Wie kann man auch andere Texte als Spaltenüberschriften verwenden?
In der folgenden Abbildung wird dargestellt, welche Texte bei welchen Features verwendet werden.

Das CL-Programm
Im letzten Artikel wurde der Hauptteil des CL-Programms entwickelt und dargestellt (siehe folgende Abbildung):

(1) In der ersten Subroutine (SUBR) wird geprüft, ob die angegebene Datei vorhanden ist.
/* Prüfen Datei, ob vorhanden */
SUBR SUBR(SUBR)
CHKOBJ OBJ(&BIB/&DAT) OBJTYPE(*FILE)
MONMSG MSGID(CPF9801) EXEC(DO)
SNDUSRMSG MSG('Datei nicht vorhanden. Bitte neu aufrufen.')
return
enddo
ENDSUBR
CL-Quelle: Prüfung, ob Datei vorhanden
(2) Bei den Subroutinen SUBR0, SUBR1 und SUBR2 wird nur der CL-Befehl CPYTOIMPF mit entsprechender Parametrierung verwendet.
Ein Beispiel mit *SQL.
/* CSV-Datei mit Spaltenüberschrift *SQL */
SUBR SUBR(SUBR1)
CPYTOIMPF FROMFILE(&BIB/&DAT) TOSTMF('/home/TB/xxx.csv') +
MBROPT(*REPLACE) FROMCCSID(*FILE) +
STMFCCSID(*PCASCII) RCDDLM(*CRLF) FLDDLM(';') +
DECPNT(*COMMA) ADDCOLNAM(*SQL)
ENDSUBR
CL-Quelle: CPYTOIMPF mit *SQL
(3) Bei den Subroutinen SUBR3, SUBR4 und SUBR5 wird zunächst die CSV-Datei initialisert.
Danach wird die ausgewählte Überschriftsart mit der SQL-Prozedur QSYS2.IFS_WRITE in die CSV-Datei geschrieben.
Und im dritten Schritt wird der CL-Befehl CPYTOIMP mit den Parametern ADDCOLNAM(*NONE) und STMFCCSID(*STMF) ausgeführt. Beide Parameter sind Standardwerte und erscheinen daher auch nicht bei der Befehlsausführung.
/* CSV-Datei mit Spaltenüberschrift COLUMN_HEADING */
SUBR SUBR(SUBR3)
CALLSUBR SUBR(SUBR00) /* initialisieren */
RUNSQL SQL('call qsys2.ifs_write_UTF8(path_name => +
''/home/TB/xxx.csv'', line => (select +
listagg(Column_Heading, '';'') from +
qsys2.syscolumns where +
Table_Name=''AUFTRAG'' and +
Table_Schema=''TKLLIB''), overwrite => +
''REPLACE'', end_of_line => ''CRLF'')') +
COMMIT(*NONE)
CALLSUBR SUBR(SUBR01) /* CPYTOIMPF ohne Überschrift, *STMF */
ENDSUBR
CL-Quelle: Subroutine für Spaltenüberschrift COLUMN_HEADING
Und hier ist die Initialisierung-Routine SUBR00:
/* CSV-Datei initialisieren */
SUBR SUBR(SUBR00)
RUNSQL SQL('call qsys2.ifs_write(path_name => +
''/home/TB/xxx.csv'', line => '''', overwrite +
=> ''REPLACE'', end_of_line => ''NONE'')') +
COMMIT(*NONE)
ENDSUBR
CL-Quelle: Initialisierungs-Routine SUBR00
Testen des CL-Programms
Mit den folgenden CL-Befehlen können alle Varianten des CL-Programms ausgeführt werden:
/* CL-Programm CSVDATCL */
CL:CALL PGM(TKLLIB/CSVDATCL) PARM('TKLLIB' 'AUFTRAG' '0') ; -- ohne Überschrift
CL:CALL PGM(TKLLIB/CSVDATCL) PARM('TKLLIB' 'AUFTRAG' '1') ; -- mit Überschrift *SQL
CL:CALL PGM(TKLLIB/CSVDATCL) PARM('TKLLIB' 'AUFTRAG' '2') ; -- mit Überschrift *SYS
CL:CALL PGM(TKLLIB/CSVDATCL) PARM('TKLLIB' 'AUFTRAG' '3') ; -- mit Überschrift COLUMN_HEADING
CL:CALL PGM(TKLLIB/CSVDATCL) PARM('TKLLIB' 'AUFTRAG' '4') ; -- mit Überschrift COLUMN_TEXT
CL:CALL PGM(TKLLIB/CSVDATCL) PARM('TKLLIB' 'AUFTRAG' '5') ; -- mit Überschrift LONG_COMMENT
SQL-Script: CL-Programmaufrufe
Für die Anzeige des Inhaltes der CSV-Datei kann wieder einmal eine SQL-Funktion herangezogen werden:
-- Inhalt der CSV-Datei anzeigen
select line_number, line
from table (
qsys2.ifs_read(
path_name => '/home/TB/xxx.csv',
end_of_line => 'CRLF',
maximum_line_length => default,
ignore_errors => 'YES')
);
SQL-Script: Anzeige des Inhaltes einer IFS-Datei
Weitere Infos zu QSYS2.IFS_READ gibt es hier.
Ideen zur Verbesserung des CL-Programms
Wie Sie sicher bemerkt haben, sind der Datei- und der Bibliotheksname als Eingabe-Parameter definiert. Im Programm selbst werden beim Schreiben ins IFS jeweils feste Werte verwendet.
Der Name und der Pfad der CSV-Datei werden konstant angegeben. Hier könnte auch eine Variable zum Einsatz kommen wie zum Beispiel:
/* Create CSV file name from date */
CHGVAR &CSVNAME VALUE('xxx_' *CAT &DATE *CAT '.csv')
CPYTOIMPF FROMFILE(TKLLIB/AUFTRAG) +
TOSTMF(&CSVNAME) +
...
Falls Sie weitere Anregungen und Ideen haben, können Sie mich gerne kontaktieren.
Die Texte einer Tabelle für die Überschriften können auch im Nachhinein geändert und hinzugefügt werden, ohne dass die Daten der Tabelle beeinflusst werden.
Vielleicht könnte auch folgende Lösung kurzfristig ausreichen:
/*--------------------------------------------------------*/
/* Tabelle in QTEMP kopieren mit Angabe der Spaltennamen */
/*--------------------------------------------------------*/
drop table qtemp.auftrag if exists;
Create table qtemp.auftrag as
(select Auftragsnummer as "Auftrags-Nummer" ,
Kundennummer as "Kunden-Nummer",
Auftragsdatum as "Auftrags-Datum" ,
Auslieferungsdatum as "Auslieferungs-Datum",
Auftragserfasser as "Auftrags-Erfasser"
from tkllib.auftrag) with data;
select * from qtemp.auftrag;
-- ADDCOLNAM(*SQL)
CL:CPYTOIMPF FROMFILE(qtemp/AUFTRAG) TOSTMF('/home/TB/xxx.csv') MBROPT(*REPLACE) RCDDLM(*CRLF) FLDDLM(';')
DECPNT(*COMMA) ADDCOLNAM(*SQL);
SQL-Script: Ein weiterer Lösungsansatz
Verwendete Features
In diesem Artikel wurden die folgenden Features verwendet:
- DDS – externe Dateibeschreibung
- CRTPF – Datei mit DDS erstellen
- CREATE OR REPLACE TABLE – Tabelle mit SQL erstellen
- QSYS2.GENERATE_SQL – SQL Stored Procedure
- CPYTOIMPF – CL-Befehl
- QSYS2.SYSCOLUMNS – Systemkatalog Spalten
- LISTAGG – SQL Aggregatfunkton
- QSYS2.IFS_WRITE – SQL Stored Procedure
- QSYS2.IFS_READ – SQL Tabellenfunktion
- CHGPF – CL-Befehl
Vorschau:
Sobald es neue Infos zu ACS gibt, melde ich mich wieder.
Bis dahin wünsche ich Ihnen weiterhin viel Spaß beim Vermehren Ihrer Fertigkeiten.
Den Autor Theo Bär erreichen Sie unter:
EDV-Beratung Theo Bär
Ringmauerweg 1
69250 Schönau
Tel.: (+49) 6228 912 630
E-Mail: info@edv-baer.com
Für 88 Euro gibt’s hier sechs Monate lang tiefgreifendes IBM i und SQL Wissen. Hier kann man abonnieren.