BJCooperIT
Programmer
I have a need to validate row combinations of a child block.
[ol][li]There must be one child row[/li]
[li]There can be no duplicate IDs in the MSID table except for one value, 9999, that may be used by any DIST.[/li][/ol]
(Parent Block = DIST, Child Block = MSID) These are valid key combinations in MSID:
These are not:
The problem is complicated by the navigation restriction in WHEN-VALIDATE triggers. The original developer put the validation code on the KEY-COMMIT trigger. The code did a first_record and then "walked" thru the rows using next_record with complicated logic to prevent duplicates.
I pointed out 2 flaws:
[ol][li]1. If all the rows were not displayed in the block (due to clear_record, query-by-example, etc.) that the validation would not be correct.[/li]
[li]There are several ways the data can be committed, such as during clear_block or enter_query thus the validation would not occur.[/li][/ol]
We tried putting the validation in database triggers to raise an application error, but received the error:
The only other thing that occurs to me is to trap every way the data can be committed, and have KEY-COMMIT perform the validation procedure that would issue a SAVEPOINT, POST the changes, do the validation selects from the database, and then either COMMIT or ROLLBACK as appropriate. I don't like this solution, I have always told my developers that validation should never happen on a KEY-anything trigger.
Is there a better solution?
[sup]Beware of false knowledge; it is more dangerous than ignorance.[/sup][sup] ~George Bernard Shaw[/sup]
Systems Project Analyst/Custom Forms & PL/SQL - Oracle/Windows
[ol][li]There must be one child row[/li]
[li]There can be no duplicate IDs in the MSID table except for one value, 9999, that may be used by any DIST.[/li][/ol]
(Parent Block = DIST, Child Block = MSID) These are valid key combinations in MSID:
Code:
DIST ID
1 4589
1 9999
2 1234
2 9999 <-- OK
Code:
DIST ID
3 1234
4 [COLOR=red]1234[/color] <-- duplicate
I pointed out 2 flaws:
[ol][li]1. If all the rows were not displayed in the block (due to clear_record, query-by-example, etc.) that the validation would not be correct.[/li]
[li]There are several ways the data can be committed, such as during clear_block or enter_query thus the validation would not occur.[/li][/ol]
We tried putting the validation in database triggers to raise an application error, but received the error:
ORA-04091 table string.string is mutating, trigger/function may not see it
Cause: A trigger (or a user defined PL/SQL function that is referenced in this statement) attempted to look at (or modify) a table that was in the middle of being modified by the statement which fired it.
Action: Rewrite the trigger (or function) so it does not read that table.
The only other thing that occurs to me is to trap every way the data can be committed, and have KEY-COMMIT perform the validation procedure that would issue a SAVEPOINT, POST the changes, do the validation selects from the database, and then either COMMIT or ROLLBACK as appropriate. I don't like this solution, I have always told my developers that validation should never happen on a KEY-anything trigger.
Is there a better solution?
[sup]Beware of false knowledge; it is more dangerous than ignorance.[/sup][sup] ~George Bernard Shaw[/sup]
Systems Project Analyst/Custom Forms & PL/SQL - Oracle/Windows