Rob*_*een 7 sql constraints check-constraints
我知道SQL约束可以强制数据满足有效性标准.但是,诸如"学生成绩只能在'最终'标志为假"时才能更新标准呢?这样的更新标准是否必须由应用程序处理?
触发器、约束和附加列。
从最后开始:
附加列存储要“固定”的值:
ALTER TABLE ADD SavedGrade int
Run Code Online (Sandbox Code Playgroud)约束限制列的改变Grade:
ALTER TABLE Students
ADD CONSTRAINT CK_Grade CHECK (Finalised = 'false' OR Grade = SavedGrade)
Run Code Online (Sandbox Code Playgroud)当列更新时,触发器更新附加列Grade(以下适用于 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
Run Code Online (Sandbox Code Playgroud)所以,只要Finalised = 'false',该Grade列就可以改变。当它改变时,该值立即存储到SavedGrade列中。(我们直接更新SavedGrade,因为否则约束将不允许我们设置为Finalised。'true')一旦设置,由于约束Finalised,您将无法再更改列。Grade
简短的回答:不,当 Finalized 为“true”时,SQL 约束本身不能阻止对列 Grade 的更改(但允许其他情况下的更改)。
SQL 约束有多种类型:CHECK、DEFAULT、NOT NULL、UNIQUE、主键和外键。
其中每一个都可以单独或组合地限制或影响列的值,但不能阻止对允许的值进行更新。特别是,这些约束都不能阻止基于之前的 Grade 和 Finalized 值对 Grade 和/或 Finalized 进行更新。
UPDATE 触发器可以执行以下操作:比较 Grade 的新值和旧值,如果这些值不同且 Finalized = 'true',则回滚 UPDATE 并显示解释性错误消息。
然而,应用程序可以而且应该更优雅地执行这样的“业务规则”。规则本身可以对何时可以更改最终值进行一些说明。例如,是否可以同时更改 Grade 并设置 Finalized = 'false'?触发逻辑可以处理这些细节,并且将其安装为故障保护是合理的,同时使规则在应用程序(前端/中间件/后端)的某个位置明确。