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.