Continuando com a pergunta Obtenha todas as linhas envolvidas entre as relações de tabelas , agora tenho que excluir todas as linhas desses códigos. Explico:
tenho um SQL Server 2016 com as seguintes tabelas:
CREATE TABLE [dbo].[Code] (
[CodeId] INT IDENTITY (1, 1) NOT NULL,
[Serial] VARCHAR(20) NOT NULL,
[AggregationLevelId] TINYINT NOT NULL,
[CommissioningFlag] TINYINT NOT NULL,
[ ... ]
CONSTRAINT [PK_CODE] PRIMARY KEY CLUSTERED ([CodeId] ASC),
CONSTRAINT [UC_CODE_SERIAL] UNIQUE NONCLUSTERED ([Serial] ASC),
CONSTRAINT [FK_Code_AggregationLevelConfiguration]
FOREIGN KEY ([AggregationLevelId])
REFERENCES [dbo].[AggregationLevelConfiguration] ([AggregationLevelConfigurationId])
)
CREATE TABLE [dbo].[Aggregation] (
[AggregationId] INT NOT NULL,
CONSTRAINT [PK_AGGREGATIONS] PRIMARY KEY CLUSTERED ([AggregationId] ASC),
CONSTRAINT [FK_Aggregation_Code]
FOREIGN KEY ([AggregationId])
REFERENCES [dbo].[Code] ([CodeId])
)
CREATE TABLE [dbo].[AggregationChildren] (
[AggregationChildrenId] INT NOT NULL,
[AggregationId] INT NOT NULL,
[Position] INT NOT NULL,
CONSTRAINT [PK_AGGREGATION_CHILDS] PRIMARY KEY CLUSTERED ([AggregationChildrenId] ASC),
CONSTRAINT [FK_AggregationChildren_Code]
FOREIGN KEY ([AggregationChildrenId])
REFERENCES [dbo].[Code] ([CodeId]),
CONSTRAINT [FK_AggregationChildren_Aggregation]
FOREIGN KEY ([AggregationId])
REFERENCES [dbo].[Aggregation] ([AggregationId]) ON DELETE CASCADE
)
Aggregation
e AggregationChildren
representam as relações entre as linhas na tabela Code
.
Uma agregação terá 1 ou mais filhos de agregação. E também, um código em filhos de agregação pode ter 0 ou mais filhos de agregação.
É algo assim:
Code1
|___________________
| |
Code2 Code3
|________ |________________
| | | | |
Code4 Code5 Code6 Code7 Code8
Todos os itens acima são Code.Serial
valores.
Todos os Code.CodeId
valores para esses seriais estão na Aggregation
tabela para Code1
, Code2
e Code3
.
E, para esses seriados, Code2
, Code3
, Code4
, Code5
, Code6
, Code7
, e Code8
estão na AggregationChildren
tabela.
Eu preciso excluir as linhas desses seriais Aggregation
e AggregationChildren
tabelas.
Usando a resposta da pergunta anterior, tentei fazer isso:
DECLARE @Serial VARCHAR(20) = 'Code1';
;WITH rc AS
(
SELECT AggregationId Id
FROM dbo.Aggregation
WHERE AggregationId = (SELECT CodeId FROM dbo.Code WHERE Serial = @Serial)
UNION ALL
SELECT ac.AggregationChildrenId Id
FROM dbo.AggregationChildren ac
JOIN rc
ON ac.AggregationId = rc.Id
)
UPDATE c
SET CommissioningFlag = 130
FROM dbo.Code c
JOIN rc
ON c.CodeId = rc.Id;
GO
Delete ag from dbo.Aggregation ag
inner join rc
on ag.AggregationId = rc.Id;
Mas eu não sei como usar o DELETE FROM
com a rc
declaração. Mas acho que só preciso dos Codes
que estão em Aggregation
e AggregationChildren
. Talvez eu precise modificar a With
instrução para obter primeiro as linhas na Aggregation
tabela porque tenho uma tabela ON DELETE CASCADE
em AggregationChildren
.
Como posso obter todos os códigos para excluir da Aggregation
tabela?
De acordo com seu esquema de tabela onde há uma regra
ON DELETE CASCADE
emFK_AggregationChildren_Aggregation
chave estrangeira, você pode excluir apenas os registros afetados da tabela 'Agregação'.Use a mesma consulta recursiva para buscar linhas, mas adicionando AggregationID de filhos e, em seguida, exclua códigos AggregationId distintos.
Este é o resultado:
db<>fiddle here