将新成绩添加到数据库时,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数据库

SqlAlchemy 将新字段添加到类并在表中创建相应的列

sql [ALTER TABLE ADD COLUMN]将新列添加到现有表#SQL

将新列添加到 wordpress 数据库

将新列添加到现有表中并使用 PL/SQL 中游标中的值更新它们