【问题标题】:Database Triggers: On Insert数据库触发器:插入时
【发布时间】:2011-11-23 12:14:57
【问题描述】:

这是一个简单的例子。

我想在Table1 (Name, Age, Sex) 中插入数据。该表在插入数据时会自动增加serial#(int)。

我想在Table1 insert 上放置一个触发器,以便在插入数据后,它会从Table1 中提取serial#(int) 并将Serial#Name 放入Table2 和@987654329 @ 和 some other data 中的 Table3

可以通过触发器实现吗?

或者,我应该从table1 中选择(最后一个)Serial 并通过手动增加它来调用其他表上的插入,在我曾经插入Table1 的同一SP 中?

哪种方法更好?

编辑 1:
假设表:

Serial | UID | Name | Age | Sex | DateTimeStamp
(int | uniqueidentifier | nvarchar | smallint | nchar | DateTime ) 

默认NewID() 和默认GetDate() 作为UIDDateTimeStampINSERTED 表会在 DatetimeStamp 字段中具有 Datetime-Of-Insertion 吗?意思是,我最初没有输入任何 Serial、GUID 或 DatetimeStamp,它们会出现在 INSERTED 表中吗?


编辑2: 你能给我指点关于触发器的好书/文章吗?我读了mastering SQL server 2005,并没有从中得到太多。谢谢!

【问题讨论】:

  • YES - 您的INSERTED将具有这些值!

标签: sql sql-server sql-server-2008 triggers


【解决方案1】:

当然,您可以使用触发器来执行此操作 - 类似于:

CREATE TRIGGER trg_Table1_INSERT
ON dbo.Table1 AFTER INSERT 
AS BEGIN
   INSERT INTO dbo.Table2(SerialNo, Name)
      SELECT SerialNo, Name
      FROM Inserted

   INSERT INTO dbo.Table3(SomeOtherCol)
      SELECT SomeOtherCol
      FROM Inserted
END

或者你需要在这里做的任何事情......

重要的是要了解触发器将被调用每个语句一次 - 而不是每插入行一次。因此,如果您有一个插入 10 行的语句,您的触发器将被调用一次,伪表 Inserted 将包含已插入语句中的这 10 行。

【讨论】:

  • 所以,T1 将有 10 行,INSERTED 将有 10 行,但 T2 和 T3 不会?你说的是这个吗?
  • @AnubhavSaini:是的,是的,不是的。是的,Table1 将有 10 行,因此,Inserted 将有 10 行。您需要考虑到这一点,例如您需要知道并相应地进行编程(许多开发人员总是假设Inserted 中只有一行)。不 - 使用我上面的代码,Table2Table3获得 10 个新行!
  • @marc_s 只是为了清楚起见,每个语句调用一次触发器,而不是每个批处理一次(除非可能是这种情况,批处理只是一个语句)
  • @RalphShillington:抱歉 - 是的,你是对的 - 每个语句一次。最重要的是:不是每行一次!对于许多总是认为Inserted 只是单行并执行SELECT FROM Inserted..... 并因多行而失败的人来说,这就是“杀手”
  • @marc_s,每次在Table1中插入都会将所有行从Inserted into Table2插入(INSERT INTO dbo.Table2(SerialNo, Name) SELECT SerialNo, Name FROM Inserted),这个不能接受!
【解决方案2】:

是的,这可以通过触发器实现。

当您使用INSERT 触发器时,您可以访问表示要插入的行的INSERTED 逻辑表,其中包含新ID 的值。

【讨论】:

    【解决方案3】:

    是的,可以通过触发器来实现,但请记住,TRIGGER 不接受任何输入,也不提供任何输出,因此您只能通过在触发器中查询来收集所需的数据,但要满足插入到你的 Table2 和 Table3

    CREATE TRIGGER tr_YourDesiredTriggerName ON Table1
     FOR INSERT
     AS
     BEGIN
        -- Inserting data to Table2
    INSERT INTO Table2( Serial, Name) 
       SELECT i.Serial, i.Name 
           FROM Table1 AS t1 INNER JOIN Inserted AS i ON t1.Serial = i.Serial
           AND i.Serial NOT IN  ( SELECT t2.Serial FROM Table2 AS t2 )
    
        -- Inserting data to Table3     
    INSERT INTO Table3( Serial, OtherData)  -- select from other table
       SELECT i.Serial, OtherData
           FROM OtherTable AS ot INNER JOIN Inserted AS i ON ot.Serial = i.Serial
           AND i.Serial NOT IN ( SELECT t3.Serial FROM Table3 AS t3 )
    END
    

    【讨论】:

      【解决方案4】:

      如果您无法控制插入源,请使用触发器。如果您确实可以控制插入源,则可以修改插入过程以添加辅助表行。

      您还可以控制未来的插入吗?如果为这个表创建了另一个插入怎么办?如果您使用触发器,那么辅助插入也将自动处理。如果不是,那么第二次插入过程可能会省略第二次插入。根据您的应用程序,这可能是好是坏。

      【讨论】:

        猜你喜欢
        • 2012-07-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-27
        • 1970-01-01
        相关资源
        最近更新 更多