我写了这个触发器,在数据插入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;
答案 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