如何检索通过insert ... select插入的行的标识?

时间:2009-02-22 17:21:13

标签: sql sql-server identity

我通过类似于此的查询插入记录:

insert into tbl_xyz select field1 from tbl_abc

现在我想要检索插入记录的新生成的IDENTITY值。如何以最小的锁定量和最大的可靠性来做到这一点?

4 个答案:

答案 0 :(得分:19)

您可以使用OUTPUT子句获取此信息。

您可以将信息输出到临时目标表或视图。

以下是一个例子:

DECLARE @InsertedIDs TABLE (ID bigint)
INSERT into DestTable (col1, col2, col3, col4)
OUTPUT INSERTED.ID INTO @InsertedIDs
SELECT col1, col2, col3, col4 FROM SourceTable

然后,您可以查询已插入ID的表InsertedID。

答案 1 :(得分:2)

@@ IDENTITY将返回最后插入的IDENTITY值,因此您有两个可能的问题

  1. 请注意插入table_xyz时执行的触发器,因为这可能会更改@@ IDENTITY的值。

  2. tbl_abc是否有多行。如果是这样,则@@ IDENTITY将仅返回最后一行的标识值

  3. 可以使用SCOPE__IDENTITY()代替@@ IDENTITY来解决问题1 问题2更难解决。 tbl_abc中的field1是否在tbl_xyz中定义了唯一记录,如果是这样,您可以使用标识列重新选择table_xyz中的数据。使用CURSORS还有其他解决方案,但这些解决方案会很慢。

答案 2 :(得分:1)

SELECT @@IDENTITY

这就是我以前做过的。不确定这是否会满足你后期的一半。

修改
也找到了这个链接,但不确定它是否相同...
How to insert multiple records and get the identity value?

答案 3 :(得分:1)

据我所知,你不能在同一个脚本中使用直接SQL来实现这一点。但是你可以创建一个INSERT触发器。现在,我讨厌触发器,但这是实现它的一种方式。

根据您要执行的操作,您可能希望首先将行插入临时表或表变量,然后以这种方式处理结果集。希望您可以链接到一个独特的列。

您还可以锁定表格,获取最大密钥,插入行,然后再次获取最大密钥并执行范围。

<强>触发:

--Use the Inserted table.  This conaints all of the inserted rows.
SELECT * FROM Inserted

临时表:

insert field1, unique_col into #temp from tbl_abc

insert into tbl_xyz (field1, unique_col) select field1, unique_col from tbl_abc

--This could be an update, or a cursor, or whatever you want to do
SELECT * FROM tbl_xyz WHERE EXISTS (SELECT top 1 unique_col FROM #temp WHERE unique_col = tbl_xyz.unique_col)

关键范围:

Declare @minkey as int, @maxkey as int

BEGIN TRANS --You have to lock the table for this to work

  --key is the name of your identity column
  SELECT @minkey = MAX(key) FROM tbl_xyz
  insert into tbl_xyz select field1 from tbl_abc
  SELECT @maxkey = MAX(key) FROM tbl_xyz

COMMIT Trans

SELECT * FROM tbl_xyz WHERE key BETWEEN @minkey and @maxkey