Tipos de Triggers

Após esta aula, você será capaz de:

  • Usar Triggers de Linha e de Instrução
  • Usar Triggers INSTEAD OF

Triggers de Linha e de Instrução

Triggers de Linha

Um trigger de linha é disparado tantas vezes quanto o número de linhas afetadas pela instrução que o ativa. Quando a cláusula FOR EACH ROW está presente na cláusula CREATE TRIGGER, o trigger é um trigger de linha. A trigger a seguir requer a tabela “salary_changes” conforme DDL abaixo:

Exemplo de um trigger de linha:

Neste exemplo, se uma instrução UPDATE modificar 20 registros na tabela EMPLOYEES, este trigger será disparado 20 vezes, uma vez para cada linha afetada.

Triggers de Instrução

Um trigger de instrução é disparado uma vez para a instrução que o ativa, independentemente do número de linhas afetadas. Para criar um trigger de instrução, você omite a declaração FOR EACH ROW na cláusula CREATE TRIGGER.

 

Antes de criar a trigger precisamos das tabelas JOB_HISTORY e HR_EVENTS, o DDL da JOB_HISTORY e HR_EVENTS está logo abaixo:

Exemplo de um trigger de instrução:

Agora vamos deletar um registro para verificar o funcionamento da trigger:

Este trigger específico é disparado uma vez após uma instrução DELETE ser emitida contra a tabela JOB_HISTORY, independentemente do número de linhas afetadas.

Triggers de instrução devem ser usados quando as operações realizadas pelo trigger não dependem dos dados em registros individuais. Por exemplo, se você quiser limitar o acesso a uma tabela apenas ao horário comercial, você pode usar um trigger de instrução.

Exemplo de um trigger de instrução mais complexo:

Este trigger verifica o dia da semana e a hora antes de permitir modificações na tabela EMPLOYEES. Se a operação for tentada fora do horário permitido, uma exceção será lançada.

INSTEAD OF Triggers

Até agora, vimos triggers definidos em tabelas de banco de dados. O PL/SQL também fornece triggers que são definidos em views de banco de dados. Uma view é uma representação personalizada de dados que pode ser referida como uma “consulta armazenada”.

Exemplo de uma view:

Assim como as tabelas, as views podem ser manipuladas via instruções INSERT, UPDATE e DELETE, com algumas restrições. Quando qualquer uma dessas instruções é emitida contra uma view, os dados correspondentes são modificados na tabela subjacente.

No entanto, algumas restrições são impostas às views em termos de se elas podem ser modificadas. Estas restrições se aplicam à instrução SELECT subjacente, também referida como “consulta de view”. Uma view não pode ser modificada se sua consulta contiver:

  • Operações de conjunto como UNION, UNION ALL, INTERSECT e MINUS
  • Funções de grupo como AVG, COUNT, MAX, MIN e SUM
  • Cláusulas GROUP BY ou HAVING
  • Cláusulas CONNECT BY ou START WITH
  • O operador DISTINCT
  • A pseudocoluna ROWNUM

Antes de criarmos uma view não-modificável vamos primeiro criar alguns objetos para usarmos nessa view. Nós vamos usar novas tabelas porque o schema HR tem muitas constraints de integridade referencial (Foreign Key) o que não faz parte do escopo desse material.

Aqui estão as DDLs de criação dos objetos:

E agora finalmente, um exemplo de uma view não modificável:

Esta view não é atualizável porque contém a função de grupo COUNT(). Tentar deletar desta view resultaria em um erro:

Para contornar essas limitações, o PL/SQL fornece triggers INSTEAD OF. Um trigger INSTEAD OF é criado como um trigger de linha e é disparado em vez da instrução de ativação (INSERT, UPDATE, DELETE) que foi emitida contra uma view, permitindo que você modifique diretamente as tabelas subjacentes.

Exemplo de um trigger INSTEAD OF:

Explicação Detalhada:

  1. Estrutura de Dados:
    • Criamos tabelas para projects, employees_new, e project_allocations, que formam a base do nosso sistema.
    • A nova tabela hr_events_new é usada para registrar eventos de RH, substituindo a antiga hr_events. Isso porque a estrutura original do schema HR contém várias constraints de integridade que teriam que ser tratadas antes da execução.
  2. View Complexa:
    • employee_project_summary é uma view não modificável diretamente devido ao uso de funções de agregação (COUNT, SUM) e cláusula GROUP BY.
    • Esta view combina informações de funcionários com seus projetos e orçamentos totais.
  3. INSTEAD OF Trigger:
    • O trigger employee_project_summary_delete é acionado quando uma operação DELETE é tentada na view employee_project_summary.
    • Este trigger é necessário porque a view não é diretamente modificável devido à sua complexidade.
  4. Lógica do Trigger:

    a) Verifica se o funcionário a ser deletado é um gerente.

    b) Conta o número de projetos aos quais o funcionário está alocado.

    c) Se o funcionário for um gerente, atualiza os subordinados, removendo a referência ao gerente.

    d) Remove todas as alocações de projetos do funcionário.

    e) Remove o funcionário da tabela employees_new.

    f) Registra a ação na nova tabela hr_events_new, incluindo detalhes sobre se era um gerente e quantas alocações de projetos foram removidas.

  5. Logging e Auditoria:
    • Todas as ações são registradas na tabela hr_events_new, proporcionando uma trilha de auditoria clara.

Para testar o trigger, você pode executar:

Este comando acionará o trigger, que realizará todas as operações necessárias nas tabelas subjacentes e registrará o evento na tabela hr_events_new.

Este INSTEAD OF trigger demonstra como podemos manter a integridade dos dados e realizar operações complexas em cascata, mesmo quando trabalhamos com views não modificáveis diretamente. É uma técnica poderosa para gerenciar dados em sistemas complexos, permitindo operações que de outra forma seriam impossíveis em views agregadas ou complexas.

Considerações Adicionais sobre INSTEAD OF Triggers

Ao trabalhar com INSTEAD OF triggers, é importante entender as implicações de suas ações em um ambiente de banco de dados complexo. Vamos explorar um exemplo mais detalhado para ilustrar alguns desafios potenciais:

Suponha que temos uma view mais complexa que combina informações de várias tabelas:

Agora, vamos criar um INSTEAD OF trigger para lidar com operações de DELETE nesta view:

Este trigger INSTEAD OF é mais complexo e ilustra vários pontos importantes:

  1. Operações em Cascata: O trigger não apenas remove o empregado, mas também verifica e potencialmente remove departamentos e localizações vazias. Isso demonstra como um INSTEAD OF trigger pode gerenciar operações complexas em cascata que envolvem múltiplas tabelas.
  2. Considerações de Integridade: O trigger toma cuidado para não remover países, mesmo se uma localização for removida. Isso ilustra a necessidade de considerar cuidadosamente as implicações de cada ação em um ambiente de banco de dados complexo.
  3. Tratamento de Erros: O trigger inclui tratamento de exceções para capturar e registrar quaisquer erros que possam ocorrer durante a execução.
  4. Logging: O trigger registra suas ações em uma tabela de eventos, o que é uma prática útil para auditoria e depuração.

Desafios e Considerações

Ao projetar INSTEAD OF triggers, especialmente para views complexas, é importante considerar:

  1. Desempenho: Triggers complexos que realizam muitas operações podem impactar o desempenho do banco de dados.
  2. Integridade dos Dados: Certifique-se de que todas as operações em cascata mantenham a integridade dos dados e respeitem as restrições de chave estrangeira.
  3. Concorrência: Em um ambiente multi-usuário, considere como as operações do trigger podem interagir com outras transações concorrentes.
  4. Manutenção: Triggers complexos podem ser difíceis de manter e depurar. Documente bem o propósito e a lógica do trigger.
  5. Teste: Teste exaustivamente os triggers INSTEAD OF para garantir que eles lidem corretamente com todos os cenários possíveis.

Conclusão

INSTEAD OF triggers são uma ferramenta poderosa que permite operações aparentemente diretas em views complexas. Eles podem encapsular lógica de negócios complexa e manter a integridade dos dados em várias tabelas relacionadas. No entanto, eles devem ser usados com cuidado e projetados com consideração às relações entre tabelas, desempenho e manutenção futura.

Ao usar INSTEAD OF triggers, você está essencialmente criando uma camada de abstração entre a view e as tabelas subjacentes, permitindo que os usuários interajam com os dados de uma maneira que parece simples e direta, enquanto operações complexas ocorrem nos bastidores.

Esta abordagem pode ser muito útil para simplificar interfaces de usuário ou APIs, ao mesmo tempo em que mantém a flexibilidade e o controle sobre como as operações são realmente executadas no nível do banco de dados.

Scroll to Top