2008-10-29 18 views
9

Deseo crear un disparador para verificar qué se está eliminando contra las reglas comerciales y luego cancelar la eliminación si es necesario. ¿Algunas ideas?Cómo cancelo una eliminación en SQL

La solución utilizó el desencadenador En lugar de Eliminar. El rollback tran detuvo la eliminación. Tenía miedo de tener un problema de cascada cuando lo eliminé, pero eso no pareció suceder. Tal vez un gatillo no se puede disparar a sí mismo.

+0

Vale la pena ver lo que otras personas contribuyen antes de determinar la respuesta. La pregunta tiene menos de una hora. –

Respuesta

18

Use un disparador INSTEAD OF DELETE (vea MSDN) y decida dentro del activador lo que realmente desea hacer.

1

El activador puede revertir la transacción actual, lo que tendrá el efecto de cancelar la eliminación. Como también lo indica el póster anterior, también puede usar un en lugar de desencadenar.

1

según la documentación de MSDN sobre INSTEAD OF DELETE desencadenantes:

The deleted table sent to a DELETE trigger contains an image of the rows as they existed before the DELETE statement was issued.

Si he entendido bien la eliminación se ha hecho en ejecución. ¿Qué me estoy perdiendo?

De todos modos, no entiendo por qué desea eliminar los registros y si no se pasan las reglas de negocio, vuelva a eliminar esos registros. Juraría que debería ser más fácil probar si pasas las reglas de negocios antes de borrar los registros.

Y hubiera dicho que use una transacción, no he escuchado antes acerca de INSTEAD OF activadores.

+0

El problema es que la aplicación permite al usuario eliminar algo asignado a ellos, pero como no tengo el código fuente, solo puedo detenerlo en el nivel DB. No deseo que los usuarios eliminen las tareas que les han sido asignadas y que no están completas. –

7

La solución utilizó el desencadenador En lugar de Eliminar. El rollback tran detuvo la eliminación. Tenía miedo de tener un problema de cascada cuando hice la eliminación, pero parece que eso no sucedió. Tal vez un gatillo no se puede disparar a sí mismo. De todos modos, gracias a todos por su ayuda.

ALTER TRIGGER [dbo].[tr_ValidateDeleteForAssignedCalls] 
on [dbo].[CAL] 
    INSTEAD OF DELETE 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    DECLARE @RecType VARCHAR(1) 
    DECLARE @UserID VARCHAR(8) 
    DECLARE @CreateBy VARCHAR(8) 
    DECLARE @RecID VARCHAR(20) 

    SELECT @RecType =(SELECT RecType FROM DELETED) 
    SELECT @UserID =(SELECT UserID FROM DELETED) 
    SELECT @CreateBy =(SELECT CreateBy FROM DELETED) 
    SELECT @RecID =(SELECT RecID FROM DELETED) 

    -- Check to see if the type is a Call and the item was created by a different user 
    IF @RECTYPE = 'C' and not (@[email protected]) 

    BEGIN 
     RAISERROR ('Cannot delete call.', 16, 1) 
     ROLLBACK TRAN 
     RETURN 
    END 

    -- Go ahead and do the update or some other business rules here 
    ELSE 
     Delete from CAL where RecID = @RecID  

END 
+1

Si intenta eliminar más de un registro, obtiene el error: _Subquery devolvió más de 1 valor. Esto no está permitido cuando la subconsulta sigue =,! =, <, <= , >,> = o cuando la subconsulta se usa como una expresión. Por lo tanto, debe verificar los permisos de otra manera (como _seleccionar @C = conteo (1) desde ELIMINADO, donde ..._) – inon

Cuestiones relacionadas