2016-07-29 108 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的外鍵。

如果我上面的代碼示例工作正常,但我希望這個想法能夠有用,如果不是我的執行,我會很驚訝。