0

我发现了一个新问题:我有两个表ClassesStudents学生通过[ClassID]列引用班级。有名为[Count]的列,它存储引用学生的计数,我正在尝试通过学生表上的AFTER INSERT,DELETE触发器更新它。我写了一个简单的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 的兼容模式。

4

2 回答 2

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

一个英文翻译...

  • 更新类(设置修订和计数)
  • 在学生表中更改班级的位置
  • 该班级在每个班级的学生人数集中
于 2012-08-02T21:00:47.047 回答
0

好吧,您的触发器没有被触发的主要原因是因为您正在执行更新,而您的触发器正在执行 INSERT 和 DELETE。

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

AFTER DELETE, INSERT, UPDATE

代替

AFTER DELETE, INSERT

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

顺便说一句,为什么要逐条执行?使用完整的结果集执行此操作要快得多!

于 2012-08-03T10:01:10.357 回答