执行插入语句后,我要么选择
我不明白这为什么会发生。
你能想到原因吗?
SCOPE_IDENTITY
或者 @@IDENTITY
。
SCOPE_IDENTITY
返回 null 但是 @@IDENTITY
不会。我不明白这为什么会发生。
你能想到原因吗?
SCOPE_IDENTITY
或者 @@IDENTITY
。
SCOPE_IDENTITY
返回 null 但是 @@IDENTITY
不会。下面是一个使用 SCOPE_IDENTITY() 返回 null 但 @@IDENTITY 返回值的示例:
插入数据到一个没有标识列的表中, 这个表有一个插入触发器, 触发器会在一个带标识列的历史记录表中插入一条记录。 在本地作用域中,SCOPE_IDENTITY() 将返回 null(因为没有标识列), 但是 @@IDENTITY 将报告触发器中的标识列值。
请注意,SCOPE_IDENTITY() 存在已知的 bug:https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=328811
最好的解决方案是使用 OUTPUT INTO 来处理标识列,它可以捕获一组 ID 并且不受 SCOPE_IDENTITY() Bug 的影响:
declare @x table (tableID int identity not null primary key, datavalue varchar(10))
declare @y table (tableID int, datavalue varchar(10))
INSERT INTO @x values ('aaaa')
INSERT INTO @x values ('bbbb')
INSERT INTO @x values ('cccc')
INSERT INTO @x values ('dddd')
INSERT INTO @x values ('eeee')
INSERT INTO @x
(datavalue)
OUTPUT INSERTED.tableID, INSERTED.datavalue --<<<<OUTPUT INTO SYNTAX
INTO @y --<<<<OUTPUT INTO SYNTAX
SELECT
'value='+CONVERT(varchar(5),dt.NewValue)
FROM (SELECT id as NewValue from sysobjects where id<20) dt
ORDER BY dt.NewValue
select * from @x
select * from @y
SCOPE_IDENTITY()
在99%的情况下都可以正常工作。再次强调,这一切都是正确的,但对于那些仍在学习@@IDENTITY
和SCOPE_IDENTITY()
之间区别的人来说,可能有点压力。 - Aaronaught@x
是目标表,数据将进入该表,而 @y
是为收集插入到最终 INSERT
语句中的 @x
中的每个新行的 ID 而创建的表。来自 OUTPUT
语句的数据进入其后面的 INTO
,而不是前面的 INTO
。 - Matt ArnoldKM说得非常到位:
@@IDENTITY
会给你返回最后一个插入的自增长ID值,并不管它是在哪张表中被插入的(需要考虑触发器,例如用于审计表,甚至有一系列嵌套的触发器……)
SCOPE_IDENTITY()
则会返回在当前语句所处范围内最后一个被插入表的自增长ID,也就是那些被当前语句实际引用的表的ID(而不是所有被触发器更新过的表的ID)
SCOPE_IDENTITY()
会给你当前作用域内最后一个IDENTITY
- 可能没有,所以你会得到NULL
。但是如果你在一个没有IDENTITY
的表上进行插入,然后触发器被触发,可能会将审计数据插入到另一个表中(该表具有IDENTITY
列),那么@@IDENTITY
将返回该值(来自审计表)。这对你有意义吗?所以请撤销那个踩踏 - 它完全没有必要... - marc_s当使用sp_executesql进行插入时,SCOPE_IDENTITY将返回NULL,因为你已经不在插入的作用域内了!
Context.Database.ExecuteSqlCommand("INSERT ...")
进行插入时,它会使用sp_executesql包装命令,因此丢失了scope_identity。 - Marcos Dimitrio我在MSDN上找到了这个:
如果在范围内尚未发生对标识列的任何INSERT语句调用函数,则SCOPE_IDENTITY()函数将返回null值。
您可以在此阅读:http://msdn.microsoft.com/en-us/library/ms190315.aspx
您的SQL代码将非常有帮助。
INSTEAD OF INSERT
触发器的原因,SCOPE_IDENTITY()
和 OUTPUT INTO
都无法使用。解决方案是重新设计触发器使其成为 AFTER INSERT
- 幸运的是,在我的情况下我能够这样做。