重置 SCOPE_IDENTITY()
我有一个存储过程,它首先将一些数据插入到临时表中,然后将一行插入到另一个表中。我在第二次插入后调用 Scope_Identity() 以获取新插入的记录 Identity。
如果第二次插入由于连接而没有执行任何操作,我想检查 Scope_Identity 并引发异常。但 Scope_Identity 返回在第二次插入之前从临时表插入创建的最后一个标识。
有没有办法在调用第二次插入之前重置 SCOPE_IDENTITY,或者有更好的方法来确定第二次插入是否实际上没有插入任何内容?
I have a stored procedure that first inserts some data into a temp table and then inserts a row into another table. I am calling Scope_Identity() after the second insert to pick up the newly inserted record Identity.
If the second insert does nothing due to a join, I want to check the Scope_Identity and raise an exception. But Scope_Identity is returning the last identity created from the temp table insert before the second insert.
Is there a way to reset SCOPE_IDENTITY before calling the second insert, or a better way to determine if the second insert didn't actually insert anything?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
第二次插入后立即检查
@@ROWCOUNT
。如果为 0,则未插入任何行。Check
@@ROWCOUNT
immediately after the 2nd insert. If it is 0 then no rows were inserted.马丁·史密斯的回答完全回答了您的问题。
这显然是互联网上唯一询问如何重置 Scope_Identity() 的页面。
我相信这对于任何使用 T-SQL 的人来说都是至关重要的。
我将这个答案留给任何来这里的人(像我一样)寻找由上一个插入语句插入的身份(并且不是最后一个随机成功的身份插入)。
这就是我想出的:
Martin Smith's answer totally answers your question.
This is apparently the only page on the internet asking how to reset the Scope_Identity().
I believe this is vital for anyone working with T-SQL.
I am leaving this answer for anyone who came here (like me) looking for the identity that was inserted by the previous insert statement (and not the last randomly successful identity insert).
This is what I came up with:
我认为给出的其他答案可能更实用,但我确实想在这里记录我的发现,以防有一天它对某人有所帮助。 (这是在 SQL Server 2005 中;不确定这种行为在较新的版本中是否仍然存在。)
该技巧的基础是利用以下属性(来自
@@IDENTITY
的联机丛书文档):“ INSERT、SELECT INTO 或批量复制语句完成后,如果该语句没有影响任何具有标识列的表,则 @@IDENTITY 返回 NULL。”尽管我找不到明确的说明,但这种行为似乎也适用于 SCOPE_IDENTITY() 。因此,我们完成了一个INSERT
语句,该语句不会影响任何具有标识列的表:因此,对于您的情况,您似乎可以
在之前重置
SCOPE_IDENTITY()
执行第二个INSERT
。I think other answers given may be more practical, but I did want to record my finding here in case it helps someone some day. (This is in SQL Server 2005; not sure whether this behavior persists in newer versions.)
The basis of the trick is an exploitation of the following property (from Books Online's documentation of
@@IDENTITY
): "After an INSERT, SELECT INTO, or bulk copy statement is completed . . . If the statement did not affect any tables with identity columns, @@IDENTITY returns NULL." Although I can't find it explicitly stated, it appears that this behavior applies toSCOPE_IDENTITY()
as well. So, we complete anINSERT
statement that does not affect any tables with identity columns:So, for your case, it would seem that you could do
to reset
SCOPE_IDENTITY()
before performing your secondINSERT
.在考虑了几种替代方案后,我发现自己喜欢@BenThul对相关问题的回答:
正如你可以从我的文章中看到的最后的
SELECT CASE...
,在我的情况下,我试图以一个INT NOT NULL
结束,这将帮助我了解是否插入了一行(在这种情况下)我想要它的 ID)或不想要。 (如果可能的话,我一开始就不建议处于这种情况!)您将使用@result
做什么取决于您需要做什么。我喜欢 INSERT 和 @result 之间的关系是明确的,并且不太可能被我可能没有考虑到的其他干预操作所污染。我还喜欢
@result
自然地处理插入多行的情况。Having considered several alternatives, I find myself liking a riff on @BenThul's answer to a related question:
As you can see from my final
SELECT CASE...
, in my situation I was trying to end up with a singleINT NOT NULL
that would help me understand whether a row was inserted (in which case I wanted its ID) or not. (I would not recommend being in this situation in the first place, if possible!) What you would do with@result
depends on what you need to do.I like that the relationship between the
INSERT
and@result
is explicit and unlikely to be contaminated by other intervening operations I might not be thinking about. I also like that@result
naturally handles cases with more than one row inserted.MikeTeeVee的答案是我与马丁-史密斯的回答非常有力。
这是我的合并使用:
MikeTeeVee's answer which I found when combined with the answer from Martin-Smith's answer is very powerful.
Here is my merged use: