I know that SQL constraints can force data to meet validity criteria. However, what about criteria such as "Student's grade can only be updated when the 'finalised' flag is false"? Do such update criteria have to be handled by the application?
A trigger, a constraint, and an additional column.
Starting from the end:
The additional column stores the value that is to be 'fixed':
ALTER TABLE ADD SavedGrade int
The constraint restricts the change of the Grade
column:
ALTER TABLE Students
ADD CONSTRAINT CK_Grade CHECK (Finalised = 'false' OR Grade = SavedGrade)
The trigger updates the additional column when the Grade
column gets updated (the following is for SQL Server):
CREATE TRIGGER StudentsFinaliseGrade
ON Students AFTER INSERT, UPDATE
AS
IF UPDATE(Grade)
UPDATE Students
SET SavedGrade = i.Grade
FROM inserted i
WHERE i.ID = Students.ID
AND i.Grade <> i.SavedGrade
So, as long as Finalised = 'false'
, the Grade
column may be changed. When it is changed, the value is immediately stored into the SavedGrade
column. (We are updating SavedGrade
directly, because otherwise the constraint wouldn't allow us to set Finalised
to 'true'
.) As soon as Finalised
is set, you can no longer change the Grade
column because of the constraint.