3

ツリー (部品表スタイル) を構築し、いくつかのデータを変換しています。次の表を検討してください。

部品表

  • BomID
  • 親ID

今、私はそれを埋めるためにCTEを使用しています:

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 は、結合の前に挿入された最後のレコードの ID のみを提供します。

IDを取得するにはどうすればよいですか? Table3 は変更できますが、Table1 または Table2 は変更できません

row_number()再帰クエリに対して未定義の動作があるため、ここでは使用できません。

GUID を使用できることはわかっていますが、それが唯一のオプションですか?

4

2 に答える 2

3

生成された ID を CTE でキャプチャすることはできません。nullただし、 asを使用してすべての行をターゲット テーブルに挿入し、別の update ステートメントでParentID更新することはできます。これを行うには、ここで説明されているテクニックParentIDを使用できます。merge

-- 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 の完全な作業サンプルです

于 2012-04-25T08:20:00.683 に答える
2

@@identityセッションの実際の ID 値を示します。

CTEwithは使用できませんIDENTITY FUNCTIONが、一時テーブルを使用できます。

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
)
于 2012-04-23T10:52:04.060 に答える