Manipulando Triggers no PostgreSQL

Olá novamente caros leitores!

Primeiramente me desculpem pela demora para liberar uma nova postagem sobre o Postgres, é que as últimas semanas foram muito movimentadas, realizei minha entrevista na UFSCar para o ingresso no programa de mestrado do Departamento de Computação e ainda na semana retrasada recebi a notícia da minha aprovação, então imaginem o tamanho da felicidade e a correria com as festas de fim de ano.

Bom, mas vamos ao que interessa, hoje irei falar sobre as triggers, ou funções de gatilho, como você queria chamar. Uma das coisas mais interessantes da implementação das funções no Postgres é que você pode escolher qual linguagem vai usar para programar sua trigger! Isso mesmo, então antes de mais nada, eu separei abaixo a lista de algumas linguagens, e o link para mais informações sobre elas, veja:

Agora que você já sabe dessa maravilha do Postgres irei dizer que aqui, iremos exemplificar as triggers utilizando a PL/pgSQL. Mas antes da prática no código fonte, iremos trabalhar um pouco sobre a definição e funcionamento das triggers no PostgreSQL.

Você deve saber que os nossos gatilhos funcionam baseados em eventos, dois: before (antes de alguma coisa) e after (depois de alguma coisa). Explicando: você pode determinar que uma trigger dispare após (after) a inserção em determinada tabela do banco ou antes (before) da tal inserção, por exemplo.

É muito importante que você dê uma olhada abaixo na lista de variáveis que podem ser utilizadas dentro da estrutura da função da sua trigger, vale a pena dar uma lida, no entanto existem duas que a leitura é obrigatória, que são a new e a old. Elas são usadas da seguinte maneira:

  • 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 exmplo. Abaixo você verá o exemplo de uma trigger.

Outras variáveis especiais que você pode usar:

  • 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.

Perguntas (quase) nunca feitas sobre triggers:

  • 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!

CRIAÇÃO DE UMA TRIGGER

Agora vamos a parte pática irei realizar um único exemplo, neste link você e encontrar mais exemplos de triggers. No nosso, considere as duas tabelas abaixo:

Repare que na construção da tabela funcionarios eu não coloquei nenhuma regra de validação, como por exemplo not null, foi de propósito! Nossa trigger irá realizar a (simples) validação da entrada de dados na tabela e em seguida guardar que tipo de operação foi feita, por quem e a data na tabela funcionarios_log.

Agora a construção da stored function que será “chamada” pela trigger e sua agregação como trigger:

Note que realizei as devidas validações utilizando o operador NEW, porque agora iremos atrelar a trigger a tabela dizendo que ela será executada durante um insert ou update. Observe também que o declaramos um return “trigger” e especificamos os delimitadores $$, você pode encontrar mais informações sobre a estruturação de procedures de triggers na documentação do PostgreSQL, e por fim note que especificamos qual linguagem é utilizada para a construção da trigger, no caso plpgsql.

Veja abaixo como definimos a trigger, chamando a procedure que construímos anteriormente:

Pronto! Agora sua trigger já está funcionando nos eventos INSERT e UPDATE na tabela funcionários, faça os testes!

 

PARA ALTERAR UMA TRIGGER  QUE JÁ EXISTA

Repare que não postei a imagem dos resultados para induzir você a testar o código! Faça os scripts de insert e update e veja as saídas produzidas pelo SGBD, acredito que você irá se divertir muito com os resultados!

Se você quiser saber mais sobre os triggers e sobre o PostgreSQL eu recomendo um livro (se você também for chegado a papel) que utilizei na minha monografia, intitulado PostgreSQL: Guia do Desenvolvedor, de André Milani.

Como você que leu (conseguiu chegar até aqui) triggers são um assunto muito extenso para se tratar aqui no blog, recomendo que você leia as referências e pesquisa mais sobre o assunto, é um tema muito interessante e útil para o dia a dia!

Referências:

Abraços,

Tiago

Publicado por

Prof. Me. Tiago A. Silva

Prof. Me. Tiago A. Silva

Mestre em Tecnologia (UNICAMP, 2018), Licenciado em Computação e Pedagogia (Claretiano, 2017 e 2018, respectivamente), Especialista em Desenvolvimento de Software para Web com ênfase em Java (UNIFEG, 2015), Especialista em Educação a Distância (FACEL, 2017) e Tecnólogo em Informática para Gestão de Negócios (FATEC Mococa, 2010). Atualmente sou Professor no Ensino Técnico no Centro Paula Souza. Já atuei como Professor no Ensino Superior no Centro Universitário Moura Lacerda (2017), Programador de Sistemas na Prefeitura de Cajuru (2014-2017), além de possuir 11 anos de experiência em desenvolvimento web trabalhando com diversas ferramentas e frameworks.

7 comentários em “Manipulando Triggers no PostgreSQL”

  1. Olá Tiago, preciso criar uma trigger que rode sobre a própria tabela que vai chamar a Trigger ou seja será recursiva.

    Tentei no inicio da Trigger desativar a mesma, mas recebo um erro de execução.
    Qual caminho devo estudar para resolver meu problema?

  2. Quando eu crio um trigger para uma tabela que JÁ CONTÉM registros, teoricamente nenhum dos registros já existentes na tabela precisa ser reprocessado para considerar o trigger recentemente criado, certo?

    Porém, estou criando um trigger em uma tabela que possui cerca de 9 milhões de registros, e o tempo para a criação do trigger está alto demais!! O PostgreSQL executa algum tipo de processamento com esses registros no momento de criar o trigger ??

  3. Olá.
    Sou novo em banco de dados e estou estudando sobre trigger.

    Preciso que quando eu adcionar um novo registro em uma tabela (clientes) a trigger faça um insert em outra tabela.
    A estrutura está da seguinte forma: tenho uma tabela clientes, uma tabela chamada modulos e uma chamada modulo_cliente.

    Na tabela modulo existem varios registros que quero relacionar a um cliente na tabela modulo_cliente a cada inserção.

    Desde já agradeço.

    1. Olá João!
      Recomendo que você leia a documentação do postgres sobre triggers: https://www.postgresql.org/docs/9.2/plpgsql-trigger.html
      Esse link também parece interessante: https://www.devmedia.com.br/trabalhando-com-triggers-no-postgresql/33531

      Aqui no post, eu falei agora sobre isso aqui:
      CREATE TRIGGER validacao_insert BEFORE INSERT OR UPDATE ON funcionarios
      FOR EACH ROW EXECUTE PROCEDURE valida_dados_funcionario();

      Perdoe o conteúdo desatualizado, escrevi essa série sobre o postgres já tem alguns anos.

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *