我要从另一个表B向表A中插入多个记录。是否有一种方法可以获取表A记录的标识值并在不使用游标的情况下更新表b记录?
1 2 3 4 5 6 7 8 9 10 11 12 13
| 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 Server2005。
使用2005年以来的ouput子句:
1 2 3 4 5 6 7
| DECLARE @output TABLE (id INT)
INSERT INTO A (fname, lname)
OUTPUT inserted.ID INTO @output
SELECT fname, lname FROM B
SELECT * FROM @output |
现在您的表变量具有您插入的所有行的标识值。
仔细阅读您的问题,您只想根据表A中的新标识值更新表B。
插入完成后,只需运行更新...
1 2 3 4
| UPDATE B
SET NewID = A.ID
FROM B INNER JOIN A
ON (B.FName = A.Fname AND B.LName = A.LName) |
这假定FName / LName组合可用于键匹配表之间的记录。如果不是这种情况,则可能需要添加其他字段以确保记录正确匹配。
如果没有备用键可以匹配记录,那么根本就没有意义,因为表B中的记录无法相互区分。
据我了解,您遇到的问题是您想要插入具有标识列的表A,并且想要保留不具有表B的身份。
为此,您只需要打开表A上的标识插入即可。这将允许您定义插入时的ID,只要它们不冲突,就可以了。然后,您可以执行以下操作:
1
| INSERT INTO A(IDENTITY, fname, lname) SELECT newid, fname, lname FROM B |
不确定您使用的是哪个数据库,但是对于sql server,打开身份插入的命令将是:
1
| SET identity_insert A ON |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| -- 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 |
我建议使用uniqueidentifier类型而不是身份。在这种情况下,您可以在插入之前生成ID:
1 2 3
| UPDATE B SET NewID = NEWID()
INSERT INTO A(fname,lname,id) SELECT fname,lname,NewID FROM B |
您可以通过加入行号来获得。之所以可能这样做是因为,由于它是一个标识,因此在添加项目时它只会递增,并且将按照您选择它们??的顺序进行。
如果始终希望出现这种情况,则可以在TableA上放置AFTER INSERT触发器,该触发器将更新表B。
MBelly确实物有所值-但是,即使不需要这样做,触发器也将始终尝试更新表B(因为您也要从表C中插入?)。
Darren在这里也是正确的,您无法将多个身份作为结果集返回。您的选择是使用光标并为插入的每一行获取身份,或者使用Darren之前和之后存储身份的方法。只要您知道标识的增量,它就应该起作用,只要您确保该表对于所有三个事件都已锁定。
如果是我,而且不是时间紧迫的问题,我会带游标去。