简体   繁体   English

如何获取通过insert…select插入的行的标识?

[英]How can I retrieve the identities of rows that were inserted through insert…select?

I am inserting records through a query similar to this one: 我通过类似于此查询的查询插入记录:

insert into tbl_xyz select field1 from tbl_abc

Now I would like to retreive the newly generated IDENTITY Values of the inserted records. 现在,我想检索插入记录的新生成的IDENTITY值。 How do I do this with minimum amount of locking and maximum reliability? 如何以最小的锁定量和最大的可靠性做到这一点?

You can get this information using the OUTPUT clause. 您可以使用OUTPUT子句获取此信息。

You can output your information to a temp target table or view. 您可以将信息输出到临时目标表或视图。

Here's an example: 这是一个例子:

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

You can then query the table InsertedIDs for your inserted IDs. 然后,您可以在表InsertedIDs中查询所插入的ID。

@@IDENTITY will return you the last inserted IDENTITY value, so you have two possible problems @@ IDENTITY将返回您最后插入的IDENTITY值,因此您有两个可能的问题

  1. Beware of triggers executed when inserting into table_xyz as this may change the value of @@IDENTITY. 注意插入table_xyz时执行的触发器,因为这可能会更改@@ IDENTITY的值。

  2. Does tbl_abc have more than one row. tbl_abc是否有多于一行。 If so then @@IDENTITY will only return the identity value of the last row 如果是这样,则@@ IDENTITY将仅返回最后一行的标识值

Issue 1 can be resolved by using SCOPE__IDENTITY() instead of @@IDENTITY Issue 2 is harder to resolve. 可以通过使用SCOPE__IDENTITY()而不是@@ IDENTITY来解决问题1。问题2很难解决。 Does field1 in tbl_abc define a unique record within tbl_xyz, if so you could reselect the data from table_xyz with the identity column. tbl_abc中的field1是否在tbl_xyz内定义了唯一记录,如果这样,您可以使用标识列从table_xyz中重新选择数据。 There are other solutions using CURSORS but these will be slow. 还有其他使用CURSORS的解决方案,但是它们会很慢。

SELECT @@IDENTITY

This is how I've done it before. 这就是我之前所做的。 Not sure if this will meet the latter half of your post though. 不确定是否可以满足您帖子的后半部分。

EDIT 编辑
Found this link too, but not sure if it is the same... 也找到了此链接,但不确定是否相同...
How to insert multiple records and get the identity value? 如何插入多个记录并获取身份值?

As far as I know, you can't really do this with straight SQL in the same script. 据我所知,在同一脚本中使用纯SQL确实无法做到这一点。 But you could create an INSERT trigger. 但是您可以创建一个INSERT触发器。 Now, I hate triggers, but it's one way of doing it. 现在,我讨厌触发器,但这是做到这一点的一种方法。

Depending on what you are trying to do, you might want to insert the rows into a temp table or table variable first, and deal with the result set that way. 根据您要尝试执行的操作,可能需要先将行插入到临时表或表变量中,然后以这种方式处理结果集。 Hopefully, there is a unique column that you can link to. 希望有一个可以链接到的唯一列。

You could also lock the table, get the max key, insert your rows, and then get your max key again and do a range. 您还可以锁定表,获取最大键,插入行,然后再次获取最大键并进行范围设置。

Trigger: 触发:

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

Temp Table: 临时表:

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)

Key Range: 按键范围:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM