2016-12-26 27 views
1

親テーブルと子テーブルがあります。子を挿入するための親IDのIDを取得する方法

目的は、新しい主キーを除いてレコードを複製することです。

オリジナルのテーブルの挿入後

Parent(id) 
1 

Child(id,parentId, data) 
1,1 
2,1 

Parent 
1 
2 

Child 
1,1 
2,1 
3,2 
4,2 

私はそれをどのように行うのですか?私が問題を抱えている部分は、子レコードで使用するための新しい親キーを取得することです。

これはこれまで私が思い付いたことです。アプローチ以下

--DECLARE VARS 
declare @currentMetadataDocumentSetId int = 1, --Ohio 
    @newMetadataDocumentSetid int = 3; --PA 

--CLEANUP 
IF OBJECT_ID('tempdb..#tempFileRowMap') IS NOT NULL 
    /*Then it exists*/ 
    DROP TABLE #tempFileRowMap 

--Remove existing file row maps. 
delete from file_row_map where metadata_document_set_id = @newMetadataDocumentSetid; 


--Create a temptable to hold data to be copied. 
Select [edi_document_code], 
    [functional_group], 
    [description], 
    3 as [metadata_document_set_id], 
    [document_name], 
    [incoming_file_row_subtype], 
    [metadata_document_id], 
    [document_subcode], 
    [outgoing_file_row_subtype], 
    [asi_type_code], 
    [asi_action_code], 
    [metadata_document_set], 
    file_row_map_id as orig_file_row_map_id 
into #tempFileRowMap 
from file_row_map fileRowMap 
where metadata_document_set_id = @currentMetadataDocumentSetId; 


--Select * from #tempFileRowMap; 
Insert into file_row_map select 
[edi_document_code], 
[functional_group], 
[description], 
[metadata_document_set_id], 
[document_name], 
[incoming_file_row_subtype], 
[metadata_document_id], 
[document_subcode], 
[outgoing_file_row_subtype], 
[asi_type_code], 
[asi_action_code], 
[metadata_document_set] 
from #tempFileRowMap 

--Show Results 
Select * from file_row_map fileRowMap where fileRowMap.metadata_document_set_id = @newMetadataDocumentSetid 


--Update Detail 
Select 
[file_row_map_id], 
[file_row_column], 
[element_code], 
[element_metadata_id], 
[col_description], 
[example], 
[translate], 
[is_used], 
[is_mapped], 
[page_num], 
[subcode], 
[qualifier], 
[loop_code], 
[loop_subcode], 
[default_value], 
[delete_flag] 
into #tempFileRowMapDetail 
from [dbo].[file_row_map_detail] d 
left join #tempFileRowMap m 
on m.orig_file_row_map_id = d.file_row_map_id 

select * from #tempFileRowMapDetail 
+1

[これは役立つかもしれない](http://stackoverflow.com/a/38217498/3094533) –

+0

がChild_ID列自動ナンバーですか? –

+0

@ZoharPeled、マージの面白いリンク。以前は「マージ」について知らなかった。 –

答えて

1

正確な親テーブルの主キー値を取得するには、OUTPUT句を使用します。

あなたのケース

--For Capturing inserted ID 
CREATE TABLE #ID_CAPTURE (PARENT_ID INT,ORDER_NME VARCHAR(20)); 

--Your Intermidiate Data To insert into Actual Tables 
CREATE TABLE #DUMMY_TABLE (ORDER_NME VARCHAR(20), ITEM_NME VARCHAR(20)); 

--Actual Tables 
CREATE TABLE #ORDER_PARENT (ORDER_ID INT IDENTITY,ORDER_NME VARCHAR(20)) 
CREATE TABLE #ORDER_CHILD (CHILD_ID INT IDENTITY ,ORDER_ID INT, ORDER_NME VARCHAR(20)) 


INSERT INTO #DUMMY_TABLE 
SELECT 'BILL1','Oil' 
UNION ALL 
SELECT 'BILL1', 'Gas' 
UNION ALL 
SELECT 'BILL2', 'Diesel' 

のための例のスキーマを構築することができます今すぐ挿入アイデンティティ値を取得するための他の方法があります

INSERT INTO #ORDER_PARENT 
OUTPUT inserted.ORDER_ID, inserted.ORDER_NME into #ID_CAPTURE 

SELECT DISTINCT ORDER_NME FROM #DUMMY_TABLE 


INSERT INTO #ORDER_CHILD 

SELECT C.PARENT_ID, ITEM_NME FROM #DUMMY_TABLE D 
INNER JOIN #ID_CAPTURE C ON D.ORDER_NME = C.ORDER_NME 



SELECT * FROM #ID_CAPTURE 
SELECT * FROM #ORDER_CHILD 

親&子表の挿入を行います。

参照ドキュメント@@IDENTITY (Transact-SQL)SCOPE_IDENTITY

+1

これはうまく機能しました。 –

0

試してみてください。

DECLARE @Table1 TABLE (
    ID   INT NOT NULL PRIMARY KEY, 
    ParentID INT NULL, -- FK 
    [Desc]  VARCHAR(50) NOT NULL 
); 
INSERT @Table1 (ID, ParentID, [Desc]) 
VALUES 
(1, NULL, 'A'), 
(2, 1, 'AA.1'), 
(3, 1, 'AA.2'), 
(4, NULL, 'B'), 
(5, 4, 'BB.1'), 
(6, 4, 'BB.2'), 
(7, 4, 'BB.3'), 
(8, 7, 'BBB.1'); 

DECLARE @ParentID INT = 4; 

DECLARE @LastID INT = (SELECT TOP(1) ID FROM @Table1 x ORDER BY x.ID DESC) 
IF @LastID IS NULL 
BEGIN 
    RAISERROR('Invalid call', 16, 1) 
    --RETURN ? 
END 
SELECT @LastID AS LastID; 
/* 
LastID 
----------- 
8 
*/ 

DECLARE @RemapIDs TABLE (
    OldID INT NOT NULL PRIMARY KEY, 
    [NewID] INT NOT NULL UNIQUE 
); 

WITH CteRecursion 
AS (
    SELECT 1 AS Lvl, crt.ID, crt.ParentID --, crt.[Desc] 
    FROM @Table1 crt 
    WHERE crt.ID = @ParentID 
    UNION ALL 
    SELECT cld.Lvl + 1 AS Lvl, crt.ID, crt.ParentID --, crt.[Desc] 
    FROM @Table1 crt 
    JOIN CteRecursion cld ON crt.ParentID = cld.ID 
) 
INSERT @RemapIDs (OldID, [NewID]) 
SELECT r.ID, @LastID + ROW_NUMBER() OVER(ORDER BY r.Lvl) AS [NewID] 
FROM CteRecursion r; 

--INSERT @Table1 (ID, ParentID, [Desc]) 
SELECT nc.[NewID] AS ID, np.[NewID] AS ParentID, o.[Desc] 
FROM @Table1 o -- old 
JOIN @RemapIDs nc /*new child ID*/ ON o.ID = nc.OldID 
LEFT JOIN @RemapIDs np /*new parent ID*/ ON o.ParentID = np.OldID 
/* 
ID   ParentID Desc 
----------- ----------- -------------------------------------------------- 
9   NULL  B 
10   9   BB.1 
11   9   BB.2 
12   9   BB.3 
13   12   BBB.1 
*/ 

注:いくつかのマイナーな変更では、ワット動作するはずです。多くはParentIDの値です。

+0

少しの説明を追加できますか?私はこれが良い答えだと確信していますが、私のスキルはそれをSQLから理解するだけではありません。 –

+0

Ref https://msdn.microsoft.com/en-us/library/bb677173.aspx –

+0

「深い優先順位での比較」のセクションを参照してください。 –

関連する問題