oon*_*alo 6 sql t-sql sql-server sql-server-2008
我希望能够在同一个表中克隆记录及其后代.我的表的一个例子如下:
表格1
id | parentid | name
---------------------
1 | 0 | 'Food'
2 | 1 | 'Taste'
3 | 1 | 'Price'
4 | 2 | 'Taste Requirements'
Run Code Online (Sandbox Code Playgroud)
"id"列是主键并自动递增."食物"记录(即id = 1)在其下面有两个记录,称为"品味"和"价格"."味道"记录下面有一个名为"味道要求"的记录.我希望能够克隆'Food'记录,以便Table1看起来如下所示:
表格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'
Run Code Online (Sandbox Code Playgroud)
(其中'Cookies'是我想要创建的新类别的名称).我可以使用以下方法选择'Food'的所有后代:
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
Run Code Online (Sandbox Code Playgroud)
我可以使用以下方法克隆'Food'记录(即id = 1)
insert into Table1 ( parentid, name )
select ( parentid, 'Cookies' )
from Table1 where id = 1
Run Code Online (Sandbox Code Playgroud)
但我在尝试将两个查询结合起来克隆"食物"的后代时遇到了问题.此外,我试图避免使用存储过程,触发器,curosrs等.我正在尝试做什么?我在网上看到了一些例子但是无法将它们应用到我的要求中.
正如马丁所建议的,您需要启用IDENTITY_INSERT才能推动自己的身份价值观。您可能还需要获取表锁以确保 Max( Id ) 返回正确的值。
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
Run Code Online (Sandbox Code Playgroud)
结果
编号 | 父 ID | 姓名 --| -------- | ----------------- 1 | 0 | 食物 2 | 1 | 品尝 3 | 1 | 价格 4 | 2 | 口味要求 5 | 0 | 食物副本 7 | 5 | 味道副本 8 | 5 | 价格副本 9 | 7 | 口味要求副本
| 归档时间: |
|
| 查看次数: |
303 次 |
| 最近记录: |