Tuesday, 10 November 2020

Don't forget to unlink GENERALLOAD in form triggers

I wrote a post-update trigger for a form yesterday; the code seemed correct when I looked at it, but it didn't work when added to the form. The code itself took some data from the form, inserted them into the GENERALLOAD table then called an interface in order to do something in another form. I extracted the code and rearranged it slightly to become a self-standing procedure so that I could debug it; the procedure worked properly. So why didn't the trigger work? 

The answer half came to me when walking the dog at 5:30 am (always a productive time for mental debugging): check other triggers for this form to see whether they linked the GENERALLOAD table, and more importantly, whether they unlinked the table. And of course, I found another post-update trigger that I wrote that linked GENERALLOAD but did not unlink it.

In the context of the form, when the second trigger came to link GENERALLOAD, the link failed because the table was already linked. Had I been clever enough to display a warning message if the link failed, instead of skipping to the end of the trigger, then I would have known immediately what the problem was.

Moral of the story: ALWAYS UNLINK GENERALLOAD at the end of a trigger!!

This isn't as clear cut as one would like to think. Normally one writes code such as

EXECUTE INTERFACE 'STATUSMAILQ', SQL.TMPFILE, '-L', :$.G2; SELECT MESSAGE INTO :PAR1 FROM ERRMSGS WHERE USER = SQL.USER AND TYPE = 'i'; ERRMSG 99 WHERE :RETVAL > 0;

The question is: does ERRMSG cause the linked table (:$.G2 in this case) to be unlinked? I suspect not, so alternative methods have to be found in a trigger - probably using WRNMSG, then unlinking the table, then jumping to the end of the procedure. Or unlinking directly after the 'execute' line and before the 'select' line; this way, RETVAL will hold the result of the SELECT statement.

No comments:

Post a Comment