一括挿入に sp_xml_preparedocument を使用しています。しかし、親テーブルに一括挿入し、新しく挿入された行ごとに scope_identity を取得してから、子テーブルに一括挿入したいと考えています。
これを行うには、プロシージャで親テーブルのテーブル変数を取得し、親テーブルに挿入するはずのデータをそのテーブルに挿入します。カーソル内の各行をループし、実際のテーブルに挿入してから子テーブルに挿入します。
しかし、カーソルのないバッター方法はありますか? 最適解が欲しい
一括挿入に sp_xml_preparedocument を使用しています。しかし、親テーブルに一括挿入し、新しく挿入された行ごとに scope_identity を取得してから、子テーブルに一括挿入したいと考えています。
これを行うには、プロシージャで親テーブルのテーブル変数を取得し、親テーブルに挿入するはずのデータをそのテーブルに挿入します。カーソル内の各行をループし、実際のテーブルに挿入してから子テーブルに挿入します。
しかし、カーソルのないバッター方法はありますか? 最適解が欲しい
常に、カーソルは悪だから!
ソース ファイルから子レコードを親レコードにリンクする何らかの方法があると仮定しています。また、子テーブルが XML の子ノードとして表される XML ファイルから一括挿入していると思いますか? 処理しようとしている XML の例を教えていただければ、非常に役に立ちます。ここでは、XML が次のようになっていると仮定します。
<root>
<parent>
<num>1</num>
<name>P1</name>
<children>
<child>
<num>1</num>
<name>C1</name>
</child>
...
親テーブルには以下が含まれますparent_key
:
DECLARE @parent TABLE (
num INT,
parent_name VARCHAR(100),
parent_key INT
)
子テーブルには独自のフィールドと、親からの識別要素があります。
DECLARE @child TABLE (
num INT,
child_name VARCHAR(100),
parent_num INT
)
親テーブルにデータが取り込まれますが、これは簡単なので、その例を含めるつもりはありません。parent_key フィールドは NULL のままにして、既知の値のみを設定します。
子テーブルには
INSERT INTO @child
SELECT * FROM OpenXML(@iDoc, '/root/parent/children/child', 2) WITH (
num INT,
name VARCHAR(100),
parent_num INT AS '../../num'
)
通常どおり、親テーブルに挿入します。
INSERT INTO #parent (num, parent_name)
SELECT num, parent_name FROM @parent ORDER BY num
次に、ROW_NUMBER と @@IDENTITY を使用して、親の主キーに使用される ID 値を取得できます。
;WITH cte1 AS (SELECT COUNT(*) AS cnt FROM @parent),
cte2 AS (SELECT ROW_NUMBER() OVER (ORDER BY num) AS row_num, num FROM #parent)
UPDATE p SET parent_key = @@IDENTITY - cte1.cnt + cte2.row_num
FROM @parent p, cte1, cte2
WHERE p.num = cte2.num
そこから、あなたは大丈夫なはずです。