Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Cascade menyalin baris dengan semua baris anak dan baris anak mereka, dll

Saya berasumsi bahwa Blocks.BlockID , Elevations.ElevationID , Floors.FloorID , Panels.PanelID adalah kunci utama dan IDENTITY yang dibuat secara otomatis .

  • Satu Block memiliki banyak Elevations .
  • Satu Elevation memiliki banyak Floors .
  • Satu Floors memiliki banyak Panels .

Saya akan menggunakan MERGE dengan OUTPUT klausa.

MERGE dapat INSERT , UPDATE dan DELETE baris. Dalam hal ini kita hanya perlu INSERT .

1=0 selalu salah, jadi NOT MATCHED BY TARGET bagian selalu dieksekusi. Secara umum, mungkin ada cabang lain, lihat dokumen.WHEN MATCHED biasanya digunakan untuk UPDATE;WHEN NOT MATCHED BY SOURCE biasanya digunakan untuk DELETE , tapi kita tidak membutuhkannya di sini.

Bentuk rumit dari MERGE setara dengan INSERT sederhana , tetapi tidak seperti INSERT sederhana OUTPUT-nya klausa memungkinkan untuk merujuk ke kolom yang kita butuhkan. Ini memungkinkan untuk mengambil kolom dari tabel sumber dan tujuan sehingga menyimpan pemetaan antara ID lama yang ada dan ID baru yang dihasilkan oleh IDENTITY .

Blokir

Salin yang diberikan Block dan ingat IDs dari Block new yang baru .Kita dapat menggunakan INSERT sederhana dan SCOPE_IDENTITY di sini, karena BlockID adalah kunci utama dan hanya satu baris yang dapat dimasukkan.

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();

Elevasi

Salin Elevation dari Block lama dan tetapkan mereka ke Block baru .Ingat pemetaan antara IDs lama dan IDs yang baru dibuat di @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)
;

Lantai

Salin Floors menggunakan pemetaan antara ElevationID lama dan baru .Ingat pemetaan antara IDs lama dan IDs yang baru dibuat di @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)
;

Panel

Salin Panels menggunakan pemetaan antara FloorID lama dan baru .Ini adalah detail tingkat terakhir, jadi kita bisa menggunakan INSERT sederhana dan jangan ingat pemetaan 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
;



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara menggunakan variabel untuk nama database di T-SQL?

  2. Memodifikasi Pekerjaan Agen SQL Server (T-SQL)

  3. Jalankan sp_msforeachdb dalam aplikasi Java

  4. Daftar Format Tanggal Tersedia dengan CONVERT() di SQL Server

  5. Bagaimana Anda memeriksa apakah IDENTITY_INSERT diatur ke ON atau OFF di SQL Server?