6

テーブルAIの各レコードについて、テーブルBに新しく挿入されたレコードのscope_identityに基づいて、フィールドの1つの外部キー値を更新します。

外部キー(scope_identity)値を受け取るには、テーブルAのレコードごとにテーブルBに新しいレコードを作成する必要があります。

たとえば、次の表の各行について、表Bに新しい行/外部キーを作成することに基づいて、nullの外部キーフィールドを更新します。

表A:

|Id|ForeignKey|
|1 |NULL      |
|2 |NULL      |
|3 |NULL      |
|4 |NULL      |
|5 |NULL      |

擬似コードとして、私はこのSQLのようなものを考えました:

update TableA 
set ForeignKey = (INSERT INTO TableB VALUES (value1) select SCOPE_IDENTITY())

何か案が?

4

3 に答える 3

6

カーソルを使用してTableAをループし、レコードを作成できます。

DECLARE @Id int
DECLARE @ForeignKey int

DECLARE C CURSOR FOR SELECT Id FROM TableA

OPEN C

FETCH NEXT FROM C INTO @Id

WHILE @@FETCH_STATUS = 0
BEGIN
    INSERT INTO TableB VALUES (value1)
    SET @ForeignKey = SCOPE_IDENTITY()

    UPDATE TableA
    SET ForeignKey = @ForeignKey
    WHERE Id = @Id

    FETCH NEXT FROM C INTO @Id
END

CLOSE C
DEALLOCATE C
于 2012-07-29T17:06:48.470 に答える
0

SQL Server 2008以降でINSERTと関連付けられたUPDATEを実行するセットベースの方法は、MERGE...OUTPUTステートメントを使用することです。

-- This table variable will hold the correlation between the two tables
declare @NewLinks table (dst_id int, src_id int)

merge TableB dst
using TableA src
    on 1 = 0 --inserts all from src into dst, add WHERE-like limit here
when not matched --should never match, since this is an INSERT-like query
    insert (<dst_column_list>) values (<src_column_list>)
output INSERTED.<dst_surrogate_key>, src.<src_surrogate_key>
into @NewLinks

update src
set src.ForeignKey = nl.dst_id
from TableA src
join @NewLinks nl
    on nl.src_id = src.Id

INSERTステートメント(INSERT ... SELECT形式でも)にはFROM句from_table_nameがないため、完全な相関関係を取得するためにOUTPUT句で参照することはできません。MERGEは常にUSING句をFROM句と見なすため、OUTPUTのソーステーブルと宛先テーブルの両方へのアクセスを許可しながら、INSERT...SELECT構造を模倣するために使用できます。

MERGE ... OUTPUTを使用してINSERTに関連付けられたUPDATEを作成すると、カーソルまたはループを使用したRBARソリューションの非効率的な使用が、単一の一時テーブルまたはテーブル値変数の保守に置き換えられます。

于 2015-03-30T20:39:46.203 に答える
0

私が見つけたもう1つの方法は、ROW_NUMBER関数を使用してテーブルを任意に結合し、その派生クエリを使用してFKを更新することです。tableAとtableBの間にはまだ関係がないという考えです。新しい外部キーを取得するには、それらをリンクする必要があります。ROW_NUMBERのような任意の値でそれらを結合すると、IDを取得する単一の行を選択する方法が得られます。

最初に新しいレコードを作成します

INSERT INTO TableB VALUES (value1)

それらを任意に結合するクエリをROW_NUMBERに記述します(これは次のステップで使用します)

SELECT
    tableARows.Id, 
    tableBRows.TheNewId
FROM
(
    SELECT Id, Row =  ROW_NUMBER() OVER (ORDER BY Id) FROM tableA
)tableARows INNER JOIN
(
    SELECT TheNewId, Row = ROW_NUMBER() OVER (ORDER BY TheNewId) FROM tableB
)tableBRows ON tableARows.Row = tableBRows.Row

次に、tableAにtableBからの新しいFKを入力するための完全なUPDATEステートメント

UPDATE tableA 
SET tableA.ForeignKey = LinkedKeys.TheNewId
FROM
(
    SELECT
        tableARows.Id, 
        tableBRows.TheNewId
    FROM
    (
        SELECT Id, Row =  ROW_NUMBER() OVER (ORDER BY Id) FROM tableA
    )tableARows INNER JOIN
    (
        SELECT TheNewId, Row = ROW_NUMBER() OVER (ORDER BY TheNewId) FROM tableB
    )tableBRows ON tableARows.Row = tableBRows.Row
)LinkedKeys INNER JOIN
tableA  ON tableA.Id = LinkedKeys.Id

これが私が使用したテーブル定義の例です。

CREATE TABLE tableA (Id INT, ForeignKey INT)
INSERT INTO tableA VALUES (100,NULL),(200,NULL),(300,NULL)


CREATE TABLE tableB (TheNewId INT)
INSERT INTO tableB VALUES(5000),(6000),(7000)
于 2020-01-10T16:34:41.227 に答える