Eliminar filas de dos tablas
-
20-08-2019 - |
Pregunta
Tengo dos mesas. Esas tablas tienen dos relaciones entre ellas.
Table 1
* ID_XPTO (PK)
* Detail
Table 2
* ID_XPTO (FK) (PK)
* ID_XPTO2 (FK) (PK)
Esas dos relaciones existen.
Table 1 -< Table2
Table 1 -< Table2
Mi pregunta es que necesito eliminar alguna fila en la tabla 1. Actualmente estoy haciendo,
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)
Sé que podría usar ON DELETE SET NULL en table2. De esa manera, podría buscar todas las filas con valor nulo en ID_XPTO2 y eliminarlas, pero DBA no quiere usarlo.
¿Hay alguna solución mejor para hacer este proceso?
Solución
Tiene estas opciones:
-
Eliminar en dos declaraciones, como lo está haciendo ahora. Eliminar de la Tabla2 primero.
-
Eliminar de dos tablas en una declaración, si su marca de base de datos admite la sintaxis
DELETE
de varias tablas (por ejemplo, MySQL). Esto no es SQL estándar, pero es útil. -
Use restricciones de integridad referencial en cascada (entiendo que su DBA ha rechazado esta opción).
-
Escriba un activador
BEFORE DELETE
en la Tabla1, para eliminar o establecer NULL cualquier referencia en la Tabla2. Consulte con su DBA para ver si esto es más aceptable que las restricciones de RI en cascada.
Finalmente, le aconsejaría hablar con su DBA y hacerle la misma pregunta que hizo aquí. Descubra qué solución preferiría que usara. La gente de StackOverflow puede responder preguntas técnicas, pero parece que se trata de una pregunta de política de TI .
Otros consejos
Use ON DELETE CASCADE
. Automáticamente eliminará las filas de referencia.
¿Por qué no usas 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
Dos métodos que conozco:
-
Puede usar ON DELETE CASCADE
-
Escriba su SQL para limpiar después de sí mismo, es decir:
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