8
Abril.com Mais sites Abril Assine Loja SAC Grupo Abril Abril Mídia Distribuição Gráfica AbrilEducação +de10.500artigospublicadosem11anos FaçaLogin/Cadastre-se 0 1 POSTGRESQL Triggers no PostgreSQL Like 0 ÚLTIMASNOTÍCIAS 05/03ÀS11H03 Twittervaiencerrarappsdo TweetDeckparaiPhone,Android edesktop 05/03ÀS10H03 MicrosoftlançaOfficeDeveloper ToolsparaVisualStudio2012 05/03ÀS09H03 Androiddominarádownloadsde appsparasmartphonesesteano 05/03ÀS08H03 GoogleexplicacomooGoogle funciona 04/03ÀS05H03 iMastersPROlançacursoao vivodeDesignMobile TODASASNOTÍCIAS» PORTAL FÓRUM IMASTERS BOX CURSOS ONLINE 7MASTERS AGENDA COLETIVOS INTERCON REPOS DESIGN&UX FRONT-END DEV BD MOBILE MKTDIGITAL APIS SEARCH INFRA TECH E-COMMERCE ANALYTICS Página 1 de 8 Triggers no PostgreSQL | iMasters 05/03/2013 http://imasters.com.br/artigo/10644/postgresql/triggers-no-postgresql/

Triggers No Postgres

  • Upload
    evann

  • View
    178

  • Download
    1

Embed Size (px)

Citation preview

Page 1: Triggers No Postgres

Abril.com Mais sites Abril Assine Loja SACGrupo Abril Abril Mídia Distribuição Gráfica Abril Educação

+ de 10.500 artigos publicados em 11 anos

Faça Login / Cadastre-se

0 1

POSTGRESQL

Triggers no PostgreSQL

Like 0

ÚLTIMAS NOTÍCIAS

05/03 ÀS 11H03

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

05/03 ÀS 10H03

Microsoft lança 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 lança curso ao vivo de Design Mobile

TODAS AS NOTÍCIAS »

PORTAL FÓRUM IMASTERS BOX CURSOS ONLINE 7MASTERS AGENDA COLETIVOS INTERCON REPOS

DESIGN & UX FRONT-END DEV BD MOBILE MKT DIGITAL APIS SEARCH INFRA TECH E-COMMERCE ANALYTICS

Página 1 de 8Triggers no PostgreSQL | iMasters

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

Page 2: Triggers No Postgres

os dados de entrada também 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 funções de triggers utilizando linguagens procedurais.

Criando uma trigger

A sintaxe para a criação de uma trigger é apresentada abaixo:

CREATE TRIGGER nome { BEFORE | AFTER } { evento [ OR ... ] }

ON tabela [ FOR [ EACH ] { ROW | STATEMENT } ]

EXECUTE PROCEDURE

nome_da_função ()

Argumentos:

■ nome é o nome da trigger.

■ before | after determina se a função 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 não for especificado nenhum dos dois, o

padrão é FOR EACH STATEMENT.

■ nome_da_função especifica a função de trigger.

Um exemplo de criação de uma trigger é apresentado abaixo:

CREATE TRIGGER "u_tg_validaCpf " BEFORE INSERT

ON CLIENTE FOR EACH ROW

EXECUTE PROCEDURE u_fn_validaCpf();

Criando triggers functions (funções de trigger)

Vamos agora aprender a criar funções de trigger. Uma função de trigger deve ser codificada em

uma linguagem procedural disponível 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 funções.

Para criar esses objetos, execute os scripts abaixo:

/* Criação do banco de dados */

CREATE DATABASE bd_triggers

WITH ENCODING='WIN1252'

OWNER="SYSDBA"

TABLESPACE=pg_default;

/* Criação do esquema que conterá as tabelas e triggers */

CREATE SCHEMA sc_triggers;

/* Criação das tabelas onde serão usadas as triggers */

CREATE TABLE sc_triggers.tb_a (

cod serial,

valor varchar(20),

CONSTRAINT pk_tb_a_cod PRIMARY KEY (cod)

);

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 função 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

DESTAQUES

IMASTERS BOXCatálogo completa de ferramentas online para auxílio de desenvolvedores.

LABORATÓRIO DE SCRIPTS PHPParticipe do laboratório público e colaborativo de scripts PHP criado pelos moderadores e participantes do Fórum PHP iMasters

Find us on Facebook

iMasters

Like

32,510 people like iMasters.

Facebook social plugin

Página 2 de 8Triggers no PostgreSQL | iMasters

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

Page 3: Triggers No Postgres

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 função, antes temos que definir em qual linguagem

procedural esta função será codifificada. Vamos utilizar a linguagem PL/pgSQL para criar nossa

função de trigger. Antes de criar a função temos que verificar se esta linguagem está disponível 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 disponíveis no banco de dados.

Repare que a linguagem plpgsql (PL/pgSQL) já está instalada no banco de dados.

Agora vamos criar a função. 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 função “fn_insert_tb_b” no esquema “sc_triggers”. Observe que essa função não recebe

parâmetros e retorna o tipo trigger. A linguagem que será utilizada para escrever a função é

especificada logo após a palavra “LANGUAGE”. Depois, criamos o código da função entre aspas,

após a palavra “AS”. Observe que nossa função 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 operação.

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 após um insert ter sido realizado na tabela “tb_a”.

Depois de criarmos nossa função 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 também dois

registros na tabela “tb_b”.

Depois fazemos um select na tabela “tb_b”. O resultado é mostrado abaixo:

Página 3 de 8Triggers no PostgreSQL | iMasters

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

Page 4: Triggers No Postgres

Nossa trigger está funcionando corretamente.

Ordem de execução de triggers

Podemos ter mais de uma trigger associada ao mesmo evento e momento, neste caso a ordem de

execução das triggers é definida pela ordem alfabética de seus nomes.

Triggers recursivas

Se uma função de trigger executar comandos SQL, estes comandos podem disparar triggers

novamente. Isto é

conhecido como cascatear triggers. Não existe limitação direta do número de níveis de

cascateamento. É possível 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 recursões 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 também todos os

objetos que dependem dela (CASCADE) ou recusaremos sua exclusão (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:

Página 4 de 8Triggers no PostgreSQL | iMasters

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

Page 5: Triggers No Postgres

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 parâmetro 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 informações sobre as triggers do banco de dados

Podemos obter várias informações sobre as triggers de nosso banco de dados. Essas informações

estão disponíveis 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 também obter essas informações diretamente da tabela de sistema “pg_trigger” do

schema “pg_catalog”.

Exemplo:

SELECT * FROM PG_CATALOG.PG_TRIGGER

Finalizo assim este artigo. Abraços

Referências:

■ Documentação oficial do PostgreSQL 8.0 ( http://pgdocptbr.sourceforge.net/ )

Danilo Abranches

é técnico em Informática Industrial pelo Instituto Federal de Educação, Ciência e Tecnologia - MG, e graduando em Gestão Ambiental pelo Instituto Vianna Júnior. É analista de sistemas júnior na Handcom Inovações Tecnológicas onde trabalha com .NET e NHibernate no desenvolvimento de aplicações para diversos segmentos.

Página do autorEmail

Leia os últimos artigos publicados por Danilo Abranches

Triggers no PostgreSQL

Treeview dinâmica com ASP.NET e Ajax

Triggers no Firebird

Página 5 de 8Triggers no PostgreSQL | iMasters

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

Page 6: Triggers No Postgres

COMENTE TAMBÉM10 COMENTÁRIOS

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 função 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

Não conheço função para isso e acredito que não exista, mas você poderia fazer

isso utilizando como auxílio 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 sugestão para melhorar o seu

tutorial.

Problema:

Na criação da trigger abaixo , não é necessário referencia ao schema e a tabela na hr informar

a coluna ao inserir um registro, eu segui o tutorial na versão 8.3 do banco e isso causou erro.

O erro não é na hr da criação da trigger e sim na hr de dar um insert na tb_a, então 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; ‘;

Sugestão:

Quando estive verificando no meu banco se tinha a linguagem PL/pgSQL, através da query

que vc passou, eu vi que meu banco não estava com a linguagem habilitada conforme o seu

exemplo. No seu exemplo vc conta que ela ja esteja habilitada, então a sugestão é que

adicione o código de adicionar essa linguagem, senão o tutorial abaixo disso não serveria.

Pesquisei na internet e achei o seguinte codigo que habilita em caso de a linguagem não

aparecer no resultado do select.

CREATE TRUSTED PROCEDURAL LANGUAGE ‘plpgsql’

HANDLER plpgsql_call_handler

VALIDATOR plpgsql_validator;

Bem, basicamente é isso,

parabéns pelo tutorial e por ajudar a propagar o conhecimento :D

Absss

Há 1026 dias Responder

Danilo Abranches

Olá Reinaldo!

Agradeço pelo elogio e fico contente que tenha gostado do artigo, e mais ainda

por ter contribuido com seu aprendizado.

Sua sugestão é 100% válida, a linguagem pode não estar habilitada no banco. O

default, se não me engano, é vir instalada, exceto para o banco postgres.

Obrigado pela sugestão e pela observação!

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 não da insert, vc pode me ajudar

função:

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

Página 6 de 8Triggers no PostgreSQL | iMasters

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

Page 7: Triggers No Postgres

ON compras.t_solicitacaoFOR EACH ROWEXECUTE PROCEDURE compras.insert_audit();

Há 883 dias Responder

Danilo AbranchesOlá!Você disse que o insert não é feito. Ocorre algum erro?Me mande um e-mail, assim conversamos melhor.

Há 829 dias Responder

Leandro Correa dos SantosExcelente artigo. Detalhado, direto ao ponto e muito relevante.Agora ficou fácil entender as triggers….Parabéns.

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 Replicação de dados no Postgre. Um pequeno protótipo, pois estamos com alguns problemas de queda conexao com banco externo (imaginável 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 estão 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, depoósitos e saques, todos totalizados dia a dia. até ai tudo bem, o problema que me apareceu agora é que as vezes vai ser necessário realizar lançamentos retroativos, os quais vao desatualizar todos os saldos posteriores aquela data. Se fosse possível 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á agradeço.

Há 305 dias Responder

QUAL A SUA OPINIÃO?

TwitterSiga o perfil do iMasters

LinkedInCadastre-se no grupo iMasters

gitHubCódigos iMasters DEV

RSSAssine os feeds

SOCIAL MEDIA

[email protected]

NEWSLETTER

Fique por dentro de todas as novidades, eventos, cursos, conteúdos exclusivos e muito mais.

Copyright © 2013 Todos os direitos reservados

Página 7 de 8Triggers no PostgreSQL | iMasters

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

Page 8: Triggers No Postgres

ENVIAR »

Sobre o iMasters

Política de Privacidade

Fale conosco

Página 8 de 8Triggers no PostgreSQL | iMasters

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