簡體   English   中英

INSERT到另一個表中的表和UPDATE外鍵(Sql Server 2008)

[英]INSERT into table and UPDATE foreign key in another table (Sql Server 2008)

我有兩個表, TableATableB像這樣:

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

TableB
----------------------------
|  id  |  some_other_data  |
| ---- | ----------------- |
|      |                   |
----------------------------

目前, TableB為空, TableA FK列對所有行都為null 我需要一次性初始化scrit填充寫TableB和初始化一些行(嚴格標准,不是所有)在FK列TableA的標識從行插入TableB

我知道有兩種方法可以做到這一點:

1)使用whilescope_identity() ,在TableB插入新行並在每次迭代時更新TableA ,同時在TableA存在行,應該更新

while (exists (select 1 from TableA where [condition]))
begin
    insert into TableB (some_other_data) values ('some_other_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_other_data, temp) select 'some_other_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_other_data)
        output inserter.id as insertedId
        values ('some_other_data')
    )
)
where [condition]

有沒有更簡單的方法來做這個while使用或修改任何表?

在尋找類似案例的解決方案時,我發現了這個問題。 唯一的區別是我想用TableA中的每一行填充TableB(沒有where子句)。

我找到了你建議的第三個選項的解決方案(使用insert的輸出),但是,由於你使用INSERT和SELECT中的數據,你不能使用OUTPUT子句。 這使我指出了正確的方向:

DECLARE @MyTableVar table(tableBId int, tableAId int)

MERGE INTO TableB
using TableA AS AP
on 1=0
WHEN NOT MATCHED THEN
   Insert(some_other_data) 
           Values('some_other_data')
           Output inserted.ID, AP.ID INTO @MyTableVar;

update TableA set new_FK_column_on_B = (select tableBId from @MyTableVar where tableAId = TableA.ID)

請注意,執行此秒時間將在TableB中創建新條目。 如果您只想在TableB中創建新行,而TableA中沒有設置外鍵,則可以使用此腳本:

DECLARE @MyTableVar TABLE(tableBId int, tableAId int)

MERGE INTO TableB AS B
USING TableA AS AP
ON A.new_FK_column_on_B = B.id
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 )
WHERE TableA.new_FK_column_on_B IS NULL;

你可以做所有這些作為設置操作:

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;

這假設b中的id列聲明為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循環。

免責聲明:我沒有經過測試,我在記事本中寫道:

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. 從表A(ID +數據)中獲取行,我們將使用它來填充B並存儲它們(我使用的是內存表)
  2. 將這些行插入B並存儲相應的B ID(再次存入內存表中)
  3. 我假設內存表中的兩個行的順序現在都匹配,所以我們的想法是我們可以將兩個內存表一起連接到行號上以獲得表A Id和它的表B Id - 我們用它來更新表A的外來鍵。

如果上面的代碼示例按原樣工作,我會非常驚訝,但希望這個想法有用,如果不是我的執行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM