4

我正在通过与此类似的查询插入记录:

insert into tbl_xyz select field1 from tbl_abc

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

4

4 回答 4

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

然后,您可以在 InsertedIDs 表中查询您插入的 ID。

于 2009-02-22T17:34:56.230 回答
2

@@IDENTITY 会返回你最后插入的 IDENTITY 值,所以你有两个可能的问题

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

  2. tbl_abc 是否不止一行。如果是这样,那么@@IDENTITY 将只返回最后一行的标识值

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

于 2009-02-22T17:37:47.517 回答
1
SELECT @@IDENTITY

这就是我以前的做法。不过,不确定这是否会满足您帖子的后半部分。

编辑
也找到了这个链接,但不确定它是否相同......
如何插入多条记录并获取标识值?

于 2009-02-22T17:23:37.253 回答
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
于 2009-02-22T17:51:40.587 回答