首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQL Server :更新另一个表的After Insert触发器

SQL Server :更新另一个表的After Insert触发器
EN

Stack Overflow用户
提问于 2016-03-29 12:46:06
回答 3查看 10.8K关注 0票数 0

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

但是它不会向Att_process表中插入数据。SQL Server中未显示任何错误。你能帮我解决这个问题吗?

代码语言:javascript
复制
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;
EN

回答 3

Stack Overflow用户

发布于 2016-03-29 12:56:23

两个主要问题:

  • 您看到的不是包含新插入行的Inserted伪表,而是假设触发器每行调用一次- this is
  • 这种情况,触发器在每个语句中调用一次,Inserted伪表将包含多行-您需要处理

因此,请尝试以下代码:

代码语言:javascript
复制
CREATE TRIGGER [dbo].[trgAfterInsert] ON [dbo].[CHECKINOUT]
AFTER  INSERT 
AS
    -- grab all the rows from the "Inserted" pseudo table
    -- and insert into the "checkin_time" column, if the value
    -- of the HOUR is less than 12
    INSERT INTO Att_process (USERID, checkin_time)
        SELECT  
            i.USERID, i.CHECKTIME
        FROM  
            Inserted i
        WHERE
            DATEPART(HOUR, i.CHECKTIME) < 12

    -- grab all other rows (HOUR is greater than or equal to 12)
    -- and insert into the "checkout_time" column
    INSERT INTO Att_process (USERID, checkout_time)
        SELECT  
            i.USERID, i.CHECKTIME
        FROM  
            Inserted i
        WHERE
            DATEPART(HOUR, i.CHECKTIME) >= 12
票数 2
EN

Stack Overflow用户

发布于 2016-03-29 15:23:01

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

下面是一个如何修改触发器代码的示例。

代码语言:javascript
复制
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的话。当然,触发器是在表的基础上工作的,所以在执行insert语句的任何地方,触发器都会工作。如果使用Output子句,则应该保证将数据插入到该表中的唯一SQL语句是用于维护两个表之间的一致性。

票数 1
EN

Stack Overflow用户

发布于 2016-03-29 14:44:18

试试这个,因为您没有使用' inserted‘魔术表来提取最后插入的数据。

代码语言:javascript
复制
 DECLARE @uid INT;
 DECLARE @checkin DATETIME;

 SELECT @uid = USERID  FROM inserted   

 SELECT @checkin = CHECKTIME FROM inserted 
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36275638

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档