sql >> データベース >  >> RDS >> Sqlserver

すべての子行とその子行などを含む行をカスケードコピーします

    Blocks.BlockIDだと思います 、Elevations.ElevationIDFloors.FloorIDPanels.PanelID 主キーであり、自動生成されたIDENTITY

    • 1つのBlock 多くのElevationsがあります 。
    • 1つのElevation 多くのFloorsがあります 。
    • 1つのFloors 多くのPanelsがあります 。

    MERGEを使用します OUTPUTを使用 条項。

    MERGE INSERTできます 、UPDATE およびDELETE 行。この場合、必要なのはINSERTだけです。 。

    1=0 は常にfalseであるため、NOT MATCHED BY TARGET 一部は常に実行されます。通常、他のブランチが存在する可能性があります。ドキュメントを参照してください。WHEN MATCHED 通常、UPDATEに使用されます;WHEN NOT MATCHED BY SOURCE 通常、DELETEに使用されます 、ただし、ここでは必要ありません。

    この複雑な形式のMERGE 単純なINSERTと同等です 、ただし、単純なINSERTとは異なります そのOUTPUT 句を使用すると、必要な列を参照できます。ソーステーブルと宛先テーブルの両方から列を取得できるため、IDENTITYによって生成された古い既存のIDと新しいIDの間のマッピングを保存できます。 。

    ブロック

    指定されたBlockを1つコピーします IDsを覚えておいてください 新しいBlockの 。単純なINSERTを使用できます およびSCOPE_IDENTITY ここでは、BlockID は主キーであり、挿入できる行は1つだけです。

    DECLARE @blockToCopy int = 1;
    DECLARE @VarNewBlockID int;
    INSERT INTO Blocks
        (ProjectID
        ,BlockName
        ,BlockDescription)
    SELECT
        ProjectID
        ,'NewNameTest'
        ,'NewDescTest'
    FROM Blocks
    WHERE Blocks.BlockID = @blockToCopy
    ;
    SET @VarNewBlockID = SCOPE_IDENTITY();
    

    標高

    Elevationsをコピーします 古いBlockから それらを新しいBlockに割り当てます 。古いIDs間のマッピングを覚えておいてください 新しく生成されたIDs @MapElevationsで 。

    DECLARE @MapElevations TABLE(OldElevationID int, NewElevationID int);
    
    MERGE INTO Elevations
    USING
    (
        SELECT
            ElevationID
            ,@VarNewBlockID AS BlockID
            ,ElevationName
            ,ElevationDescription
        FROM Elevations
        WHERE Elevations.BlockID = @blockToCopy
    ) AS Src
    ON 1 = 0
    WHEN NOT MATCHED BY TARGET THEN
    INSERT
        (BlockID
        ,ElevationName
        ,ElevationDescription)
    VALUES
        (Src.BlockID
        ,Src.ElevationName
        ,Src.ElevationDescription)
    OUTPUT
        Src.ElevationID AS OldElevationID
        ,inserted.ElevationID AS NewElevationID
    INTO @MapElevations(OldElevationID, NewElevationID)
    ;
    

    フロア

    Floorsをコピーします 古いものと新しいものの間のマッピングを使用するElevationID 。古いIDs間のマッピングを覚えておいてください 新しく生成されたIDs @MapFloorsで 。

    DECLARE @MapFloors TABLE(OldFloorID int, NewFloorID int);
    
    MERGE INTO Floors
    USING
    (
        SELECT
            Floors.FloorID
            ,M.NewElevationID AS ElevationID
            ,Floors.FloorName
            ,Floors.FloorDescription
        FROM
            Floors
            INNER JOIN Elevations ON Elevations.ElevationID = Floors.ElevationID
            INNER JOIN @MapElevations AS M ON M.OldElevationID = Elevations.ElevationID
        WHERE Elevations.BlockID = @blockToCopy
    ) AS Src
    ON 1 = 0
    WHEN NOT MATCHED BY TARGET THEN
    INSERT
        (ElevationID
        ,FloorName
        ,FloorDescription)
    VALUES
        (Src.ElevationID
        ,Src.FloorName
        ,Src.FloorDescription)
    OUTPUT
        Src.FloorID AS OldFloorID
        ,inserted.FloorID AS NewFloorID
    INTO @MapFloors(OldFloorID, NewFloorID)
    ;
    

    パネル

    Panelsをコピーします 古いものと新しいものの間のマッピングを使用するFloorID 。これは詳細の最後のレベルであるため、単純なINSERTを使用できます。 IDsのマッピングを忘れないでください 。

    INSERT INTO Panels
        (FloorID
        ,PanelName
        ,PanelDescription)
    SELECT
        M.NewFloorID
        ,Panels.PanelName
        ,Panels.PanelDescription
    FROM
        Panels
        INNER JOIN Floors ON Floors.FloorID = Panels.FloorID
        INNER JOIN Elevations ON Elevations.ElevationID = Floors.ElevationID
        INNER JOIN @MapFloors AS M ON M.OldFloorID = Floors.FloorID
    WHERE Elevations.BlockID = @blockToCopy
    ;
    



    1. mysqlの特定のユーザーの合計ログイン-ログアウト時間を計算する

    2. master..spt_valuesを使用して列を分割する理由(および方法)

    3. Django / Python:設定を指すようにリレーションを更新します。AUTH_USER_MODEL

    4. クエリPythonで名前でフィールドを取得するにはどうすればよいですか?