IC SunsetThe developerWorks Connections platform will be sunset on December 31, 2019. On January 1, 2020, this forum will no longer be available. More details available on our FAQ.
Topic
  • 4 replies
  • Latest Post - ‏2019-07-22T11:40:08Z by PederUdesen
Arthur_Adams
Arthur_Adams
7 Posts

Pinned topic Which program caused a trigger program to run?

‏2013-07-03T10:22:52Z |

This is just me musing about things and I don't really expect a response that answers the question, but why aren't the details of the causing program included in the trigger data? It's not as if it's impossible because journals include the updating program name, so why wasn't the same functionality included with triggers?

I realise there are ways around this, having read numerous threads in various forums all asking how to determine the program name, so it would seem to be a common requirement. It's just a shame the developers never thought of it.

 

  • B.Hauser
    B.Hauser
    6 Posts

    Re: Which program caused a trigger program to run?

    ‏2013-07-04T05:24:59Z  

    When firing an trigger the database manager intitiates either the QDBPUT (for input triggers) or QDBUDR (for update, delete or read triggers) program which itself calls the trigger program.

    So you only need to go backwards in the callstack and find out the callstack entry before the last QDBPUT or QDBUDR.  For reading the callstack you may use the QWVRCSTK (Retrieve Call Stack) API.

    An other way would be to use a simple CL program with  SNDRCVMSG as follows:

    /*****************************************************************/   
    /*    Object. . . . . . . . .  : PRVPGM                          */ 
    /*    Funkcion. . . . . . . .  : Retrieve Caller Programm        */   
    /*                               from Call Stack                 */    
    /*    Parameter . . . . . . .  : CALLER   10 A                   */    
    /*                               CALLED   10 A                   */    
    /*    Author  . . . . . . . .  : B.Hauser                        */    
    /*****************************************************************/ 
                PGM        PARM(&CALLER           +           

                                &CALLED)   

    /* ---------------------------------------------------------------*/  

                DCL        VAR(&CALLER) TYPE(*CHAR) LEN(10)         

                DCL        VAR(&CALLED) TYPE(*CHAR) LEN(10)        

                DCL        VAR(&MSGKEY)   TYPE(*CHAR) LEN(4)  

                DCL        VAR(&SENDER)   TYPE(*CHAR) LEN(80)

    /* ---------------------------------------------------------------*/ 

                SNDPGMMSG  MSG('TEST')                                  +       

                           TOPGMQ(*PRV (&CALLED))                       +            

                           MSGTYPE(*RQS)                                +        

                           KEYVAR(&MSGKEY)       

      

               RCVMSG     PGMQ(*PRV (&CALLED))                         + 

                          MSGKEY(&MSGKEY)                              +      

                          SENDER(&SENDER)    

     

               CHGVAR     VAR(&CALLER) VALUE(%SST(&SENDER 56 10))  

    ENDE:     ENDPGM

    Simply pass QDBPUT or QDBUDR (depending whether an input, update or delete trigger is performed) in the CALLED parameter. And you'll get back the program that initiated the trigger in the CALLER parameter.

    Birgitta

     

    Updated on 2013-07-04T05:33:06Z at 2013-07-04T05:33:06Z by B.Hauser
  • Arthur_Adams
    Arthur_Adams
    7 Posts

    Re: Which program caused a trigger program to run?

    ‏2013-07-05T09:00:27Z  
    • B.Hauser
    • ‏2013-07-04T05:24:59Z

    When firing an trigger the database manager intitiates either the QDBPUT (for input triggers) or QDBUDR (for update, delete or read triggers) program which itself calls the trigger program.

    So you only need to go backwards in the callstack and find out the callstack entry before the last QDBPUT or QDBUDR.  For reading the callstack you may use the QWVRCSTK (Retrieve Call Stack) API.

    An other way would be to use a simple CL program with  SNDRCVMSG as follows:

    /*****************************************************************/   
    /*    Object. . . . . . . . .  : PRVPGM                          */ 
    /*    Funkcion. . . . . . . .  : Retrieve Caller Programm        */   
    /*                               from Call Stack                 */    
    /*    Parameter . . . . . . .  : CALLER   10 A                   */    
    /*                               CALLED   10 A                   */    
    /*    Author  . . . . . . . .  : B.Hauser                        */    
    /*****************************************************************/ 
                PGM        PARM(&CALLER           +           

                                &CALLED)   

    /* ---------------------------------------------------------------*/  

                DCL        VAR(&CALLER) TYPE(*CHAR) LEN(10)         

                DCL        VAR(&CALLED) TYPE(*CHAR) LEN(10)        

                DCL        VAR(&MSGKEY)   TYPE(*CHAR) LEN(4)  

                DCL        VAR(&SENDER)   TYPE(*CHAR) LEN(80)

    /* ---------------------------------------------------------------*/ 

                SNDPGMMSG  MSG('TEST')                                  +       

                           TOPGMQ(*PRV (&CALLED))                       +            

                           MSGTYPE(*RQS)                                +        

                           KEYVAR(&MSGKEY)       

      

               RCVMSG     PGMQ(*PRV (&CALLED))                         + 

                          MSGKEY(&MSGKEY)                              +      

                          SENDER(&SENDER)    

     

               CHGVAR     VAR(&CALLER) VALUE(%SST(&SENDER 56 10))  

    ENDE:     ENDPGM

    Simply pass QDBPUT or QDBUDR (depending whether an input, update or delete trigger is performed) in the CALLED parameter. And you'll get back the program that initiated the trigger in the CALLER parameter.

    Birgitta

     

    Thanks for your reply and your simple, yet clever solution, which I will be making use of in the near future.

    My question though, which not many people will be in a position to answer, was really 'why is the program name available in a journal, but not in trigger data' and I suppose the only real answer is 'because it is'.

  • robberendt
    robberendt
    64 Posts

    Re: Which program caused a trigger program to run?

    ‏2019-07-08T11:42:13Z  

    Thanks for your reply and your simple, yet clever solution, which I will be making use of in the near future.

    My question though, which not many people will be in a position to answer, was really 'why is the program name available in a journal, but not in trigger data' and I suppose the only real answer is 'because it is'.

    See also STACK_INFO at

    https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/IBM%20i%20Technology%20Updates/page/DB2%20for%20i%20-%20Services

    IDK if any of the special registers at the following would help:

    https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/db2/rbafzspecreg.htm

  • PederUdesen
    PederUdesen
    10 Posts

    Re: Which program caused a trigger program to run?

    ‏2019-07-22T11:40:08Z  

    I recommend using the API QWVRCSTK (Retrieve Call Stack).

     

    For years we were using the method of sending a message to a location in the call stack and retrieve it again in order to find the name of the calling program.
    It worked fine on os/400 V7R1 but not after an upgrade to V7R3.

     

    I opened a discussion on this and also an explanation why the old method didn't work:

    https://www.ibm.com/developerworks/community/forums/html/topic?id=ee1fdb68-595d-4613-bc92-4a00496c9936&ps=25

     

    Regards

    Peder