将新成绩添加到数据库时,Microsoft sql 会触发自动更新 GPA
Posted
技术标签:
【中文标题】将新成绩添加到数据库时,Microsoft sql 会触发自动更新 GPA【英文标题】:Microsoft sql triggers auto update GPA when new grade is added to the database 【发布时间】:2021-12-14 11:41:45 【问题描述】:有2张桌子:
学生(学号、LName、FName、GPA)
Enroll(enrollid, CourseID, Semester, Grade)
我想创建一个触发器,每次添加新成绩时都会更新 GPA,计算如下
gpa = (old.gpa + new.grade)/count(grade) where studentid = new.studentid
这是我的代码,但它不起作用
Create trigger [dbo].[stud_marks]
on
[dbo].[enroll]
after INSERT,update
AS
DECLARE @id as int
DECLARE @newgrade as int
SELECT @id = studentid, @newgrade = grade
FROM inserted
begin
UPDATE students
set gpa = (gpa + @newgrade)/count(@id)
end
显示错误:
Msg 157, Level 15, State 1, Procedure stud_marks, Line 16 [Batch Start Line 7]
An aggregate may not appear in the set list of an UPDATE statement.
【问题讨论】:
请不要对我们大喊大叫;我们可以很好地阅读小写字母,谢谢。 在表中存储聚合值几乎总是一个坏主意。如果您想将这些值作为列使用,请使用VIEW
。
如果您发现自己在触发器中使用局部变量,您几乎可以肯定是doing it wrong
如果要监控GradeValues
的插入,为什么要在students
上定义触发器?我真的不明白你的模式,你能解释一下外键关系吗?最好只使用索引视图
您的触发器存在重大缺陷。您假设 insert 将只包含一行。这不是触发器在 sql server 中的工作方式,插入的将包含插入语句中的所有行。但如前所述,存储计算数据是有问题的。对于这种事情,视图将是一个更好的解决方案。
【参考方案1】:
正如其他人所说,这不是一个好主意,不是 3NF,并且会导致数据不一致。这些都是坏事,不要这样做。
话虽如此,问题不在于您的触发器,而在于您的 UPDATE。
您并未将更新限制为特定学生,而是尝试在更新中执行聚合,这是一个禁忌。这就是你的更新应该看起来的样子,我以一种老屁的方式实现了它,没有使用 WITH,但是 a)我是个老屁,而且 b)你让我远离了看我的“Matlock” “马拉松来写这个。无论如何,这是您应该编写的更新。
UPDATE students
set gpa = (select avg(grade) + @newgrade from enroll where studentid=@id)
/(select count(*)+1 from enroll where studentid=@id )
where studentid=@id
好吧,现在我得回去做些老屁的事情了。如果你们中的任何一个打手给我一个“好的,Boomer”,请记住——我可以操作手动变速器。
【讨论】:
以上是关于将新成绩添加到数据库时,Microsoft sql 会触发自动更新 GPA的主要内容,如果未能解决你的问题,请参考以下文章
sql 使用凭据u:admin,p:password将新管理员用户添加到wordpress数据库
sql 使用凭据u:admin,p:password将新管理员用户添加到wordpress数据库