Mit dem neuesten Technologierefresh für 7.5 TR 4 und 7.4 TR 10 kam die neue scalare SQL Funktion IFS_UNLINK zum Löschen von IFS Dateien auf die IBMi. Anhand von Beispielen können sie sehen, wie einfach und nützlich damit gearbeitet werden kann.
1. Beschreibung der SQL Funktion
IFS_UNLINK befindet sich in der Bibliothek SYSTOOLS und hat nur einen Parameter, den Pfadnamen. Testen sie es im ACS.
VALUES SYSTOOLS.IFS_UNLINK('/home/export/test/MyTestFile1.csv');
Das Ergebnis ist entweder 0 = gelöscht ohne Fehler oder eine Nummer <> 0 mit der Fehlernummer. Falls die Datei nicht existiert, erhalten sie den Fehler 3025. Das ist etwas kompliziert und es ist eine gute Idee, den Fehlertext zu erhalten. Dafür gibt es die SQL Funktion ERRNO_INFO. Dazu verbinden wir beide SQL Funktionen.
VALUES SYSTOOLS.ERRNO_INFO(
SYSTOOLS.IFS_UNLINK('/home/export/test/MyCSVTest1.csv')
);
und erhalten folgendes Ergebnis:
Die Datei ist vorhanden und wurde gelöscht
Quelle: RossDie Datei ist nicht vorhanden
Quelle: Ross2. Praktische Anwendung
Der Ausgangspunkt für unser Beispiel ist ein IFS-Verzeichnis mit unterschiedlichen Dateien und die Aufgabe ist, alle Dateien größer als 1MB zu löschen.
Um alle Dateien im Verzeichnis aufzulisten, verwende ich die SQL-Funktion IFS_OBJECT_STATISTICS. Bitte beachten sie, dass es sinnvoll ist, den PATH_NAME in CCSID 1208 = UTF8 zu casten, da sonst Fehler bei Dateinamen mit Sonderzeichen entstehen können.
SELECT cast(PATH_NAME as varchar(128) CCSID 1208) AS PATH_NAME,
OBJECT_TYPE, CREATE_TIMESTAMP, DATA_SIZE
FROM TABLE(
QSYS2.IFS_OBJECT_STATISTICS(
START_PATH_NAME => '/home/export/test',
SUBTREE_DIRECTORIES => 'NO',
OBJECT_TYPE_LIST => '*ALLSTMF *ALLDIR'
)
);
Das hat folgendes Ergebnis:
Quelle: RossDer nächste Schritt ist eine CTE (Common Table Expression), die alle IFS-Dateien findet, die größer als 1MB sind und diese gleichzeitig löscht.
WITH X (PATH_NAME, OBJECT_TYPE, CREATE_TIMESTAMP, DATA_SIZE, ERRNO) as (
SELECT cast(PATH_NAME as varchar(128) CCSID 1208) AS PATH_NAME,
OBJECT_TYPE, CREATE_TIMESTAMP, DATA_SIZE,
SYSTOOLS.IFS_UNLINK(PATH_NAME)
FROM TABLE(
QSYS2.IFS_OBJECT_STATISTICS(
START_PATH_NAME => '/home/export/test',
SUBTREE_DIRECTORIES => 'NO',
OBJECT_TYPE_LIST => '*ALLSTMF'
)
)
) SELECT X.*, SYSTOOLS.ERRNO_INFO(X.ERRNO) AS "Error Description"
FROM X
WHERE DATA_SIZE > 1000000;
Hier ist das Ergebnis:
Quelle: Ross3. Einbinden IFS_UNLINK in ein RPG-Programm
Als erstes erstelle ich ein Array für die IFS Dateien, die ich mit dem obigen SQL auslese. Das Besondere an dem Array ist die Definition mit DIM(*AUTO:10000). Das bedeutet, das Array hat eine maximale Kapazität von 10.000 Einträgen und vergrößert sich automatisch. Mit %Elem(IFSArray) erhalte ich immer die genaue Zahl der Einträge.
dcl-ds IFSArray Dim(*Auto:10000) qualified inz;
File varchar(128);
Type varchar(10);
Created timestamp;
Size int(10);
end-ds;
Im nächsten Schritt fülle ich das Array mit allen Dateien aus dem Verzeichnis. Es ist möglich, das Füllen mit einer Schleife zu machen, aber mit der Anweisung
Fetch Cursor for 10.000 ROWS into :IFSArray
geht das viel bequemer in einem Schritt ohne Schleife
exec sql declare Cursor01 cursor for
select cast(PATH_NAME as varchar(128) CCSID 1208) AS PATH_NAME,
OBJECT_TYPE, CREATE_TIMESTAMP, DATA_SIZE
from table(
QSYS2.IFS_OBJECT_STATISTICS(
START_PATH_NAME => '/home/export/test',
SUBTREE_DIRECTORIES => 'NO',
OBJECT_TYPE_LIST => '*ALLSTMF'
)
);
exec sql open Cursor01;
exec sql Fetch Cursor01 for 10000 rows into :IFSArray;
exec sql GET DIAGNOSTICS :Records = ROW_COUNT;
exec sql close Cursor01;
Als nächstes lese ich das Array mit einer Schleife durch, um alle IFS Dateien zu finden, die größer als 1MB sind und diese dann zu löschen. Die gelöschten Dateien protokolliere ich mit der SQL Funktion QSYS2.SEND_MESSAGE ins SYSLOG.
for Index = 1 to Counter;
if IFSArray(Index).Size > 1000000;
File = IFSArray(Index).File;
exec sql set :Error =
SYSTOOLS.ERRNO_INFO(SYSTOOLS.IFS_UNLINK(:File));
Text = 'Delete: ' + IFSArray(Index).File + ' ' +
IFSArray(Index).Type + ' ' + Error;
exec sql
CALL QSYS2.SEND_MESSAGE('SQL7064', length(:Text), :Text);
endif;
endfor;
Hier ist das vollständige Listing des Programmes
ctl-opt dftactgrp(*no) main(main);
//------------------------------------------------------------------//
// //
// Delete IFS-Files //
// //
//----------------- //
// R.Ross 08.2024 * //
//------------------------------------------------------------------//
// SQL-Options //
//------------------------------------------------------------------//
exec sql set option datfmt=*iso, timfmt=*iso, commit=*none,
decmpt=*period, closqlcsr=*endactgrp;
//------------------------------------------------------------------//
// Main //
//------------------------------------------------------------------//
dcl-proc main;
dcl-ds IFSArray Dim(*Auto:10000) qualified inz;
File varchar(128);
Type varchar(10);
Created timestamp;
Size int(10);
end-ds;
dcl-s Records uns(10);
dcl-s Counter uns(10);
dcl-s Index uns(10);
dcl-s File varchar(128);
dcl-s Text varchar(128);
dcl-s Error varchar(128);
exec sql declare Cursor01 cursor for
select cast(PATH_NAME as varchar(128) CCSID 1208) AS PATH_NAME,
OBJECT_TYPE, CREATE_TIMESTAMP, DATA_SIZE
from table(
QSYS2.IFS_OBJECT_STATISTICS(
START_PATH_NAME => '/home/export/test',
SUBTREE_DIRECTORIES => 'NO',
OBJECT_TYPE_LIST => '*ALLSTMF'
)
);
exec sql open Cursor01;
exec sql Fetch Cursor01 for 10000 rows into :IFSArray;
exec sql GET DIAGNOSTICS :Records = ROW_COUNT;
exec sql close Cursor01;
Counter = %Elem(IFSArray);
for Index = 1 to Counter;
if IFSArray(Index).Size > 1000000;
File = IFSArray(Index).File;
exec sql set :Error =
SYSTOOLS.ERRNO_INFO(SYSTOOLS.IFS_UNLINK(:File));
Text = 'Delete: ' + IFSArray(Index).File + ' ' +
IFSArray(Index).Type + ' ' + Error;
exec sql
CALL QSYS2.SEND_MESSAGE('SQL7064', length(:Text), :Text);
endif;
endfor;
end-proc;
//------------------------------------------------------------------//
Das Ergenis im SYSLOG:
Quelle: RossViel Spaß beim Ausprobieren.
Den Autor Rainer Ross erreichen Sie unter:
Rainer Ross IT-Beratung, Bgm.-Hollweck-Str. 6, 85599 Parsdorf
Ausgezeichnet mit dem Innovationspreis der IBM und Spezialist für Webservices und Webanwendungen auf IBM i so schnell wie Greenscreen
Beispiel: www.myhofi.com/myapps/HTML/Myapp.html
Tel. (+49) 151/684 375 53 oder 089/413 252 94,
E-Mail: rainer_ross@web.de
Web: www.myhofi.com – Hotels finden – leicht gemacht
