Tutti noi utilizziamo quotidianamante l’istruzione SELECT per recuperare dati dal database. La SELECT è quindi generalmente considerata un’istruzione “passiva”, che si limita a restituire risultati senza alterare nulla.
Ma con una piccola aggiunta, anche una normalissima SELECT può trasformarsi in una azione “attiva”, in grado di agire sul database ma anche sul sistema !
Il segreto sta nell’accoppiata tra la SELECT e la ben nota procedura QCMDEXC, che consente di eseguire un comando CL, e che a partire dalle versioni 7.4 TR4 e 7.3 TR10 viene fornita anche sotto forma di funzione scalare. Questo fa si che QCMDEXC sia richiamabile all’interno di qualsiasi query SQL.
Vediamo subito un esempio pratico: la ridenominazione di massa di un gruppo di file IFS.
Nelle applicazioni è comune avere delle funzioni che creano dei file IFS con una certa denominazione, li inviano a server remoti e poi li rinominano in modo che non vengano più considerati nel successivo ciclo di elaborazione. In questo esempio abbiamo 5 file .csv nella nostra cartella IFS:
Supponiamo di averli inviati al server remoto tutti insieme (per esempio tramite FTP con un comando MPUT), ora vogliamo rinominarli tutti cambiando l’estensione da “.csv” a “.ok” in modo da identificare i file elaborati.
Grazie alle funzioni e ai servizi SQL, siamo in grado di rinominare in un colpo solo tutti i file, cambiandogli l’estensione.
Ecco l’istruzione:
---- RENAME di massa di file IFS
-- 1: estrazione elenco file IFS da rinominare
WITH a AS (
SELECT path_name,
UPPER(REPLACE(path_name, '/home/MDUCA/FAQ400_15/', '')) filename
FROM TABLE(ifs_object_statistics(
START_PATH_NAME => '/home/MDUCA/FAQ400_15',
SUBTREE_DIRECTORIES => 'NO' ,
OBJECT_TYPE_LIST => '*ALLSTMF'
))
WHERE UPPER(path_name) LIKE '%/FILE%.CSV'
)
-- 2: composizione comando CL
, b AS (
SELECT
'REN OBJ(''' CONCAT TRIM(path_name) CONCAT ''') NEWOBJ('''
CONCAT REPLACE(filename, '.CSV', '.OK') CONCAT
''')' cmd
FROM a
)
-- 3: esecuzione comandi
SELECT b.*, qsys2.qcmdexc(cmd)
FROM b
;
Analizziamola in dettaglio: nella prima CTE, con il servizio IFS_OBJECT_STATISTICS estraiamo l’elenco dei file della cartella /home/MDUCA/FAQ400_15; viene estratto il percorso completo (path_name) ed il solo nome del file (convertito in maiuscolo, per considerare maiuscole e minuscole indistintamente). L’elenco filtra solo i file con nome che inizia con “FILE” e con estensione “.csv”.
Con la seconda CTE si legge l’elenco appena estratto e si compone il comando di ridenominazione oggetto (REN); questo è il comando che verrà dato in pasto alla procedura QCMDEXC. In questa fase la fatica peggiore è come sempre litigare con gli apici…
Per finire, leggendo con una SELECT l’elenco dei comandi REN composti prima e passandoli come parametro alla funzione QCMDEXC, i comandi di sistema verranno eseguiti. La funzione QCMDEXC restituisce “1” se il comando è andato a buon fine, altrimenti restituirà il valore “-1”.
Ed ecco i nostri file rinominati come desiderato.
L’accoppiata vincente tra SELECT e QCMDEXC può trasformarsi in un utile e potente strumento per eseguire massivamente comandi a fronte di un elenco di elementi, evitando di doverlo fare uno per uno manualmente. Si pensi per esempio alla ricompilazione di tutti i source di una certa libreria, allo spostamento in altre librerie di oggetti non utilizzati, e via dicendo.
I servizi e le funzioni del DB2 si confermano strumenti efficacissimi per semplificare la vita degli sviluppatori, conoscerli ed applicarli correttamente permette di ottenere applicazioni chiare, di facile manutenzione e soprattutto… moderne !
DOCUMENTAZIONE:
Table function IFS_OBJECT_STATISTICS
https://www.ibm.com/docs/en/i/7.4?topic=services-ifs-object-statistics-table-function
Funzione scalare QCMDEXC
https://www.ibm.com/docs/en/i/7.4?topic=services-qcmdexc-scalar-function