Excluir linhas de duas tabelas
-
20-08-2019 - |
Pergunta
Eu tenho duas tabelas. Essas tabelas têm dois relação entre eles.
Table 1
* ID_XPTO (PK)
* Detail
Table 2
* ID_XPTO (FK) (PK)
* ID_XPTO2 (FK) (PK)
Essas duas relações existe.
Table 1 -< Table2
Table 1 -< Table2
A minha pergunta é que eu preciso apagar alguns linha na tabela 1. Atualmente estou fazendo,
declare @table Table (xptoTable2 int)
insert into @table
select ID_XPTO2
from Table2
where ID_XPTO = @ID_XPTO
delete from Table2
where ID_XPTO = @ID_XPTO
delete from Table
where ID_XPTO in (select xptoTable2from @table)
Eu sei que eu poderia usar ON DELETE SET NULL em table2. Nessa maneira que eu poderia, então, procurar todas as linhas com valor nulo no ID_XPTO2 e excluí-los, mas DBA não quer usá-lo.
Existe alguma solução melhor para fazer este processo?
Solução
Você tem as seguintes opções:
-
Excluir em duas demonstrações, como você está fazendo agora. Excluir da Table2 em primeiro lugar.
-
Excluir de duas tabelas em uma instrução, se a sua marca de banco de dados suporta multi-mesa sintaxe
DELETE
(por exemplo, MySQL). Este não é o padrão SQL, mas é útil. -
Use cascata restrições de integridade referencial (Eu entendo o seu DBA tem vetou essa opção).
-
Escrever um
BEFORE DELETE
gatilho na tabela 1, para eliminar ou conjunto NULL qualquer referência no Table2. Verifique com o seu DBA para ver se este é mais aceitável do que as restrições RI em cascata.
Finalmente, gostaria de aconselhar falar com o seu DBA e fazendo a mesma pergunta que você fez aqui. Descubra o que solução ele / ela prefere que você use. Pessoas em StackOverflow pode responder a perguntas técnicas, mas parece que você está lidando com um TI questão política .
Outras dicas
Use ON DELETE CASCADE
. Ele será automaticamente Excluir referenciando linhas.
Por que você não usar ON DELETE CASCASE
?
DROP TABLE t_f
DROP TABLE t_m
CREATE TABLE t_m (id INT NOT NULL IDENTITY PRIMARY KEY , value VARCHAR(50))
CREATE TABLE t_f (id INT NOT NULL IDENTITY PRIMARY KEY, m INT, CONSTRAINT fk_m FOREIGN KEY (m) REFERENCES t_m(id) ON DELETE CASCADE)
INSERT INTO t_m (value) VALUES ('test')
INSERT INTO t_f (m) VALUES (1)
DELETE FROM t_m
SELECT * FROM t_m
SELECT * FROM t_f
id value
------------ ------
0 rows selected
id m
------------ ------
0 rows selected
Dois métodos que eu conheço:
-
Você pode usar ON DELETE CASCADE
-
Escreva seu SQL para limpar depois de si ou seja:
DECLARE @DetailCriteria ... SET @DetailCriteria = '....' BEGIN TRAN -- First clear the Table2 of any child records DELETE FROM Table2 WHERE ID_XPTO IN (SELECT ID_XPTO FROM Table1 WHERE Detail = @DetailCriteria) OR ID_XPTO2 IN (SELECT ID_XPTO FROM Table1 WHERE Detail = @DetailCriteria) -- Next clear Table2 (which will delete fine because you've followed the referential chain) DELETE FROM Table1 WHERE Detail = @DetailCriteria -- commit if you're happy (should check @@ERROR first) COMMIT