使用触发器从 Table 插入记录多行数据
Recording Multiple Rows of Data from Table Insertion Using Trigger
我尝试创建一个触发器来将在我的 Food
table 上完成的数据操作存储在另一个名为 FoodTriggerTable
的 table 中。当我只插入一行数据时,我可以在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');
如何修复我的触发器,使其也记录第二行数据操作?
您需要考虑基于集合 - inserted
是一个 table,插入或更新的每条记录对应一行。像正常使用它一样使用它 table - 不要尝试将其转换为过程编程,例如
INSERT INTO FoodTriggerTable (FoodID, FoodName, FoodDesc, FoodPrice, InsertAction, InsertActionTime)
select FoodId, FoodName, FoodDesc, FoodPrice, null, getdate()
from Inserted
注意:现在每行 1 个时,不确定您想要什么 InsertAction - 由您决定。
编辑:程序实际上是正确的术语。在 T-SQL 中做事时,您通常是在操纵数据集,这是它的设计目的,因为它是一种数据库编程语言。所以通常你会尝试根据数据集来构建和解决问题。这在编写触发器时非常明显,因为 insert/update/delete 可能涉及任意数量的记录,您必须处理它。您当然可以使用游标和循环回到过程编程,但性能会受到影响。那里有很多关于这个的文章,这里是一个例子 https://www.sqlshack.com/introduction-set-based-vs-procedural-programming-approaches-t-sql/
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
我尝试创建一个触发器来将在我的 Food
table 上完成的数据操作存储在另一个名为 FoodTriggerTable
的 table 中。当我只插入一行数据时,我可以在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');
如何修复我的触发器,使其也记录第二行数据操作?
您需要考虑基于集合 - inserted
是一个 table,插入或更新的每条记录对应一行。像正常使用它一样使用它 table - 不要尝试将其转换为过程编程,例如
INSERT INTO FoodTriggerTable (FoodID, FoodName, FoodDesc, FoodPrice, InsertAction, InsertActionTime)
select FoodId, FoodName, FoodDesc, FoodPrice, null, getdate()
from Inserted
注意:现在每行 1 个时,不确定您想要什么 InsertAction - 由您决定。
编辑:程序实际上是正确的术语。在 T-SQL 中做事时,您通常是在操纵数据集,这是它的设计目的,因为它是一种数据库编程语言。所以通常你会尝试根据数据集来构建和解决问题。这在编写触发器时非常明显,因为 insert/update/delete 可能涉及任意数量的记录,您必须处理它。您当然可以使用游标和循环回到过程编程,但性能会受到影响。那里有很多关于这个的文章,这里是一个例子 https://www.sqlshack.com/introduction-set-based-vs-procedural-programming-approaches-t-sql/
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