Sql 级联复制包含所有子行及其子行的行,等等
我试图跟踪商业建筑施工中的项目(特别是混凝土覆层)Sql 级联复制包含所有子行及其子行的行,等等,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我试图跟踪商业建筑施工中的项目(特别是混凝土覆层) 一个项目可以有多个街区(一个街区是一个独立的建筑) 一个块可以有多个立面(建筑面;北、东等) 立面可以有多个楼层(高层建筑) 地板可以有许多面板(面板是混凝土覆层的一部分) 为了使在数据库中构建面板时更容易,以便可以跟踪它们,我希望能够复制一个块(因为10次中有9次,每个块都是相同的,只是有一些小的更改) 就餐桌而言: 块 Blocks.BlockID, Blocks.BlockName, Blocks.BlockDescription
- 一个项目可以有多个街区(一个街区是一个独立的建筑)
- 一个块可以有多个立面(建筑面;北、东等)
- 立面可以有多个楼层(高层建筑)
- 地板可以有许多面板(面板是混凝土覆层的一部分)
Blocks.BlockID,
Blocks.BlockName,
Blocks.BlockDescription,
Projects.ProjectID
Elevations.ElevationID,
Elevations.ElevationName,
Elevations.ElevationDescription,
Blocks.BlockID
Floors.FloorID,
Floors.FloorName,
Floors.FloorDescription,
Elevations.ElevationID
Panels.PanelID,
Panels.PanelName,
Panels.PanelDescription,
Floors.FloorID
高程
Blocks.BlockID,
Blocks.BlockName,
Blocks.BlockDescription,
Projects.ProjectID
Elevations.ElevationID,
Elevations.ElevationName,
Elevations.ElevationDescription,
Blocks.BlockID
Floors.FloorID,
Floors.FloorName,
Floors.FloorDescription,
Elevations.ElevationID
Panels.PanelID,
Panels.PanelName,
Panels.PanelDescription,
Floors.FloorID
楼层
Blocks.BlockID,
Blocks.BlockName,
Blocks.BlockDescription,
Projects.ProjectID
Elevations.ElevationID,
Elevations.ElevationName,
Elevations.ElevationDescription,
Blocks.BlockID
Floors.FloorID,
Floors.FloorName,
Floors.FloorDescription,
Elevations.ElevationID
Panels.PanelID,
Panels.PanelName,
Panels.PanelDescription,
Floors.FloorID
面板
Blocks.BlockID,
Blocks.BlockName,
Blocks.BlockDescription,
Projects.ProjectID
Elevations.ElevationID,
Elevations.ElevationName,
Elevations.ElevationDescription,
Blocks.BlockID
Floors.FloorID,
Floors.FloorName,
Floors.FloorDescription,
Elevations.ElevationID
Panels.PanelID,
Panels.PanelName,
Panels.PanelDescription,
Floors.FloorID
如果我复制一个块,它需要
在第二个层叠(尝试复制每个立面内的所有楼层)之后,会出现错误。我知道为什么会出错(我不是将原始ID与要复制到的新ID一起列出,而是自己输出新ID,这样它就没有什么可复制的了,因为它们还不存在),但我不知道如何修复它。我假设
Blocks.BlockID
,Elevations.ElevationID
,floorrid
,Panels.PanelID
是主键和自动生成的IDENTITY
- 一个
有许多块
立面
- 一个
有许多立面
楼层
- 一个
有许多楼层
面板
OUTPUT
子句
合并
可以插入
,更新
和删除
行。
在这种情况下,我们只需要插入
1=0
始终为false,因此始终执行目标不匹配的部分。
一般来说,可能还有其他分支,请参见文档。
匹配时
通常用于更新
;
当与源代码不匹配时
通常用于删除
,但此处不需要它们
这种复杂的合并
形式相当于简单的插入
,
但与简单的INSERT
不同,它的OUTPUT
子句允许引用我们需要的列。
它允许从源表和目标表中检索列,从而保存映射
在旧的现有ID和由IDENTITY
生成的新ID之间
块
复制一个给定的块
,并记住新块的ID
。
我们可以在这里使用简单的INSERT
和SCOPE\u IDENTITY
,
因为BlockID
是主键,只能插入一行
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();
高程
Blocks.BlockID,
Blocks.BlockName,
Blocks.BlockDescription,
Projects.ProjectID
Elevations.ElevationID,
Elevations.ElevationName,
Elevations.ElevationDescription,
Blocks.BlockID
Floors.FloorID,
Floors.FloorName,
Floors.FloorDescription,
Elevations.ElevationID
Panels.PanelID,
Panels.PanelName,
Panels.PanelDescription,
Floors.FloorID
从旧的块
复制立面
,并将其指定给新的块
。
还记得@MapElevations
中旧ID
和新生成的ID
之间的映射吗
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)
;
楼层
Blocks.BlockID,
Blocks.BlockName,
Blocks.BlockDescription,
Projects.ProjectID
Elevations.ElevationID,
Elevations.ElevationName,
Elevations.ElevationDescription,
Blocks.BlockID
Floors.FloorID,
Floors.FloorName,
Floors.FloorDescription,
Elevations.ElevationID
Panels.PanelID,
Panels.PanelName,
Panels.PanelDescription,
Floors.FloorID
使用新旧立面ID
之间的映射复制楼层
。
还记得@maplowers
中旧ID
和新生成的ID
之间的映射吗
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)
;
面板
Blocks.BlockID,
Blocks.BlockName,
Blocks.BlockDescription,
Projects.ProjectID
Elevations.ElevationID,
Elevations.ElevationName,
Elevations.ElevationDescription,
Blocks.BlockID
Floors.FloorID,
Floors.FloorName,
Floors.FloorDescription,
Elevations.ElevationID
Panels.PanelID,
Panels.PanelName,
Panels.PanelDescription,
Floors.FloorID
使用新旧floorrid
之间的映射复制面板
。
这是最后一级详细信息,因此我们可以使用simpleINSERT
,而不必使用
记住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
;
为什么需要复制立面图、配电盘和项目?新块不能仍然指向现有标高等,因此不是代码编写服务。当你陷入困境时,我们可以帮助你,但我们不会为你做你的工作。如果你试着写这篇文章,然后分享你尝试过的内容和部分,怎么样就前端而言,存储过程是最容易实现的,但以最简单的为准easiest@cloudsafe因为每个其他项目都必须构建和安装,所以每个项目都必须是唯一可识别的。@VladimirBaranov以前从未使用过merge。要想知道怎么做可不是件容易的事。有机会得到一些指导吗?:)妙极了!我为它添加了另一层,因此现在面板可以有许多“产品”(例如windows)。这一解释使得将面板合并/输出变得很容易,而新的最终层则是一个简单的插入!非常感谢!