SQL Server:插入触发器后更新另一个表

时间:2016-03-29 04:46:06

标签: sql sql-server triggers

我写了这个触发器,在数据插入CHECKINOUT表后将数据插入到另一个表中。

但它没有将数据插入Att_process表。 SQL Server中没有出现任何错误。你能帮我解决这个问题吗?

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TRIGGER [dbo].[trgAfterInsert] ON [dbo].[CHECKINOUT]
AFTER  INSERT 
AS
     DECLARE @uid INT;
     DECLARE @checkin DATETIME;

     SELECT @uid = i.USERID
     FROM [CHECKINOUT] i;

     SELECT @checkin = i.CHECKTIME
     FROM [CHECKINOUT] i;

     IF(DATEPART(HOUR, @checkin) < 12)
     BEGIN
        INSERT INTO Att_process (USERID, checkin_time)
        VALUES (@uid, @checkin);
     END;
     ELSE
     BEGIN
         INSERT INTO Att_process (USERID, checkout_time)
         VALUES (@uid, @checkin);
     END;

3 个答案:

答案 0 :(得分:2)

两个主要问题:

  • 您没有查看包含新插入行的Inserted伪表

  • 你假设每行调用一次触发器 - 这是的情况,触发器每语句调用一次,{{1伪表将包含多行 - 您需要处理

请尝试使用此代码:

Inserted

答案 1 :(得分:1)

正如许多SQL开发人员所做的那样,您遇到了与SQL Server触发器相同的错误。在表上执行多个insert语句时,您已经错过了这种情况。 触发器仅对SQL语句执行一次,而不是对每一行执行。 因此,触发器中的代码应该能够涵盖受SQL语句影响的所有行的所有任务。

以下是如何更改触发器代码的示例。

ALTER TRIGGER [dbo].[trgAfterInsert] ON [dbo].[CHECKINOUT]
AFTER  INSERT 
AS

INSERT INTO Att_process (USERID, checkin_time, checkout_time)
select
    USERID, 
    case when DATEPART(HOUR, CHECKTIME) < 12 then CHECKTIME else null end,
    case when DATEPART(HOUR, CHECKTIME) < 12 then null else CHECKTIME end
FROM inserted

要获得稳定的结果,请使用触发代码中可用的已插入和已删除内部表。

您可以进一步检查样本SQL Trigger to log changes,了解如何使用已删除和已插入的表格。

我希望能帮到你,

最后一点,如果您可以同时使用SQL Output clause to insert data into two tables。 但当然触发器在table base上工作,因此执行insert语句时触发器工作。如果使用Output子句,则应保证将数据插入该表的唯一SQL语句是保持两个表之间的一致性。

答案 2 :(得分:-1)

试试这个,因为你没有使用&#39;插入&#39;魔术表提取最后插入的数据。

 DECLARE @uid INT;
 DECLARE @checkin DATETIME;

 SELECT @uid = USERID  FROM inserted   

 SELECT @checkin = CHECKTIME FROM inserted