如何从同一张表复制TreeView的行并使用不同的ID列更新并复制parent_id

时间:2018-09-10 15:47:07

标签: sql-server

enter image description here

我想复制表并将不同的值放在Type = B列和auto_increment id上并复制父ID

表格=菜单

Id | parent_id | order | section | name | url | type

100 | NULL | 7 | web | Tasks | ~/en/Tasks | A

102 | 100 | 1 | web | Pages | ~/en/Pages | A

103 | 100 | 4 | web | Category | ~/en/Category | A

104 | NULL | 3 | web | DLM | ~/en/DLM | A

105 | 104 | 6 | web | ONS | ~/en/ONS | A

106 | 104 | 2 | web | HBO | ~/en/HBO | A

107 | NULL | 7 | web | Tasks | ~/en/Tasks | B

108 | 107 | 1 | web | Pages | ~/en/Pages | B

109 | 107 | 4 | web | Category | ~/en/Category | B

110 | NULL | 3 | web | DLM | ~/en/DLM | B

111 | 110 | 6 | web | ONS | ~/en/ONS | B

112 | 110 | 2 | web | HBO | ~/en/HBO | B

2 个答案:

答案 0 :(得分:0)

这可能不是最有效的,但是可以完成工作。它假定名称是唯一的。我在示例中省略了不必要的列。另外,您不能将变量放入identity子句中,因此需要将其包装在EXEC中

IF OBJECT_ID (N'paths', N'U') IS NOT NULL 
DROP TABLE paths
IF OBJECT_ID (N'new_paths', N'U') IS NOT NULL 
DROP TABLE new_paths

CREATE TABLE paths (
    id INT,
    parent_id INT,
    name NVARCHAR(20)
)

INSERT INTO dbo.paths
(id,parent_id,name)
VALUES
(100, NULL, 'Tasks'),
(102, 100, 'Pages'),
(103, 100, 'Category'),
(104, NULL, 'DLM'),
(105, 104, 'ONS'),
(106, 104, 'HBO')

DECLARE @start_value INT 
SET @start_value = (SELECT MAX(id) FROM paths) + 1

DECLARE @sql nvarchar(1000)
SET @sql = N'
CREATE TABLE new_paths (
    id INT IDENTITY(' + CAST(@start_value AS nvarchar) + ',1),
    parent_id INT,
    name NVARCHAR(20)
)
'
EXEC sp_executesql @stmt = @sql

INSERT INTO new_paths (parent_id,name)
SELECT Parent_id, name FROM dbo.paths

;WITH mappings AS (
SELECT n.*, p.id AS old_id
FROM new_paths n
INNER JOIN paths p
ON p.name = n.name
)

UPDATE n
SET n.parent_id = m.id
FROM new_paths n
INNER JOIN mappings m
ON m.old_id = n.parent_id

--SELECT * FROM new_paths

答案 1 :(得分:0)

请参见以下解决问题的方法,如果不清楚,请在注释中提出问题,我在代码注释中添加了一些解释

已编辑,用于管理GUID(根据评论)

-- declare table var
declare @table table ([Increment] int identity(1,1), Id uniqueidentifier, [parent_id] nvarchar(50), [order] int, [section] nvarchar(50), [name] nvarchar(50), [url] nvarchar(50), [type] nvarchar(50))

-- insert values into this table
insert into @table
select [Id],
    [parent_id], 
    [order], 
    [section], 
    [name], 
    [url], 
    'B'
from your_table
where [type] = 'A'

-- loop your temp table
declare @max_temp int = (select max(Increment) from @table)
declare @curr int = 1
declare @parent_value uniqueidentifier = null

while (@curr <= @max_temp)
begin
    -- do diffrent inserts depend on parent_id value
    if (select parent_id from @table) = null
    begin
        -- set below var, it will be used in next insert where parent_id is not null
        set @parent_value = (select Id from @table where Increment = @curr)

        insert into your_table ([parent_id], [order], [section], [name], [url], [type])
        select 
            [parent_id], 
            [order], 
            [section], 
            [name], 
            [url], 
            [type]
        from @table 
        where Id = @curr
    end
    else
    begin
        insert into your_table ([parent_id], [order], [section], [name], [url], [type])
        select 
            isnull(@parent_value, [parent_id]), 
            [order], 
            [section], 
            [name], 
            [url], 
            [type]
        from @table 
        where Id = @curr
    end

    -- update current
    set @curr = @curr + 1
end