Peter Dow (ML) wrote:
I hope you're not feeling picked on here!  I'm still having a hard time 
understanding your objection and some of your explanations.
  If I were, I would just accuse everyone of being blind and give up. 
Albeit, I am almost there.
CRPence wrote:
   No.  Insert Trigger act between the trigger program and the
database; they have their own contractual obligations.  A Read
Trigger is between the HLL and the database.  That is what makes
them totally different. 
What does this mean?  From the app pgm point of view, all of these 
triggers  --  READ, INSERT, UPDATE, DELETE --  are between it and
the database.
  *INSERT\*BEFORE
  HLLPGM->HLLWRITE->[TRIGGER->CHGDTA->DBWRITE]->HLLPOSTWRITELOGIC
    Contract is between TRIGGER&DBWRITE, the row of CHGDTA is validated 
and logged by the database.  Whatever the HLLPGM wrote, that program is 
still aware of, and can continue with that same HLL logic _unaffected_, 
knowing that it just wrote what it wrote.  This remains true, 
irrespective of what the trigger might have really done in its contract 
with the db write.
  *READ\*AFTER
  HLLPGM->HLLREADx->[DBREAD->TRIGGER]->CHGDTA->HLLPOSTREADLOGIC
    Contract is between the DBREADx&TRIGGER, the row of CHGDTA occurs 
outside the realm of the database but impacts the database row, and the 
logic in the HLL-Post-Read activity may be impacted because the physical 
data that it should be receiving may not match what was received.
    What if the read was a keyed-read and the key value was modified 
such that it is no longer collating.  The coded assumption of the 
program *and* its run-time HLL routines [that the data is arriving in a 
known order] are caught unaware, and the output [to the program] is 
flawed.  If the row is not also then updated, the logic in the program 
is operating against a value which is different in the physical row than 
in the program.  Although this may be desirable in the wished-it-were-so 
change-capable read trigger, that is a *huge* problem for any other 
READer of that row, without being *very* *very* *aware* of the magical 
manipulation taking place without the full validation and logging of the 
database.  Contrast this with a UDF, where the program *asks* for the 
data to have been changed, and when the row retrieval occurred, it was 
according to the result of the UDF when so requested.
   I have obviously not been articulating well, the flaws in a change 
capable trigger, since all that comes from it is the repeated argument 
that "anything can mess with the data, so a Read Trigger should be able 
to as well."  So maybe a theoretical example, assuming the added Read 
Trigger is change capable:
     create table qgpl.  T  (i int, c char)
     addpftrg qgpl/T *after *read pgm(plusone)
     -- plusone returns a value one greater than in field i
     insert into table qgpl.T values(1, DEFAULT)
     call read4upd /* open T for upd, read, upd C='', close */
     -- trigger program is called, set i = 2 as /desired/
     -- Does the row update to the value 2 or stay 1 ?
     -- Well, to pass the row with that value to the program,
     -- the buffer was just updated to have the value 2
     -- So the program updates without changing the value i,
     -- yet the value in the table for i is now 2
   The same table now, with the value 2:
     select i from qgpl.T where i <= 2 into :ii
   The fetched value ii does not meet the selection logic; i.e. ii=3 
whereas all coded logic is with respect to selecting only values that 
were /less than or equal to two/.  Where is the logic in that?  This is 
much worse for /native/ programs, where logic is more likely to be 
deferred to the application and HLL run-time.
What if you turned your example around?  Put an update trigger on a 
file.  Have it always add 1 to i.  Now what?  App pgm reads the file, 
adds 1 to i, updates the record.  If i started out as 1, it is now 3.  
Where's the logic in that?
  If the business rule for the data on writing is that every value i is 
one greater than every posted value, then that is acceptable and has no 
impact on the READ from the database.  Indeed a read, increment, and 
update will double increment.  That was a business rule being applied to 
the physical data that is entirely separate from the logic of the 
program... Well unless the programmer knows about the trigger and thinks 
there is some flaw in the business rules, so then tries to instead of 
inserting the incremented value inserts one less for every value of i; 
but that is its own cranial failure in its own right.  So if the value 
always needs to be incremented on a write, then the logic was applied... 
and the data owner says "That is good.  That is right."  If the result 
was flawed, then it was a flaw in the business rule or the trigger 
program, but the value which was written was capable of being logged; 
all activity remained in the realm of the db.
  It should be absolutely clear, and why I am somewhat frustrated [and 
thus my opening comment here], how it can not be *intuitively obvious* 
with simple _logic_, why the above given SELECT is horribly impacted by 
an intermediary changing the selected\read data.  Compare that SELECT 
with the following which are each logical [assuming no intermediary 
changing the value of i without the knowledge of either the database 
selection or the program processing the selected row(s)]:
    select iplusone(i) from qgpl.T where i <= 2
    select i from qgpl.T where iplusone(i) <= 2
    select iplusone(i) from qgpl.T where iplusone(i) <= 2
  In these three SELECT, the _requesting_ program is fully aware that 
the value of i is being manipulated by the iplusone() function.  No 
flawed logic here.  Revisit the case where an intermediary has changed 
the value of i, and there is clearly flawed logic whereby the incorrect 
results are inherent by the specified selection in the WHERE clause.
  If those SELECT were encapsulated in a VIEW which a program referred 
to, the logic remains valid.  The same can not be said if the modified 
results were obtained instead from an intermediary changing the row data 
outside of the db.
Regards, Chuck
As an Amazon Associate we earn from qualifying purchases.