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