我有两个表,TableA
和TableB
,如下所示:
TableA
-------------------------------------------
| id | some_data | new_FK_column_on_B |
| ---- | ----------- | ------------------ |
| 1 | ... | null |
| ... | ... | null |
| 999 | ... | null |
-------------------------------------------
TableB
----------------------
| id | some_data |
| ---- | ----------- |
| | |
----------------------
目前,TableB
为空,TableA
中的FK列为null
所有行。我需要编写一次性初始化scrit以填充TableB
,并在TableA
中通过插入TableB
的行中的标识符初始化某些行(标准,而不是所有行)的FK列。 / p>
我知道有两种方法可以做到这一点:
1)使用while
和scope_identity()
,在TableB
中插入新行并在每次迭代时更新TableA
,同时在TableA
中存在行,更新
while (exists (select 1 from TableA where [condition]))
begin
insert into TableB (some_data) values ('some_data')
update TableA set new_FK_column_on_B
where id = (select top 1 id from TableA where [condition])
end
2)在TableB
中创建临时列,在id
中存储TableA
行,为其插入,然后使用TableA
更新join
alter table TableB add temp int
go
insert into TableB (some_data, temp) select 'some_data', id from TableA where [condition]
update TableA
set new_FK_column_on_B = b.id
from TableB as b
join TableA as a on a.id = b.temp
alter table TableB drop column temp
此外,我试图以某种方式使用output
这样的insert
,但它的语法不正确:
update TableA
set new_FK_column_on_B =
(
select insertedId from
(
insert into TableB (some_data)
output inserter.id as insertedId
values ('some_data')
)
)
where [condition]
有没有更简单的方法可以在不使用while
或修改任何表格的情况下执行此操作?
答案 0 :(得分:0)
您可以执行以下操作:
insert into b(some_data)
select distinct some_data
from a;
update a
set new_FK_column_on_B = b.id
from a join
b
on a.some_data = b.some_data;
这假设id
中的b
列被声明为identity()
,因此会自动分配。这是一个好主意,但如果你想手动完成,那么第一个查询就像:
insert into b(some_data)
select row_number() over (order by (select null)), some_data
from (select distinct some_data
from a
) a;
不需要while
循环。
答案 1 :(得分:0)
免责声明:我没有经过测试,我在记事本中写道:
DECLARE @TableAValues TABLE (IdTableA int, SomeData varchar)
INSERT INTO @TableAValues(IdTableA, SomeData)
SELECT id, 'some_data' FROM TableA
DECLARE @TableBIds TABLE (IdTableB int)
INSERT INTO TableB(SomeData)
OUTPUT INSERTED.ID INTO @TableBIds
SELECT SomeData FROM @TableAValues
UPDATE ta
SET ta.new_FK_column_on_B = tbi.IdTableB
FROM dbo.TableA AS ta
INNER JOIN @TableAValues AS tav ON ta.id = tav.IdTableA -- used in case more records were added to table in the interim.
LEFT OUTER JOIN @TableBIds tbi On tav.RowNum = tbi.RowNum
注意:我在内存表中使用,但是如果你担心内存使用情况,你可能只需将它们转换为磁盘上的临时表。
我想去的想法:
如果上面的代码示例按原样工作,我会非常惊讶,但希望这个想法有用,如果不是我的执行。
答案 2 :(得分:0)
我在寻找类似案例的解决方案时发现了这个问题。唯一的区别是,我想在TableB中为TableA中的每一行填充一行(无子句)。
我找到了建议的第三个选项的解决方案(使用insert的输出),但是,由于将INSERT与SELECT中的数据一起使用,因此无法使用OUTPUT子句。 This为我指明了正确的方向:
DECLARE @MyTableVar table(tableBId int, tableAId int)
MERGE INTO TableB
using TableA AS AP
on 1=0
WHEN NOT MATCHED THEN
Insert(some_data)
Values(AP.some_data)
Output inserted.ID, AP.ID INTO @MyTableVar;
update TableA set new_FK_column_on_B = (select tableBId from @MyTableVar where tableAId = TableA.ID)
我还没有尝试为您的情况运行此确切的脚本,但是距离应该不会太远。