In alcune situazioni, in un programma RPG può essere necessario eseguire della logica differenziata che dipende dalla funzione che lo ha richiamato. Normalmente si tende a gestire questo comportamento passando al programma un opportuno parametro, ma nel caso di programmi che agiscono molto “in profondità”, la catena dei richiami può essere abbastanza lunga ed avere più livelli; in questo caso è necessario assicurarsi che un parametro impostato dal primo programma si propaghi correttamente fino al programma finale.
Un’altra soluzione è quella di sapere se il programma corrente è stato richiamato da un altro programma, direttamente oppure nella catena di richiami; in questo modo a seconda del chiamante si potranno eseguire le logiche opportune.
E per questo scopo, chi ci viene in aiuto se non l’accoppiata DB2 + SQL ? Nella sempre più ricca collezione di servizi DB2, nella sezione “Application Services” troviamo la funzione di tabella STACK_INFO, che restituisce l’elenco delle chiamate del job.
Grazie a questa funzione, con una semplice query possiamo sapere facilmente se un determinato programma fa parte della catena dei richiami:
SELECT COUNT(*)
FROM TABLE (QSYS2.STACK_INFO('*')) s
WHERE program_library_name NOT LIKE 'QSYS%'
AND program_name = 'MYPGM'
;
Se il conteggio restituisce un valore maggiore o uguale a 1, sappiamo che il programma corrente è stato richiamato da MYPGM. Con la funzione scalare COUNT otterremo sempre un valore, anche nel caso in cui il programma non sia presente nell’elenco. Questa query esclude dalla selezione le librerie di sistema che iniziano con QSYS.
La funzione ha due parametri:
I parametri job_name e thread_id ci permettono di ottenere l’elenco dei richiami anche di job e processi diversi da quello corrente, il che agevola eventuali verifiche su altri job attivi.
Le informazioni restituite da STACK_INFO sono numerose, tra le più utili abbiamo il nome della procedura chiamante ed il numero della specifica del richiamo.
Nel caso la verifica del chiamante dovesse essere eseguita in molti programmi, niente di meglio che incapsulare questa logica in una procedura di un programma di servizio.
Di seguito il source di una procedura di service program, che riceve un parametro (il programma da ricercare) e restituisce un flag booleano che indica se il programma specificato nel parametro fa parte della catena dei richiami.
Il sorgente completo è disponibile su GitHub a questo link:
https://github.com/MD2706GIT/FAQ400
//********************************************************************
// isCalledFrom - Check if a given program is in call stack
//
// INPUT Parms:
// - pPgm - Program name CHAR(10)
//
// OUTPUT Parms:
// - Flag "1"=found "0"=not found BOOLEAN
//
//********************************************************************
dcl-proc isCalledFrom export;
dcl-pi isCalledFrom ind;
dcl-parm pPgm char(10) const ; // program name
end-pi;
dcl-s found ind;
monitor;
found = *off;
Exec SQL
SET :found:indNull = (SELECT DISTINCT '1'
FROM TABLE (QSYS2.STACK_INFO('*')) s
WHERE program_library_name NOT LIKE 'QSYS%'
AND program_name = :pPgm
)
;
if indNull = -1;
found = *off;
endif;
on-error;
found = *off;
endmon;
return found;
end-proc;
Ecco un semplice esempio di richiamo della procedura:
dcl-s found ind ;
. . .
found = isCalledFrom('FAQ40012B') ;
DOCUMENTAZIONE:
STACK_INFO :
https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/rzajq/rzajqudfstackinfo.htm
Le funzioni di debug con Visual Studio Code sono disponibili da qualche tempo ma questa nuova versione 2.10.0 semplifica la…
A distanza di due anni e mezzo dal mio post Trasferire oggetti con ObjectConnect ed Enterprise Extender, sono finalmente riuscito…
Con un piccolo trucco anche una semplice istruzione SELECT può eseguire qualsiasi comando di sistema ! Vediamo come...
Una mini-guida a puntate per la configurazione, gestione, uso e risoluzione dei problemi di IBM i NetServer
Una mini-guida a puntate per la configurazione, gestione, uso e risoluzione dei problemi di IBM i NetServer
Una mini-guida a puntate per la configurazione, gestione, uso e risoluzione dei problemi di IBM i NetServer