Tsql 从SQL insert语句中获取新的uniqueidentifier的最佳方法,同时还要确定插入的成功或失败?

Tsql 从SQL insert语句中获取新的uniqueidentifier的最佳方法,同时还要确定插入的成功或失败?,tsql,uniqueidentifier,identity-column,rowcount,output-clause,Tsql,Uniqueidentifier,Identity Column,Rowcount,Output Clause,我开始使用UniqueIdentifier,遇到了一个意想不到的问题 首先,在我通常使用SCOPE_IDENTITY()的情况下,对于uniqueidentifier,这已经不可能了,尽管在概念上,它仍然涉及自动生成的id值,这是默认(newid()或newsequentialid()约束的结果 我决定在INSERT语句中使用OUTPUT子句将UUID输出到表变量。现在我想了想,OUTPUT子句使SCOPE_IDENTITY过时了,因为它是一种更清晰、更强大的方法,可以实现同样的效果,甚至更多(

我开始使用UniqueIdentifier,遇到了一个意想不到的问题

首先,在我通常使用SCOPE_IDENTITY()的情况下,对于uniqueidentifier,这已经不可能了,尽管在概念上,它仍然涉及自动生成的id值,这是默认(newid()或newsequentialid()约束的结果

我决定在INSERT语句中使用OUTPUT子句将UUID输出到表变量。现在我想了想,OUTPUT子句使SCOPE_IDENTITY过时了,因为它是一种更清晰、更强大的方法,可以实现同样的效果,甚至更多(例如,为所有插入的行获得对多个自动生成列的清晰、直接访问)

但是,使用输出后,我现在想知道这会如何影响通常在插入之后进行的@rowcount测试。@rowcount会反映在main语句中插入的行数还是由output子句插入到表变量中的行数

您可能会认为它不会有什么不同(即计数应该是相同的),但它确实会有不同,因为它表示,即使insert语句失败,OUTPUT子句也会返回值并填充表

包含OUTPUT子句的UPDATE、INSERT或DELETE语句将 即使语句遇到错误和错误,也将行返回给客户端 被向后滚动。如果在以下情况下发生任何错误,则不应使用结果: 你运行这个声明

它确实提到了@rowcount只在使用OUTPUT时才会反映最外面的语句,但它提到这是嵌套查询的上下文。因为我的例子中的OUTPUT子句是最外层语句的一部分,所以不清楚如果insert语句失败,@rowcount是否会报告插入到输出表中的行数

declare@new_uuid表(ID uniqueidentifier);
插入用户(ID、PersonID、用户名、密码、备注、已启用)
将输出INSERTED.UUID插入@new_UUID
值(@id、@personid、@username、@password、@notes、@enabled)
如果(@@rowcount 1)转到失败--这是否反映了插入到用户或@new_uuid中的行?如果插入失败,行仍然输出到@new_uuid,该怎么办?

我已经通过以下TSQL代码对这种行为进行了实验测试:

create function NEWOBJECTID() returns int as begin return 1 / 0; end --function that would typically perform work to create a new object id, but intentionally throws an error instead
go

declare @uuidtable table (UUID uniqueidentifier);

insert into Users (ID)
output INSERTED.UUID into @uuidtable --UUID column has default constraint of (newid())
values (dbo.NEWOBJECTID()); --value to insert will throw an error

print @@rowcount; --called immediately after statement to see how it was affected by the failure
select * from @idtable; --see if anything was output into the table variable

此语句的结果是@rowcount返回零,并且@uuidtable变量中存在零行,但请继续阅读,因为此结果有误导性

起初,这让我相信,由于没有插入任何行,因此不会发生输出。这是错误的,一个简单的修改就证明了这一点

insert into Users (ID)
output INSERTED.UUID into @uuidtable --UUID column has default constraint of (newid())
values
(1), --value to insert should succeed
(2), --value to insert should succeed
(dbo.NEWOBJECTID()); --value to insert will throw an error
当我这次运行它时@@rowcount仍然是零;但是,带有两个新的唯一标识符的2行被输出到@uuiddable中

这表示@rowcount反映了插入的最终行数,即零,因为尽管前两个值已成功插入并输出到@uuidtable,但由于该错误,整个语句已回滚


由于在输出表中插入了两行,但由于语句失败,最终插入了零行,@rowcount报告为零,这证明它反映的是insert语句本身插入的行数,而不是沿途插入到输出表中的行数。这也证实了文档中所说的,即使整个语句失败,行也会被输出。

行数是否会反映插入主语句的行数,或者OUTPUT子句插入表变量的行数?
这不是胡闹,但您试过了吗?这似乎是对一些容易验证的东西的大量的总结;尽管我可以/将要/已经测试并找到了答案,但出于社区的利益,我还是发布了这个问题,这样,如果其他人遇到这种情况,这个记录可以帮助他们。同时,即使我通过实验验证了这一行为,这也不能回答是否有更好的方法来获取值,或者有更好的方法来检查语句是否成功的问题。问题是如何最好地完成这项简单的任务,同时也展示了如何产生复杂的问题。有效的推理,请投赞成票!重要提示:您的报价中提到的文档“即使语句遇到错误并回滚,输出子句也会将行返回给客户机。”请注意,我强调的是“客户机”,如果您的
输出是一个表,那么它将与其他所有内容一起有效回滚,不会向输出目标表中添加新行。