Sql server SQL Server仅在更改时触发以更新计算列

Sql server SQL Server仅在更改时触发以更新计算列,sql-server,triggers,Sql Server,Triggers,对于时间安排项目,我有两个表:tbl_时隙,它保存可用时间,slotid作为主键,totalmembers统计此时隙的预约数量,tbl_预约,主键apptid保存实际预约,使用slotid作为链接到插槽信息的外键 我需要在创建/删除/更改约会时自动更新totalmembers列。我在下面编写的触发器不会更新tbl_时间段列totalmembers中的正确约会数 我只是稍微修改了一下触发器,它对我起了作用: CREATE TRIGGER [dbo].[tr_totalmembers] ON [d

对于时间安排项目,我有两个表:tbl_时隙,它保存可用时间,slotid作为主键,totalmembers统计此时隙的预约数量,tbl_预约,主键apptid保存实际预约,使用slotid作为链接到插槽信息的外键

我需要在创建/删除/更改约会时自动更新totalmembers列。我在下面编写的触发器不会更新tbl_时间段列totalmembers中的正确约会数


我只是稍微修改了一下触发器,它对我起了作用:

CREATE TRIGGER [dbo].[tr_totalmembers] 
ON [dbo].[TBL_appointments]
AFTER UPDATE, INSERT, DELETE 
AS 
BEGIN
UPDATE tbl_timeslots 
SET totalmembers = a.cnt 
from 
(
SELECT slotid,COUNT(1) as cnt 
 FROM tbl_appointments 
 group by slotid
 ) a
WHERE
   tbl_timeslots.slotid=a.slotid
 END
或者,如果有特定问题,请提及,以便我们进行研究。

计算totalmembers的更好方法是创建并使用索引视图:

CREATE VIEW dbo.vw_timeslots_with_totalmembers
WITH SCHEMA_BINDING
AS
SELECT  a.slotid, COUNT_BIG(*) AS totalmembers
FROM    dbo.tbl_appointments a
GROUP BY a.slotid
GO

CREATE UNIQUE CLUSTERED INDEX IUC_vw_timeslots_with_totalmembers_slotid
ON dbo.vw_timeslots_with_totalmembers (slotid)
GO

DECLARE @slotid INT = 123
SELECT  totalmembers
FROM    dbo.vw_timeslots_with_totalmembers WITH(NOEXPAND) -- This table hint is needed in order to force usage of indexed view
WHERE   slotid = @slotid
GO
注意:有关设置的正确配置,请阅读以下说明。请参阅“索引视图的必需设置选项”一节:


注2:如果最后一个SELECT语句返回0行,这意味着当前插槽没有约会,我假设当前插槽有效。

请编辑您的问题,将相关表格DDL包括在内,并解释什么不起作用。太低还是太高?是倍数吗?将“更新日期时间”列添加到目标表并将其更新为审核也很有帮助。如果使用您编写的触发器删除插入后的所有内容(包括插入的内容)时,如果我对tbl_约会进行任何更新,我会收到一个错误没有更新任何行,,,,,更新或删除的行值使该行不唯一或更改了多行3行。此外,请注意,tbl_约会上还有更多字段,大多数95%的更新不会更改slotid。因此,我只想更新字段totalmembers,如果在tbl_约会中更改了字段slotid,并且如果添加或删除了行,您可以更具体地说明您在tbl_约会中发布了什么更新,因为对我来说,它工作正常。首先,我尝试在tbl_约会中将slotid从1更改为零,以便记录,当这不起作用时,我试着在tbl_约会中编辑一个人的名字。在这两次更新中,我都遇到了相同的错误。我尝试了下面的更新,考虑到只有1%的tbl_约会更新在slotid字段中,所以两次更新都在进行元处理,在索引维护和锁问题方面,这个解决方案不会增加很多不必要的开销吗?任何索引都会带来开销,但这会小于触发器的开销。从我的观点来看,在这种情况下,与类似的命令式方法相比,任何声明性解决方案(例如索引视图)的开销都应该更小。
CREATE VIEW dbo.vw_timeslots_with_totalmembers
WITH SCHEMA_BINDING
AS
SELECT  a.slotid, COUNT_BIG(*) AS totalmembers
FROM    dbo.tbl_appointments a
GROUP BY a.slotid
GO

CREATE UNIQUE CLUSTERED INDEX IUC_vw_timeslots_with_totalmembers_slotid
ON dbo.vw_timeslots_with_totalmembers (slotid)
GO

DECLARE @slotid INT = 123
SELECT  totalmembers
FROM    dbo.vw_timeslots_with_totalmembers WITH(NOEXPAND) -- This table hint is needed in order to force usage of indexed view
WHERE   slotid = @slotid
GO