Jeg antager, at Blocks.BlockID , Elevations.ElevationID , Floors.FloorID , Panels.PanelID er primærnøgler og autogenereret IDENTITY .
- Én
Blockhar mangeElevations. - Én
Elevationhar mangeFloors. - Én
Floorhar mangePanels.
Jeg ville bruge MERGE
med OUTPUT klausul.
MERGE kan INSERT , UPDATE og DELETE rows.I dette tilfælde behøver vi kun INSERT .
1=0 er altid falsk, så NOT MATCHED BY TARGET del udføres altid. Generelt kan der være andre grene, se docs.WHEN MATCHED bruges normalt til at UPDATE;WHEN NOT MATCHED BY SOURCE bruges normalt til at DELETE , men vi har ikke brug for dem her.
Denne indviklede form for MERGE svarer til simpel INSERT , men i modsætning til simpel INSERT dens OUTPUT klausulen gør det muligt at henvise til de kolonner, vi har brug for. Det giver mulighed for at hente kolonner fra både kilde- og destinationstabeller og gemmer således en kortlægning mellem gamle eksisterende ID'er og nye ID'er genereret af IDENTITY .
Bloker
Kopier en given Block og husk ID af den nye Block .Vi kan bruge simpel INSERT og SCOPE_IDENTITY her, fordi BlockID er primærnøgle, og der kan kun indsættes én række.
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();
Koder
Kopiér Elevations fra gammel Block og tildel dem til den nye Block .Husk kortlægningen mellem gamle IDs og nygenererede IDs i @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)
;
Etager
Kopiér Floors ved hjælp af kortlægning mellem gammelt og nyt ElevationID .Husk kortlægningen mellem gamle IDs og nygenererede IDs i @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)
;
Paneler
Kopiér Panels ved hjælp af kortlægning mellem gammelt og nyt FloorID .Dette er det sidste niveau af detaljer, så vi kan bruge simple INSERT og husk ikke kortlægningen af 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
;