Trigger

Gatilho ou trigger é um recurso de programação executado sempre que o evento associado ocorrer. Trigger é um tipo especial de procedimento armazenado, que é executado sempre que há uma tentativa de modificar os dados de uma tabela que é protegida por ele.

É muito utilizada para ajudar a manter a consistência dos dados ou para propagar alterações em um determinado dado de uma tabela para outras. Um bom exemplo é um gatilho criado para controle de quem alterou a tabela, nesse caso, quando a alteração for efetuada, o gatilho é "disparado" e grava em uma tabela de histórico de alteração, o usuário e data/hora da alteração.

Em SQL, para se criar um trigger utiliza-se do CREATE TRIGGER, e para removê-lo deve-se usar DROP TRIGGER.

DROP TRIGGER nome ON tabela [ CASCADE | RESTRICT ] 

Quando há uma tentativa de inserir, atualizar ou excluir os dados em uma tabela, e um TRIGGER tiver sido definido na tabela para essa ação específica, ele será executado automaticamente, não podendo nunca ser ignorado.

O TRIGGER e a instrução que o aciona são tratados como uma única transação, que poderá ser revertida em qualquer ponto do procedimento

Uma função de gatilho pode ser criada para executar antes (BEFORE) ou após (AFTER) as consultas INSERT, UPDATE OU DELETE, uma vez para cada registro (linha) modificado ou por instrução SQL. Logo que ocorre um desses eventos do gatilho a função do gatilho é disparada automaticamente para tratar o evento.

A função de gatilho deve ser declarada como uma função que não recebe argumentos e que retorna o tipo TRIGGER. Após criar a função de gatilho, estabelecemos o gatilho pelo comando CREATE TRIGGER. Uma função de gatilho pode ser utilizada por vários gatilhos.

CREATE TRIGGER nome { BEFORE | AFTER } 
   ON tabela [ FOR [ EACH ] { ROW | STATEMENT } ]
   EXECUTE PROCEDURE nome_da_função ( argumentos )
  • NEW: No caso da trigger ser disparada por um INSERT a variável NEW irá abrigar os valores a ser inseridos, e caso seja um evento do tipo UPDATE, NEW irá conter a nova versão dos valores a serem atualizados (veja o exemplo no código abaixo).
  • OLD: Esta variável é utilizada no caso do evento DELETE armazena os dados que estão sendo excluídos, e no caso do UPDATE a versão antiga dos dados.

O acesso dos dados se dá em ambas as variáveis dessa maneira: NEW.COD_CLIENTE, por exemplo.

  • TG_NAME: Contém o nome do trigger que foi disparado.
  • TG_WHEN: Contem quando o evento foi disparado, sendo BEFORE ou AFTER.
  • TG_LEVEL: Diz em qual ponto da trigger.
  • TG_OP: Tipo de operção que está sendo executada: INSERT, UPDATE ou DELETE.
  • TG_RELID: Contém a ID do objeto que está disparando o gatilho.
  • TG_RELNAME: Nome da tabela que disparou o gatilho (obsoleto).
  • TG_TABLE_NAME: Nome da tabela que disparou o gatilho.
  • TG_NAME_SCHEMA: Nome do schema onde está a tabela que disparou a trigger.
  • TG_NARGS: Número de argumentos fornecidos para a Stored Function do trigger.
  • TG_ARGV[]: Os argumentos que foram fornecidos.
  • Sabe-se que pode atrelar mais de uma trigger por tabela, então qual a ordem de execução das triggers?
    R: A ordem de execução é alfabética.
  • Triggers podem ser recursivas?
    R: Sim! Os gatilhos podem executar comandos SQL, e os mesmos podem disparar outras triggers. Este cenário é conhecido como cascateamento de triggers, assim pode ser que a trigger passe a se “auto disparar”, ou seja, chamadas recursivas da própria trigger, fique atento a recursões infinitas!

CREATE TABLE funcionarios (

    ID_FUNCIONARIO SERIAL,

    NOME VARCHAR(255),

    IDADE INTEGER,

    FUNCAO VARCHAR(150),

    PRIMARY KEY(ID_FUNCIONARIO)

);

CREATE TABLE FUNCIONARIOS_LOG (

    USUARIO VARCHAR(150) NOT NULL,

    TIPO_ACAO VARCHAR(25) NOT NULL,

    DATA_ALTERACAO TIMESTAMP NOT NULL,

    PRIMARY KEY (COD_ALTERACAO));

CREATE FUNCTION valida_dados_funcionario() RETURNS TRIGGER AS $$

BEGIN

    IF NEW.NOME IS NULL THEN

        RAISE EXCEPTION 'Por Favor, digite o nome do funcionario!';

    END IF;

    IF NEW.IDADE < 0 THEN

        RAISE EXCEPTION 'Desculpe, o funcionario não pode ter % anos', NEW.IDADE;

    END IF;

    INSERT INTO FUNCIONARIOS_LOG (USUARIO, TIPO_ACAO, DATA_ALTERACAO) VALUES (CURRENT_USER, TG_OP, CURRENT_TIMESTAMP);

    RETURN NEW;

END;

$$ LANGUAGE plpgsql;

CREATE TRIGGER validacao_insert BEFORE INSERT OR UPDATE ON funcionarios

FOR EACH ROW EXECUTE PROCEDURE valida_dados_funcionario();

Made with Slides.com