2012-05-04 24 views

Respuesta

29

En esta situación, es probable que sea mejor hacer un activador de "después" regular. Este es el enfoque más común para este tipo de situación.

Algo así como

CREATE TRIGGER TRG_AUD_DEL 
ON yourTable 
FOR DELETE 
AS 
    INSERT INTO my_audit_table (col1, col2, ...) 
    SELECT col1, col2... 
    FROM DELETED 

Lo que ocurrirá es, cuando un registro (o registros!) Se eliminan de la tabla, se insertará la fila eliminada en my_audit_table La tabla DELETED es una tabla virtual que contiene el registro (s) tal como fueron inmediatamente antes de la eliminación.

Además, tenga en cuenta que el desencadenador se ejecuta como parte de la transacción implícita en la instrucción de eliminación, por lo que si la eliminación falla y retrocede, el desencadenador también se revertirá.

+0

Gracias por la respuesta, que funciona bien – user1374263

+1

Tomando nota de que para la reversión a trabajar en un error que un bloque try/catch puede ser necesaria dentro de el desencadenante [(ejemplo)] (http://dba.stackexchange.com/questions/57909) posiblemente depende de qué causa el error. – crokusek

+1

Buen punto, pero recuerde que solo se aplica a RAISEERROR. Un error de terminación de sentencia regular (por ejemplo, violación de PK, etc.) dará como resultado que la reversión de la transacción implícita comience fuera del activador. –

10

También es posible usar INSTEAD OF DELETE

CREATE TRIGGER dbo.SomeTableYouWhatToDeleteFrom 
ON dbo.YourTable 
INSTEAD OF DELETE 
AS 
BEGIN 

    -- Some code you want to do before delete 

    DELETE YourTable 
    FROM DELETED D 
    INNER JOIN dbo.YourTable T ON T.PK_1 = D.PK_1 
END 
+8

EN LUGAR DE ELIMINAR no se puede utilizar ya que tengo eliminada la cascada habilitada en la tabla. – user1374263

+2

FWIW, podría cambiar todas las claves externas de eliminación en cascada a claves externas planas y procesar las eliminaciones desde este desencadenador, que dejarían en claro en un solo lugar todo lo que estaba sucediendo como resultado de la eliminación. – Tony

0

Se podría hacer en los pasos siguientes para digamos que en este ejemplo estoy usando tabla de clientes:

CREATE TABLE CUSTOMERS(
    ID INT    NOT NULL, 
    NAME VARCHAR (20)  NOT NULL, 
    AGE INT    NOT NULL, 
    ADDRESS CHAR (25) , 
    LAST_UPDATED DATETIME, 
    PRIMARY KEY (ID) 
); 
  1. Crear Historia:

    CREATE TABLE CUSTOMERS_HIST( 
    ID INT    NOT NULL, 
    NAME VARCHAR (20)  NOT NULL, 
    AGE INT    NOT NULL, 
    ADDRESS CHAR (25) , 
    LAST_UPDATED DATETIME, 
    PRIMARY KEY (ID) 
    ); 
    
  2. Trigger en la tabla de origen, como a continuación en caso de borrado:

    CREATE TRIGGER TRG_CUSTOMERS_DEL 
    ON CUSTOMERS 
    FOR DELETE 
    AS 
        INSERT INTO CUSTOMERS_HIST (ID, NAME, AGE, ADDRESS, LAST_UPDATED) 
        SELECT ID, NAME, AGE, ADDRESS, LAST_UPDATED 
        FROM DELETED 
    
Cuestiones relacionadas