Last Updated on 8 Aprile 2020 by Roberto De Pedrini

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:

  • job_name: identificativo di un job. ‘*’ indica il job corrente
  • thread_id: identificativo di un processo (opzionale)

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

Related Posts
DB2 for i SQL – Stringhe – POSSTR-LOCATE-LOCATE_IN_STRING (IT)

Introduzione Spesso, nelle nostre applicazioni, abbiamo la necessità di lavorare con le stringhe di testo e l'SQL del DB2 può Read more

DB2 for i & SQL – FAQ & Howto (Part. 1) (IT)

Database DB2 e SQL ... forse lo strumento più potente e completo che abbiamo sulla piattaforma IBM i: ecco una Read more

Annuncio IBM i 7.4

Arriva direttamente con l'uovo di Pasqua questo annuncio IBM per le novità della versione IBM i 7.4, versione iNext secondo Read more

Generated Always Columns – Approfondimenti (IT)

Introduzione "Generated Always Column": sono colonne, campi, di una tabella il cui contenuto è controllato direttamente dal sistema ... e Read more

About author

Senior Analyst/Developer e divulgatore in ambito IBM i. Già collaboratore dell'edizione italiana della rivista "System i News" ed autore di diverse pubblicazioni su tools e tecniche di sviluppo in ambiente IBM i.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *