使用触发器

时间:2018-10-31 05:23:14

标签: sql-server triggers

我尝试创建一个触发器来将在我的Food表上完成的数据操作存储在另一个称为FoodTriggerTable的表中。当我仅插入一行数据时,我可以在FoodTriggerTable中很好地记录数据操作。但是,一次插入多行时,仅存储第一行数据的信息。我有以下触发器:

CREATE TRIGGER InsertFoodTrigger ON Food
AFTER INSERT
AS
    DECLARE @FoodID varchar(5);
    DECLARE @FoodName nvarchar(50);
    DECLARE @FoodDesc nvarchar(200);
    DECLARE @FoodPrice money;
    DECLARE @InsertAction varchar(200);
    DECLARE @InsertActionTime datetime;
    DECLARE @Amount int;

    SELECT @FoodID = i.FoodID FROM INSERTED i;
    SELECT @FoodName = i.FoodName FROM INSERTED i;
    SELECT @FoodDesc = i.FoodDesc FROM INSERTED i;
    SELECT @FoodPrice = i.FoodPrice FROM INSERTED i;
    SELECT @Amount = COUNT(*) FROM INSERTED i;

    SET @InsertAction = 'You''ve inserted ' +  CONVERT(varchar(10), @Amount) + ' data into ''Food'' table';

    INSERT INTO FoodTriggerTable (FoodID, FoodName, FoodDesc, FoodPrice, InsertAction, InsertActionTime)
    VALUES (@FoodID, @FoodName, @FoodDesc, @FoodPrice, @InsertAction, GETDATE());
GO

然后我尝试了以下INSERT

INSERT INTO Food
VALUES  ('CH006', 'Dummy Data 1', 'Dummy data', '0', '34'),
        ('CH007', 'Dummy Data 2', 'Dummy data', '0', '75');

如何修复触发器,使其同时记录第二行数据操作?

2 个答案:

答案 0 :(得分:3)

您需要考虑基于集合的情况-插入的是一个表,每个插入或更新的记录都有一行。就像使用普通表一样使用它-不要尝试将其转换为函数式编程,例如

INSERT INTO FoodTriggerTable (FoodID, FoodName, FoodDesc, FoodPrice, InsertAction, InsertActionTime)
  select FoodId, FoodName, FoodDesc, FoodPrice, null, getdate()
  from Inserted

注意:现在每行1个时,不确定要使用哪个InsertAction-由您决定。

编辑:程序实际上是正确的术语。在使用T-SQL进行操作时,通常会操纵数据集,这是它设计的目的,因为它具有数据库编程语言。因此,通常您会尝试根据数据集来框架化并解决您要解决的问题。在编写触发器时,这非常明显,因为插入和更新/删除可能涉及任意数量的记录,因此您必须处理该记录。当然,您可以使用游标和循环来回退到过程编程,但是性能会受到影响,我想它并不是这样做的方法:)有很多文章,这里有一个示例https://www.sqlshack.com/introduction-set-based-vs-procedural-programming-approaches-t-sql/

答案 1 :(得分:1)

CREATE TRIGGER InsertFoodTrigger ON Food
AFTER INSERT
AS
    INSERT INTO FoodTriggerTable (FoodID, FoodName, FoodDesc, FoodPrice, InsertAction, InsertActionTime)
    SELECT FoodID, FoodName, FoodDesc, FoodPrice, 'You''ve inserted ' +  CONVERT(varchar(10), (SELECT COUNT(*) FROM inserted)) + ' data into ''Food'' table', GETDATE()
    FROM inserted
GO