我认为
Blocks.BlockID,
Elevations.ElevationID,
Floors.FloorID,
Panels.PanelID是主键和自动生成的
IDENTITY。
- 一个
Block
有很多Elevations
。 - 一个
Elevation
有很多Floors
。 - 一个
Floor
有很多Panels
。
我会用
MERGEwith
OUTPUT子句。
MERGE可以
INSERT,
UPDATe和
DELETE行。在这种情况下,我们只需要
INSERT。
1=0始终为假,因此
NOT MATCHED BY TARGET始终执行该部分。通常,可能还有其他分支,请参阅文档。
WHENMATCHED通常用于
UPDATE;
WHEN NOT MATCHED BY SOURCE通常用于
DELETE,但是我们在这里不需要它们。
这种复杂的形式
MERGE等效于simple
INSERT,但与simple不同,
INSERT它的
OUTPUT子句允许引用我们需要的列。它允许从源表和目标表中检索列,从而节省了旧的现有ID和由生成的新ID之间的映射
IDENTITY。
堵塞
复制给定的一个,
Block并记住
ID新的
Block。我们可以在此处使用simple
INSERT和
SCOPE_IDENTITY,因为它
BlockID是主键,并且只能插入一行。
DECLARE @blockToCopy int = 1;DECLARE @VarNewBlockID int;INSERT INTO Blocks (ProjectID ,BlockName ,BlockDescription)SELECT ProjectID ,'NewNameTest' ,'NewDescTest'FROM BlocksWHERe Blocks.BlockID = @blockToCopy;SET @VarNewBlockID = SCOPE_IDENTITY();
高程
Elevations从旧版本复制
Block并分配给新版本
Block。还记得老之间的映射
IDs和新生成的
IDs在
@MapElevations。
DECLARE @MapElevations TABLE(OldElevationID int, NewElevationID int);MERGE INTO ElevationsUSING( SELECt ElevationID ,@VarNewBlockID AS BlockID ,ElevationName ,ElevationDescription FROM Elevations WHERe Elevations.BlockID = @blockToCopy) AS SrcON 1 = 0WHEN NOT MATCHED BY TARGET THENINSERT (BlockID ,ElevationName ,ElevationDescription)VALUES (Src.BlockID ,Src.ElevationName ,Src.ElevationDescription)OUTPUT Src.ElevationID AS OldElevationID ,inserted.ElevationID AS NewElevationIDINTO @MapElevations(OldElevationID, NewElevationID);
楼层数
Floors使用新旧版本之间的映射进行复制
ElevationID。还记得老之间的映射
IDs和新生成的
IDs在
@MapFloors。
DECLARE @MapFloors TABLE(OldFloorID int, NewFloorID int);MERGE INTO FloorsUSING( 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 SrcON 1 = 0WHEN NOT MATCHED BY TARGET THENINSERT (ElevationID ,FloorName ,FloorDescription)VALUES (Src.ElevationID ,Src.FloorName ,Src.FloorDescription)OUTPUT Src.FloorID AS OldFloorID ,inserted.FloorID AS NewFloorIDINTO @MapFloors(OldFloorID, NewFloorID);
面板
Panels使用新旧版本之间的映射进行复制
FloorID。这是最后一级的细节,因此我们可以使用简单的方法,
INSERT而无需记住的映射
IDs。
INSERT INTO Panels (FloorID ,PanelName ,PanelDescription)SELECt M.NewFloorID ,Panels.PanelName ,Panels.PanelDescriptionFROM 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.FloorIDWHERe Elevations.BlockID = @blockToCopy;



