sexta-feira, 5 de fevereiro de 2010

INSTEAD OF INSERT TRIGGER

Um analista hoje me questionou sobre as instead of triggers, como uma solução para uma tabela, que quando criada não contemplou chaves primárias ou qualquer tipo de controle de redundância. Devido a esse problema, a tabela já apresentava registros duplicados, e uma vez que o problema já existe, é necessário administrá-lo já que não podemos resolvê-lo.

Em busca da solução perfeita...


Uma das soluções possíveis foi a de criar uma instead of trigger. O conceito das instead of trigger, é como o próprio nome diz, substituir a execução do insert,update..  por um outro bloco de código. Ou seja, caso você esteja criando uma INSTEAD OF INSERT trigger, mas você deverá re-fazer o insert dentro da trigger. Parece meio doido? Também achei, mas para o que estávamos precisando, resolveu muito bem.

Depois de estudar um pouco, implementei este exemplo de como utilizar este tipo de trigger. Acompanhe:


CREATE TABLE TESTE_TRG_INSTEAD(
  CODIGO INT,
  NOME VARCHAR(100)
)
GO

ALTER TRIGGER TRG_TESTE_INSTEAD ON TESTE_TRG_INSTEAD
      INSTEAD OF INSERT
AS
BEGIN

      DECLARE @CODIGO INT
      SELECT
            @CODIGO=CODIGO
      FROM
            INSERTED
   
      IF EXISTS(SELECT 0 FROM TESTE_TRG_INSTEAD
                    WHERE CODIGO=@CODIGO)
      BEGIN
           
            RAISERROR ('Código já existe!', 16, 1)
            ROLLBACK TRAN

      END
      ELSE
      BEGIN

            SET NOCOUNT ON   
           
            INSERT INTO TESTE_TRG_INSTEAD
            SELECT CODIGO,NOME FROM INSERTED

            SET NOCOUNT OFF

      END

END
GO

INSERT INTO TESTE_TRG_INSTEAD VALUES (1,'Rodrigo')
INSERT INTO TESTE_TRG_INSTEAD VALUES (2,'Carolina')
INSERT INTO TESTE_TRG_INSTEAD VALUES (3,'Luisa')

Até aí em cima, tudo funciona!


INSERT INTO TESTE_TRG_INSTEAD VALUES (1,'Rodrigo')

Porém o insert aí de cima, gera a mensagem aí de baixo.


Msg 50000, Level 16, State 1, Procedure TRG_TESTE_INSTEAD, Line 16
Código já existe!
Msg 3609, Level 16, State 1, Line 1
The transaction ended in the trigger. The batch has been aborted.

Até a próxima!

Nenhum comentário:

Postar um comentário

Leave your comment here!