Você está na página 1de 9

TRIGGERS

Um trigger uma instruo que o sistema executa automaticamente como um efeito


colateral de uma modificao no banco de dados. Para criar um mecanismo de trigger,
temos de cumprir dois requisitos:
1. Especificar quando um trigger deve ser executado. Isso desmembrado em
um evento que faz com que o trigger seja verificado em uma condio que
precisa ser satisfeita para que a execuo do trigger prossiga.
2. Especificar as aes a serem tomadas quando o trigger for executado.
Este modelo de trigger conhecido como modelo evento-condio-ao para
triggers.
O banco de dados armazena triggers como se fossem dados normais, de modo que
sejam persistentes e acessveis a todas as operaes de banco de dados. Quando
entramos com um trigger no banco de dados, o sistema de banco de dados assume a
responsabilidade por execut-lo sempre que o evento especificado ocorre e a
condio correspondente satisfeita.
Necessidade de triggers
Triggers so mecanismos teis para alertar as pessoas ou para iniciar certas tarefas
automaticamente quando certas condies so atendidas. Como ilustrao, suponha
que, em vez de permitir saldos de conta negativos, o banco trate de saldos devedores
definindo o saldo da conta como zero e criando um emprstimo no valor do saldo
devedor. O banco d a esse emprstimo um nmero idntico ao nmero da conta com
saldo devedor. Nesse exemplo, a condio para executar o trigger uma atualizao
na relao conta que resulte em um valor negativo de saldo. Suponha que o saque de
algum dinheiro na conta de Frederico tenha tornado o saldo da conta negativo.
Imagine que t indica a tupla de conta com um valor de saldo negativo. As aes a
serem tomadas so:

Inserir uma nova tupla na relao emprstimo com


s[nmero_emprstimo] = t[nmero_conta]
s[nome_agncia] = t[nome_agncia]
s[quantia] = -t[saldo]

Oberve que, como t[saldo] negativo, negamos t[saldo] para obter o valor do
emprstimo um nmero positivo.

Inserir uma nova tupla u na relao tomador com


u[nome_cliente] = Frederico
u[nmero_emprstimo] = t[nmero_conta]

Definir t[saldo] como 0.

Como outro exemplo do uso de triggers, suponha que um depsito queira manter um
estoque mnimo de cada item; quando o nvel de estoque de um item ficar abaixo do
nvel mnimo, um pedido dever ser feito automaticamente. assim que a regra
comercial pode ser implementada por meio de triggers: em uma atualizao do nvel
de estoque de um item, o trigger deve compar-lo ao nvel de estoque mnimo e, se
Prof. Antonio Almeida de Barros Jnior

Pg. 1

estiver abaixo ou igual ao mnimo, um novo pedido acrescentado a uma relao


pedidos.
Observe que os sistemas de trigger normalmente no podem realizar atualizaes fora
do banco de dados e, portanto, no exemplo de reposio de estoque, no podemos
usar um trigger para fazer um pedido diretamente no mundo exterior. Em vez disso,
acrescentamos um pedido relao pedidos, como no exemplo de estoque. preciso
criar um processo do sistema em execuo permanentemente, que periodicamente
varre a relao pedidos e faz os pedidos. Esse processo do sistema tambm anotaria
quais tuplas na relao pedidos foram processadas e quando cada pedido foi feito. O
processo tambm acompanharia as entregas dos pedidos e alertaria gerentes em
caso de condies excepcionais, como atrasos nas entregas. Alguns sistemas de
banco de dados oferecem suporte interno para enviar e-mail a partir de consultas SQL
e triggers, usando a tcnica que indicaremos.

CREATE TRIGGER trigger_saldo_devedor AFTER UPDATE ON conta


REFERENCING NEW ROW AS nrow
FOR EACH ROW
WHEN nrow.saldo < 0
BEGIN ATOMIC
INSERT INTO tomador
(SELECT nome_cliente, numero_conta
FROM depositante
WHERE nrow.numero_conta = depositante.numero_conta);
INSERT INTO emprstimo VALUES
(nrow.numero_conta, nrow.nome_agencia, - nrow.saldo);
UPDATE conta SET saldo = 0
WHERE conta.numero_conta = nrow.numero-conta
END

Figura 1 Exemplo de sintaxe SQL:1999 para triggers.

Triggers em SQL
Os sistemas de banco de dados baseados em SQL utilizam bastante os triggers,
embora antes da SQL: 1999 eles no fizessem parte do padro SQL. Infelizmente,
cada sistema de banco de dados implementou sua prpria sintaxe para os triggers,
levando a incompatibilidades.
Essa definio de trigger especifica que o trigger iniciado aps qualquer atualizao
da relao conta ser executada. Uma instruo de atualizao SQL poderia atualizar
vrias tuplas da relao, e a clusula for each row no cdigo do trigger percorreria
explicitamente cada linha atualizada. A clusula referencing new row as cria uma
varivel nrow (chamada varivel de transio), que armazena o valor de uma linha
atualizada aps a atualizao.
A instruo when especifica uma condio, a saber, nrow.saldo < 0. O sistema
executa o restante do corpo do trigger somente para tuplas que satisfazem a condio.
A clsula begin atomic ... end serve para coletar vrias instrues SQL em uma nica
instruo composta. As duas instrues insert com a estrutura begin ... end executam
tarefas especficas de criao de novas tuplas nas relaes tomador e emprstimo
para representar o novo emprstimo. A instruo update serve par definir o saldo da
conta de volta a 0 a partir do seu antigo valor negativo.

Prof. Antonio Almeida de Barros Jnior

Pg. 2

O evento de disparo e as aes podem tomar muitas formas:


O evento de disparo pode ser insert ou delete, em vez de update.
Por exemplo, a ao sobre delete de uma conta poderia se verificar se os
mantenedores da conta possuem quaisquer contas restantes, e se no tiverem, exclulos da relao depositante.
Como outro exemplo, se um novo depositante for inserido, a ao disparada poderia
ser enviada uma carta de boas-vindas ao depositante. Obviamente, um trigger no
pode causar tal ao diretamente fora do banco de dados, mas poderia acrescentar
uma tupla a uma relao que armazena endereos aos quais as cartas de boas-vindas
precisam ser enviadas. Um processo separado passaria por essa tabela, e imprimiria
cartas a serem enviadas.
Muitos sistemas de banco de dados do suporte a uma srie de outros eventos de
disparo, por exemplo, quando um usurio (aplicao) efetua o login no banco de
dados (ou seja, abre uma conexo), quando o sistema desliga ou quando so feitas
mudanas nas configuraes do sistema.

Para as atualizaes, o trigger pode especificar colunas cuja atualizao faz


com que o trigger seja executado. Por exemplo, se a primeira linha do trigger
de saldo devedor fosse substituda por
CREATE TRIGGER trigger_saldo_devedor AFTER UPDATE OF saldo ON conta

Ento o trigger seria executado somente nas atualizaes de saldo; as


atualizaes de outros atributos no causariam sua execuo.

A clusula referencing old row as pode ser usada para criar uma varivel
armazenando o valor antigo de uma linha atualizada ou excluda. A clusula
referencing new row as pode ser usada com inseres alm de atualizaes.
Triggers podem ser ativados antes (before) do evento (insert/delete/update), ao
invs de depois (after) do evento.
Esses triggers servem como restries extras que podem impedir atualizaes
invlidas. Por exemplo, se no quisermos permitir saldos devedores, podemos
criar um trigger before que verifica se o novo saldo negativo e, se for, reverte
a transao. Embora um trigger after pudesse ter sido usado para essa
finalidade, seu uso resultaria na atualizao sendo feito primeiro, para depois
na transao ser revertida.
Como outro exemplo, suponha que o valor em um campo de nmero de
telefone de uma tupla inserida esteja em branco, o que indica a ausncia de
um nmero de telefone. Podemos definir um trigger que substitua o valor pelo
valor null. A instruo set pode ser usada para executar tais modificaes.
CREATE TRIGGER trigger_nulo BEFORE UPDADE ON r
REFERENCING NEW ROW AS nrow
FOR EACH ROW
WHEN nrow.numero_telefone =
SET nrow.numero_telefone = null

Em vez de executar uma ao para cada linha efetuada, podemos executar


uma nica ao para a instruo SQL inteira que causou o

Prof. Antonio Almeida de Barros Jnior

Pg. 3

insert/delete/update. Para fazer isso, usamos a clusula for each statement


no lugar da clusula for each row.
As clusulas referencing old table as ou referencing new table as podem
ser usadas para referenciar tabelas temporrias (chamadas tabelas de
transio) contendo todas as linhas afetadas. As tabelas de transio no
podem ser usadas com triggers before, mas podem ser usadas com triggers
after, independentemente de serem triggers de instruo ou triggers de linha.
Uma nica instruo SQL pode, ento, ser usada para executar vrias aes
com base nas tabelas de transio.

Triggers podem ser desativados ou ativados; como padro, eles so ativados


quando criados, mas podem ser desativados por meio de alter trigger
nome_trigger disable (alguns bancos de dados utilizam uma sintaxe
alternativa, como disable trigger nome_trigger). Um trigger que foi desativado
pode ser ativado novamente. E tambm pode ser descartado usando o
comando drop trigger nome_trigger, que o remove permanentemente.

Retornando ao nosso exemplo de estoque de depsito, suponha que tenhamos as


seguintes relaes:
estoque(item, nvel), que observa a quantidade atual (nmero/peso/volume) do
item no depsito.
nivelmin(item, nvel), que observa a quantidade mnima que deve ser mantida
para esse item.
novopedido(item, quantidade), que observa a quantidade do item a ser pedida
quando seu nvel ficar abaixo do mnimo.
pedidos(item, quantidade), que observa a quantidade do item a ser pedida.
Observe que precisamos ter cuidado para fazer um pedido apenas quando a
quantidade cair de cima do nvel mnimo para abaixo do nvel mnimo. Se verificar
apenas se o novo valor aps uma atualizao est abaixo do nvel mnimo, poderemos
fazer um pedido erroneamente quando o item j tiver sido pedido. Podemos ento
usar o trigger mostrado na figura 2 para pedir o item.

CREATE TRIGGER trigger_pedido AFTER UPDATE OF quantia ON estoque


REFERENCING OLD ROW AS orow, NEW ROW AS nrow
FOR EACH ROW
WHEN nrow.nivel <= (SELECT nivel
FROM minnivel
WHERE minnivel.item = orow.item)
AND orow.nivel > (SELECT nivel
FROM minnivel
WHERE minnivel.item = orow.item)
BEGIN
INSERT INTO pedidos
(SELECT item, quantia
FROM novopedido
WHERE novopedido.item = orow.item)
END

Figura 2 Exemplo de trigger para novo pedido de um item.

Prof. Antonio Almeida de Barros Jnior

Pg. 4

Muitos sistemas de banco de dados oferecem implementaes de trigger fora do


padro, ou implementam apenas alguns dos recursos de trigger. Por exemplo, muitos
sistemas de banco de dados no implementam a clusula before, e a palavra-chave
on usada no lugar de after. Eles podem no implementar a clusula referencing.
Em vez disso, podem especificar tabelas de transio usando as palavras-chave
inserted ou deleted. A figura 3 ilustra como o trigger de saldo devedor seria escrito no
Microsoft SQLServer. Leia o manual do usurio do sistema de banco de dados que
voc usa a fim de obter mais informaes sobre os recursos do trigger que ele admite.
CREATE TRIGGER trigger_saldo_devedor ON conta
FOR UPDATE
AS
IF inserted.saldo < 0
BEGIN
INSERT INTO tomador
(SELECT nome_cliente, numero_conta
FROM depositante, inserted
WHERE inserted.numero_conta = depositante.numero_conta)
INSERT INTO emprestimo
VALUES
(inserted.numero_conta, inserted.nome_agencia, - inserted.saldo)
UPDATE conta SET saldo = 0
FROM conta, inserted
WHERE conta.numero_conta = inserted.numero_conta
inserted.numero_conta = depositante.numero_conta)
END

Figura 3 Exemplo de trigger na sintaxe do MS-SQL Server.

Quando no usar triggers


Existem muitos bons usos para triggers, como aqueles que j vimos na seo anterior,
mas alguns usos podem ser tratados melhor por meio de tcnicas alternativas. Por
exemplo, no passado, os projetistas de sistemas usavam triggers para manter dados
de resumo. Por exemplo, eles usavam triggers no insert/delete/update de uma relao
funcionrio contendo atributos salrio e departamento para manter o total de salrios
de cada departamento. Porm, muitos sistemas de banco de dados hoje admitem
views materializadas, que oferecem um modo muito mais fcil de manter dados de
resumo. Os projetistas tambm usavam muito triggers para replicar bancos de dados;
eles usavam triggers insert/delete/update de cada relao para registrar as mudanas
nas relaes, chamadas relaes change ou delta. Um processo separado copiava as
mudanas para a rplica (cpia) do banco de dados, e o sistema executava as
mudanas na rplica. Porm, os sistemas de banco de dados modernos oferecem
facilidades embutidas para a replicao de banco de dados, tornando os triggers
desnecessrios para a replicao na maioria dos casos.
De fato, muitas aplicaes de trigger, incluindo nosso trigger de exemplo de saldo
devedor, podem ser substitudas pelo uso apropriado dos procedimentos
armazenados. Por exemplo, suponha que as atualizaes no atributo saldo de conta
sejam feitas apenas por meio de um procedimento armazenado em particular. Esse
procedimento, por sua vez, verificaria o saldo negativo e executaria as aes do
trigger de saldo devedor. Os programadores devem ter cuidado para no atualizar
diretamente o valor de saldo, mas atualiz-lo apenas por meio do procedimento
armazenado; isso poderia ser garantido no dando a aplicao/usurio autorizao
Prof. Antonio Almeida de Barros Jnior

Pg. 5

para executar o atributo saldo, mas oferecendo autorizao para executar o


procedimento armazenado que est associado. Um encapsulamento semelhante pode
ser usado para substituir o trigger novopedido por um procedimento armazenado.
Outro problema com os triggers est na execuo no intencionada da ao disparada
quando os dados so carregados de uma cpia de backup, ou quando atualizaes do
banco de dados em um site so replicadas em um site de backup. Nesses casos, a
ao disparada j foi executada, e normalmente no deve ser executada novamente.
Ao carregar dados, os triggers podem ser desativados explicitamente. Para sistema de
rplica de backup que podem ter de assumir o comando no lugar do sistema principal,
os triggers teriam de ser desativados inicialmente e ativados quando o site de backup
assumisse o processamento no lugar do principal. Como alternativa, alguns sistemas
de banco de dados permitem que os triggers sejam especificados como not for
replication, o que garante que eles no sejam executados no site de backup durante
a replicao do banco de dados. Outros sistemas de banco de dados oferecem uma
varivel do sistema que indica que o banco de dados uma rplica nas quais as
aes do banco de dados esto sendo reproduzidas; o corpo do trigger deve verificar
essa varivel e sair se ela for verdadeira. As duas solues evitam a necessidade de
desativao e ativao explcita de triggers.
Os triggers devem ser escritos com muito cuidado, pois um erro de trigger detectado
em tempo de execuo causa a falha da instruo insert/delete/update que disparou o
trigger. Alm do mais, a ao de um trigger pode disparar um outro. No pior dos casos,
isso poderia levar a uma cadeia infinita de disparos. Por exemplo, suponha que um
trigger insert sobre uma relao tenha uma ao que causa outro insert (novo) na
mesma relao. A ao de insert ento dispara outra ao de insert, e assim por
diante, add infinitum. Os sistemas de banco de dados normalmente limitam a extenso
de tais cadeias de triggers (por exemplo, a 16 ou 32) e consideram que existe um erro
se houver cadeias de disparo maiores.
Ocasionalmente, os triggers so chamados de regras, ou regras ativas, mas no
devem ser confundidos com as regras do Datalog que na realidade so definies de
view.

Prof. Antonio Almeida de Barros Jnior

Pg. 6

Implementao de Trigger em MySQL


O MySQL finalmente suporta uma das caractersticas mais importantes de um servidor
de base de dados desde a verso 5.0.2. Os Trigger so implementado no MySQL,
seguindo a sintaxe padro SQL: 2003.
Quando voc cria um trigger no MySQL, as suas definio so guardadas no arquivo
com extenso .TRG numa pasta da base de dados com a seguintes especificaes:
/data_folder/database_name/table_name.trg
O arquivo est em formato de texto, voc pode usar qualquer editor de texto para
modific-lo.
Quando um trigger implementado no MySQL, este tem todos os recursos do
standard SQL, mas existem algumas restries que voc deve estar ciente:
No permitido chamar um stored procedure em um trigger.
No permitido criar um trigger para uma view ou a tabela temporria.
No permitido o uso de transaes (commit e roolback) num trigger.
A declarao de retorno (return) no permitida num trigger.
Criar um trigger para uma tabela da base de dados faz com que o cache de
consultas seja invalidado.
Todos os triggers para uma tabela da base de dados devem ter nomes nicos.
permitido que triggers para tabelas diferentes com o mesmo nome, mas
recomendado que dentro da mesma base de dados sejam dados nomes diferentes
aos triggers. Para criar o trigger, tem de se usar a seguinte sintaxe:
(BEFORE | AFTER) _tableName_ (INSERT | UPDATE |DELETE)
Sintaxe Completa
CREATE TRIGGER <nome_trigger>
{BEFORE | AFTER}
{DELETE | INSERT | UPDATE}
ON <tabela>
FOR EACH ROW
BEGIN
<comandos_compostos>
e / ou
<commandos_simples>
END;

Figura 4 Sintaxe de trigger do MySQL.

CREATE TRIGGER usado para criar triggers.


nome_trigger deve seguir a seguinte conveno:
o [trigger_time]_[table_name]_[trigger_event];
o Exemplo before_itempedido_update.
o Onde:
trigger_time pode ser BEFORE or AFTER. Voc deve especificar
o trigger_time quando define um trigger. Use BEFORE, quando
voc deseja processar ao antes da mudana a ser feita numa
tabela e AFTER, se voc precisa para processar ao depois
que as mudanas serem feitas.
trigger_event pode ser INSERT, UPDATE e DELETE.

Prof. Antonio Almeida de Barros Jnior

Pg. 7

Um trigger pode disparar apenas com um evento. Para definir trigger que iniciem
mltiplos eventos, voc tem que definir vrios triggers, uma para cada evento.

Por padro um trigger deve estar associado a uma tabela especfica. Sem uma
tabela o trigger no existe. Por isso voc tem que especificar o nome da tabela
aps a palavra chave ON.

O MySQL fornece as palavras reservadas OLD e NEW para ajudar a escrever


triggers mais eficientes.- A palavra reservada OLD refere-se linha existente
antes da atualizao dos dados e a palavra reservada NEW refere-se nova
linha aps a atualizao de dados.

Exemplo
DELIMITER //
CREATE TRIGGER t_altera_saldo_produto
BEFORE UPDATE ON produtos
FOR EACH ROW
BEGIN
SET @old = OLDquantprod;
SET @new = NEW.quantprod;
END;
DELIMITER; //

Figura 5 Exemplo de trigger na sintaxe do MySQL.

Manuteno de Triggers em MySQL


Uma vez criado o trigger e associado a uma tabela, voc pode ver o trigger, indo
diretamente para a pasta que contm o trigger. O trigger armazenado como arquivo
de texto na pasta da base de dados da seguinte forma:
/Data_Folder / database_name / table_name.trg

Com qualquer editor de texto simples como o bloco de notas voc pode visualizar o
cdigo do trigger.
O MySQL fornece-lhe uma outra maneira de ver o cdigo do seu trigger, executando a
seguinte instruo SQL:
SELECT * FROM Information_Schema.Trigger
WHERE Trigger_schema = 'database_name' AND Trigger_name = 'trigger_name';

Figura 6 Cdigo SQL para visualizar um trigger.


Deste modo, voc no v apenas o contedo do trigger, mas tambm outros
metadados associados a ele, como nome da tabela, definidor (nome do MySQL, que
criou o trigger).
Para encontrar todos os triggers associados a uma base de dados, basta executar a
seguinte instruo SQL:
SELECT Information_Schema.Trigger
WHERE Trigger_Schema = 'database_name;

Figura 7 Cdigo SQL para visualizar todos os triggers de uma base.

Prof. Antonio Almeida de Barros Jnior

Pg. 8

Para encontrar todos os triggers associados a uma tabela da base de dados, basta
executar a seguinte instruo SQL:
SELECT * FROM Information_Schema.Trigger;
WHERE Trigger_Schema = 'database_name' AND Event_object_table = 'table_name';

Figura 8 Cdigo SQL para visualizar os triggers de uma tabela.


No MySQL voc no s so capazes de ver o trigger, mas tambm remover um trigger
existente. Para remover um trigger voc pode usar a instruo SQL DROP TRIGGER
como segue:
DROP TRIGGER table_name.trigger_name;

Figura 9 Cdigo SQL para excluir um trigger.


Para modificar um trigger, voc deve exclu-lo e recri-lo. O MySQL no fornece uma
instruo SQL para alterar um gatilho existente, como alterao de objetos de bases
de dados, tais como tabelas e stored procedures.
Referncias
MySQL Triggers. Curso Profissional Tcnico de Gesto e Programao de Sistemas
Informticos.
Escola
Secundria
Madeira
Torres.
Disponvel
em
<
http://pt.scribd.com/doc/51023905/Tutorial-MySQL-Triggers>

Prof. Antonio Almeida de Barros Jnior

Pg. 9