Вставить внутри рекурсивный CTE в SQL Server - PullRequest
0 голосов
/ 25 февраля 2020

У меня есть таблица, которая имеет отношение записи родитель-потомок по двум полям. Я написал запрос с рекурсивным cte, который возвращает все дочерние записи к определенной. Теперь мне нужно вставить их в другую таблицу, где отношение родитель-потомок установлено с помощью полей Recorded, ParentId. RecordId - это идентификатор, первичный ключ. Есть ли способ выполнить вставку внутри CTE, чтобы появился идентификатор (RecordId), который я могу использовать при получении (и вставке) дочерних записей как ParentId?

Схема исходной таблицы:

CREATE TABLE dbo.table1 
(
    PartIndex1 nvarchar(30) NOT NULL,
    PartName1 nvarchar(30) NOT NULL,
    PartType nvarchar(5) NOT NULL,
    PartIndex2 nvarchar(30) NOT NULL,
    PartName2 nvarchar(30) NOT NULL,
    Qty int NOT NULL,

    CONSTRAINT PK_table1 PRIMARY KEY CLUSTERED (PartIndex1, PartName1, PartType, PartIndex2, PartName2, Qty)
) ON [PRIMARY]
GO

Пример сценария данных:

INSERT INTO dbo.table1(PartIndex1, PartName1, PartType, PartIndex2, PartName2, Qty) 
VALUES (N'PI1', N'PN001', N'B', N'PI1', N'PN002', 1)
GO

INSERT INTO dbo.table1(PartIndex1, PartName1, PartType, PartIndex2, PartName2, Qty) 
VALUES (N'PI1', N'PN001', N'D', N'PI1', N'PN003', 1)
GO

INSERT INTO dbo.table1(PartIndex1, PartName1, PartType, PartIndex2, PartName2, Qty) 
VALUES (N'PI1', N'PN002', N'D', N' ', N'B01', 40)
GO

INSERT INTO dbo.table1(PartIndex1, PartName1, PartType, PartIndex2, PartName2, Qty) 
VALUES (N'PI1', N'PN002', N'D', N'PI1', N'PN003', 2)
GO

INSERT INTO dbo.table1(PartIndex1, PartName1, PartType, PartIndex2, PartName2, Qty) 
VALUES(N'PI1', N'PN002', N'D', N'PI2', N'PN004', 1)
GO

INSERT INTO dbo.table1(PartIndex1, PartName1, PartType, PartIndex2, PartName2, Qty) 
VALUES (N'PI1', N'PN006', N'B', N'PI1', N'PN002', 3)
GO

INSERT INTO dbo.table1(PartIndex1, PartName1, PartType, PartIndex2, PartName2, Qty) 
VALUES (N'PI1', N'PN006', N'B', N'PI2', N'PN004', 1)
GO

INSERT INTO dbo.table1(PartIndex1, PartName1, PartType, PartIndex2, PartName2, Qty) 
VALUES (N'PI1', N'PN007', N'B', N'PI1', N'PN003', 2)
GO

Мой рекурсивный запрос CTE и результат:

; WITH cte AS
(SELECT
    *
  FROM dbo.table1
  WHERE partIndex1 = 'PI1'
  AND partName1 = 'PN001'

  UNION ALL

  SELECT
    t2.*
  FROM cte o
  JOIN dbo.table1 t2
    ON o.partIndex2 = t2.partIndex1
    AND o.partName2 = t2.partName1)
SELECT
  *
FROM cte


PartIndex1   PartName1  PartType PartIndex2  PartName2  Qty
------------ ---------- -------- ----------- ---------- ---
PI1          PN001      B        PI1         PN002      1
PI1          PN001      D        PI1         PN003      1
PI1          PN002      D                    B01        40
PI1          PN002      D        PI1         PN003      2
PI1          PN002      D        PI2         PN004      1

У меня есть все дочерние записи 'PN001'. И мне нужно вставить его в другую таблицу.

Целевая таблица:

CREATE TABLE dbo.table2 
(
    RecordId INT IDENTITY,
    Parent INT NULL,
    SetName NVARCHAR(128) NOT NULL,
    PartIndex1 NVARCHAR(30) NOT NULL,
    PartName1 NVARCHAR(30) NOT NULL,
    PartType NVARCHAR(5) NOT NULL,
    PartIndex2 NVARCHAR(30) NOT NULL,
    PartName2 NVARCHAR(30) NOT NULL,
    Qty INT NOT NULL,

    CONSTRAINT PK_table1 PRIMARY KEY CLUSTERED (RecordId)
)
ON [PRIMARY]
GO

Ожидаемый результат:

RecordId  ParentId SetName   PartIndex1   PartName1  PartType PartIndex2  PartName2  Qty
--------- -------- --------- ------------ ---------- -------- ----------- ---------- ---
42351     NULL     DataSet41 PI1          PN001      B        PI1         PN002      1
42352     NULL     DataSet41 PI1          PN001      D        PI1         PN003      1
42353     42353    DataSet41 PI1          PN002      D                    B01        40
42354     42353    DataSet41 PI1          PN002      D        PI1         PN003      2
42355     42353    DataSet41 PI1          PN002      D        PI2         PN004      1   

1 Ответ

0 голосов
/ 25 февраля 2020

Предполагается, что вы уже создали таблицу "dbo.table2" в своей базе данных.

Вы можете использовать этот запрос: - Но я не знаю, как вы получаете значения для ParentId.

    insert into dbo.table3 
    ( Parent,
      SetName,
      PartIndex1,
      PartName1,
      PartType,
      PartIndex2,
      PartName2,
      Qty)
select t2.Parent,'DataSet41' as SetName,t1.PartIndex1,t1.PartName1,t1.PartType,t1.PartIndex2,
t1.PartName2,t1.Qty from dbo.table1 t1 left outer join dbo.table3 t2 on t1.partindex1=t2.partindex1

Пожалуйста, обновите информацию о том, как вы получаете значение для productid, поскольку он не является столбцом идентификаторов и не используется в dbo.table1.

...