栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

复制层次结构数据时保留父子关系

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

复制层次结构数据时保留父子关系

CTE与可以很好地配合使用

MERGE
,但是在SQL Server 2005中是有问题的。对于先前引起误解的注释,我们深表歉意。

下面显示了如何克隆项目(具有多棵树)并修正父项以将新森林与旧森林分开。请注意,它不依赖于ID的任何特定排列,例如,它们不必是密集的,单调递增的…。

-- Sample data.declare @Projects as Table  ( Id Int Identity, ProjectId Int, Value VarChar(16), ParentId Int Null );insert into @Projects ( ProjectId, Value, ParentId ) values  ( 611, 'Animal', 0 ),  ( 611, 'Frog', 1 ),  ( 611, 'Cow', 1 ),  ( 611, 'Jersey Cow', 3 ),  ( 611, 'Plant', 0 ),  ( 611, 'Tree', 5 ),  ( 611, 'Oak', 6 );-- Display the raw data.select * from @Projects;-- Display the forest.with IndentedProjects ( Id, ProjectId, Value, ParentId, Level, Path ) as  ( -- Start with the top level rows.  select Id, ProjectId, Value, ParentId, 0, Convert( VarChar(1024), Right( '000' + Convert( VarChar(4), Id ), 4 ) )    from @Projects    where ParentId = 0  union all  -- Add the children one level at a time.  select P.Id, P.ProjectId, P.Value, P.ParentId, IP.Level + 1, Convert( VarChar(1024), IP.Path + '<' + Right( '000' + Convert( VarChar(4), P.Id ), 4 ) )    from IndentedProjects as IP inner join      @Projects as P on P.ParentId = IP.Id  )  select Space( Level * 2 ) + Value as [IndentedValue], Id, ProjectId, Value, ParentId, Level, Path    from IndentedProjects    order by Path;-- Clone the project.declare @OldProjectId as Int = 611;declare @NewProjectId as Int = 42;declare @Fixups as Table ( OldId Int, [NewId] Int );begin transaction -- With suitable isolation since the hierarchy will be invalid until we apply the fixups!insert into @Projects  output Inserted.ParentId, Inserted.Id    into @Fixups  select @NewProjectId, Value, Id -- Note that we save the old Id in the new ParentId.    from @Projects as P    where ProjectId = @OldProjectId;-- Apply the fixups.update PNew  set ParentId = IsNull( FNew.[NewId], 0 )  -- Output the fixups just to show what is going on.  output Deleted.Id, Deleted.ParentId as [ParentIdBeforeFixup], Inserted.ParentId as [ParentIdAfterFixup]  from @Fixups as F inner join    @Projects as PNew on PNew.Id = F.[NewId] inner join -- Rows we need to fix.    @Fixups as FOld on FOld.OldId = PNew.ParentId inner join    @Projects as POld on POld.Id = FOld.OldId left outer join    @Fixups as FNew on FNew.OldId = POld.ParentId;commit transaction;-- Display the forest.with IndentedProjects ( Id, ProjectId, Value, ParentId, Level, Path ) as  ( -- Start with the top level rows.  select Id, ProjectId, Value, ParentId, 0, Convert( VarChar(1024), Right( '000' + Convert( VarChar(4), Id ), 4 ) )    from @Projects    where ParentId =0  union all  -- Add the children one level at a time.  select P.Id, P.ProjectId, P.Value, P.ParentId, IP.Level + 1, Convert( VarChar(1024), IP.Path + '<' + Right( '000' + Convert( VarChar(4), P.Id ), 4 ) )    from IndentedProjects as IP inner join      @Projects as P on P.ParentId = IP.Id  )  select Space( Level * 2 ) + Value as [IndentedValue], Id, ProjectId, Value, ParentId, Level, Path    from IndentedProjects    order by Path;


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/392604.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号