Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 需要使用父ID复制数据_Sql_Sql Server_Sql Server 2012 - Fatal编程技术网

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