2013-01-02 89 views
3

此问题之前已被问过......但我似乎无法找到我正在寻找的确切答案......我需要插入一堆记录并取回插入的标识值...我这样做:TSQL获取插入的ID

INSERT MyTable(col1, ....) 
OUTPUT inserted.IdentityColumn 
SELECT p.i.value('@XmlAttribute', 'nvarchar(128)') FROM @myXml.nodes('/root/i') AS p(i) 

这工作得很好......

输入SQL事务复制与更新订阅,这使对用户复制表上的触发器。

输出不再在这种情况下工作...

所以,现在我在做这个......但我有一种不好的预感在我的这个直觉,我觉得我已经打开大门一个并发问题(虽然我不积极)。

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 
DECLARE @currentIdentity bigint 
SET @currentIdentity = SELECT IDENT_CURRENT('MyTable') + 1 
... 
SELECT IdentityColumn FROM MyTable WHERE IdentityColumn <= IDENT_CURRENT('MyTable') AND IdentityColumn >= @currentIdentity 

建议?这也很糟糕,因为该方法不适用于生成的uniqueidentifiers。

+0

为什么您的第一条语句不能用于复制?似乎它是第二个由于ID分区而复制的问题。 – RBarryYoung

+1

如果表上有任何触发器,则不能使用OUTPUT语法。 – Jeff

回答

4

您可以使用插入到表变量中的OUTPUT变体。从documentation

如果OUTPUT子句指定而未同时指定INTO关键字,DML操作的目标不能有它对于给定的DML操作定义任何启用的触发器。例如,如果在UPDATE语句中定义OUTPUT子句,则目标表不能有任何已启用的UPDATE触发器。

重点加)

所以,你可以有:

DECLARE @IDs table (ID int not null) 
INSERT MyTable(col1, ....) 
OUTPUT inserted.IdentityColumn INTO @IDs 
SELECT p.i.value('@XmlAttribute', 'nvarchar(128)') FROM @myXml.nodes('/root/i') AS p(i) 

SELECT * from @IDs 

这将有大致相同的行为原来,除非你正在处理例如行计数消息。

+0

但是后来我无法获得身份证明......不是吗? – Jeff

+0

@ JeffN825 - 我不确定你在问什么。如果你的第一个查询(使用'OUTPUT'没有'INTO')产生你想要的结果集,那么我显示的查询(修改为包含'INTO')应该产生完全相同的结果。即使表格上定义了触发器,它也会工作,这就是您说的问题所在。 –

+0

我看,现在试着,谢谢! – Jeff