You are on page 1of 10

PROGRAMAO EM BANCO DADOS Stored Procedure e Trigger

A tecnologia de banco de dados permite persistir dados de forma a compartilha-los com varias aplicaes. Aplicao 1 aplicao 2 aplicao 3

SGDB

Banco de Dados

Por meio dos SGBD - Sistema Gerenciador de Banco de Dados - possvel gerenciar o acesso a dados em um BD. A SQL - linguagem de consulta estruturada - , uma linguagem padro ANSI para manipular dados por meio de um sistema gerenciador de banco de dados. A SQL pode ser dividida em 3 sub-linguagens: DDL - linguagem de definio de dados DCL - linguagem de controle de dados DML - linguagem de manipulao de dados Os SGDB devem disponibilizar recursos para manipulao de dados por meio de PL (linguagens procedimentais), j que a SQL uma linguagem no procedimental. Por exemplo: Linguagem procedimental Readln(y); Y= x*x; Println(x); f linguagem no procedimenta select x,y rom razes where y = x*x

----------------------------------------------------------------------------------------

Println(y); ---------------------------------------------------------------------------------------Nota de Aula Prof. Sidney Vieira 1

A programao em PL feita por meio de function(funo), Store Procedure (procedimentos armazenada) e Trigger (gatilho). Cada SGDB tem sua maneira prpria para tratar esses elementos de programao. As sintaxes apresentadas a seguir referem-se ao ambiente Postgresql. Stored Procedure O postgresql emprega o conceito de function para definir stored procedure ( procedimentos armazenados) Sintaxe bsica: Definio da funo: -----------------------------------------------------------------------------------------------------------------Create function nome_da_funo (tipo_dado_variavel1, tipo_dado_variavel2, tipo_dado_variavelN) Return tipo AS '<corpo da funo>' LANGUAGE `nome da linguagem usada no corpo` --------------------------------------------------------------------------------------------------------------

Dentre as linguagens possveis para o postgresql temos: SQL PERL uso da funo: --------------------------------------------------------------------------------------------------------------------------------nome_da_funo(valor_para_variavel1,valor_para_variavel1, ..., valor_para_variavelN) --------------------------------------------------------------------------------------------------------------------------------A aspa no nome da linguagem pode ser opcional, depende da verso do Postgresql (no 8.3 ela j opcional) Quando definimos que a linguagem de uma funo e sql, LANGUAGE SQL, s podemso empregar comandos da sql em seu corpo. PLPGSQL TEL C PYTHONU

Nota de Aula Prof. Sidney Vieira

A definio do corpo da funo depende da linguagem para plpgsql, devendo ser delimitada por aspas simples ' ou cifro duplo $$. Obedece a seguinte sintaxe:

Uso de ' para delimitar o corpo da funo 'declare variavel1 tipo_da_varialvel1, variavel2 tipo_da_variavel2, ... BEGIN INSTRUO 1 INSTRUO 2 RETURN VALOR RETORNO END;'

Uso de '$$ para delimitar o corpo da funo $$declare variavel1 tipo_da_varialvel1, variavel2 tipo_da_variavel2, ... BEGIN INSTRUO 1 INSTRUO 2 RETURN VALOR RETORNO END;$$

Obs: 1 a declarao de variveis, por meio da palavra reservada declare, opcional 2 - Para que uma funo retorne mais de um valor, mais de uma linha de uma tabela, o tipo de dado no retorno return tipo deve ser SETOF nome_tabela 3 - As variveis que correspondem aos n-valores passados como parmetros para a funo devem ser referenciadas como $1, $2, $3, .. $n 4 Quando o corpo da funo for definido com o uso de aspas simples devemos delimitar a funo com $$ para que o compilador no interprete a aspa simples do corpo da funo como fim da funo. Exemplos: 1 - Funo sem parmetros de entrada primeiro: definio da funo Create function dois() returns integer as `select 2; language sql; segundo: uso da funo Select dois();
Nota de Aula Prof. Sidney Vieira 3

2 - funo com parmetros de entrada primeiro: criao da funo create funcition media(decimal,decimal) returns decimal as $$ select ($1+$2)/2; $$ language sql; segundo: uso da funo caso1 select media(10,8); caso2 select media(8,9); 3 - Funo que totaliza os valores de itens de uma nota de venda da tabela item_nota CREATE FUNCTION totalNota(INTEGER) RETURNS INTEGER AS ' SELECT SUM(preco) FROM item_Nota WHERE numNota = $1; ' LANGUAGE 'SQL'; 4 Funo maior salrio de tabela funcionrio Etapas: 4.1 criar a tabela create table func(cod integer, nome varchar(30), salrio decimal(10,2), comissao decimal(10,2)); 4.2 inserir dados na tabela criada insert into func values(1, 'ZE',1000,500); insert into func values(2, 'IVO',1500,200); insert into func values(3, 'EVA',1800,100); 4.3 crie uma funo maior_salario, para exibir o maior salario create function maior_salario() returns decimal as 'select Max(salario) from func;' language sql;

Nota de Aula Prof. Sidney Vieira

4.4 usar a funo que retorna o maior salario select maior_salario(); 5 - Funo que concatena textos Create function soma(text, text) returns char as $$ Declare resultado text; Begin resultado := $1 || $2; return resultado; End;$$ language 'plpgsql'; usando a funo: select soma('Sidney ','Silva'); 6 Funo que retorna o nome dos clientes que fizeram cadastro hoje( data corrente) CREATE FUNCTION cadastro_hoje() RETURNS SETOF clientes AS ' SELECT nome FROM clientes WHERE datacadastro = current_date; ' LANGUAGE 'SQL'; 7- Funo que disponibilize o maior valor de venda. create function maiorvenda() returns decimal as 'select Max(valor) from venda;' language sql; usando a funo: select maiorvenda(); 8- Funo que disponibilize o valor total obtido com vendas create function valortotal() returns decimal as 'select sum(valor) from venda;' language sql; usando a funo: select valortotal(); 9- Crie um store procedure que disponibilize data da ultima venda
Nota de Aula Prof. Sidney Vieira 5

create function dataultimavenda() returns date as 'select max(data) from venda;' language sql; usando a funo: select dataultimavenda(); TRIGGER Uma funo de gatilho, trigger, uma ao que o SGBD deve desencadear antes ou depois de um dos seguintes comandos: insert, update ou delete. Sintaxe: Create trigger nome_gatilho {before ou after} {evento[or evento]} on table for each {row ou STATEMENT } execute procedure nome_funo (v1,v2,...,vn) Em gatilho onde tem-se FOR EACH ROW o procedimento em execute procedure chamado uma vez para cada linha que a operao modifica. J se tivermos FOR EACH STATEMENT ocorrer somente uma chamada ao procedimento descrito em execute procedure , no importando quantas linhas sejam modificadas . Variveis disponveis no ambiente de programao - PL NEW Tipo de dado RECORD; varivel contendo a nova linha do banco de dados, para as operaes de INSERT/UPDATE nos gatilhos no nvel de linha. OLD Tipo de dado RECORD; varivel contendo a antiga linha do banco de dados, para as operaes de UPDATE/DELETE nos gatilhos no nvel de linha. . TG_NAME Tipo de dado name; varivel contendo o nome do gatilho disparado. TG_WHEN Tipo de dado text; uma cadeia de caracteres contendo BEFORE ou AFTER, dependendo da definio do gatilho. TG_LEVEL Tipo de dado text; uma cadeia de caracteres contendo ROW ou STATEMENT, dependendo da definio do gatilho. TG_OP Tipo de dado text; uma cadeia de caracteres contendo INSERT, UPDATE, ou DELETE, informando para qual operao o gatilho foi disparado. TG_RELID Tipo de dado oid; o ID de objeto da tabela que causou o disparo do gatilho.
Nota de Aula Prof. Sidney Vieira 6

TG_RELNAME Tipo de dado name; o nome da tabela que causou o disparo do gatilho. TG_NARGS Tipo de dado integer; o nmero de argumentos fornecidos ao procedimento de gatilho na instruo CREATE TRIGGER. TG_ARGV[] Tipo de dado matriz de text; os argumentos da instruo CREATE TRIGGER. O contador do ndice comea por 0. ndices invlidos (menor que 0 ou maior ou igual a tg_nargs) resultam em um valor nulo.

Exemplos: 1 Gatilho que aps efetuar uma incluso, alterao ou excluso na tabela func armazema dados para auditoria na tabela func_auditoria Primeiro criar a tabela func_auditoria --------------------------------------------------------------------------------------------------------------create table func_auditoria( operacao varchar(1), usuario varchar(30), data timestamp, nome_func varchar(40), salario decimal(10,2)); ------------------------------------------------------------------------------------------------------------Segundo criar a funo para o gatilho --------------------------------------------------------------------------------------------------------------CREATE FUNCTION processa_audit_func() RETURNS TRIGGER AS $$ BEGIN --- Cria uma linha na tabela func_auditoria para refletir a operao -- realizada na tabela func. Utiliza a varivel especial TG_OP -- para descobrir a operao sendo realizada. -IF (TG_OP = 'DELETE') THEN INSERT INTO func_auditoria values('E', user, now(), OLD.nome, OLD.salario); RETURN OLD; ELSIF (TG_OP = 'UPDATE') THEN INSERT INTO func_auditoria values('A', user, now(), OLD.nome, OLD.salario); RETURN NEW; ELSIF (TG_OP = 'INSERT') THEN INSERT INTO func_auditoria values ('I', user, now(), NEW.nome, NEW.salario); RETURN NEW;
Nota de Aula Prof. Sidney Vieira 7

END IF; RETURN NULL; -- o resultado ignorado uma vez que este um gatilho AFTER END; $$ language plpgsql; ----------------------------------------------------------------------------------------------------------------Terceiro criar o gatilho --------------------------------------------------------------------------------------------------------------------CREATE TRIGGER funcionario_audit AFTER INSERT OR UPDATE OR DELETE ON func FOR EACH ROW EXECUTE PROCEDURE processa_audit_func(); ---------------------------------------------------------------------------------------------------------------Quando algum usuario fizer um insert, update ou delete na tabela func o SGBD registrar os dados na tabela func_auditoria Exemplo: se fizermos uma conexo com o sgbd com o usuario postgres e atualizar a tabela func com o comando:: update func set salario = 1200.00 where cod = 1; podemos consulta a tabela func_auditoria: SELECT * FROM func_auditoria; Teremos como resultado: ----------------------------------------------------------------------"A";"postgres";"2009-10-09 17:09:43.258";"ZE";1000.00 ------------------------------------------------------------------------

2 Gatilho que antes de efetuar uma insero na tabela func verifica se o nome do funcionario nulo e se o salario nulo ou menor do que zero caso seja no faz a incluso e emite uma mensagem Primeiro definio da funo de gatilho -----------------------------------------------------------------------------------CREATE FUNCTION func_gatilho() RETURNS trigger AS $$
Nota de Aula Prof. Sidney Vieira 8

BEGIN -- Verificar se foi fornecido o nome do empregado IF NEW.nome IS NULL THEN RAISE EXCEPTION 'O nome do empregado no pode ser nulo'; END IF; IF NEW.salario IS NULL THEN RAISE EXCEPTION 'O no pode ter um salrio nulo', NEW.nome_emp; END IF; -- Quem paga para trabalhar? IF NEW.salario < 0 THEN RAISE EXCEPTION 'O funcionario no pode ter um salrio negativo', NEW.nome_emp; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; ---------------------------------------------------------------------------------------------------------------Segundo: criao do gatilho para a tabela func ----------------------------------------------------------------------------------------------------------------CREATE TRIGGER Novo_func BEFORE INSERT OR UPDATE ON func FOR EACH ROW EXECUTE PROCEDURE func_gatilho(); ---------------------------------------------------------------------------------------------------------------terceiro: o uso Quando se tenta inserir: insert into func(cod,salario) values(5,1800); O SGBD emitir a mensagem: -------------------------------------------------------------------------------------ERROR: O nome do empregado no pode ser nulo. ------------------------------------------------------------------------------------

Nota de Aula Prof. Sidney Vieira

3 Gatilho que ao se efetuar uma insero na tabela venda armazena na tabela data os seguintes valores usuario que realizou o login, a palavra "venda" e a data com hora na atual. Create trigger auditoria after insert on venda for each Statement execute procedure inseriu(); Create function inseriu() returns trigger as $$ begin insert into data values (user,'vendas',now()); return null; end; $$ language pspgsql; Create table data(usuario varchar(50), tabela varchar(50), Datahora timestamp);

4 - Crie um gatilho que a cada mudana no preo de venda de um produto armazene os dados na tabela histrico. Create trigger atualiza_preco_venda after update on produto for each row execute procedure incluir_historico(); Create function incluir_historico() returns trigger as begin if (old.valor_venda<>new.valor_venda) then insert into historico (data, user, valor_anterior, valor_atual) values (now(),user,old.valor_venda, new.valor_venda); return null; end;' language plpgsql;

Nota de Aula Prof. Sidney Vieira

10