Você está na página 1de 27

Teoria de Banco de Dados

Gatilhos

Profa.: Simone Carboni Garcia


O que são gatilhos?
• Gatilhos são procedimentos remotos escritos pelo usuário
que são invocados automaticamente quando realizada uma
operação DML sobre a tabela associada ao gatilho
(SILBERSCHATZ,2008).

• Gatilhos permitem ao usuário implementar regras de negócio


complexas sem o advento de uma linguagem de programação
externa ao banco de dados, ou seja, podem ser
implementadas dentro do próprio banco.
Benefícios de Gatilhos
• Benefícios:
– Imposição de regras de negócios de maneira centralizada.
– Possibilidade de abortar transações que ferem as regras de
negócios.
– Auditoria de atualização no banco de dados.
– Disparo de eventos diversos a partir do banco de dados.
– Podemos usar gatilhos em views.
– Uma tabela pode possuir vários gatilhos.
Componentes de um gatilho
• Todo gatilho possui:
– Associação com uma tabela
– Um evento de disparo
• INSERT
• UPDATE
• DELETE
– Controle do disparo
• AFTER/BEFORE
– Tipos
• EACH ROW/EACH STATEMENT
– Procedimento
Associação com uma tabela
• O gatilho obrigatoriamente deve estar vinculado a uma única
tabela ou view, mas dentro do procedimento podem ser
ativados gatilhos para outras tabelas.

GATILHO TABELA
Eventos de Disparo
• Eventos capazes de disparar um gatilho, são basicamente
comandos DML. O gatilho fica “escutando” as transações em
busca da transação que contenha a operação de disparo.

• DML:
– INSERT/UPDATE/DELETE

• Podemos disparar gatilhos para várias operações DML ao


mesmo tempo, basta usar o operador OR entre cada uma.

• Não é possível disparar gatilhos a partir de um SELECT, e se


fosse possível iria afetar muito a performance do banco.
Before ou After
• Usar de acordo com a situação.
– Before: Como este é executado antes, acaba
sendo ideal para estender o mecanismo de
restrições do banco de dados.
Ex: Restrições entre relações.

– After: Por ser executado depois, é útil para


monitoramento e ações externas ao Banco de
dados.
Ex: Registro de transações em uma tabela de Log.
Tipos de gatilhos
• ROW (Por linha).
– Executa X vezes quanto forem os registros da tabela.
– Não disparam quando não afeta nenhuma linha.
– Necessário quando se precisa guardar muitos registros.

• STATEMENT (Por comando).


– Executa uma vez por comando de disparo.
– Disparam mesmo quando não tem uma linha afetada.
– Quando se precisa de apenas um registro.
Procedimentos associados
• Gatilhos precisam de procedimentos para efetuarem a lógica
de programação.

• Apenas um procedimento por gatilho, para ter mais


procedimentos, crie novos gatilhos.

• Os procedimentos que servem como gatilho para o


PostgreSQL devem retornar o tipo especial TRIGGER.
Sintaxe do Gatilho
CREATE TRIGGER nome {BEFORE | AFTER}
{evento [OR ...]}
Controle de disparo
Eventos de disparo Nome do gatilho
ON nomeTabela FOR EACH {ROW | STATEMENT}

Tabela associada ao gatilho Tipo


EXECUTE PROCEDURE nomeFuncao();

Procedimento associado ao gatilho


Sintaxe do Procedimento
CREATE FUNCTION nome() RETURNS TRIGGER
AS $$
Tipo de retorno gatilho

DECLARE
<Variáveis> Nome do procedimento
BEGIN
<Códigos>
END;
$$ LANGUAGE 'plpgsql'
Novos operadores
• Precisamos, às vezes, obter valores das transações
que estão ocorrendo no momento do disparo do
gatilho ou os valores anteriores.

• Para isso contamos com duas variáveis adicionais,


que possuem funcionamento semelhante ao
RECORD.

– OLD Informação antiga da linha modificada.


– NEW Informação nova (inserida) da linha.
Variável New
• NEW - Tipo de dado RECORD; variável contendo a nova linha
do banco de dados, para as operações de INSERT/UPDATE nos
gatilhos no nível de linha. O valor desta variável é NULL nos
gatilhos no nível de instrução DELETE.

• Como toda as variáveis do tipo Record, ele pode armazenar


uma linha inteira de registros, para acessar o valor de uma
coluna que está sendo inserida ou atualizada:
Ex: New.colunadesejada
New.nome
Variável Old
• OLD - Tipo de dado RECORD; variável contendo a antiga linha
do banco de dados, para as operações de UPDATE/DELETE nos
gatilhos no nível de linha. O valor desta variável é NULL nos
gatilhos no nível de instrução INSERT.

• Como toda as variáveis do tipo Record, ele pode armazenar


uma linha inteira de registros, para acessar o valor de uma
coluna que está sendo apagada ou atualizada:
Ex: OLD.colunadesejada
OLD.nome
Exemplo 1: Sumário
• Crie um gatilho capaz de impedir a entrada de quantidades
negativas de produtos em uma determinada tabela.

• O gatilho deverá ser acionado antes do final da transação e


deverá chamar um procedimento chamado VQuant.

• No procedimento deverá ser levantada uma exceção caso


entre algum valor negativo.
Exemplo 1: Tabelas
Create table Produto (
cd numeric(6),
descricao varchar(300),
quantidade numeric(10),
primary key (cd));

INSERT INTO PRODUTO (CD,DESCRICAO,QUANTIDADE)


VALUES (1,'FEIJAO',-100);
INSERT INTO PRODUTO (CD,DESCRICAO,QUANTIDADE)
VALUES (2,'Arroz',10),
INSERT INTO PRODUTO (CD,DESCRICAO,QUANTIDADE)
VALUES (3,'Batata',-1);
Exemplo 1: Procedimento
CREATE OR REPLACE FUNCTION VQuant() RETURNS TRIGGER
AS $$
DECLARE
Se o registro inserido/atualizado for negativo
BEGIN

IF NEW.QUANTIDADE<0 THEN

RAISE EXCEPTION 'NAO É PERMITIDO QTD NEGATIVAS';

END IF;
RETURN NEW; Aborta a transação
END;
$$ LANGUAGE 'plpgsql'
Exemplo 1: Gatilho
CREATE TRIGGER TRIGPRODUTO Nome

BEFORE INSERT OR UPDATE ON PRODUTO Evento

FOR EACH ROW Tipo de disparo

EXECUTE PROCEDURE VQuant(); Procedimento Associado

O que ocorre quando o gatilho é acionado:


Exemplo 2: Sumário
• Crie um gatilho que preenchera a tabela LOG com a data
corrente e o tipo de operação realizada na tabela ALTERADA.

• Use as variáveis e métodos do PostgreSQL para obter a data


da transação, o tipo de transação e o usuário que está
realizando a transação.

• Não é necessário lançar exceções ou avisos.


Exemplo 2: Tabelas
create table alterada(
cod serial primary key,
valor varchar(50));

create table log(


cod serial primary key,
data date,
autor varchar(20),
alteracao varchar(6));

insert into alterada (valor)


values ('novo valor');
Exemplo 2: Procedimento
CREATE FUNCTION GERA_LOG() RETURNS
TRIGGER AS $$
Tempo Corrente
BEGIN

INSERT INTO LOG (DATA, AUTOR, ALTERACAO)


VALUES (NOW(), USER, TG_OP);
RETURN NEW;
END;

$$ LANGUAGE 'PLPGSQL';
Exemplo 2: Gatilho
CREATE TRIGGER GERA_LOG Nome
AFTER INSERT OR UPDATE OR DELETE Evento
ON ALTERADA Tabela Associada
FOR EACH ROW Tipo de disparo
EXECUTE PROCEDURE GERA_LOG(); Procedimento Assoc.

O que ocorre quando o gatilho é acionado:


Exceções nos gatilhos
• Se for necessário abortar o gatilho por algum motivo devemos
lançar exceções no procedimento associado ao gatilho.

• Podemos usar o RAISE NOTICE para ver alguma variável ou


para dar uma mensagem no meio do procedimento.

• A declaração das mensagem com os atributos é semelhante a


do comando PRINTF do C.
Raise Notice com Variáveis
Ex:
RAISE NOTICE 'Produto inserido: %d',prod;

Ex:
RAISE NOTICE 'Id : %d Cod: %d',i,c;

• Existem variáveis especiais que nos permitem até mesmo


saber qual é a operação DML que disparou o gatilho.
Variáveis para Gatilhos
• TG_NAME - Tipo de dado name; variável contendo o nome do gatilho
disparado.

• TG_WHEN - Tipo de dado text; uma cadeia de caracteres


contendo BEFORE ou AFTER, dependendo da definição do gatilho.

• TG_LEVEL - Tipo de dado text; uma cadeia de caracteres


contendo ROW ou STATEMENT, dependendo da definição do gatilho.

• TG_OP - Tipo de dado text; uma cadeia de caracteres


contendo INSERT, UPDATE, ou DELETE, informando para qual operação o
gatilho foi disparado.
Variáveis para Gatilhos
• TG_RELID - Tipo de dado oid; o ID de objeto da tabela que causou o
disparo do gatilho.

• TG_RELNAME - Tipo de dado name; o nome da tabela que causou o


disparo do gatilho.

• TG_NARGS - Tipo de dado integer; o número de argumentos fornecidos ao


procedimento de gatilho na instrução CREATE TRIGGER.

• TG_ARGV[] - Tipo de dado matriz de text; os argumentos da


instrução CREATE TRIGGER. O contador do índice começa por 0. Índices
inválidos (menor que 0 ou maior ou igual a tg_nargs) resultam em um
valor nulo.
Referências
• Gatilhos
MERTINS, Luciano; Slides Banco de dados II, UCPEL, 2009.

• Gatilhos PostgreSQL
http://www.postgresql.org/docs/9.2/static/sql-
createtrigger.html

• Gatilhos PostgreSQL
http://pgdocptbr.sourceforge.net/pg80/plpgsql-
trigger.html