Oracle Tutorial de gatilho PL/SQL: em vez de composto [exemplo]

O que é gatilho em PL/SQL?

GATILHOS são programas armazenados que são disparados por Oracle mecanismo automaticamente quando instruções DML como insert, update, delete são executadas na tabela ou alguns eventos ocorrem. O código a ser executado em caso de trigger pode ser definido conforme a necessidade. Você pode escolher o evento no qual o gatilho precisa ser acionado e o tempo de execução. O objetivo do gatilho é manter a integridade das informações no banco de dados.

Benefícios dos gatilhos

A seguir estão os benefícios dos gatilhos.

  • Gerando alguns valores de colunas derivadas automaticamente
  • Aplicando integridade referencial
  • Registro de eventos e armazenamento de informações sobre acesso à tabela
  • Auditoria
  • Syncreplicação cronológica de tabelas
  • Imposição de autorizações de segurança
  • Evitando transações inválidas

Tipos de gatilhos em Oracle

Os gatilhos podem ser classificados com base nos seguintes parâmetros.

  • Classificação baseada no cronometragem
  • BEFORE Trigger: É acionado antes que o evento especificado ocorra.
  • AFTER Trigger: É acionado após a ocorrência do evento especificado.
  • EM VEZ DE Gatilho: Um tipo especial. Você aprenderá mais sobre os próximos tópicos. (somente para DML)
  • Classificação baseada no nível
  • Trigger de nível STATEMENT: é acionado uma vez para a instrução de evento especificada.
  • Gatilho de nível ROW: é acionado para cada registro que foi afetado no evento especificado. (somente para DML)
  • Classificação baseada no Evento
  • Gatilho DML: É acionado quando o evento DML é especificado (INSERT/UPDATE/DELETE)
  • DDL Trigger: É acionado quando o evento DDL é especificado (CREATE/ALTER)
  • DATABASE Trigger: Dispara quando o evento do banco de dados é especificado (LOGON/LOGOFF/STARTUP/SHUTDOWN)

Portanto, cada gatilho é a combinação dos parâmetros acima.

Como criar um gatilho

Abaixo está a sintaxe para criar um gatilho.

CREATE tRIGGER

CREATE [ OR REPLACE ] TRIGGER <trigger_name> 

[BEFORE | AFTER | INSTEAD OF ]

[INSERT | UPDATE | DELETE......]

ON<name of underlying object>

[FOR EACH ROW] 

[WHEN<condition for trigger to get execute> ]

DECLARE
<Declaration part>
BEGIN
<Execution part> 
EXCEPTION
<Exception handling part> 
END;

Explicação da sintaxe:

  • A sintaxe acima mostra as diferentes instruções opcionais presentes na criação do gatilho.
  • BEFORE/AFTER especificará os horários do evento.
  • INSERIR/ATUALIZAR/LOGON/CRIAR/etc. especificará o evento para o qual o gatilho precisa ser acionado.
  • A cláusula ON especificará em qual objeto o evento mencionado acima é válido. Por exemplo, este será o nome da tabela na qual o evento DML poderá ocorrer no caso de DML Trigger.
  • O comando “FOR EACH ROW” especificará o acionador do nível ROW.
  • A cláusula WHEN especificará a condição adicional na qual o gatilho precisa ser acionado.
  • A parte de declaração, parte de execução e parte de tratamento de exceções são as mesmas das outras Blocos PL/SQL. A parte da declaração e a parte do tratamento de exceções são opcionais.

:Cláusula NOVA e :ANTIGA

Em um gatilho em nível de linha, o gatilho é acionado para cada linha relacionada. E às vezes é necessário saber o valor antes e depois da instrução DML.

Oracle forneceu duas cláusulas no gatilho de nível RECORD para manter esses valores. Podemos usar essas cláusulas para nos referirmos aos valores antigos e novos dentro do corpo do gatilho.

  • :NEW – Mantém um novo valor para as colunas da tabela/view base durante a execução do trigger
  • :OLD – Mantém o valor antigo das colunas da tabela/view base durante a execução do trigger

Esta cláusula deve ser usada com base no evento DML. A tabela abaixo especificará qual cláusula é válida para qual instrução DML (INSERT/UPDATE/DELETE).

INSIRA ATUALIZAÇÃO EXCLUIR
:NOVO VÁLIDO VÁLIDO INVÁLIDO. Não há novo valor no caso de exclusão.
:VELHO INVÁLIDO. Não há valor antigo no caso de inserção VÁLIDO VÁLIDO

EM VEZ DE Gatilho

“INSTEAD OF trigger” é o tipo especial de trigger. É usado apenas em gatilhos DML. É usado quando qualquer evento DML ocorrerá na visualização complexa.

Considere um exemplo em que uma visualização é feita a partir de 3 tabelas base. Quando qualquer evento DML for emitido nesta visualização, isso se tornará inválido porque os dados são obtidos de 3 tabelas diferentes. Portanto, neste gatilho INSTEAD OF é usado. O gatilho INSTEAD OF é usado para modificar as tabelas base diretamente, em vez de modificar a visualização de um determinado evento.

Exemplo 1: Neste exemplo, vamos criar uma visão complexa a partir de duas tabelas base.

  • Tabela_1 é tabela emp e
  • Tabela_2 é tabela de departamento.

Em seguida, veremos como o gatilho INSTEAD OF é usado para emitir UPDATE a instrução de detalhes de localização nesta visualização complexa. Também veremos como :NEW e :OLD são úteis em gatilhos.

  • Etapa 1: Criando tabelas 'emp' e 'dept' com colunas apropriadas
  • Etapa 2: preencher a tabela com valores de amostra
  • Etapa 3: Criando visualização para a tabela criada acima
  • Etapa 4: atualização da visualização antes do gatilho em vez de
  • Etapa 5: Criação do gatilho em vez de
  • Etapa 6: atualização da visualização após o acionamento, em vez do acionador

Passo 1) Criando tabela 'emp' e 'dept' com colunas apropriadas

EM VEZ DE Gatilho

CREATE TABLE emp(
emp_no NUMBER,
emp_name VARCHAR2(50),
salary NUMBER,
manager VARCHAR2(50),
dept_no NUMBER);
/

CREATE TABLE dept( 
Dept_no NUMBER, 
Dept_name VARCHAR2(50),
LOCATION VARCHAR2(50));
/

Explicação do código

  • Linha de código 1-7: Criação da tabela 'emp'.
  • Linha de código 8-12: Criação da tabela 'dept'.

saída

Tabela criada

Passo 2) Agora que criamos a tabela, iremos preenchê-la com valores de amostra e criação de visualizações para as tabelas acima.

EM VEZ DE Gatilho

BEGIN
INSERT INTO DEPT VALUES(10,‘HR’,‘USA’);
INSERT INTO DEPT VALUES(20,'SALES','UK’);
INSERT INTO DEPT VALUES(30,‘FINANCIAL',‘JAPAN'); 
COMMIT;
END;
/

BEGIN
INSERT INTO EMP VALUES(1000,'XXX5,15000,'AAA',30);
INSERT INTO EMP VALUES(1001,‘YYY5,18000,‘AAA’,20) ;
INSERT INTO EMP VALUES(1002,‘ZZZ5,20000,‘AAA',10); 
COMMIT;
END;
/

Explicação do código

  • Linha de código 13-19: Inserindo dados na tabela 'dept'.
  • Linha de código 20-26: Inserindo dados na tabela 'emp'.

saída

Procedimento PL/SQL concluído

Passo 3) Criando uma visualização para a tabela criada acima.

EM VEZ DE Gatilho

CREATE VIEW guru99_emp_view(
Employee_name:dept_name,location) AS
SELECT emp.emp_name,dept.dept_name,dept.location
FROM emp,dept
WHERE emp.dept_no=dept.dept_no;
/
SELECT * FROM guru99_emp_view;

Explicação do código

  • Linha de código 27-32: Criação da visualização 'guru99_emp_view'.
  • Linha de código 33: Consultando guru99_emp_view.

saída

Visualização criada

NOME DO EMPREGADO DEPT_NAME LOCALIZAÇÃO
ZZZ HR USA
AAAA VENDAS UK
XXX FINANCEIRO JAPÃO

Passo 4) Atualização da visualização antes do gatilho.

EM VEZ DE Gatilho

BEGIN
UPDATE guru99_emp_view SET location='FRANCE' WHERE employee_name=:'XXX’;
COMMIT;
END;
/

Explicação do código

  • Linha de código 34-38: Atualize a localização de “XXX” para 'FRANÇA'. Abriu a excepção porque o Declarações DML não são permitidos na visualização complexa.

saída

ORA-01779: não é possível modificar uma coluna que mapeia para uma tabela sem preservação de chave

ORA-06512: na linha 2

Passo 5)Para evitar o erro durante a atualização da visualização na etapa anterior, nesta etapa usaremos “em vez de gatilho”.

EM VEZ DE Gatilho

CREATE TRIGGER guru99_view_modify_trg
INSTEAD OF UPDATE
ON guru99_emp_view
FOR EACH ROW
BEGIN
UPDATE dept
SET location=:new.location
WHERE dept_name=:old.dept_name;
END;
/

Explicação do código

  • Linha de código 39: Criação do gatilho INSTEAD OF para o evento 'UPDATE' na view 'guru99_emp_view' no nível ROW. Ele contém a instrução update para atualizar o local na tabela base 'dept'.
  • Linha de código 44: A instrução de atualização usa ':NEW' e ':OLD' para encontrar o valor das colunas antes e depois da atualização.

saída

Gatilho criado

Passo 6) Atualização da visualização após vez do gatilho. Agora o erro não ocorrerá, pois o “em vez de gatilho” cuidará da operação de atualização desta visualização complexa. E quando o código for executado, a localização do funcionário XXX será atualizada para “França” de “Japão”.

EM VEZ DE Gatilho

BEGIN
UPDATE guru99_emp_view SET location='FRANCE' WHERE employee_name='XXX'; 
COMMIT;
END;
/
SELECT * FROM guru99_emp_view;

Explicação do código:

  • Linha de código 49-53: Atualização da localização de “XXX” para 'FRANÇA'. Foi bem-sucedido porque o gatilho 'INSTEAD OF' interrompeu a instrução de atualização real na visualização e executou a atualização da tabela base.
  • Linha de código 55: Verificando o registro atualizado.

Saída:

Procedimento PL/SQL concluído com sucesso

NOME DO EMPREGADO DEPT_NAME LOCALIZAÇÃO
ZZZ HR USA
AAAA VENDAS UK
XXX FINANCEIRO FRANÇA

Gatilho Composto

O gatilho composto é um gatilho que permite especificar ações para cada um dos quatro pontos de tempo no corpo do gatilho único. Os quatro pontos de tempo diferentes que ele suporta são os seguintes.

  • ANTES DA DECLARAÇÃO – nível
  • ANTES DA LINHA – nível
  • DEPOIS DA LINHA – nível
  • APÓS DECLARAÇÃO – nível

Ele fornece a facilidade de combinar ações para diferentes tempos no mesmo gatilho.

Gatilho Composto

CREATE [ OR REPLACE ] TRIGGER <trigger_name> 
FOR
[INSERT | UPDATE | DELET.......]
ON <name of underlying object>
<Declarative part>‭	‬
BEFORE STATEMENT IS
BEGIN
<Execution part>;
END BEFORE STATEMENT;

BEFORE EACH ROW IS
BEGIN
<Execution part>;
END EACH ROW;

AFTER EACH ROW IS
BEGIN
<Execution part>;
END AFTER EACH ROW;

AFTER STATEMENT IS
BEGIN
<Execution part>;
END AFTER STATEMENT;
END;

Explicação da sintaxe:

  • A sintaxe acima mostra a criação do gatilho 'COMPOUND'.
  • A seção declarativa é comum para todos os blocos de execução no corpo do gatilho.
  • Esses 4 blocos de temporização podem estar em qualquer sequência. Não é obrigatório ter todos estes 4 blocos de temporização. Podemos criar um gatilho COMPOUND apenas para os tempos necessários.

Exemplo 1: Neste exemplo, criaremos um gatilho para preencher automaticamente a coluna salário com o valor padrão 5000.

Gatilho Composto

CREATE TRIGGER emp_trig 
FOR INSERT 
ON emp
COMPOUND TRIGGER 
BEFORE EACH ROW IS 
BEGIN
:new.salary:=5000;
END BEFORE EACH ROW;
END emp_trig;
/
BEGIN
INSERT INTO EMP VALUES(1004,‘CCC’,15000,‘AAA’,30); 
COMMIT;
END;
/
SELECT * FROM emp WHERE emp_no=1004;

Explicação do código:

  • Linha de código 2-10: Criação de gatilho composto. Ele é criado para cronometrar o nível BEFORE ROW para preencher o salário com o valor padrão 5000. Isso alterará o salário para o valor padrão '5000' antes de inserir o registro na tabela.
  • Linha de código 11-14: Insira o registro na tabela 'emp'.
  • Linha de código 16: Verificando o registro inserido.

Saída:

Gatilho criado

Procedimento PL / SQL concluído com sucesso.

EMP_NAME EMP_NO SALÁRIO MANAGER DEPT_NO
CCC 1004 5000 AAA 30

Habilitando e desabilitando gatilhos

Os gatilhos podem ser ativados ou desativados. Para habilitar ou desabilitar o gatilho, uma instrução ALTER (DDL) precisa ser fornecida para o gatilho que o desabilita ou habilita.

Abaixo está a sintaxe para ativar/desativar os gatilhos.

ALTER TRIGGER <trigger_name> [ENABLE|DISABLE];
ALTER TABLE <table_name> [ENABLE|DISABLE] ALL TRIGGERS;

Explicação da sintaxe:

  • A primeira sintaxe mostra como ativar/desativar o gatilho único.
  • A segunda instrução mostra como ativar/desativar todos os gatilhos em uma tabela específica.

Resumo

Neste capítulo, aprendemos sobre os gatilhos PL/SQL e suas vantagens. Também aprendemos as diferentes classificações e discutimos o gatilho INSTEAD OF e o gatilho COMPOUND.