我开始使用uniqueidentifiers,我遇到了一个意想不到的问题。
首先,在我通常使用SCOPE_IDENTITY()的地方,使用uniqueidentifier不再可能,即使在概念上它仍然涉及默认的结果(newid()或者自动生成的id值。 newsequentialid())约束。
我决定使用INSERT语句中的OUTPUT子句将UUID输出到表变量。现在我考虑一下,OUTPUT子句使SCOPE_IDENTITY过时,考虑到它是一种更清晰,更强大的方法来实现同样的事情和更多(例如,获得对所有插入行的多个自动生成列的清晰和直接访问)。 / p>
然而,使用OUTPUT,我现在想知道它是如何影响通常在插入之后的@@ rowcount的测试。 @@ rowcount是否会反映主语句中插入的行数或者输出子句插入表变量的行数?
您可能认为它不会产生任何影响(即计数应该是相同的两种方式),但确实有所不同,因为documentation表示OUTPUT子句将返回值并填充表,即使插入语句失败。
具有OUTPUT子句的UPDATE,INSERT或DELETE语句 即使语句遇到错误,也会将行返回给客户端 回滚。如果发生任何错误,则不应使用该结果 你运行声明。
确实提到@@ rowcount特别是在使用OUTPUT时总是反映最外面的语句,但它提到这是嵌套查询的上下文。由于我的OUTPUT子句是最外层语句的一部分,因此如果insert语句失败,则不清楚@@ rowcount是否会报告插入到输出表中的行数。
declare @new_uuid TABLE (ID uniqueidentifier);
insert into Users (ID, PersonID, Username, Password, Notes, Enabled)
output INSERTED.UUID into @new_uuid
values (@id, @personid, @username, @password, @notes, @enabled )
if (@@rowcount <> 1) goto fail; --does this reflect rows inserted into Users or @new_uuid? What if the insert fails, and rows are still output to @new_uuid?
答案 0 :(得分:3)
我已通过以下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变量中存在零行,但请继续阅读,因为此结果具有误导性。
首先,这让我相信,由于没有插入行,因此不会发生OUTPUT。这是错误的,一个简单的修改就证明了这一点。
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仍为零;但是,带有两个新uniqueidentifier的2行输出到@uuidtable。
这表明@@ rowcount反映了插入的最终行数,为零,因为虽然前两个值已成功插入并且OUTPUT已插入@uuidtable,但整个语句由于以下原因而被回滚:错误。
由于在OUTPUT表中插入了两行,但由于语句失败而最终插入了零行,并且@@ rowcount报告为零,这证明它反映了insert语句本身插入的行数而不是比沿途插入OUTPUT表的行数。这也证实了文档说的内容,即使整个语句失败,行也将是OUTPUT。