对于表A中的每条记录,我想根据表B中新插入记录的scope_identity更新其中一个字段的外键值。
我需要在表B中为表A中的每条记录创建一条新记录,以便接收外键(scope_identity)值。
例如,对于下表中的每一行,我想基于在表B中创建新的行/外键来更新空外键字段。
表A:
|Id|ForeignKey|
|1 |NULL |
|2 |NULL |
|3 |NULL |
|4 |NULL |
|5 |NULL |
作为一个伪代码我想到了像这样的SQL:
update TableA
set ForeignKey = (INSERT INTO TableB VALUES (value1) select SCOPE_IDENTITY())
有什么想法吗?
答案 0 :(得分:5)
您可以使用游标循环遍历TableA并创建记录:
DECLARE @Id int
DECLARE @ForeignKey int
DECLARE C CURSOR FOR SELECT Id FROM TableA
OPEN C
FETCH NEXT FROM C INTO @Id
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO TableB VALUES (value1)
SET @ForeignKey = SCOPE_IDENTITY()
UPDATE TableA
SET ForeignKey = @ForeignKey
WHERE Id = @Id
FETCH NEXT FROM C INTO @Id
END
CLOSE C
DEALLOCATE C
答案 1 :(得分:0)
在SQL Server 2008及更高版本中执行与INSERT相关的UPDATE的基于集合的方法是使用MERGE...OUTPUT语句。
-- This table variable will hold the correlation between the two tables
declare @NewLinks table (dst_id int, src_id int)
merge TableB dst
using TableA src
on 1 = 0 --inserts all from src into dst, add WHERE-like limit here
when not matched --should never match, since this is an INSERT-like query
insert (<dst_column_list>) values (<src_column_list>)
output INSERTED.<dst_surrogate_key>, src.<src_surrogate_key>
into @NewLinks
update src
set src.ForeignKey = nl.dst_id
from TableA src
join @NewLinks nl
on nl.src_id = src.Id
由于INSERT语句(即使在INSERT ... SELECT表单中)没有FROM子句,因此无法在其OUTPUT子句中引用from_table_name
来捕获完整的相关性。由于MERGE始终将其USING子句视为FROM子句,因此它可用于模拟INSERT ... SELECT构造,同时允许访问OUTPUT中的源表和目标表。
使用MERGE ... OUTPUT创建与INSERT相关的UPDATE,使用游标或循环替换RBAR解决方案的低效使用,并维护单个临时表或表值变量。
答案 2 :(得分:0)
我发现的另一种方法是使用ROW_NUMBER function任意联接表,然后使用派生的查询更新FK。这个想法是tableA和tableB之间没有还的关系,我们只需要链接它们即可获取新的外键。将它们连接到诸如ROW_NUMBER之类的任意对象上,可以为我们提供一种方法来选择一行以从中获取ID。
首先创建新记录
INSERT INTO TableB VALUES (value1)
在ROW_NUMBER上写任意将它们联接的查询(我们将在下一步中使用它)
SELECT
tableARows.Id,
tableBRows.TheNewId
FROM
(
SELECT Id, Row = ROW_NUMBER() OVER (ORDER BY Id) FROM tableA
)tableARows INNER JOIN
(
SELECT TheNewId, Row = ROW_NUMBER() OVER (ORDER BY TheNewId) FROM tableB
)tableBRows ON tableARows.Row = tableBRows.Row
然后是完整的UPDATE语句,用来自tableB的新FK填充tableA
UPDATE tableA
SET tableA.ForeignKey = LinkedKeys.TheNewId
FROM
(
SELECT
tableARows.Id,
tableBRows.TheNewId
FROM
(
SELECT Id, Row = ROW_NUMBER() OVER (ORDER BY Id) FROM tableA
)tableARows INNER JOIN
(
SELECT TheNewId, Row = ROW_NUMBER() OVER (ORDER BY TheNewId) FROM tableB
)tableBRows ON tableARows.Row = tableBRows.Row
)LinkedKeys INNER JOIN
tableA ON tableA.Id = LinkedKeys.Id
这是我使用的示例表定义。
CREATE TABLE tableA (Id INT, ForeignKey INT)
INSERT INTO tableA VALUES (100,NULL),(200,NULL),(300,NULL)
CREATE TABLE tableB (TheNewId INT)
INSERT INTO tableB VALUES(5000),(6000),(7000)