You are on page 1of 8

Triggers no PostgreSQL | iMasters

Pgina 1 de 8

Abril.com
PORTAL

Mais sites Abril


IMASTERS BOX CURSOS ONLINE

Grupo Abril
7MASTERS

Abril Mdia
AGENDA

Distribuio

Grfica

Abril Educao

Assine

Loja

SAC

FRUM

COLETIVOS

INTERCON

REPOS

Faa Login / Cadastre-se

+ de 10.500 artigos publicados em 11 anos

DESIGN & UX

FRONT-END

DEV

BD

MOBILE

MKT DIGITAL

APIS

SEARCH

INFRA

TECH

E-COMMERCE

ANALYTICS

Like

POSTGRESQL

Triggers no PostgreSQL

LTIMAS NOTCIAS
05/03 S 11H03

Twitter vai encerrar apps do TweetDeck para iPhone, Android e desktop


05/03 S 10H03

Microsoft lana Office Developer Tools para Visual Studio 2012


05/03 S 09H03

Android dominar downloads de apps para smartphones este ano


05/03 S 08H03

Google explica como o Google funciona


04/03 S 05H03

iMasters PRO lana curso ao vivo de Design Mobile


TODAS AS NOTCIAS

http://imasters.com.br/artigo/10644/postgresql/triggers-no-postgresql/

05/03/2013

Triggers no PostgreSQL | iMasters

Pgina 2 de 8

os dados de entrada tambm incluem as linhas NEW para as triggers de INSERT e UPDATE, e a linha OLD para os triggers de UPDATE e DELETE. Ainda nesse artigo veremos como criar funes de triggers utilizando linguagens procedurais.

Criando uma trigger


A sintaxe para a criao de uma trigger apresentada abaixo:

CREATE TRIGGER nome { BEFORE | AFTER } { evento [ OR ... ] } ON tabela [ FOR [ EACH ] { ROW | STATEMENT } ] EXECUTE PROCEDURE nome_da_funo ()

DESTAQUES

Argumentos: nome o nome da trigger. before | after determina se a funo ser chamada antes ou depois do evento. evento indica em que momento a trigger ser disparada. A trigger pode ser dispara antes ou depois de um evento de DELETE, UPDATE ou INSERT. tabela indica em qual tabela a trigger estar associada. row | statement especifica se a trigger deve ser disparada uma vez para cada linha afetada pelo evento ou apenas uma vez por comando SQL. Se no for especificado nenhum dos dois, o padro FOR EACH STATEMENT. nome_da_funo especifica a funo de trigger. Um exemplo de criao de uma trigger apresentado abaixo: LABORATRIO DE SCRIPTS PHP Participe do laboratrio pblico e colaborativo de scripts PHP criado pelos moderadores e participantes do Frum PHP iMasters IMASTERS BOX Catlogo completa de ferramentas online para auxlio de desenvolvedores.

CREATE TRIGGER "u_tg_validaCpf " BEFORE INSERT ON CLIENTE FOR EACH ROW EXECUTE PROCEDURE u_fn_validaCpf();

Criando triggers functions (funes de trigger) Vamos agora aprender a criar funes de trigger. Uma funo de trigger deve ser codificada em uma linguagem procedural disponvel no banco de dados ou em linguagem C. Para nossos exemplos, vamos criar um banco de dados, um esquema (schema) e duas tabelas para demonstrar o uso dessas funes. Para criar esses objetos, execute os scripts abaixo:

/* Criao do banco de dados */ CREATE DATABASE bd_triggers WITH ENCODING='WIN1252' OWNER="SYSDBA" TABLESPACE=pg_default;
iMasters Find us on Facebook

/* Criao do esquema que conter as tabelas e triggers */ CREATE SCHEMA sc_triggers;

Like 32,510 people like iMasters.

/* Criao das tabelas onde sero usadas as triggers */ CREATE TABLE sc_triggers.tb_a ( cod serial, valor varchar(20), CONSTRAINT pk_tb_a_cod PRIMARY KEY (cod) );
Facebook social plugin

CREATE TABLE sc_triggers.tb_b ( cod serial, valor varchar(20), numero int, CONSTRAINT pk_tb_b_cod PRIMARY KEY (cod), CONSTRAINT fk_tb_b_numero FOREIGN KEY (numero) REFERENCES sc_triggers.tb_a (cod) );

Vamos agora criar uma funo de trigger simples, que ir apenas inserir um novo registro na tabela tb_b quando inserirmos algo na tabela tb_a. Observe que a tabela tb_b possui uma chave

http://imasters.com.br/artigo/10644/postgresql/triggers-no-postgresql/

05/03/2013

Triggers no PostgreSQL | iMasters

Pgina 3 de 8

estrangeira da tabela tb_a, logo, para inserirmos algo nessa tabela temos que ter o registro j gravado na tabela tb_a. Para criarmos a funo, antes temos que definir em qual linguagem procedural esta funo ser codifificada. Vamos utilizar a linguagem PL/pgSQL para criar nossa funo de trigger. Antes de criar a funo temos que verificar se esta linguagem est disponvel no banco de dados. Para isso basta executar o seguinte comando:

SELECT * FROM PG_LANGUAGE;

Temos o seguinte resultado:

A tabela de sistema PG_LANGUAGE registra as linguagens disponveis no banco de dados. Repare que a linguagem plpgsql (PL/pgSQL) j est instalada no banco de dados. Agora vamos criar a funo. Execute os comandos abaixo:

CREATE OR REPLACE FUNCTION sc_triggers.fn_insert_tb_b() RETURNS trigger LANGUAGE plpgsql AS 'begin insert into sc_triggers.tb_b (sc_triggers.tb_b.valor, sc_triggers.tb_b.numero) values (new.valor, new.cod); return new; end; ';

Criamos a funo fn_insert_tb_b no esquema sc_triggers. Observe que essa funo no recebe parmetros e retorna o tipo trigger. A linguagem que ser utilizada para escrever a funo especificada logo aps a palavra LANGUAGE. Depois, criamos o cdigo da funo entre aspas, aps a palavra AS. Observe que nossa funo faz apenas um insert na tabela tb_b com base na insert que est sendo feito na tabela tb_a e retorna a linha NEW. Devemos retornar uma linha para indicar ao PostgreSQL que ele deve continuar realizando a operao. Certo. Agora vamos criar a trigger, para isso execute o script abaixo:

CREATE TRIGGER u_tg_insert_tb_b AFTER INSERT ON sc_triggers.tb_a FOR EACH ROW EXECUTE PROCEDURE sc_triggers.fn_insert_tb_b();

Nossa trigger uma trigger AFTER INSERT e est associada a tabela tb_a do esquema sc_triggers, ou seja, ser disparada logo aps um insert ter sido realizado na tabela tb_a. Depois de criarmos nossa funo e trigger, vamos test-las. Para fazer isso execute o seguinte insert:

INSERT INTO sc_triggers.tb_a (VALOR ) VALUES ( 'abc' )

Agora se fizermos um select na tabela tb_b obteremos o seguinte resultado:

Observe que inserimos o registro na tabela tb_a o que disparou nossa trigger que inseriu um registro na tabela tb_b. Vamos agora fazer algo diferente. Execute o seguinte script:

INSERT INTO sc_triggers.tb_a (VALOR ) SELECT 'def' AS VALOR UNION SELECT 'ghi' AS VALOR

Esse script vai inserir dois registros na tabela tb_a que ir disparar a trigger a inserir tambm dois registros na tabela tb_b. Depois fazemos um select na tabela tb_b. O resultado mostrado abaixo:

http://imasters.com.br/artigo/10644/postgresql/triggers-no-postgresql/

05/03/2013

Triggers no PostgreSQL | iMasters

Pgina 4 de 8

Nossa trigger est funcionando corretamente.

Ordem de execuo de triggers


Podemos ter mais de uma trigger associada ao mesmo evento e momento, neste caso a ordem de execuo das triggers definida pela ordem alfabtica de seus nomes.

Triggers recursivas
Se uma funo de trigger executar comandos SQL, estes comandos podem disparar triggers novamente. Isto conhecido como cascatear triggers. No existe limitao direta do nmero de nveis de cascateamento. possvel que o cascateamento cause chamadas recursivas da mesma trigger; por exemplo, um trigger para INSERT pode executar um comando que insere uma linha adicional na mesma tabela, fazendo com que o trigger para INSERT seja disparado novamente. responsabilidade do programador evitar recurses infinitas nestes casos.

Alterando uma trigger


A sintaxe do comando para alterar uma trigger apresentada abaixo:

ALTER TRIGGER nome ON tabela RENAME TO novo_nome

Argumentos: nome nome do gatilho existente a ser alterado. tabela o nome da tabela onde o gatilho atua. novo_nome o novo nome do gatilho. Exemplo :

ALTER TRIGGER u_tg_insert_tb_est_triggers ON SC_TRIGGERS.TB_TESTE_TRIGGERS RENAME TO usr_tg_insert_tb_est_triggers;

Excluindo uma trigger


Para excluir uma trigger basta executar o comando abaixo:

DROP TRIGGER nome ON tabela [ CASCADE | RESTRICT ]

Argumentos: nome o nome do gatilho a ser removido. tabela o nome da tabela para a qual o gatilho est definido. [ CASCADE | RESTRICT ] indica se ao remover a trigger vamos remover tambm todos os objetos que dependem dela (CASCADE) ou recusaremos sua excluso (RESTRICT). Exemplo:

DROP TRIGGER u_tg_insert_tb_est_triggers ON SC_TRIGGERS.TB_TESTE_TRIGGERS;

Habilitando/Desabilitando triggers Para desabilitar uma trigger execute o comando abaixo:

ALTER TABLE nome_tabela DISABLE TRIGGER nome_trigger

Para desabilitar todas as triggers da tabela, execute o seguinte comando:

http://imasters.com.br/artigo/10644/postgresql/triggers-no-postgresql/

05/03/2013

Triggers no PostgreSQL | iMasters

Pgina 5 de 8

ALTER TABLE nome_tabela DISABLE TRIGGER ALL

Exemplo:

ALTER TABLE SC_TRIGGERS.TB_TESTE_TRIGGERS DISABLE TRIGGER U_TG_INSERT_TB_EST_TRIGGERS

Para habilitar uma trigger basta alterar o parmetro DISABLE para ENABLE, observe abaixo:

ALTER TABLE SC_TRIGGERS.TB_TESTE_TRIGGERS ENABLE TRIGGER U_TG_INSERT_TB_EST_TRIGGERS

Agora para habilitar todas as triggers da tabela:

ALTER TABLE SC_TRIGGERS.TB_TESTE_TRIGGERS ENABLE TRIGGER U_TG_INSERT_TB_EST_TRIGGERS

Obtendo informaes sobre as triggers do banco de dados


Podemos obter vrias informaes sobre as triggers de nosso banco de dados. Essas informaes esto disponveis na view triggers do schema information_schema presente em qualquer banco de dados do PostgreSQL. Essa view possui algumas colunas importantes. Veja a tabela abaixo:

Exemplo:

SELECT * FROM INFORMATION_SCHEMA.TRIGGERS

Podemos tambm obter essas informaes diretamente da tabela de sistema pg_trigger do schema pg_catalog. Exemplo:

SELECT * FROM PG_CATALOG.PG_TRIGGER

Finalizo assim este artigo. Abraos Referncias: Documentao oficial do PostgreSQL 8.0 ( http://pgdocptbr.sourceforge.net/ )

Danilo Abranches tcnico em Informtica Industrial pelo Instituto Federal de Educao, Cincia e Tecnologia - MG, e graduando em Gesto Ambiental pelo Instituto Vianna Jnior. analista de sistemas jnior na Handcom Inovaes Tecnolgicas onde trabalha com .NET e NHibernate no desenvolvimento de aplicaes para diversos segmentos. Pgina do autorEmail Leia os ltimos artigos publicados por Danilo Abranches Triggers no PostgreSQL Treeview dinmica com ASP.NET e Ajax Triggers no Firebird

http://imasters.com.br/artigo/10644/postgresql/triggers-no-postgresql/

05/03/2013

Triggers no PostgreSQL | iMasters

Pgina 6 de 8

10 COMENTRIOS

COMENTE TAMBM

Beto Lima Ol, gostaria de saber se ha uma maneira de alterar todos os caracteres minusculos para maiusculos direto no banco postgre. ex: tenho um banco com 10 tabelas onde em todas elas possuem registros com lowercase. Queria saber se tem alguma funo ou procedimento onde possa passar tudo pra uppercase de uma vez s. sem ter que colocar upper junto com insert. Valeu H 1076 dias Responder

Danilo Abranches No conheo funo para isso e acredito que no exista, mas voc poderia fazer isso utilizando como auxlio os metadados. H 1033 dias Responder Reinaldo Torres Fala amigo tudo bem ? Eu estive acompanhando o seu tutorial, eu achei ele bem legal e com certeza aprendi bastante coisas com ele. Conforme fui seguindo ele , achei um problema e tenho uma sugesto para melhorar o seu tutorial. Problema: Na criao da trigger abaixo , no necessrio referencia ao schema e a tabela na hr informar a coluna ao inserir um registro, eu segui o tutorial na verso 8.3 do banco e isso causou erro. O erro no na hr da criao da trigger e sim na hr de dar um insert na tb_a, ento detectei o problema na trigger e corrigi da seguinte maneira: CREATE OR REPLACE FUNCTION sc_triggers.fn_insert_tb_b() RETURNS trigger LANGUAGE plpgsql AS begin insert into sc_triggers.tb_b (valor, numero) values (new.valor, new.cod); return new; end; ; Sugesto: Quando estive verificando no meu banco se tinha a linguagem PL/pgSQL, atravs da query que vc passou, eu vi que meu banco no estava com a linguagem habilitada conforme o seu exemplo. No seu exemplo vc conta que ela ja esteja habilitada, ento a sugesto que adicione o cdigo de adicionar essa linguagem, seno o tutorial abaixo disso no serveria. Pesquisei na internet e achei o seguinte codigo que habilita em caso de a linguagem no aparecer no resultado do select. CREATE TRUSTED PROCEDURAL LANGUAGE plpgsql HANDLER plpgsql_call_handler VALIDATOR plpgsql_validator; Bem, basicamente isso, parabns pelo tutorial e por ajudar a propagar o conhecimento :D Absss H 1026 dias Responder

Danilo Abranches Ol Reinaldo! Agradeo pelo elogio e fico contente que tenha gostado do artigo, e mais ainda por ter contribuido com seu aprendizado. Sua sugesto 100% vlida, a linguagem pode no estar habilitada no banco. O default, se no me engano, vir instalada, exceto para o banco postgres. Obrigado pela sugesto e pela observao! H 1025 dias Responder Bom tarde, sou novato em postgres goataria de tira mais uma duvida com voc, segue abaixo o meu codigo fonte. OBS: quando eu tento pegar NEW.isn_usuario ele no da insert, vc pode me ajudar funo: CREATE OR REPLACE FUNCTION compras.insert_audit() RETURNS trigger AS $BODY$ begin insert into compras.t_audit(dsc_tebela,isn_tabela,isn_usu,dsc_acao, dat_audit,dsc_valor_antes,dsc_valor_despois) values (TG_RELNAME,10,NEW.isn_usuario, TG_OP,now(),,); return NEW; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100; ALTER FUNCTION compras.insert_audit() OWNER TO postgres; trigger: CREATE TRIGGER insert_audit AFTER INSERT OR UPDATE

http://imasters.com.br/artigo/10644/postgresql/triggers-no-postgresql/

05/03/2013

Triggers no PostgreSQL | iMasters

Pgina 7 de 8

ON compras.t_solicitacao FOR EACH ROW EXECUTE PROCEDURE compras.insert_audit(); H 883 dias Responder Danilo Abranches Ol! Voc disse que o insert no feito. Ocorre algum erro? Me mande um e-mail, assim conversamos melhor. H 829 dias Responder Leandro Correa dos Santos Excelente artigo. Detalhado, direto ao ponto e muito relevante. Agora ficou fcil entender as triggers. Parabns. H 558 dias Responder Jhosepher Excelente artigo. Me ajudou muito, sou novo no PostgreSQL, e ainda por cima estou fazendo meu TCC baseado nele, uma Replicao de dados no Postgre. Um pequeno prottipo, pois estamos com alguns problemas de queda conexao com banco externo (imaginvel com a realidade da internet brasileira). Estou com duvidas em qual caminho seguir, segundo meu orientador as triggers seria o mais indicado para resolver o meu problema. Resumindo, este tutorial me ajudou a intender melhor como as triggers funcionam. Muito obrigado :D H 503 dias Responder

Danilo Abranches muito bom saber que gostaram do artigo. Obrigado pessoal! H 489 dias Responder miro Danilo, bom dia, Primeiro gostaria de parabeniz-lo, estes artigos ajudam muita gente como eu, que esto buscando se aprofundar seu conhecimentos. Gostaria tbm de aproveitar e pedir uma ajuda num problema que estou tendo aqui: Tenho um projeto que guarda saldos anteriores, depositos e saques, todos totalizados dia a dia. at ai tudo bem, o problema que me apareceu agora que as vezes vai ser necessrio realizar lanamentos retroativos, os quais vao desatualizar todos os saldos posteriores aquela data. Se fosse possvel vc mencionar algum exemplo de trigguers que atualizasse automaticamente todos os saldos posteriores aquele lancamento e como essas triggers recebem os valores passados pelo sistema. Desde j agradeo. H 305 dias Responder

QUAL A SUA OPINIO?

Twitter
Siga o perfil do iMasters

LinkedIn
Cadastre-se no grupo iMasters

gitHub
Cdigos iMasters DEV

RSS
Assine os feeds

SOCIAL MEDIA
Copyright 2013 Todos os direitos reservados

NEWSLETTER
Fique por dentro de todas as novidades, eventos, cursos, contedos exclusivos e muito mais.

faleconosco@imasters.com.br

http://imasters.com.br/artigo/10644/postgresql/triggers-no-postgresql/

05/03/2013

Triggers no PostgreSQL | iMasters

Pgina 8 de 8

Sobre o iMasters Poltica de Privacidade Fale conosco

ENVIAR

http://imasters.com.br/artigo/10644/postgresql/triggers-no-postgresql/

05/03/2013

You might also like