通过触发器计算引用的记录

时间:2012-08-02 20:54:42

标签: sql sql-server-2008 stored-procedures triggers sql-server-2012

我发现了一个新问题:我有两个表, Classes 学生学生通过 [ClassID] 列引用课程的列名为 [Count] ,其中存储了引用学生的数量,我正在尝试通过 AFTER INSERT,DELETE 触发器更新< strong>学生表。 我写了一个简单的 CALC_COUNT 程序:


CREATE PROCEDURE [dbo].[CALC_COUNT]
    @classid INT
AS
BEGIN
UPDATE classes SET [Count] = (SELECT COUNT(Id) FROM students WHERE [ClassID] = @classid);
END

RETURN 0

并在触发器

中使用它
CREATE TRIGGER [MONITOR_STUDENTS_SCHEMA_TRIGGER]
    ON [dbo].[students]
    AFTER DELETE, INSERT
    AS
    BEGIN
        UPDATE [dbo].[classes] 
        SET studentsschemarev +=1  FROM inserted; 
        CALC_COUNT(SELECT [ClassID] FROM inserted UNION SELECT [ClassID] FROM deleted); 
        UPDATE [dbo].[stats] SET students_schema_rev += 1;
    END

但它不起作用。 我想,我需要一种方法来执行触发器SELECT语句中每一行的过程,但我不知道如何。

SQL Server 2012 LocalDB,与SQL Server 2008的兼容模式。

2 个答案:

答案 0 :(得分:1)

您不需要存储过程。

将您的触发器更新为

update classes
set 
   count = StudentCount,
   schemarevcount += 1
from
    classes 
        inner join
    (select * from inserted union select * from deleted) students
        on classes.classid=students.classid
        inner join 
    (select classid, count(*) as StudentCount from students group by classid) counts
        on students.classid = counts.classid

代替更新和对calc_count的调用

英文翻译......

  • 更新课程(设置修订和计数)
  • 在学生表中更改班级
  • 其中该班级是每班学生的一组学生

答案 1 :(得分:0)

嗯,你的触发器没有被触发的主要原因是因为你正在进行UPDATE,你的触发器是在INSERT和DELETE上进行的。

是的,UPDATE是DELETE和INSERT,但你必须把它放在你的足迹中:

AFTER DELETE, INSERT, UPDATE

而不是

AFTER DELETE, INSERT

接下来,在触发器本身中,您只有名为inserted和deleted的内部概念表,它们组合在一起为您提供更新。旧部分位于已删除的表中,新部分位于已插入的表中。

为什么要按顺序执行记录?使用完整的结果集更快!