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
Block
có nhiềuElevations
. - Một
Elevation
có nhiềuFloors
. - Một
Floors
có 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
;