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 只会给我在联合之前插入的最后一条记录的身份。

我能做些什么来获得身份?我可以修改 Table3 但不能修改 Table1 或 Table2

row_number()对于递归查询有未定义的行为,所以我不能在这里使用它。

我知道我可以使用 GUID,这是唯一的选择吗?

4

2 回答 2

3

您无法在 CTE 中捕获生成的身份。null但是,您可以使用as将所有行插入到目标表中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向您显示会话的实际身份值。

您不能使用CTEwithIDENTITY 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 回答