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.

Resuma esta postagem com: