SQL – Cloner un logging et ses descendants

J'aimerais pouvoir cloner un disque et ses descendants dans la même table. Un exemple de ma table serait le suivant:

Tableau 1

id | parentid | name --------------------- 1 | 0 | 'Food' 2 | 1 | 'Taste' 3 | 1 | 'Price' 4 | 2 | 'Taste Requirements' 

La colonne "id" est la key primaire et les incréments automatiques. L'logging «Food» (c'est-à-dire où id = 1) comporte deux loggings appelés «Taste» et «Price». L'logging «Taste» comporte un logging appelé «Taste Requirements». J'aimerais pouvoir cloner l'logging 'Food' afin que Table1 ressemble à ceci:

Tableau 1

 id | parentid | name --------------------- 1 | 0 | 'Food' 2 | 1 | 'Taste' 3 | 1 | 'Price' 4 | 2 | 'Taste Requirements' 5 | 0 | 'Cookies' 6 | 5 | 'Taste' 7 | 5 | 'Price' 8 | 6 | 'Taste Requirements' 

(où 'Cookies' est le nom de la nouvelle catégorie que je veux créer). Je suis capable de sélectionner tous les descendants de 'Food' en utilisant:

 with Table1_CTE( id, parentid, name ) as ( select t.id, t.parentid, t.name from Table1 t where t.id = 1 union all select t.id, t.parentid,t. name from Table1 t inner join Table1_CTE as tc on t.parentid = tc.id ) select id, parentid, name from Table1_CTE 

et je suis capable de cloner juste l'logging 'Food' (ie où id = 1) en utilisant:

 insert into Table1 ( parentid, name ) select ( parentid, 'Cookies' ) from Table1 where id = 1 

mais j'ai de la difficulté à combiner les deux requêtes pour cloner les descendants de 'Food'. En outre, j'essaie d'éviter d'utiliser des procédures stockées, des triggersurs, des curosrs, etc. Est ce que j'essaye de faire possible? J'ai vu quelques exemples sur le web mais je n'ai pas pu les appliquer à mes exigences.

Comme Martin l'a suggéré, vous devez activer IDENTITY_INSERT pour que vous puissiez pousser vos propres valeurs d'identité. Vous devrez peut-être également acquérir un verrou de table pour vous assurer que Max (Id) renvoie la valeur correcte.

 If object_id('tempdb..#TestData') is not null Drop Table #TestData GO Create Table #TestData ( Id int not null identity(1,1) Primary Key , ParentId int not null , Name varchar(50) not null ) GO Set Identity_Insert #TestData On GO Insert #TestData( Id, ParentId, Name ) Values( 1,0,'Food' ) , ( 2,1,'Taste' ) , ( 3,1,'Price' ) , ( 4,2,'Taste Requirement' ); With Data As ( Select Cast(MaxId.Id + 1 As int) As Id , T.ParentId , 'Copy Of ' + T.name As Name , T.Id As OldId , 0 As OldParentId From #TestData As T Cross Join( Select Max( id ) As Id From #TestData ) As MaxId Where T.Name = 'Food' Union All Select Cast(Parent.id + Row_Number() Over( Order By Child.Id ) + 1 As int) , Parent.Id , 'Copy of ' + Child.Name , Child.Id , Child.ParentId From Data As Parent Join #TestData As Child On Child.ParentId = Parent.OldId ) Insert #TestData( Id, ParentId, Name ) Select Id, ParentId, Name From Data GO Set Identity_Insert #TestData Off GO 

Résultats

 id |  parentid |  prénom
 - |  -------- |  -----------------
 1 |  0 |  Aliments
 2 |  1 |  Goût
 3 |  1 |  Prix
 4 |  2 |  Exigence de goût
 5 |  0 |  Copie de nourriture
 7 |  5 |  Copie du goût
 8 |  5 |  Copie du prix
 9 |  7 |  Copie de l'exigence de goût

En supposant que votre CTE prenne un logging racine et tous ses descendants (cela ne semblait pas être le cas lorsque j'ai reproduit vos données ci-dessus), vous pouvez cloner tous les loggings sélectionnés et les insert comme ceci:

 with Table1_CTE( id, parentid, name ) as ( select t.id, t.parentid, t.name from Table1 t where c.icategoryid = 1 union all select t.id, t.parentid,t. name from Table1 inner join Table1_CTE as tc on t.parentid = tc.id ) insert into dbo.testinsertheirarchy ( parentid, name ) select parentid, name from Table1_CTE