Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Kaskadowo skopiuj wiersz ze wszystkimi wierszami podrzędnymi i ich wierszami podrzędnymi itp.

Zakładam, że Blocks.BlockID , Elevations.ElevationID , Floors.FloorID , Panels.PanelID są kluczami podstawowymi i automatycznie generowanymi IDENTITY .

  • Jeden Block ma wiele Elevations .
  • Jedna Elevation ma wiele Floors .
  • Jedno Floor ma wiele Panels .

Użyłbym MERGE z OUTPUT klauzula.

MERGE może INSERT , UPDATE i DELETE rows.W tym przypadku potrzebujemy tylko INSERT .

1=0 jest zawsze fałszywe, więc NOT MATCHED BY TARGET część jest zawsze wykonywana.Ogólnie rzecz biorąc, mogą istnieć inne gałęzie, zobacz docs.WHEN MATCHED jest zwykle używany do UPDATE;WHEN NOT MATCHED BY SOURCE jest zwykle używany do DELETE , ale nie potrzebujemy ich tutaj.

Ta zawiła forma MERGE jest odpowiednikiem prostego INSERT , ale w przeciwieństwie do prostego INSERT jego OUTPUT klauzula pozwala na odwołanie się do potrzebnych nam kolumn. Pozwala na pobranie kolumn zarówno z tabel źródłowych, jak i docelowych, zapisując w ten sposób mapowanie między starymi istniejącymi identyfikatorami a nowymi identyfikatorami wygenerowanymi przez IDENTITY .

Zablokuj

Skopiuj jeden podany Block i zapamiętaj ID nowego Block .Możemy użyć prostego INSERT i SCOPE_IDENTITY tutaj, ponieważ BlockID jest kluczem podstawowym i można wstawić tylko jeden wiersz.

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

Elewacje

Skopiuj Elevations ze starego Block i przypisz je do nowego Block .Pamiętaj mapowanie między starymi IDs i świeżo wygenerowane IDs w @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)
;

Podłogi

Skopiuj Floors za pomocą mapowania między starym i nowym ElevationID .Pamiętaj mapowanie między starymi IDs i świeżo wygenerowane IDs w @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)
;

Panele

Skopiuj Panels używając mapowania między starym i nowym FloorID .To jest ostatni poziom szczegółów, więc możemy użyć prostego INSERT i nie przejmuj się mapowaniem 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. Dlaczego ISNUMERIC('.') zwraca 1?

  2. Pakiet SSIS wyświetla błąd po wdrożeniu SQL Server 2012

  3. Jak przyspieszyć DbSet.Add()?

  4. Lista operatorów porównania SQL Server

  5. Widoki w SQL Server