Triggers PL/SQL: saiba quando e por que usar

Veja neste artigo qual a necessidade e do por que da utilização de triggers em bases de dados. Será explicado o uso das Triggers em bases PL SQL da Oracle.

As triggers são programas armazenados que podem ser executados automaticamente ou podem ser disparados quando houver a ocorrência de algum evento associado a elas. Elas são, de fato, escritas para serem executadas em resposta a algum dos eventos expostos a seguir:

As triggers podem ser definidas em tabelas, views, schemas ou em alguma base de dados com a qual o evento seja associado.

Quais são os benefícios na utilização de triggers?

As triggers podem ser escritas para diferentes propósitos, dos quais podemos destacar a geração de valores derivados de colunas da base de dados automaticamente, auditoria, replicação sincronizada de tabelas, prevenção de transações inválidas, aplicação de integridade referencial, imposição de autorização de segurança, registro de eventos e armazenamento de acesso as tabelas da base de dados.

Como podemos criar uma trigger?

A sintaxe para a estrutura básica de criação de uma trigger é apresentada na Listagem 1.

Listagem 1. Sintaxe básica de criação da trigger PL/SQL.

CREATE [OR REPLACE ] TRIGGER trigger_name {BEFORE | AFTER | INSTEAD OF } {INSERT [OR] | UPDATE [OR] | DELETE} [OF col_name] ON table_name [REFERENCING OLD AS o NEW AS n] [FOR EACH ROW] WHEN (condition) DECLARE Declaration-statements BEGIN Executable-statements EXCEPTION Exception-handling-statements END;

Onde temos:

Vamos criar um exemplo simples de utilização para melhorar nossas habilidades, onde o preço de um produto muda constantemente. Então existe aí a importância de manter um histórico dos preços desses produtos. Então começaremos com a criação das tabelas de nossa base, conforme a Listagem 2.

Listagem 2. Criação das tabelas de ‘produtos’ e ‘historico_preco_produto’.

CREATE TABLE historico_preco_produto (produto_id number(5), produto_nome varchar2(50), produto_descricao varchar2(150), produto_preco_unitario number(7,2) ); CREATE TABLE produtos (produto_id number(5), produto_nome varchar2(32), produto_descricao varchar2(150), produto_preco_unitario number(7,2) );

Em seguida, vamos popular estas tabelas com informações pertinentes, conforme a Listagem 3.

Listagem 3. Populando as tabelas

INSERT INTO produtos VALUES (1, 'leite', 'bebida nutritiva', '2.50'); INSERT INTO produtos VALUES (2, 'carne bovina', 'musculo', '10.00'); INSERT INTO produtos VALUES (3, 'ovos', 'item vendido por unidade', '2.50'); INSERT INTO produtos VALUES (4, 'pão', '10 unidades', '3.50'); INSERT INTO produtos VALUES (5, 'laranja', 'fruta rica em vitamina C, quantidade minima 12 unidades', '5.00'); INSERT INTO produtos VALUES (6, 'feijão', 'Alimento rico em ferro', '4.50');

O próximo ponto agora é criarmos a nossa trigger, conforme a Listagem 4.

Listagem 4. Criação da trigger

CREATE or REPLACE TRIGGER historico_preco_trigger BEFORE UPDATE OF prd_preco_unitario ON produtos FOR EACH ROW BEGIN INSERT INTO historico_preco_produto VALUES (:old.produto_id, :old.produto_nome, :old.produto_descricao, :old.produto_preco_unitario); END; /

Agora que temos nossa tabela criada, populada com alguns registros e também com a nossa trigger pronta, vamos então realizar uma atualização em um dos valores de produtos que temos, conforme a Listagem 5.

Listagem 5. Atualização de valores

UPDATE PRODUTOS SET produto_preco_unitario = 800 WHERE produto_id = 5;

Como tivemos esta atualização em um dos itens de produtos na tabela produtos, a nossa trigger foi disparada fazendo assim a atualização da tabela ‘historico_preco_produto’.

Tipos de Triggers PL/SQL

Existem dois tipos de triggers baseados de acordo com o nível em que são disparadas:

Quando disparamos uma trigger, esta segue uma hierarquia de ações da seguinte forma:

  1. [BEFORE] - Antes da declaração da trigger ser disparada pela primeira vez.
  2. [BEFORE] - Após isso, antes da trigger disparar em nível de linha, uma vez para cada linha afetada.
  3. [AFTER] - Então, após a trigger ser disparada em nível de linha para cada linha afetada. Estes eventos alternarão entre antes e depois da trigger ser disparada.
  4. [AFTER] - E por último, depois a declaração da trigger em nível dispara.

Para facilitar o entendimento destas informações, vamos criar uma nova tabela chamada ‘produto_mensagem’, onde nós poderemos usá-la para armazenar as mensagens quando as triggers forem disparadas.Observe a Listagem 6.

Listagem 6. Tabela Produto_mensagem

CREATE TABLE produto_mensagem (Mensagem varchar2(50), Data_corrente number(32) );

Agora criaremos as declarações de BEFORE UPDATE para os níveis de declaração e de linha.

A declaração BEFORE UPDATE, nível de declaração é uma trigger que irá inserir um registro na tabela ‘produto_mensagem’ antes da instrução SQL para atualização ser executada, em nível de declaração. Observe a Listagem 7.

Listagem 7. BEFORE UPDATE

CREATE or REPLACE TRIGGER Before_Update_Stat_produto BEFORE UPDATE ON produtos Begin INSERT INTO produto_mensagem Values('Before update, statement level',sysdate); END; /

Agora a BEFORE UPDATE, nível de linha é uma trigger que vai inserir um registro na tabela ‘produto_mensagem’ antes de cada linha ser atualizada. Observe a Listagem 8.

Listagem 8. BEFORE UPDATE em nível de linha

CREATE or REPLACE TRIGGER Before_Upddate_Row_produto BEFORE UPDATE ON produtos FOR EACH ROW BEGIN INSERT INTO produto_mensagem Values('Before update row level',sysdate); END; /

A AFTER UPDATE em nível de declaração é a trigger que irá inserir um novo registro na tabela ‘checagem_produto’ depois que a declaração SQL de atualização for executada. Observe a Listagem 9.

Listagem 9. AFTER UPDATE em nível de declaração

CREATE or REPLACE TRIGGER After_Update_Stat_produto AFTER UPDATE ON produtos BEGIN INSERT INTO produto_mensagem Values('After update, statement level', sysdate); End; /

A AFTER UPDATE em nível de linha é a trigger que irá inserir um registro na tabela ‘produto_mensagem’ depois que cada linha for atualizada. Observe a Listagem 10.

Listagem 10. AFTER UPDATE em nível de linha

CREATE or REPLACE TRIGGER After_Update_Row_produto AFTER insert On produtos FOR EACH ROW BEGIN INSERT INTO produto_mensagem Values('After update, Row level',sysdate); END; /

Agora que temos tudo criado, vamos executar uma declaração de atualização na nossa tabela de produtos, conforme a Listagem 11.

Listagem 11. Atualização da tabela produtos

UPDATE PRODUTOS SET produto_preco_unitario = 1200 WHERE produto_id in (3,5);

Algo importante a se saber também com relação as triggers é que caso estas tenham sido definidas de forma idêntica, elas serão executadas sem uma ordem específica (podendo ser de forma aleatória). Caso isto seja realmente necessário, devemos ter cuidado com a integridade do banco de dados para que não haja dependência com relação à ordem de execução das triggers.

Até a próxima!

Artigos relacionados