C# 以良好的方式详细介绍format@VAAA很抱歉,到现在为止我还没注意到你对扳机的兴趣@RAMRS感谢您提出这一触发。两条注释:1)如果要忽略该行,我考虑的更多的是回滚。取决于VAAA是否真的需要保存行,或者“非活动”是否是一种解决方法。2) 我需要运行一
C# 以良好的方式详细介绍format@VAAA很抱歉,到现在为止我还没注意到你对扳机的兴趣@RAMRS感谢您提出这一触发。两条注释:1)如果要忽略该行,我考虑的更多的是回滚。取决于VAAA是否真的需要保存行,或者“非活动”是否是一种解决方法。2) 我需要运行一,c#,sql,sql-server-2012,C#,Sql,Sql Server 2012,以良好的方式详细介绍format@VAAA很抱歉,到现在为止我还没注意到你对扳机的兴趣@RAMRS感谢您提出这一触发。两条注释:1)如果要忽略该行,我考虑的更多的是回滚。取决于VAAA是否真的需要保存行,或者“非活动”是否是一种解决方法。2) 我需要运行一个测试用例来确定,但是我认为这个触发器将始终匹配新插入的记录,因为它们已经存在于tbl_时间戳中。我(或其他任何人)将研究另一种方法。我是否应该添加一个子句以排除当前记录?此外,我不建议使用回滚以避免任何数据丢失。非常努力。不幸的是,INSER
以良好的方式详细介绍format@VAAA很抱歉,到现在为止我还没注意到你对扳机的兴趣@RAMRS感谢您提出这一触发。两条注释:1)如果要忽略该行,我考虑的更多的是
回滚。取决于VAAA是否真的需要保存行,或者“非活动”是否是一种解决方法。2) 我需要运行一个测试用例来确定,但是我认为这个触发器将始终匹配新插入的记录,因为它们已经存在于tbl_时间戳中。我(或其他任何人)将研究另一种方法。我是否应该添加一个子句以排除当前记录?此外,我不建议使用回滚
以避免任何数据丢失。非常努力。不幸的是,INSERTED是一个表,所以一些连接语法是不正确的……我想他是说您不使用回滚的决定是好的,并鼓励您不要遵循我的建议:)CTE推动的单个语句更新
。并进行了测试。想想我的头脑正式被吹了!
CREATE TRIGGER trg_FindDups ON tbl_TimeStamp FOR INSERT
AS
BEGIN
DECLARE @CurrentMaxSwipeTime DATETIME
DECLARE @SwipeType
SELECT @SwipeType = EntranceType FROM INSERTED
IF (@SwipeType = 'O')
BEGIN
/* Employee is swiping OUT */
SELECT @CurrentMaxSwipeTime = MAX(T.TimeStamp) FROM tbl_TimeStamp T
WHERE T.EmployeeID = (SELECT EmployeeID FROM INSERTED) /* Same employee */
AND DATE(T.TimeStamp) = CAST(GETDATE() AS DATE) /* Same date */
AND DATEDIFF(minute,T.TimeStamp,GETDATE())<2 /* Within 2 minutes */
AND T.Status <> 'INACTIVE' /* of an active swipe */
AND T.EntraceType = 'O' /* Swiping out */
AND T.TimeStamp <> (SELECT TimeStamp FROM INSERTED) /* not the row we just inserted, H/T @mdisibio
IF @CurrentMaxSwipeTime IS NOT NULL
/* SET Status to INACTIVE */
UPDATE tbl_TimeStamp SET Status='INACTIVE' WHERE EmployeeID=(SELECT EmployeeID FROM INSERTED) AND TimeStamp=(SELECT TimeStamp FROM INSERTED)
END
ELSE
BEGIN
/* Employee is swiping in */
SELECT @CurrentMaxSwipeTime = MIN(T.TimeStamp) FROM tbl_TimeStamp T
WHERE T.EmployeeID = (SELECT EmployeeID FROM INSERTED) /* Same employee */
AND DATE(T.TimeStamp) = CAST(GETDATE() AS DATE) /* Same date */
AND DATEDIFF(minute,T.TimeStamp,GETDATE())<2 /* Within 2 minutes */
AND T.Status <> 'INACTIVE' /* of an active swipe */
AND T.EntraceType = 'I' /* Swiping in */
AND T.TimeStamp <> (SELECT TimeStamp FROM INSERTED) /* not the row we just inserted, H/T @mdisibio
IF @CurrentMaxSwipeTime IS NOT NULL
/* SET Status to INACTIVE */
UPDATE tbl_TimeStamp SET Status='INACTIVE' WHERE EmployeeID=(SELECT EmployeeID FROM INSERTED) AND TimeStamp=(SELECT TimeStamp FROM INSERTED)
END
END
CREATE TRIGGER TS_FindDups ON dbo.TS FOR INSERT
AS
BEGIN
;WITH DupRecords
AS
(
SELECT i.EmployeeId, i.[TimeStamp]
FROM inserted i
INNER JOIN dbo.TS SRC ON i.EmployeeId = SRC.EmployeeId AND i.EntranceType = SRC.EntranceType
WHERE SRC.[Status] != 'Inactive'
/* same day (nice...thanks to RamRS) */
AND CAST(i.[TimeStamp] AS date) = CAST(SRC.[TimeStamp] AS date)
/* only checking newer timestamps (also need this so DATEDIFF <= 2 works correctly) */
AND i.[TimeStamp] > SRC.[TimeStamp]
/* newer timestamps are less than two minutes for same Employee, same day, same EntranceType */
AND DATEDIFF(MINUTE, SRC.[TimeStamp], i.[TimeStamp]) <= 2
)
UPDATE dbo.TS
SET [Status] = 'Inactive'
FROM dbo.TS SRC
INNER JOIN DupRecords ON SRC.EmployeeId = DupRecords.EmployeeId AND SRC.[TimeStamp] = DupRecords.[TimeStamp]
END