Unconfigured Ad Widget

Collapse

Announcement

Collapse
No announcement yet.

RPG Trigger Procedure Working, But...

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Trevor
    replied
    RPG Trigger Procedure Working, But...

    This worked out VERY click and works great! Link to trigger code

    Leave a comment:


  • ejolro
    replied
    RPG Trigger Procedure Working, But...

    I've got the procedure to determine the name of the program that activates the Trigger working. When I do a live call to a program that updates the file, "AMODTUPDTE", I get "QDBUDR" or "QDBPUT" in the program name instead of "AMODTUPDTE" which is what I expected. I assume "QDBUDR" is update record and "QDBPUT" is add record. Can anyone explain this? Is this what I'm going to get when I make this trigger live? I wanted to get the name of the program updating the file. We have a file on the PC side of our system that is filled through Lotus Notes using a process called evolution. This file is then copied to the AS/400 and split out into a header file and a detail file on the AS/400. These two files are used to update the order header and detail file on the AS/400. We are losing the value of two fields somewhere in processing and when we run the process in test it works. That's where the trigger program comes in. We thought if we could narrow down our search parameters for where the fields are getting updated incorrectly we could fix the problem. I've got the trigger program working for *Insert, *Update, and *Delete and was directed to code on the MC site to determine the name of the program that caused the Trigger to activate. However, if there is no way to retrieve the actual name of the program doing the updating, I'm wasting my time. Does anyone have any ideas how I can get what I need? The name of the program that is doing the *Insert/*Update/*Delete to the file. Erik J. Osberg

    Leave a comment:


  • matthew.thompson@ubs.com
    replied
    RPG Trigger Procedure Working, But...

    To follow from this discussion, I have an example trigger program that we use for audit purposes over ANY file. I have tried to catch the program that initiated the Trigger by searching the program stack from the top down, customisation has been applied to exclude IBM programs (Q) but to include SQL driven requests. Code is enclosed.

    TRIGEX.RPGLE

    Leave a comment:


  • Guest's Avatar
    Guest replied
    RPG Trigger Procedure Working, But...

    Hi, I had been trying to do this on my own, when I saw this code. I got it to compile (this is my first successful attempt at a module). I am now trying to call the module from my trigger RPG program. I haven't been able to get it to compile. I think it has something to do with how I have my prototype or the call set up. The books and the on-line research I have been doing doesn't seem to work. I keep telling myself this can't be that difficult, but I'm missing something. Help! If I put a field length on the PR record, it tells me I need a EXTPGM keyword. When I add that the the PR record, it won't let me put in a field length to get back the program name. Terri Harteau Felker Brothers Corp. tshaw@felkerbrothers.com

    Leave a comment:


  • T.Holt
    replied
    RPG Trigger Procedure Working, But...

    I was thinking production mode, not debugging, when I asked. After that I found Erik's other post, explaining that he was trying to find the source of bad data. I was just wondering.

    Leave a comment:


  • Guest's Avatar
    Guest replied
    RPG Trigger Procedure Working, But...

    Ted, >Why would a trigger program need to know the name of its caller? Two reasons that I use: - Selective logging in lieu of journaling of all activity. This may be for security/audit type purposes (and you want to know the interface used to accomplish it), or it could be a case where you haven't figured out where data corruption is coming from. The trigger can watch for the data condition then log program name, user, etc. - Avoiding recursive file updates in a two-way sync. (See below) In a major S36EE to native conversion project, I had different file layouts on the native side due to things like replacing zoned/packed dates/times with real date and time fields. But I didn't want a all or nothing cutover implementation. I wanted to implement changed programs as they got converted. So every S36EE file got a trigger which would immediately reformat the data and apply it to the native copy of the file. Likewise, the native file got a trigger which would immediately reformat the data and apply it to the S36EE file. The net effect is that the RPG II code continued to work as is with the native code coexisting. Either side could read or write data in real time, and have live data. When all S36EE code accessing a given file had been replaced, the triggers could be removed and the native code would have no trace of baggage for handling the S36EE heritage. The concept works great for a two-way sync with one caveat: the triggers needed to see if it was invoked due to the *other* trigger, and if so just no-op. IOW, if the S36EE file was being updated, its trigger would update the native file. But this naturally fired the native trigger program. So it would check the "caller" name, and if (and only if) it was the S36EE trigger it would just return. Ditto for the S36EE file's trigger. Think of it as an intra-system Mimix, but with disparate file layouts. For major conversion projects, IMHO it works very well. Doug

    Leave a comment:


  • T.Holt
    replied
    RPG Trigger Procedure Working, But...

    Something about this whole idea keeps bothering me. I've always been under the impression that any called program should be able to function correctly without knowing the name of the program that called it. Why would a trigger program need to know the name of its caller?

    Leave a comment:


  • Guest's Avatar
    Guest started a topic RPG Trigger Procedure Working, But...

    RPG Trigger Procedure Working, But...

    Erik, Here is source from the example on the other forum, you may be able to determine your problem from looking at that. I haven't used this code but posted it in the hopes it will help you solve your problem. It is similar to the MC code but it loops until it gets far enough up the program stack to return the program name you want. Scott Mildenberger H NoMain * Prototype for the AppPgmName procedure D AppPgmName PR 10 D DummyPrm 1 Options( *Omit ) * Procedure to return the name of the application * program which fired the trigger P AppPgmName B Export D AppPgmName PI 10 D DummyPrm 1 Options( *Omit ) * Prototypes D SndMsg PR ExtPgm( 'QMHSNDPM' ) D MsgId 7 Const D QlMsgfName 20 Const D MsgDta 256 Const D Options( *VarSize ) D LenMsgDta 10I 0 Const D MsgType 10 Const D ClStkEntry 10 Const D ClStkCounter 10I 0 Const D MsgKey 4 D ApiErr 272 D RcvMsg PR ExtPgm( 'QMHRCVPM' ) D MsgInf 120 D LenMsgIfn 10I 0 Const D FmtName 8 Const D ClStkEntry 10 Const D ClStkCounter 10I 0 Const D MsgType 10 Const D MsgKey 4 Const D WaitTime 10I 0 Const D MsgAct 10 Const D ApiErr 272 * Local data D MsgKey S 4 D ApiErr DS D AeBytesProv 10I 0 Inz( 272 ) D AeBytesAvl 10I 0 D AeMsgId 7 D 1 D AeMsgDta 256 D MsgInf DS D MiBytesRetd 1 4B 0 D MiBytesAvl 5 8B 0 Inz( 120 ) D MiPgmName 111 120 D TrgPgmName S 10 D CurrPgmName S 10 D PgmNameChanges S 1P 0 D ClStkCounter S 10I 0 * Send a dummy message to the trigger C CallP SndMsg( 'CPF9898': 'QCPFMSG QSYS': C ' ': 1: C '*INFO': '*PGMBDY': C 1: MsgKey: C ApiErr ) * Receive the message back and pick up the trigger program name C CallP RcvMsg( MsgInf: %Size( MsgInf ): C 'RCVM0200': '*': C *Zero: '*INFO': C MsgKey: 0: C '*REMOVE': ApiErr ) C Eval TrgPgmName = MiPgmName * Keep going backward in the call stack until the program name changes * twice. The second change to the program name will be the name of * the application which caused the trigger to fire. C Eval CurrPgmName = TrgPgmName C Eval PgmNameChanges = *Zero C Eval ClStkCounter = 2 C DoU PgmNameChanges = 2 C CallP SndMsg( 'CPF9898': 'QCPFMSG QSYS': C ' ': 1: C '*INFO': '*PGMBDY': C ClStkCounter: MsgKey: C ApiErr ) C CallP RcvMsg( MsgInf: %Size( MsgInf ): C 'RCVM0200': '*': C *Zero: '*INFO': C MsgKey: 0: C '*REMOVE': ApiErr ) C If MiPgmName <> CurrPgmName C Eval CurrPgmName = MiPgmName C Eval PgmNameChanges = PgmNameChanges + 1 C Else C Eval ClStkCounter = ClStkCounter + 1 C EndIf C EndDo C Return CurrPgmName P AppPgmName E
Working...
X