如何获取由 instead of insert 触发器插入的 table 标识?

How to get a table identity inserted by instead of insert trigger?

我有一个问题描述如下:我有一个 table 有一个而不是插入触发器:

create table TMessage (ID int identity(1,1), dscp varchar(50))
GO
Alter trigger tr_tmessage on tmessage
instead of insert
as

--Set NoCount On

  insert into tmessage
  select dscp from inserted
GO
Alter proc P1
As

--Set NoCount On

insert into tmessage
(dscp)
values('some data')

Select SCOPE_IDENTITY()

GO

当我执行 P1 时,它 returns Null for SCOPE_IDENTITY() 而不是 table 的标识。我什至在 proc 的插入语句中尝试了 Output 子句。但在这种情况下,Output 子句中插入的输出 table Identity 字段再次为 0。

如有任何帮助,我们将不胜感激。

SCOPE_IDENTITY() return 来自当前范围的值,它是存储过程之外的存储过程它将是 null.use @@identity 以获得最后插入的标识。

好吧,你有很多问题。
一方面,您需要 table 上的 instead of insert 触发器,但另一方面,您希望将此触发器生成的标识返回给激活它的存储过程。

由于无法向触发器发送参数或从触发器发送参数,您必须执行以下 3 件事之一:

  1. 找到一些方法来消除对触发器的需求。
    这是我最好的推荐。

  2. 将您的存储过程分为两部分:一部分将执行 insert into 语句(包括它)之前的所有操作,从而激活 instead of insert 触发器,另一部分这将执行触发后所需的所有操作。这样您就可以在 instead of insert 触发器中使用 scope_identity() 并将它的 return 值作为参数发送到第二个存储过程。
    注意:这种设计意味着您必须一条一条地插入记录。如果您尝试插入多条记录,scope_identity() 只会 return 触发器插入的最后一行的标识。

  3. 找到一些在存储过程和 instead of 触发器之间传递数据的方法。由于触发器无法使用 except 或 return 参数,因此您将不得不使用临时 table 或常规 table。这个建议的解决方案仅作为最后的手段建议,因为它会使您的代码复杂化,并且可能还会导致一些性能问题。此外,您还必须找到一种方法来保持存储过程的执行,直到 instead of 触发器完成它的工作。我可以给你一些关于如何在过程和触发器之间共享数据的指示,但我真的建议不要选择这种解决方案。