【问题标题】:SQL Inserted table triggerSQL 插入表触发器
【发布时间】:2020-05-09 14:25:05
【问题描述】:

如果我在插入触发器中运行以下 select 语句,它是否有可能返回多个结果?: DECLARE @variable char(1) = (SELECT ID FROM insert) 如果是这样,那么最好的处理方法是什么?

这是我要解决的问题:每次将新记录插入表时,我都想将新插入的 ID 插入另一个表(如果它不存在)。

谢谢!

【问题讨论】:

  • 这不仅是可能的,而且很有可能,而且这样的代码完全是错误的(因为有一个错误等待发生)。处理它的正确方法是不要将 inserted 中的值分配给变量。您需要在问题中提供更多信息才能获得更好的答案。
  • 你可以使用 SCOPE_IDENTITY()
  • 除了 SCOPE_IDENTITY() 返回一个 标量 值,@user3510665 和 INSERT 可以影响 1 到 ∞ 行。如果再插入 2 个(它们可以并且将会插入),则会出现与为变量赋值相同的问题。 inserted 包含数据集,应视为数据集。
  • 使用INSERT...SELECT...FROM inserted WHERE NOT EXISTS 或类似的MERGE 语句有条件地从inserted 插入多行。

标签: sql sql-server


【解决方案1】:

代替

DECLARE @variable char(1) = (SELECT ID FROM inserted) 

您可以执行以下操作:

Declare @VarTempTbl as table (id int)

Insert into @VarTempTbl (id)
Select id from inserted

这样您就可以获取这些值以进行进一步处理

【讨论】:

  • 所以最后我猜我还是要循环遍历一组数据?谢谢!
【解决方案2】:

现在,我创建了两个表,一个用于主表,另一个用于当主表中发生任何插入时,该条目必须插入到另一个表中。

CREATE TABLE tblEmployee
(
Id int Primary Key,
Name nvarchar(30),
Gender nvarchar(10),
DepartmentId int
)

CREATE TABLE tblEmployee_New
(
Id int Primary Key,
Name nvarchar(30),
Gender nvarchar(10),
DepartmentId int
)

触发器:

CREATE TRIGGER TR_EMPLOYEEDETAILS_AFTEROFINSERT
ON TBLEMPLOYEE
AFTER INSERT
AS
BEGIN

TRUNCATE TABLE tblEmployee_New

INSERT INTO TBLEMPLOYEE_NEW(ID, NAME, GENDER, DEPARTMENTID)
SELECT ID, NAME, GENDER, DEPARTMENTID
FROM INSERTED 

END

现在让我们尝试将记录插入到主表中

Insert into tblEmployee values (1,'John', 'Male', 3)
Insert into tblEmployee values (2,'Mike', 'Male', 2)

它已经自动将新插入的记录插入到另一个表中。 如果您想删除以前的记录,请在上面的触发器中添加一个 drop 语句。

注意:您也可以使用#Temp Table 而不是创建另一个表('tblEmployee_New')

Kinldy 分享你的 cmets

【讨论】:

  • 非常感谢您的回复!现在,如果不截断 tblEmployee_New 表,您将如何做到这一点?
  • 是的,您可以简单地在该触发器中注释该 Truncate 语句。如果你这样做,你的 'tblEmployee_New' 还包含以前插入的行——你需要那些吗?我只使用它来获取新插入的行 - 如果您还需要以前的记录,那么您可以评论 Truncate Stmt。 @Redskin
猜你喜欢
  • 2011-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-09
  • 1970-01-01
相关资源
最近更新 更多