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?

¿Fue útil?

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:

  1. Puede usar ON DELETE CASCADE

  2. 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
    
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top