我认为这些概念对我来说很清楚,现在我不太确定。我是SQL的新手并且已经搜索了答案,但似乎太愚蠢了解无法理解可用的内容。
这是一个虚构的情况,也许我可以得到一些见解。让我们说我有一张名为注册详情的表格,其中包含学生ID,课程ID,成绩和机构。成绩通常在一个季度末分配,但如果有成绩变化,可能会在四分之一的中间更新。如果我要编写一个计算GPA的触发器......
CREATE OR REPLACE TRIGGER gpa_calc
BEFORE UPDATE OF course_grade
ON enroll_details
FOR EACH ROW
如果
,它会如何改变?如果我把BEFORE改为AFTER我会发生错误,因为你试图更新已经写入内存的表。
如果我从行级别更改为语句级别触发器,我不确定GPA是否会被正确计算,因为每次更新都不会触发GPA ...
任何帮助都将不胜感激。
答案 0 :(得分:2)
在触发器可以修改正在更新/插入的数据之前,它们对于实施数据完整性规则或提供默认值非常有用。触发器在事务提交之前运行,并且不再可能进行更新。它们是进行验证或更新汇总表的正确位置,您希望确保源值不能进一步更改。
在您的示例中,gpa可能存储在单独的表中(因为它不是所采用的任何单个类的属性),因此它可能是后触发器。如果你要根据一些复杂的逻辑添加一个触发器来修改等级(例如,如果GPA> 4.0构成一个愚蠢的例子,你不能低于C)那么那将是一个触发前的触发器在表格更新之前更改成绩。
要添加,为每个正在更新的行调用FOR EACH ROW触发器(顾名思义),并且您可以访问:old和:new。无论更新了多少行,并且您无权访问单个:new或:old值,语句级别触发器将被调用一次。它适用于基于复杂条件强制执行/阻止访问(可能您不允许在晚上10点到晚上11点之间进行更新),或者可能将表标记为“脏”并需要通过稍后的批处理模式任务进行处理(例如,导出到数据)仓库)。
答案 1 :(得分:1)
计算值将复杂性引入模型。维护它们的成本通常超过按需计算它们的成本(取决于写入和读取之间的平衡)。但有时候这个价值对于应用来说是如此重要,我们总是需要手头上的。或许我们需要对其进行审核。我们假设GPA是其中一个属性。
所以,有关GPA的几点意见:
enroll_details
表的状态,因此BEFORE或AFTER触发器无关紧要(但见下文)。通常我们使用BEFORE触发器来验证和符合值,应用计算的默认值以及我们想要发生的任何处理,无论是否应用了行。我们使用AFTER触发器进行处理,假设已经应用了行。计算像GPA这样的东西属于第二类。所以触发器应该是AFTER语句级触发器:
CREATE OR REPLACE TRIGGER gpa_calc
AFTER UPDATE OF course_grade
ON enroll_details