62

我正在从另一个表 B 向表 A 中插入多条记录。有没有办法在不使用游标的情况下获取表 A 记录的标识值并更新表 b 记录?

Create Table A
(id int identity,
Fname nvarchar(50),
Lname nvarchar(50))

Create Table B
(Fname nvarchar(50),
Lname nvarchar(50),
NewId int)

Insert into A(fname, lname)
SELECT fname, lname
FROM B

我正在使用 MS SQL Server 2005。

4

8 回答 8

166

使用 2005 年的输出子句:

DECLARE @output TABLE (id int)

Insert into A (fname, lname)
OUTPUT inserted.ID INTO @output
SELECT fname, lname FROM B

select * from @output

现在您的表变量具有您插入的所有行的标识值。

于 2008-09-19T09:14:42.550 回答
5

仔细阅读您的问题,您只想根据表 A 中的新标识值更新表 B。

插入完成后,只需运行更新...

UPDATE B
SET NewID = A.ID
FROM B INNER JOIN A
     ON (B.FName = A.Fname AND B.LName = A.LName)

这假定 FName / LName 组合可用于键匹配表之间的记录。如果不是这种情况,您可能需要添加额外的字段以确保记录正确匹配。

如果您没有允许您匹配记录的备用键,那么它根本没有意义,因为表 B 中的记录无法相互区分。

于 2008-09-18T19:48:26.480 回答
1

据我了解,您遇到的问题是您想要插入到具有标识列的表 A 中,并且您想要保留没有标识列的表 B 中的标识。

为此,您只需要在表 A 上打开身份插入。这将允许您在插入时定义您的 ID,只要它们不冲突,您应该没问题。然后你可以这样做:

Insert into A(identity, fname, lname) SELECT newid, fname, lname FROM B

不确定您使用的是什么数据库,但对于 sql server,打开身份插入的命令将是:

set identity_insert A on
于 2008-09-18T19:32:35.740 回答
1

我建议使用 uniqueidentifier 类型而不是身份。在这种情况下,您可以在插入之前生成 ID:

update B set NewID = NEWID()

insert into A(fname,lname,id) select fname,lname,NewID from B
于 2008-09-18T19:51:13.527 回答
0

如果您总是想要这种行为,您可以在 TableA 上放置一个 AFTER INSERT 触发器来更新表 B。

于 2008-09-18T19:26:27.813 回答
0

您可以通过加入行号来获得。这是可能的,因为它是一个标识,它只会随着您添加项目而增加,这将按照您选择它们​​的顺序。

于 2008-09-18T19:29:02.970 回答
0
-- first create a table for show how its works
CREATE TABLE [dbo].[myTable]
  (
     [id]   [INT] IDENTITY(1, 1) NOT NULL,
     [text] [VARCHAR](10) NULL
  )
ON [PRIMARY]

GO

-- var table for keep new inserted id
DECLARE @tblNewInserted TABLE
  (
     newids INT
  )

--use the output clause in insert statement
INSERT INTO [dbo].[myTable]
output      inserted.id
INTO @tblNewInserted
VALUES      ('aa'),('bb'),('cc')

SELECT *
FROM   @tblNewInserted 
于 2020-12-15T12:11:44.437 回答
-7

MBelly 是正确的 - 但是触发器将始终尝试更新表 B,即使这不是必需的(因为您也是从表 C 插入的?)。

Darren 在这里也是正确的,您不能将多个身份作为结果集返回。您的选择是使用游标并为您插入的每一行获取标识,或者使用 Darren 的方法在前后存储标识。只要您知道身份的增量,这应该可以工作,只要您确保表针对所有三个事件都已锁定。

如果是我,而且时间不紧迫,我会选择光标。

于 2008-09-18T19:52:48.890 回答