【问题标题】:Setting auto update trigger设置自动更新触发器
【发布时间】:2021-02-17 09:38:10
【问题描述】:

我想创建一个触发器,当表 StudentScoreDetail 更新时,它会自动更新名为 StudentScore 的表。这是我的触发器

CREATE TRIGGER Trigger_UpdateStudentScore 
ON dbo.StudentScoreDetail for update 
as
DECLARE @courseID VARCHAR(20)
DECLARE @studentID_up VARCHAR(15)
if(NOT EXISTS(SELECT inserted.CourseID FROM inserted))
BEGIN
    SET @courseID=(SELECT d.CourseID FROM deleted d)
    SET @studentID_up=(SELECT d.StudentID FROM deleted d)
END 
ELSE BEGIN
    SET @courseID=(SELECT i.CourseID FROM inserted i)
    SET @studentID_up=(SELECT i.StudentID FROM inserted i)
END
UPDATE StudentScore
SET TotalScore=(SELECT SUM(SSD.Score*(SC.[Weight]/100)) FROM StudentScoreDetail SSD JOIN ScoreComponent SC ON SSD.Component=SC.Component WHERE SSD.CourseID=@courseID AND SSD.StudentID=@studentID_up) WHERE StudentScore.CourseID=@courseID AND StudentScore.StudentID=@studentID_up
UPDATE StudentScore
SET Grade=(SELECT W.Grade FROM [Weight] W WHERE W.ScoreMin<=StudentScore.TotalScore)WHERE StudentScore.CourseID=@courseID AND StudentScore.StudentID=@studentID_up

但是它返回了一个错误:

子查询返回超过 1 个值。当子查询跟随 =、!=、、>= 或子查询用作表达式时,这是不允许的。

有人知道为什么吗?

【问题讨论】:

  • 如果您使用错误消息中的第一句话进行搜索,您会发现很多关于错误发生原因以及如何修复它的讨论。您还应该找到许多关于触发逻辑中严重缺陷的讨论。假设单行已更新,您犯了一个非常常见的错误。

标签: sql sql-server tsql triggers


【解决方案1】:

我相信您想要如下所示的代码。注意事项:

  1. Inserted and Deleted 伪表可以包含多行,您必须处理这个问题。
  2. 对于UPDATE 触发器,如果​​记录已更新,您将始终在您的Inserted 表中有记录,因此您无需检查。如果Inserted 中没有记录,那么Deleted 中也将没有记录。
  3. 在编写任何 T-SQL(包括触发器)时,您应该尽可能地编写基于集合的代码 - 如果您发现自己从一个表中填充变量来查询另一个表,您可能会做错了。
CREATE TRIGGER Trigger_UpdateStudentScore 
ON dbo.StudentScoreDetail
FOR UPDATE
AS
BEGIN
    SET NOCOUNT ON;
    
    UPDATE SS SET
        TotalScore = (
            SELECT SUM(SSD.Score*(SC.[Weight]/100))
            FROM StudentScoreDetail SSD
            JOIN ScoreComponent SC ON SSD.Component = SC.Component
            WHERE SSD.CourseID = SS.CcourseID AND SSD.StudentID = SS.SstudentID
        )
        , Grade = (
            SELECT W.Grade
            FROM [Weight] W
            WHERE W.ScoreMin <= StudentScore.TotalScore
        )
    FROM StudentScore SS
    INNER JOIN Inserted I ON SS.CourseID = I.CourseID AND SS.StudentID = I.StudentID;
END;

【讨论】:

    猜你喜欢
    • 2016-08-12
    • 2021-10-19
    • 2019-06-06
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    • 2015-07-25
    • 2017-10-06
    • 1970-01-01
    相关资源
    最近更新 更多