在sql server中克隆带有后代的记录

时间:2014-07-03 13:55:17

标签: sql sql-server-2008

以下是我的表格。

CREATE TABLE [dbo].[CCMaster](
[CCId] [int] IDENTITY(1,1) NOT NULL,
[GId] [int] NULL,
[BKId] [int] NULL,
[Class] [varchar](100) NULL,
[ParentId] [int] NULL,)

SET IDENTITY_INSERT CCMaster ON

insert into CCMaster([CCId],[GID],[BKID],[Class],[ParentId]) values(1,33,162,'CORPORATE',NULL)
insert into CCMaster([CCId],[GID],[BKID],[Class],[ParentId]) values(10,33,162,'Call center related',4)
insert into CCMaster([CCId],[GID],[BKID],[Class],[ParentId]) values(11,33,162,'Channel related',2)
insert into CCMaster([CCId],[GID],[BKID],[Class],[ParentId]) values(12,33,162,'Advertisement',6)
insert into CCMaster([CCId],[GID],[BKID],[Class],[ParentId]) values(13,33,162,'Brand Ambassador',6)
insert into CCMaster([CCId],[GID],[BKID],[Class],[ParentId]) values(14,33,162,'OTAF/TVP (New Activation)',11)
insert into CCMaster([CCId],[GID],[BKID],[Class],[ParentId]) values(15,33,162,'Service Barred',7)
insert into CCMaster([CCId],[GID],[BKID],[Class],[ParentId]) values(16,33,162,'Call center behaviour',10)
insert into CCMaster([CCId],[GID],[BKID],[Class],[ParentId]) values(17,33,162,'Store Personnel behavior',8)
insert into CCMaster([CCId],[GID],[BKID],[Class],[ParentId]) values(2,33,162,'DTH',NULL)
insert into CCMaster([CCId],[GID],[BKID],[Class],[ParentId]) values(3,33,162,'2G',NULL)
insert into CCMaster([CCId],[GID],[BKID],[Class],[ParentId]) values(4,33,162,'3GS',NULL)
insert into CCMaster([CCId],[GID],[BKID],[Class],[ParentId]) values(5,33,162,'Broadband',NULL)
insert into CCMaster([CCId],[GID],[BKID],[Class],[ParentId]) values(6,33,162,'Brand',1)
insert into CCMaster([CCId],[GID],[BKID],[Class],[ParentId]) values(7,33,162,'Barring-related',3)
insert into CCMaster([CCId],[GID],[BKID],[Class],[ParentId]) values(8,33,162,'Behaviour related',4)
insert into CCMaster([CCId],[GID],[BKID],[Class],[ParentId]) values(9,33,162,'Call center related',3)

SET IDENTITY_INSERT CCMaster OFF

此表中有数千条记录。我想只克隆GID = 33和BKID = 162的记录。子节点的父节点必须相应地匹配相应父节点的自动生成的id。我尝试了this查询,但它对我有用。

我尝试使用光标,首先插入父母,然后尝试查询孩子,但是太过分了。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

使用递归CTE获取要插入的行。

要确定要将哪个新值用作ParentId,您可以使用merge with output来获取旧CCId和新CCId之间的映射。捕获合并到表变量的输出,合并后,您可以从表变量更新ParentId

declare @T table
(
  OldCCId int,
  OldParentId int,
  NewCCId int
);

with C as 
(
  select M.*
  from dbo.CCMaster as M
  where ParentId is null and
        GId = 33 and
        BKId = 162
  union all
  select M.*
  from dbo.CCMaster as M
    inner join C
      on C.CCId = M.ParentId
)
merge into dbo.CCMaster as M
using C
on 1 = 0
when not matched then
  insert(GID, BKID, Class)
    values (C.GID, C.BKID, C.Class)
output C.CCId,
       C.ParentId,
       inserted.CCId
  into @T;

update M
set ParentId = T2.NewCCId
from CCMaster as M
  inner join @T as T1
    on M.CCId = T1.NewCCId
  inner join @T as T2
    on T1.OldParentId = T2.OldCCId;

SQL Fiddle