Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Каскадно копиране на ред с всички дъщерни редове и техните дъщерни редове и т.н

Предполагам, че Blocks.BlockID , Elevations.ElevationID , Floors.FloorID , Panels.PanelID са първични ключове и автоматично генерирани IDENTITY .

  • Един Block има много Elevations .
  • Една Elevation има много Floors .
  • Един Floor има много Panels .

Бих използвал MERGE с OUTPUT клауза.

MERGE може INSERT , UPDATE и DELETE редове. В този случай имаме нужда само от INSERT .

1=0 винаги е невярно, така че NOT MATCHED BY TARGET част винаги се изпълнява. По принцип може да има други разклонения, вижте документите.WHEN MATCHED обикновено се използва за UPDATE;WHEN NOT MATCHED BY SOURCE обикновено се използва за DELETE , но не ни трябват тук.

Тази сложна форма на MERGE е еквивалентен на обикновен INSERT , но за разлика от простия INSERT неговият OUTPUT клауза позволява препращане към колоните, от които се нуждаем. Позволява извличане на колони както от изходни, така и от таблици на местоназначение, като по този начин спестява съпоставяне между стари съществуващи идентификатори и нови идентификатори, генерирани от IDENTITY .

Блокиране

Копирайте даден Block и запомнете IDs на новия Block .Можем да използваме просто INSERT и SCOPE_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();

Коти

Копирайте Elevations от стария Block и ги присвоете на новия Block .Запомнете съпоставянето между старите IDs и прясно генерирани IDs в @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)
;

Етажи

Копирайте Floors използвайки картографиране между стар и нов ElevationID .Запомнете съпоставянето между старите IDs и прясно генерирани IDs в @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)
;

Панели

Копирайте Panels използвайки съпоставяне между стар и нов FloorID .Това е последното ниво на подробности, така че можем да използваме просто INSERT и не запомнете съпоставянето на 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. Скриване на SQL база данни от Management Studio

  2. комбиниране на днес и общото предишно от днес на същата колона води до една sql заявка

  3. Съвети за използване на SQL Server със Salesforce

  4. Как да зададете стойност по подразбиране за съществуваща колона

  5. Неуспешно влизане за потребител (Microsoft SQL Server, грешка:18456) SQL Server 2005