Mishandling updates that affect the primary key
We have fixed one problem in our trigger, but it has
another serious bug; it does not handle the case when the primary key
column is also modified. Listing 7 demonstrates the problem. This time, the code also updates the ItemLabel column, which forms part of our Primary Key, as well as the Barcode column.
In this case, the modified row does not get inserted
into the log table. The problem is that our trigger relies on the
implicit assumption that the primary key column in the Items
table is immutable, and so can be relied on to uniquely identify a row.
If the PK column is modified, the trigger has no way to relate the old
value of Barcode to the new one.
As usual, we need either to enforce this assumption
or to eliminate it. If we choose to ensure that our primary key column
cannot change, we must modify our trigger to enforce it, as shown in Listing 8.
To test this trigger, we can rerun Listings 4 and 7.
If, however, our business rules allow changes to be made to labels on
items, then we need some other immutable column; some column that cannot
be changed, and so can uniquely identify a row.
This is one of those cases when IDENTITY columns are so useful. Listing 9 adds an IDENTITY column and creates a UNIQUE constraint to make sure that the IDENTITY column is always unique.
This new IDENTITY column, ItemID, is immutable; it is not possible to modify an IDENTITY column, as Listing 10 demonstrates.
We can now use our immutable ItemId column
so that it does not have to assume that the primary key will never
change, and so fixes the weakness in our trigger, as shown in Listing 11.
Again, to test this trigger, we can rerun Listings 4 and 7.
When developing triggers, we need to beware of
assuming that the primary key column(s) cannot change. We have learned
how to enforce this assumption when it makes sense, and how to eliminate
this assumption when it does not make sense.