0

状況:
ソースとターゲットであるテーブルから別のテーブルに情報を挿入しています。情報がターゲットに挿入されると、主キーが作成されます。(この場合は整数です。)次に、ソーステーブルに結び付けることができる必要があります。ただし、移動するデータに基づいて、ターゲットテーブルとソーステーブルの間で1:1の一致を確実に取得することはできません。

質問:
ターゲットテーブルのrecord(x)用に作成された主キーをコピーし、一括挿入が行われているときにソーステーブルの同じrecord(x)に外部キーとしてコピーする方法はありますか?

詳細:
SQLでこれを実行しようとしています。私にはこの問題の回避策がありますが、私が求めていることを実行する方法が必要だと思います。

4

3 に答える 3

2

この素晴らしい記事を読んだ後、私は自分の答えを見つけました。

http://sqlblog.com/blogs/adam_machanic/archive/2009/08/24/dr-output-or-how-i-learned-to-stop-worrying-and-love-the-merge.aspx

MERGEとそのOUTPUT句を使用して、探していたものを実現しました。これは、これを理解するために使用したサンプルコードです。

まず、#Temp2、#Temp3、#Temp4の3つの一時テーブルを作成しました。#Temp2はソーステーブルと見なされます。#Temp3がターゲットテーブルになり、#Temp4がブリッジになります。次に、非常に単純なデータを数行挿入しました。この場合は、値という1つのフィールドだけです。

CREATE TABLE #Temp2(
OldID INT IDENTITY(1,1),
Value INT,
NewFK INT)

CREATE TABLE #Temp3(
NewerID INT IDENTITY(1,1),
Value INT)

CREATE TABLE #Temp4(
OldID INT NOT NULL,
NewerID INT NOT NULL,
Value INT)

INSERT INTO #Temp2(Value)
VALUES(30), (40), (50), (70)

INSERT INTO #Temp3(Value)
VALUES (333), (444), (555), (777)

次に、ダーティな作業を行うMERGEステートメントがあります。#Temp2から値を取得し、それを#Temp3に入れます。次に、#Temp3で作成されたID、#Temp2からのID、および渡された値を取得し、それらをすべて#Temp4にスローします。

MERGE INTO #Temp3 AS tgt
USING #Temp2 AS src
ON 1=0
WHEN NOT MATCHED THEN
    INSERT(
    Value)
    VALUES(
    src.Value)
OUTPUT
    src.OldID,
    INSERTED.NewerID,
    src.Value
INTO #Temp4(OldID, NewerID, Value);

次に、ステージングテーブル#Temp2に対してUPDATEを実行して、NewFKフィールドを新しいIDで更新しました。最後に、単純なSELECTを実行して、更新された情報を確認します。

UPDATE X
SET X.NewFK = Z.NewerID
FROM #Temp2 X
JOIN #Temp4 Z
ON X.OldID = Z.OldID

SELECT * FROM #Temp2

これは私が必要としていたことを正確に達成し、物事を行うためのかなり合理化された方法です。これがこの質問に出くわす一部の人々に役立つことを願っています。あなたの洞察と反応をみんなに感謝します。

注: MERGEはSQLServer2008で導入されたと思います。

ジョナサン

于 2013-02-07T20:52:55.337 に答える
0

ターゲットでSharedExtPKを取得できる場合、これは機能するはずです。
この場合、logIDはソースのPKです。
テスト済み:

DECLARE @MyTableVar table(
  TargetPK     int NOT NULL,
  SourcePK     int NOT NULL
  );

INSERT INTO IdenOutPut (someValue, sharedExtKey)
  OUTPUT INSERTED.iden, 
         INSERTED.sharedExtKey
  INTO @MyTableVar
    SELECT name, logID
    FROM CatID

update sPK 
set sPK.ExtPK = tTbl.TargetPK
FROM @MyTableVar as tTbl 
JOIN CatID as sPK 
  on sPK.logID = tTbl.SourcePK 
GO

挿入する値が一意である場合は、それを使用できます。
しかし、それはよりトリッキーになるでしょう。

于 2013-02-06T20:52:01.207 に答える
0

1つのアプローチは、ターゲットテーブルのID挿入を「オン」に設定することです(http://msdn.microsoft.com/en-us/library/ms188059.aspx)。次に、挿入を実行する前に、そのIDを「ソース」データの一部にします。完了したら、ID挿入をオフに戻すことを忘れないでください。

編集
あなたの状況はわかりませんが、私が過去に取ったアプローチの1つは、将来のある時点でソースを参照する必要が生じた場合に備えて、「外部ソースID」を保持するフィールドを作成することです。私の場合、これは参照用であり、通常のトランザクションでの使用ではありません。

于 2013-02-06T18:37:01.233 に答える