Professional Documents
Culture Documents
Pgina 1 de 8
Abril.com
PORTAL
Grupo Abril
7MASTERS
Abril Mdia
AGENDA
Distribuio
Grfica
Abril Educao
Assine
Loja
SAC
FRUM
COLETIVOS
INTERCON
REPOS
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
http://imasters.com.br/artigo/10644/postgresql/triggers-no-postgresql/
05/03/2013
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.
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 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
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:
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:
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
Pgina 4 de 8
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.
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 :
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:
http://imasters.com.br/artigo/10644/postgresql/triggers-no-postgresql/
05/03/2013
Pgina 5 de 8
Exemplo:
Para habilitar uma trigger basta alterar o parmetro DISABLE para ENABLE, observe abaixo:
Exemplo:
Podemos tambm obter essas informaes diretamente da tabela de sistema pg_trigger do schema pg_catalog. Exemplo:
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
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
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
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
Pgina 8 de 8
ENVIAR
http://imasters.com.br/artigo/10644/postgresql/triggers-no-postgresql/
05/03/2013