2012-04-19 24 views
10

Digamos que tengo 3 mesas en una jerarquía:VEZ de disparadores y Cascade caminos

TableA -> TableB -> TableC 

TableC tiene una relación de clave externa con TableB y TableB tiene una relación de clave externa con TableA.

Si elimino un registro en TableA, debería eliminar en cascada hacia abajo a través de la jerarquía. Usar ON DELETE CASCADE funcionaría bien.

Sin embargo digamos que necesito poner un disparador INSTEAD OF en TableC. Según entiendo, un activador INSTEAD OF no se puede colocar en una tabla que tenga una cascada de eliminación. Tomado de MSDN:

Para los desencadenadores INSTEAD OF, la opción DELETE no está permitida en las tablas que tienen una relación referencial que especifica una acción en cascada ON DELETE.

Si tengo que tomar la eliminación en cascada TableB->TableC fuera, que tendría que utilizar un disparador INSTEAD OF para hacer cumplir la integridad referencial, y luego tengo el mismo problema con TableB->TableA. Este es un ejemplo simple, pero imagine que el camino de la cascada es mucho más grande. Parece que podría bola de nieve fácilmente a lo largo de una larga trayectoria en cascada.

¿Cuáles son las mejores prácticas para hacer frente a este escenario?

+1

¿Qué desea que haga el desencadenador (en lugar de eliminar) que no rompería la integridad referencial? –

+0

Quiero evitar añadir más complicaciones al ejemplo, ya que no estoy buscando soluciones de rediseño de tablas, sino más bien una respuesta al escenario específico. Sin embargo, para referencia, TableC usa el modelo de lista de adyacencia para almacenar una jerarquía. Estoy usando el desencadenador INSTEAD OF para eliminar de forma recursiva a través de la jerarquía. HierarchyID no es posible debido al uso de SS2005. –

+2

Sin rediseñar la tabla, quizás esto pueda ayudar: [Servidor SQL: borrar con LLAVE EXTRANJERA autorreferencial] (http://explainextended.com/2010/03/03/sql-server-deleting-with-self-referential- foreign-key /) –

Respuesta

3

Suponiendo que debe utilizar los desencadenadores INSTEAD OF y los desencadenadores DESPUÉS no son una opción, lo mejor es a) controlar estrictamente el esquema para que pueda b) guiar el INSTEAD OF desencadena de forma regular para implementar el CASCADE DELETE y cualquier otra operación que necesites.

Crea las restricciones FK como antes, pero sin ningún comportamiento en cascada. En el nombre de FK, utilice una convención para indicar qué tipo de comportamiento en cascada y el comportamiento personalizado deberían producirse, por ejemplo:

  • FK_UC_DC_Table1_Table2 - actualización en cascada, cascada de eliminar
  • FK_UC_DN_Table1_Table3 - actualización en cascada, eliminar conjunto nulo

Use lo que tenga sentido, pero cree las FK, son metadatos útiles para la generación de códigos, y puede usar los nombres FK para registrar las directivas para el generador de códigos.

Me gustaría ir un paso más allá y aislar estas tablas en su propio esquema. No se comportarán del mismo modo que otras tablas, y al principio tendrán más problemas al probar y ajustar la generación de código. Lo mejor es mantener todo esto en cuarentena, y fácilmente identificable por un contenedor común.

Un esquema dedicado también le informará a cualquiera que modifique los datos que se aplican las diferentes reglas y comportamientos.

3

El estándar de mejores prácticas es definir VEZ de disparadores en vistas, no en tablas .

Si tiene que utilizar un desencadenador en una actualización/eliminación de FK, es mejor usar DESPUÉS, ya que siempre se ejecutará.

Si desea cancelar las acciones en cascada pero retiene las FK, simplemente configure la acción FK en NO ACTION.

+0

Lamentablemente, los desencadenadores DESPUÉS no son una solución en este escenario ya que se violará la integridad referencial antes de que se dispare el desencadenante. –

+0

¿Puede ser más específico sobre lo que quiere que el disparador * haga *? – matchdav

+0

Consulte el segundo comentario debajo de la pregunta. Sin embargo, no estoy tan preocupado con la implementación, sino más bien con lo que haría la gente dado el escenario genérico. Aprecio que esto pueda depender de la implementación, ¡pero aún así! –