2016-07-29 112 views
2

我有两个表,TableATableB这样的表和UPDATE的外键:INSERT到另一个表(SQL Server 2008中)

TableA 
------------------------------------------- 
| id | some_data | new_FK_column_on_B | 
| ---- | ----------- | ------------------ | 
| 1 |  ...  |  null  | 
| ... |  ...  |  null  | 
| 999 |  ...  |  null  | 
------------------------------------------- 

TableB 
---------------------- 
| id | some_data | 
| ---- | ----------- | 
|  |    | 
---------------------- 

目前,TableB是空的,而在TableA FK列所有行均为null。我需要编写一次性初始化scrit以填充TableB并通过插入TableB的行中的标识符为TableA初始化某些行(标准,非全部)的FK列。

我知道两种方法可以做到这一点:

使用 whilescope_identity(),插入新行 TableB,并在每次迭代更新 TableA,而存在于 TableA行,应更新

1)

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中创建临时列,在TableA中存储行id,为其插入,然后使用join更新TableA

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 

此外,我试图从insert这样莫名其妙output使用,但它的语法不正确:

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

你可以做到这一切的操作集:

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; 

这里假定bid列被声明为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循环。

+0

这不是一种情况,因为'table_'和'tableB'的'some_data'不一样。它可能是各种各样的列,不同类型,并且它不是唯一的表,它可以重复。 – user2123532

+0

我认为这不是@ user2123532所说的完整答案。 – roll

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 

注:我使用在内存中的表,但如果你担心内存使用情况,你很可能只是切换的这不是在所有的测试,我在记事本写了这用于磁盘上的临时表。

的想法我会在这里:从表格中的

  1. 抢行(ID +数据),我们将用于填充B和存储他们(我使用的是存储表)
  2. 将这些行插入到B中并存储B的相应ID(再次存储在内存表中)
  3. 我假设两个内存表中的行的顺序现在都会匹配,所以我们的想法是我们可以将它们连接到内存中在行号上一起获取表A ID与它的表B ID - 我们用它来更新表A的外键。

如果我上面的代码示例工作正常,但我希望这个想法能够有用,如果不是我的执行,我会很惊讶。