sql – 复制父,子和孙子记录

前端之家收集整理的这篇文章主要介绍了sql – 复制父,子和孙子记录前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个父表,表示一个文件,表中的每个记录在子表中有n个子记录.每个孩子记录可以有n个孙子记录.这些记录处于已发布状态.当用户修改已发布的文档时,我们需要克隆父项及其所有的子孙.

表结构如下所示:

CREATE TABLE [ql].[Quantlist] (
    [QuantlistId]   INT           IDENTITY (1,1) NOT NULL,[StateId]       INT           NOT NULL,[Title]         VARCHAR (500) NOT NULL,CONSTRAINT [PK_Quantlist] PRIMARY KEY CLUSTERED ([QuantlistId] ASC),CONSTRAINT [FK_Quantlist_State] FOREIGN KEY ([StateId]) REFERENCES [ql].[State] ([StateId])
);

儿童

CREATE TABLE [ql].[QuantlistAttribute]
(
    [QuantlistAttributeId] INT IDENTITY (1,1),[QuantlistId] INT NOT NULL,[Narrative] VARCHAR (500) NOT NULL,CONSTRAINT [PK_QuantlistAttribute] PRIMARY KEY ([QuantlistAttributeId]),CONSTRAINT [FK_QuantlistAttribute_QuantlistId] FOREIGN KEY ([QuantlistId]) REFERENCES [ql].[Quantlist]([QuantlistId]),)

CREATE TABLE [ql].[AttributeReference]
(
    [AttributeReferenceId] INT IDENTITY (1,[QuantlistAttributeId] INT NOT NULL,[Reference] VARCHAR (250) NOT NULL,CONSTRAINT [PK_QuantlistReference] PRIMARY KEY ([AttributeReferenceId]),CONSTRAINT [FK_QuantlistReference_QuantlistAttribute] FOREIGN KEY ([QuantlistAttributeId]) REFERENCES [ql].[QuantlistAttribute]([QuantlistAttributeId]),)

在我的存储过程中,我传入QuantlistId,我想要克隆为@QuantlistId.由于QuantlistAttribute表中有一个ForeignKey,所以我也可以很容易克隆.

INSERT INTO [ql].[Quantlist] (
    [StateId],[Title],) SELECT 
    1,Title,FROM [ql].[Quantlist]
    WHERE QuantlistId = @QuantlistId

SET @ClonedId = SCOPE_IDENTITY()

INSERT INTO ql.QuantlistAttribute(
        QuantlistId,Narrative)
    SELECT 
        @ClonedId,Narrative,FROM ql.QuantlistAttribute
    WHERE QuantlistId = @QuantlistId

故障归结于AttributeReference.如果我克隆了30个QuantlistAttribute记录,那么如何克隆参考表中的记录,并将其与刚插入到QuantlistAttribute表中的新记录进行匹配?

INSERT INTO ql.AttributeReference(
            QuantlistAttributeId,Reference,)
        SELECT 
            QuantlistAttributeId,FROM ql.QuantlistReference
        WHERE ??? I don't have a key to go off of for this.

我以为我可以使用一些临时链接表来保存旧的属性id以及新的属性id.我不知道如何将旧的Attribute Id插入临时表以及它们的新属性.通过QuantlistId插入现有的属性很简单,但是我无法确定如何确保以某种方式将正确的新旧Id连接在一起,以便可以克隆AttributeReference表.如果我可以获得新的和旧的Id链接的QuantlistAttribute,我可以加入该临时表,并找出如何恢复新克隆的引用与新克隆属性的关系.

对此的任何帮助将是非常棒的.我花了最后一天半的时间想出来,没有运气:/

请原谅一些sql不一致.我重新写了sql的真正快速,修剪了很多其他列,相关表和约束,这是不需要这个问题.

编辑

在做一点挖掘之后,我发现OUTPUT可能对此有用.有没有办法使用OUTPUT将我刚插入的QuantlistAttributeId记录映射到他们起源的QuantlistAttributeId?

解决方法

您可以使用OUTPUT获取插入的行.

>您可以根据ORDER BY c.QuantlistAttributeId ASC的顺序将数据插入到QuantlistAttribute中
>有一个临时表/表变量3列

> id标识列
>新的QuantlistAttributeId
>旧的QuantlistAttributeId.

>使用OUTPUT将QuantlistAttribute的新标识值插入到临时表/表变量中.
新的ID按照与c.QuantlistAttributeId相同的顺序生成
>使用由QuantlistAttributeId排序的row_number()根据表变量的row_number()和id匹配旧的QuantlistAttributeId和新的QuantlistAttributeIds,并更新表变量中的值或旧的QuantlistAttributeId
>使用临时表并加入AttributeReference并一次性插入记录.

注意:
INSERT INTO SELECT和ROW_NUMBER()中的ORDER BY需要匹配的旧的QuantlistAttributeId,因为查看您的问题,似乎没有其他逻辑键将旧的和新的记录映射到一起.

查询上述步骤

DECLARE @ClonedId INT,@QuantlistId INT = 0

INSERT INTO [ql].[Quantlist] (
    [StateId],[Title]
) SELECT 
    1,Title
    FROM [ql].[Quantlist]
    WHERE QuantlistId = @QuantlistId

SET @ClonedId = SCOPE_IDENTITY()
--Define a table variable to store the new QuantlistAttributeID and use it to map with the Old QuantlistAttributeID
DECLARE @temp TABLE(id int identity(1,newAttrID INT,oldAttrID INT)

INSERT INTO ql.QuantlistAttribute(
        QuantlistId,Narrative)
        --New QuantlistAttributeId are created in the same order as old QuantlistAttributeId  because of ORDER BY
        OUTPUT inserted.QuantlistAttributeId,NULL INTO @temp
    SELECT 
        @ClonedId,Narrative
    FROM ql.QuantlistAttribute c
    WHERE QuantlistId = @QuantlistId
    --This is required to keep new ids generated in the same order as old
    ORDER BY c.QuantlistAttributeId ASC

    ;WITH CTE AS
    (
        SELECT c.QuantlistAttributeId,--Use ROW_NUMBER to get matching id which is same as the one generated in @temp
        ROW_NUMBER()OVER(ORDER BY c.QuantlistAttributeId ASC) id
        FROM ql.QuantlistAttribute c
        WHERE QuantlistId = @QuantlistId
    )
    --Update the old value in @temp 
    UPDATE T
    SET oldAttrID = CTE.QuantlistAttributeId
    FROM @temp T
    INNER JOIN CTE ON T.id = CTE.id


INSERT INTO ql.AttributeReference(
            QuantlistAttributeId,Reference)
        SELECT 
            T.NewAttrID,Reference
        FROM ql.AttributeReference R
        --Use OldAttrID to join with ql.AttributeReference and insert NewAttrID
        INNER JOIN @temp T
        ON T.oldAttrID = R.QuantlistAttributeId

希望这可以帮助.

猜你在找的MsSQL相关文章