テーブル内の行をコピーするストアド プロシージャを作成しています。
これがテーブルです
これをコピーしたいのですが、ParentId を新しい行にリンクする必要があります。単純な INSERT INTO > SELECT FROM を実行すると、上記のように、ParentId は新しい ProductId ではなく ProductId 22 にリンクされます。
なにか提案を?
テーブル内の行をコピーするストアド プロシージャを作成しています。
これがテーブルです
これをコピーしたいのですが、ParentId を新しい行にリンクする必要があります。単純な INSERT INTO > SELECT FROM を実行すると、上記のように、ParentId は新しい ProductId ではなく ProductId 22 にリンクされます。
なにか提案を?
あなたの質問は完全に明確ではありませんが、正しく理解できれば、その階層を維持しながら階層を構築するいくつかの行をコピーしようとしています。
これは、1 つのステップで行うことはできません。最初に行をコピーし、新しい ID と一致する古い ID を記録する必要があります。次に、新しい行の参照を更新して、新しい親を指すようにすることができます。
これを行う最も簡単な方法は、MERGE ステートメントを使用することです。
CREATE TABLE dbo.tst(id INT IDENTITY(1,1), parent_id INT, other INT);
INSERT INTO dbo.tst(parent_id, other)VALUES(NULL,1);
INSERT INTO dbo.tst(parent_id, other)VALUES(1,2);
INSERT INTO dbo.tst(parent_id, other)VALUES(1,3);
INSERT INTO dbo.tst(parent_id, other)VALUES(3,4);
INSERT INTO dbo.tst(parent_id, other)VALUES(NULL,5);
INSERT INTO dbo.tst(parent_id, other)VALUES(5,6);
CREATE TABLE #tmp(old_id INT, new_id INT);
MERGE dbo.tst AS trg
USING dbo.tst AS src
ON (0=1)
WHEN NOT MATCHED
AND (src.id >= 1) --here you can put your own WHERE clause.
THEN
INSERT(parent_id, other)
VALUES(src.parent_id, src.other)
OUTPUT src.id, INSERTED.id INTO #tmp(old_id, new_id);
UPDATE trg SET
parent_id = tmp_translate.new_id
FROM dbo.tst AS trg
JOIN #tmp AS tmp_filter
ON trg.id = tmp_filter.new_id
JOIN #tmp AS tmp_translate
ON trg.parent_id = tmp_translate.old_id;
SELECT * FROM dbo.tst;
コメントのある行は、コピーする行を選択するための独自の where 句を配置できる場所です。参照されているすべての親を実際にコピーしてください。親なしで子をコピーすると、更新はそれをキャッチせず、最終的に古い親を指すことになります。
また、トランザクションで MERGE と UPDATE をラップして、他の誰かが新しい未完成のレコードを読み取らないようにする必要があります。
これを行うために使用できSELECT
ます。列の順序を手動で指定するだけです。テーブルが Product と呼ばれ、ProductId が自動インクリメントされると仮定した例を次に示します。で返される最初の列SELECT
が古い行の主キーであることに注意してください。
INSERT dbo.Product
SELECT
ProductId,
ArtNo,
[Description]
Specification,
Unit,
Account,
NetPrice
OhTime
FROM dbo.Product AS P
WHERE P.ParentId = 22
それは役に立ちますか?