3

트리 (bill of materials 스타일)를 만들고 일부 데이터를 변환 중입니다. 그것을 채우기 위해 나는 CTE를 사용하고 지금 T-SQL : ID 열이있는 CTE

BillOfMaterials

  • BomId
  • ParentId : 다음 표를 고려 ​​

    with BOM as 
    (
    select @@identity as BomId, null as ParentId <some other fields> from MyTable 
    union all 
    select @@identity as BomId, 
         parent.BomId as ParentId, 
         some other fields 
    from MyTable2 
    inner join BOM parent on blabla) 
    
    insert into MyTable3 
    select * from BOM 
    

    문제는 다음 @@ identity는 나에게 조합 앞에 삽입 된 마지막 레코드의 신원만을 알려줍니다.

    신원을 확인하려면 어떻게해야합니까? Table3은 수정할 수 있지만 Table1이나 Table2는 수정할 수 없습니다.

    row_number()은 재귀 쿼리에 대해 정의되지 않은 동작을하므로 여기서는 사용할 수 없습니다.

    GUID를 사용할 수 있다는 것을 알고 있습니다. 유일한 옵션입니까?

답변

3

당신은에서 생성 된 정체성을 캡처 할 수 없습니다

당신은 IDENTITY FUNCTIONCTE를 사용할 수 있지만 임시 테이블을 사용할 수 있습니다 CTE. 그러나 모든 행을 null으로 표 대상 테이블에 삽입하고 ParentID으로 입력 한 다음 별도의 업데이트 문으로 ParentID을 업데이트 할 수 있습니다. 이를 수행하려면 merge을 사용하고 here을 설명하는 기술을 사용할 수 있습니다.

-- Helper table to map new id's from source 
-- against newly created id's in target 
declare @IDs table 
( 
    TargetID int, 
    SourceID int, 
    SourceParentID int 
) 

-- Use merge to capture generated id's 
merge BillOfMaterials as T 
using SourceTable as S 
on 1 = 0 
when not matched then 
insert (SomeColumn) values(SomeColumn) 
output inserted.BomId, S.BomID, S.ParentID into @IDs; 

-- Update the parent id with the new id 
update T 
set ParentID = I2.TargetID 
from BillOfMaterials as T 
    inner join @IDs as I1 
    on T.BomID = I1.TargetID 
    inner join @IDs as I2 
    on I1.SourceParentID = I2.SourceID 

여기에 전체 작업 SE-Data

+2

잘 연주했습니다. 고마워요! :) – Bas

2

@@identity에는 세션에 대한 실제 신원 값이 표시됩니다.

SELECT IDENTITY(int,1,1) AS BomId, un.* 
INTO #BOM 
FROM <your union> as un 

당신이 CTE를 사용하려면이 :

with BOM as 
(
    SELECT ROW_NUMBER() OVER(ORDER BY <column>) AS BomId, un.* 
    FROM <your union> as un 
) 
+0

ROW_NUMBER에 샘플() 재귀 쿼리에 대한 동작을 보증되지이다. – Bas

+0

흠 나는 그것에 대해 알지 못했습니다. 이상하다. 나는 더 나은/다른 옵션을 찾을 수 없습니다. 따라서 NEWID()를 사용해야합니다. – devarc

+0

우리 팀에서는 많은 시간과 다양한 구현을 위해 CTE에서 row_number()를 사용해 왔습니다. 우리는 어떤 문제도 발견하지 못했습니다. 정확히 무슨 뜻이야? – Vladislav