Sql 需要使用父ID复制数据
我有一个具有父子关系的表,并且希望为同一表中的不同实体复制相同的行,以保持父子关系彼此同步 桌子Sql 需要使用父ID复制数据,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,我有一个具有父子关系的表,并且希望为同一表中的不同实体复制相同的行,以保持父子关系彼此同步 桌子 Id ParentId EnityId CreatedTime 1 null 'me202' 20/1/2019 12:00:25 2 1 'me202' 20/1/2019 12:02:25 3 2 'me202' 20/1/2019 12:04:25 4 1 'me202' 20/1/2019 12:06:25 我想复制实体“me203
Id ParentId EnityId CreatedTime
1 null 'me202' 20/1/2019 12:00:25
2 1 'me202' 20/1/2019 12:02:25
3 2 'me202' 20/1/2019 12:04:25
4 1 'me202' 20/1/2019 12:06:25
我想复制实体“me203”的上述记录,例如:
Id ParentId EnityId CreatedTime
1 null 'me202' 20/1/2019 12:00:25
2 1 'me202' 20/1/2019 12:02:25
3 2 'me202' 20/1/2019 12:04:25
4 1 'me202' 20/1/2019 12:06:25
5 null 'me203' 20/1/2019 12:00:25
6 5 'me203' 20/1/2019 12:02:25
7 6 'me203' 20/1/2019 12:04:25
8 5 'me203' 20/1/2019 12:06:25
我正在使用以下查询:
INSERT INTO abc (ParentId, EnityId)
Select
Case
WHEN ParentId IS NULL THEN ParentId
ELSE
(Select top 1 id From abc Where
CreatedTime = (Select CreatedTime From abc Where id = ParentId )
AND id != ParentId AND EnityId = 'me203')
END
, 'me203'
From abc Where entityid= 'me202'
上述查询将父项插入为null。如果id列的类型为int identity1,1:
哇,这很难看,但它确实有用
DECLARE @StartID int = 1;
DECLARE @Rows table (ID int, ParentID int, EntityID char(5), CreatedTime datetime2(0), [Level] int);
WITH rCTE AS(
SELECT YT.ID,
YT.ParentID,
YT.EntityID,
YT.CreatedTime,
1 AS [Level]
FROM dbo.YourTable YT
WHERE YT.ID = @StartID
UNION ALL
SELECT YT.ID,
YT.ParentID,
YT.EntityID,
YT.CreatedTime,
r.[Level] + 1 AS [Level]
FROM dbo.YourTable YT
JOIN rCTE r ON YT.ParentID = r.ID)
INSERT INTO @Rows (ID,
ParentID,
EntityID,
CreatedTime,
Level)
SELECT r.ID,
r.ParentID,
'me203' AS EntityID,
r.CreatedTime,
r.[Level]
FROM rCTE r
ORDER BY r.ID;
DECLARE @I int = 1;
DECLARE @IDs table (New int, Old int)
WHILE @I <= (SELECT MAX([Level]) FROM @Rows) BEGIN
MERGE INTO dbo.YourTable YT USING @Rows R ON [Level] != @i
WHEN NOT MATCHED THEN
INSERT (ParentID,EntityID, CreatedTime)
VALUES (R.ParentID, R.EntityID, R.CreatedTime)
OUTPUT inserted.ID, R.ID
INTO @IDs (New,Old);
UPDATE R
SET R.ParentID = I.New
FROM @Rows R
JOIN @IDs I ON R.ParentID = I.Old
WHERE R.[Level] = @I + 1
SET @I = @I + 1;
END
您只能通过迭代来实现这一点;插入子级的一个要求是知道父级ID的值。但是,如果其他用户正在对表执行插入操作,则可能会出现并发问题。例如,如果谁否决了这一点,谁就可以解释为什么这一点没有用,那就太好了;当DB Fiddle显示时,这将提供请求的结果。
DECLARE @StartID int = 1;
DECLARE @Rows table (ID int, ParentID int, EntityID char(5), CreatedTime datetime2(0), [Level] int);
WITH rCTE AS(
SELECT YT.ID,
YT.ParentID,
YT.EntityID,
YT.CreatedTime,
1 AS [Level]
FROM dbo.YourTable YT
WHERE YT.ID = @StartID
UNION ALL
SELECT YT.ID,
YT.ParentID,
YT.EntityID,
YT.CreatedTime,
r.[Level] + 1 AS [Level]
FROM dbo.YourTable YT
JOIN rCTE r ON YT.ParentID = r.ID)
INSERT INTO @Rows (ID,
ParentID,
EntityID,
CreatedTime,
Level)
SELECT r.ID,
r.ParentID,
'me203' AS EntityID,
r.CreatedTime,
r.[Level]
FROM rCTE r
ORDER BY r.ID;
DECLARE @I int = 1;
DECLARE @IDs table (New int, Old int)
WHILE @I <= (SELECT MAX([Level]) FROM @Rows) BEGIN
MERGE INTO dbo.YourTable YT USING @Rows R ON [Level] != @i
WHEN NOT MATCHED THEN
INSERT (ParentID,EntityID, CreatedTime)
VALUES (R.ParentID, R.EntityID, R.CreatedTime)
OUTPUT inserted.ID, R.ID
INTO @IDs (New,Old);
UPDATE R
SET R.ParentID = I.New
FROM @Rows R
JOIN @IDs I ON R.ParentID = I.Old
WHERE R.[Level] = @I + 1
SET @I = @I + 1;
END