Tutorial: Desenvolvendo Triggers em SQL com Abrangência e Precisão Técnica
Published: 2023-12-07 20:58:13

Nomes: Alisson Honório, Brayan Cavalcanti, Ricardo Oliveira.

**1. Introdução:**

 Neste tutorial, exploraremos a criação de triggers em SQL, oferecendo uma visão 
abrangente e técnica sobre o assunto. A compreensão dos conceitos fundamentais, a 
aplicação prática e exemplos relevantes serão destacados para uma aprendizagem 
eficaz.

**2. Conceitos Básicos:**

Evento: O evento que aciona o trigger, como INSERT, UPDATE ou DELETE.
Tabela: A tabela à qual o trigger está vinculado.
Ação: As instruções SQL que são executadas quando o trigger é acionado.

**3. Sintaxe Básica do Trigger:**

CREATE: Cria o Trigger.
OR REPLACE: Opcional, substitui o trigger se ele já existir.
BEFORE ou AFTER: Indica quando o trigger deve ser acionado.
INSERT, UPDATE, ou DELETE: Especifica o evento que aciona o trigger.
REFERENCING NEW e OLD: Referência às linhas sendo afetadas (útil em triggers 
UPDATE)

```
CREATE [OR REPLACE] TRIGGER nome_do_trigger
[BEFORE | AFTER] [INSERT | UPDATE | DELETE]
ON nome_da_tabela
[REFERENCING NEW AS novo OLD AS antigo]
FOR EACH ROW
BEGIN
   -- corpo do trigger
END;
/

```

**4. Exemplo de Trigger Simples:**

Vamos criar um trigger simples que exibe uma mensagem quando ocorrer uma 
inserção em uma tabela chamada exemplo.

```
CREATE OR REPLACE TRIGGER trigger_exemplo
AFTER INSERT
ON exemplo
FOR EACH ROW
BEGIN
   DBMS_OUTPUT.PUT_LINE('Uma nova linha foi inserida em "exemplo"!');
END;
/
```
Este exemplo fornece uma base sólida para compreender a estrutura de um trigger 
simples.

**5. Exemplo de Trigger para Controle de Estoque:**

Agora, criaremos um trigger mais prático que atualiza automaticamente o estoque 
disponível em uma tabela chamada produto sempre que houver uma venda

```
CREATE OR REPLACE TRIGGER atualizar_estoque
AFTER INSERT
ON venda
FOR EACH ROW
UPDATE produto
SET quantidade_disponivel = quantidade_disponivel - :NEW.quantidade_vendida
WHERE produto_id = :NEW.produto_id;
/
```

Neste exemplo:
O trigger é acionado após uma nova linha ser inserida na tabela venda.
Ele atualiza a tabela produto, subtraindo a quantidade vendida do estoque disponível

**6. Testando os Triggers:**

Agora, você pode testar os triggers realizando inserções nas tabelas associadas.

```
-- Exemplo de inserção na tabela 'exemplo'
INSERT INTO exemplo (coluna1, coluna2) VALUES ('valor1', 'valor2');

-- Exemplo de inserção na tabela 'venda'
INSERT INTO venda (produto_id, quantidade_vendida) VALUES (1, 10);

```
Após a execução dessas inserções, os triggers serão acionados, e você verá as 
mensagens de saída ou as atualizações de estoque, conforme definido nos triggers.


**7. Alguns outros exemplos práticos:**

--Imagine que você queira auditar todas as alterações feitas em uma tabela chamada 
clientes. Vamos criar um trigger que registra as alterações em uma tabela de auditoria.

```
CREATE OR REPLACE TRIGGER auditar_clientes
BEFORE INSERT OR UPDATE OR DELETE
ON clientes
FOR EACH ROW
BEGIN
   IF INSERTING THEN
      INSERT INTO auditoria_clientes (acao, cliente_id, data_modificacao)
      VALUES ('Inserção', :NEW.cliente_id, SYSDATE);
   ELSIF UPDATING THEN
      INSERT INTO auditoria_clientes (acao, cliente_id, data_modificacao)
      VALUES ('Atualização', :NEW.cliente_id, SYSDATE);
   ELSIF DELETING THEN
      INSERT INTO auditoria_clientes (acao, cliente_id, data_modificacao)
      VALUES ('Exclusão', :OLD.cliente_id, SYSDATE);
   END IF;
END;
/

```
Este trigger cria um registro na tabela “auditoria_clientes” sempre que uma inserção, 
atualização ou exclusão ocorre na tabela clientes.

--Suponha que você tenha uma tabela reservas e queira garantir que uma reserva só 
seja feita se a quantidade de assentos disponíveis for suficiente. Vamos criar um trigger 
para aplicar essa restrição.

```
CREATE OR REPLACE TRIGGER verificar_assentos_disponiveis
BEFORE INSERT
ON reservas
FOR EACH ROW
BEGIN
   IF :NEW.quantidade_assentos > (SELECT assentos_disponiveis FROM sala WHERE sala_id = :NEW.sala_id) THEN
      RAISE_APPLICATION_ERROR(-20001, 'Não há assentos suficientes disponíveis para esta reserva.');
   END IF;
END;
/
```
Este trigger impede a inserção de uma reserva se a quantidade de assentos solicitados 
for maior do que os assentos disponíveis na sala correspondente.

--Vamos supor que você tenha uma tabela tarefas com uma coluna de data de 
conclusão (data_conclusao) e queira atualizar automaticamente essa data quando a 
tarefa for marcada como concluída. Vamos criar um trigger para realizar essa tarefa.

```
CREATE OR REPLACE TRIGGER atualizar_data_conclusao
BEFORE UPDATE
ON tarefas
FOR EACH ROW
BEGIN
   IF :NEW.status = 'Concluída' AND :OLD.status <> 'Concluída' THEN
      :NEW.data_conclusao := SYSDATE;
   END IF;
END;
/
```
Este trigger verifica se o status da tarefa foi alterado para 'Concluída' e, nesse caso, 
atualiza automaticamente a data de conclusão para a data atual.

**8. Conclusão:**
 Este tutorial abrange de maneira precisa a criação de triggers em SQL, 
proporcionando um entendimento profundo e prático. A estrutura organizada, a 
clareza na explicação e os exemplos relevantes contribuem para uma experiência de 
aprendizado eficaz