如何插入多个记录并获得标识值?
我正在从另一个表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.
解决方案
如果始终希望出现这种情况,则可以在TableA上放置一个AFTER INSERT触发器,该触发器将更新表B。
我们可以通过加入行号来获得。这是可能的,因为因为它是一个标识,所以它会随着我们添加项目的增加而增加,并且将按照我们选择它们的顺序进行。
据我了解,我们遇到的问题是我们想要插入具有标识列的表A,并且想要保留不具有表B的身份。
为此,我们只需要打开表A上的标识插入。这将允许我们定义插入时的ID,并且只要它们不冲突,就可以了。然后,我们可以执行以下操作:
Insert into A(identity, fname, lname) SELECT newid, fname, lname FROM B
不确定我们使用的是哪个数据库,但是对于sql server,打开标识插入的命令将是:
set identity_insert A on
仔细阅读问题,我们只想基于表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中的记录无法相互区分。
我建议使用uniqueidentifier类型而不是身份。在这种情况下,我们可以在插入之前生成ID:
update B set NewID = NEWID() insert into A(fname,lname,id) select fname,lname,NewID from B
MBelly是对的,但是即使不需要,触发器也将始终尝试更新表B(因为我们也是从表C插入?)。
达伦(Darren)在这里也是正确的,我们无法将多个身份作为结果集返回。选择是使用光标并为插入的每一行获取身份,或者使用Darren之前和之后存储身份的方法。只要我们知道标识的增量,它就应该起作用,只要我们确保该表对于所有三个事件都已锁定。
如果是我,而且不是时间紧迫的问题,那我就去找个游标。
使用2005年的ouput子句:
DECLARE @output TABLE (id int) Insert into A (fname, lname) OUTPUT inserted.ID INTO @output SELECT fname, lname FROM B select * from @output
现在,表变量具有我们插入的所有行的标识值。