sql >> Database >  >> RDS >> Sqlserver

Kopieer een rij met alle onderliggende rijen en hun onderliggende rijen, enz.

Ik neem aan dat Blocks.BlockID , Elevations.ElevationID , Floors.FloorID , Panels.PanelID zijn primaire sleutels en automatisch gegenereerde IDENTITY .

  • Eén Block heeft veel Elevations .
  • Eén Elevation heeft veel Floors .
  • Eén Floor heeft veel Panels .

Ik zou MERGE gebruiken met OUTPUT clausule.

MERGE kan INSERT , UPDATE en DELETE rijen.In dit geval hebben we alleen INSERT . nodig .

1=0 is altijd onwaar, dus de NOT MATCHED BY TARGET deel wordt altijd uitgevoerd. In het algemeen kunnen er andere branches zijn, zie docs.WHEN MATCHED wordt meestal gebruikt om UPDATE;WHEN NOT MATCHED BY SOURCE wordt meestal gebruikt om DELETE , maar we hebben ze hier niet nodig.

Deze ingewikkelde vorm van MERGE is gelijk aan eenvoudig INSERT ,maar in tegenstelling tot eenvoudig INSERT zijn OUTPUT clausule maakt het mogelijk om te verwijzen naar de kolommen die we nodig hebben. Hiermee kunnen kolommen worden opgehaald uit zowel bron- als doeltabellen, waardoor een toewijzing wordt opgeslagen tussen oude bestaande ID's en nieuwe ID's gegenereerd door IDENTITY .

Blokkeren

Kopieer een gegeven Block en onthoud de ID van het nieuwe Block .We kunnen eenvoudige INSERT . gebruiken en SCOPE_IDENTITY hier, omdat BlockID is de primaire sleutel en er kan slechts één rij worden ingevoegd.

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();

Verhogingen

Kopieer Elevations van oud Block en wijs ze toe aan het nieuwe Block .Denk aan de toewijzing tussen oude IDs en vers gegenereerde IDs in @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)
;

Vloeren

Kopieer Floors met behulp van mapping tussen oud en nieuw ElevationID .Denk aan de toewijzing tussen oude IDs en vers gegenereerde IDs in @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)
;

Panelen

Kopieer Panels met behulp van mapping tussen oud en nieuw FloorID .Dit is het laatste detailniveau, dus we kunnen eenvoudig INSERT . gebruiken en denk niet aan de toewijzing van 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. Het uitvoeringsplan van de query in postgresql handmatig wijzigen?

  2. Oracle bulkimport

  3. MySQL-query die waarden vergelijkt met waarden van vorige rijen

  4. Bepaal of twee namen dicht bij elkaar liggen