Tôi giả sử rằng Blocks.BlockID , Elevations.ElevationID , Floors.FloorID , Panels.PanelID là khóa chính và IDENTITY được tạo tự động .
- Một
Blockcó nhiềuElevations. - Một
Elevationcó nhiềuFloors. - Một
Floorscó nhiềuPanels.
Tôi sẽ sử dụng MERGE
với OUTPUT mệnh đề.
MERGE có thể INSERT , UPDATE và DELETE Hàng. Trong trường hợp này, chúng ta chỉ cần INSERT .
1=0 luôn là false, vì vậy NOT MATCHED BY TARGET một phần luôn được thực thi. Nói chung, có thể có các nhánh khác, hãy xem tài liệu. WHEN MATCHED thường được sử dụng để UPDATE; WHEN NOT MATCHED BY SOURCE thường được sử dụng để DELETE , nhưng chúng tôi không cần chúng ở đây.
Dạng phức tạp này của MERGE tương đương với INSERT đơn giản , nhưng không giống như INSERT đơn giản OUTPUT của nó mệnh đề cho phép tham chiếu đến các cột mà chúng ta cần. Nó cho phép truy xuất các cột từ cả bảng nguồn và bảng đích, do đó lưu ánh xạ giữa các ID cũ hiện có và ID mới được tạo bởi IDENTITY .
Chặn
Sao chép một Block đã cho và nhớ ID của Block mới Chúng ta có thể sử dụng INSERT đơn giản và SCOPE_IDENTITY tại đây, bởi vì BlockID là khóa chính và chỉ có thể chèn một hàng.
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();
Độ cao
Sao chép Elevations từ Block cũ và gán chúng vào Block mới . Ghi nhớ ánh xạ giữa các ID cũ và ID mới được tạo trong @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)
;
Tầng
Sao chép Floors sử dụng ánh xạ giữa ElevationID cũ và mới . Ghi nhớ ánh xạ giữa các ID cũ và ID mới được tạo trong @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)
;
Bảng điều khiển
Sao chép Panels sử dụng ánh xạ giữa FloorID cũ và mới Đây là mức chi tiết cuối cùng, vì vậy chúng ta có thể sử dụng INSERT đơn giản và đừng nhớ ánh xạ của ID .
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
;