I am having some trouble trying to determine where all of the errors are coming from that I am seeing.
If I run the below code...
DEFINE TEMP-TABLE ttList NO-UNDO FIELD tId AS INTEGER INDEX tabix IS PRIMARY UNIQUE tId. MAINBLOCK: DO ON ERROR UNDO, LEAVE: CREATE ttList. ASSIGN ttList.tId = 1. CREATE ttList. ASSIGN ttList.tId = 1. END. /* MAINBLOCK */
I see ** ttList already exists with 1. (132), but I see it 4 times.
So if I change the code to add some messages, like the below...
DEFINE TEMP-TABLE ttList NO-UNDO FIELD tId AS INTEGER INDEX tabix IS PRIMARY UNIQUE tId. MAINBLOCK: DO ON ERROR UNDO, LEAVE: MESSAGE "1" VIEW-AS ALERT-BOX INFO BUTTONS OK. CREATE ttList. ASSIGN ttList.tId = 1. MESSAGE "2" VIEW-AS ALERT-BOX INFO BUTTONS OK. CREATE ttList. ASSIGN ttList.tId = 1. END. /* MAINBLOCK */ MESSAGE "3" VIEW-AS ALERT-BOX INFO BUTTONS OK.
I then see message 1 and 2, then I see the first error 132 (as expected), then I see message 3, but then I see the other 3 error 132's before I return back to the editor.
I don't understand why I am getting the additional error 132 messages?
OpenEdge 10.2B08
Windows 7 (64 bit)
The short version why the error repeats:
- Because the temp-table is no-undo the 2nd record stays in the buffer. (if the temp-table is undoable AND a transaction is active the buffer will be emptied while the record is undone).
- The AVM tries to flush buffers that moved out of scope at certain points. (Such as when a procedure ends.) And it validates the current contents when doing so to prevent the underlying table from going into an inconsistent state. Every time such a flush happens, the error will be raised again and the buffer sticks around because it can't be flushed correctly.
Two ways to avoid this:
1. Make the temp-table undoable and wrap any activity on it in a transaction. Which is probably not the most efficient way, and may introduce transaction scoping issues as a side effect.
2. In the block where you create temp-table records, CATCH any error that occurs. Then in the CATCH block delete the record and re-throw the exception. (Re-throwing is under the assumption that you *do* want the initial error to remain visible to the rest of your code )
The short version why the error repeats:
- Because the temp-table is no-undo the 2nd record stays in the buffer. (if the temp-table is undoable AND a transaction is active the buffer will be emptied while the record is undone).
- The AVM tries to flush buffers that moved out of scope at certain points. (Such as when a procedure ends.) And it validates the current contents when doing so to prevent the underlying table from going into an inconsistent state. Every time such a flush happens, the error will be raised again and the buffer sticks around because it can't be flushed correctly.
Two ways to avoid this:
1. Make the temp-table undoable and wrap any activity on it in a transaction. Which is probably not the most efficient way, and may introduce transaction scoping issues as a side effect.
2. In the block where you create temp-table records, CATCH any error that occurs. Then in the CATCH block delete the record and re-throw the exception. (Re-throwing is under the assumption that you *do* want the initial error to remain visible to the rest of your code )
Much appreciated Frank, a very thorough explanation.