Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Xếp tầng sao chép một hàng với tất cả các hàng con và các hàng con của chúng, v.v.

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ều Elevations .
  • Một Elevation có nhiều Floors .
  • Một Floors có nhiều Panels .

Tôi sẽ sử dụng MERGE với OUTPUT mệnh đề.

MERGE có thể INSERT , UPDATEDELETE 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
;



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Lỗi SQL 2008 VS 2012:Cú pháp không chính xác gần từ khóa 'COMPUTE'

  2. Làm thế nào để lấy mức lương cao thứ n từ một bảng mà không cần sử dụng TOP và truy vấn phụ?

  3. Chẩn đoán bế tắc trong SQL Server 2005

  4. Hibernate (/ JPA) phân trang phía máy chủ và MS SQL Server

  5. Trả lại danh sách các cột được tính toán trong SQL Server