29 de mayo de 2001

I.R. con Triggers (SQL)

Probablemente en las futuras versiones de SQL Server Microsoft incluya la propagación en cascada de las restricciones de claves externas, de momento hasta la versión 7, o lo gestionamos en la aplicación cliente o con procedimientos almacenados.

Estos procedimientos los podemos aplicar a cualquier gestor de base de datos, (SQL Server, Informix, Oracle, Sybase, etc), siempre verificando la sintaxis, ya que de un gestor a otro varía. Los procedimientos expuestos son aplicables a SQL Server.

Tablas Inserted y Deleted

Estas tablas contienen las filas modificadas almacenadas en el registro de transacciones, en realidad son vistas, su estructura coincide con la tabla que acaba de ser modificada. Se utilizan para conocer que cambios se han realizado, hago referencia a ellas dentro de los Triggers.

Borrado en cascada

Este tipo de disparador es fácil de implementar. Con un ejemplo lo ilustraremos mejor, vamos a crear un Trigger para borrar la cabecera de una factura y sus líneas.
CREATE TRIGGER CabFac_Del_LinFac ON CabFac                
FOR DELETE AS
IF @@ROWCOUNT = 0  
  RETURN  
DELETE LinFac  
FROM LinFac L, deleted d  
WHERE L.Id_Fac = d.Id_Fac  
IF @@ERROR  0  
  BEGIN  
    RAISEERROR (‘Error al borrar líneas de factura….’, 16, 1)  
    ROLLBACK TRAN
    RETURN
  END
Hay que tener presente que los Triggers se activan posteriormente a la acción, por tanto hay que revisar las restricciones de clave externa de la tabla de CabFac para que permita borrar.

Actualizaciones en cascada

Esto si que se complica un poco. Pensemos en lo que significa modificar una clave primaria, seria como eliminar una fila e insertar una nueva, esto hace que perdamos la relación entre las filas a las que deben afectar los cambios. Personalmente os recomiendo que limitéis la actualización a una fila, de este modo las tablas inserted y deleted solo tendrán una fila. Utilicemos el ejemplo de la cabecera y líneas de factura para ilustrar este procedimiento.
CREATE TRIGGER
CabFac_Upd_LinFac ON CabFac  
FOR UPDATE AS  
   DECLARE @nRows INT, @nId_Old INT, @nId_new INT  
  SELECT @nRows = @@ROWCOUNT  
  IF @nRows = 0  
    RETURN  
  IF UPDATED(Id_Fac)  
    BEGIN  
    IF @nRows = 1  
      BEGIN  
        SELECT @nId_Old = Id_Fac FROM deleted  
        SELECT @nId_New = Id_Fac FROM inserted  
        UPDATE LinFac SET id_Fac = @nId_New  
        WHERE Id_Fac = @nId_Old  
      END  
  ELSE  
    BEGIN  
      RAISERROR (‘No se puede actualizar mas de una Factura a la vez’, 16, 1)  
      ROLLBACK TRAN  
      RETURN  
    END
  END

Algunas recomendaciones

Revisar las restricciones de claves externas ya que pueden impedir que se dispare el Trigger.
Una buena técnica para las actualizaciones en cascada es insertar una nueva fila con el valor de la clave nueva, modificar las filas de la tabla que hacen referencia a este valor y por ultimo eliminar la fila antigua.

Rapidito

Como podéis observar integrar todo este código de Triggers es una tarea ardua, sobre todo en bases de datos con muchas tablas, para agilizar este proceso podemos utilizar el Asistente para Upsizing del VFP (solo SQL Server y Oracle :-( ) , el Access (con mucho cuidado ;-) ) u otra herramienta especifica para estos menesteres.

Luis Rey García
Advanced & Frontdata Systems, S.L.

No hay comentarios. :

Publicar un comentario