Você está na página 1de 10

PROGRAMAÇÃO EM BANCO DADOS Stored Procedure e Trigger

A tecnologia de banco de dados permite persistir dados de forma a compartilha-los com

varias aplicações.

Aplicação 1 aplicação 2 aplicação 3

aplicações. Aplicação 1 aplicação 2 aplicação 3 SGDB Banco de Dados Por meio dos SGBD -
SGDB
SGDB
aplicações. Aplicação 1 aplicação 2 aplicação 3 SGDB Banco de Dados Por meio dos SGBD -
Banco de Dados
Banco de
Dados

Por meio dos SGBD - Sistema Gerenciador de Banco de Dados - é possível gerenciar o

acesso a dados em um BD.

A SQL - linguagem de consulta estruturada - , é uma linguagem padrão 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 definição de dados

DCL - linguagem de controle de dados

DML - linguagem de manipulação de dados

Os SGDB ‘devem’ disponibilizar recursos para manipulação de dados por meio de PL

(linguagens procedimentais), já que a SQL é uma linguagem não procedimental.

Por exemplo:

Linguagem procedimental

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

linguagem não procedimenta

Readln(y);

select x,y

Y= x*x;

f

rom raízes

Println(x);

where y = x*x

Println(y);

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

A programação em PL é feita por meio de function(função), Store Procedure

(procedimentos armazenada) e Trigger (gatilho). Cada SGDB tem sua maneira própria para

tratar esses elementos de programação.

As sintaxes apresentadas a seguir referem-se ao ambiente Postgresql.

Stored Procedure

O

postgresql

emprega

o

( procedimentos armazenados)

Sintaxe básica:

Definição da função:

conceito

de

function

para

definir

stored

procedure

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

Create function nome_da_função (tipo_dado_variavel1, tipo_dado_variavel2, …

tipo_dado_variavelN)

Return tipo AS

'<corpo da função>'

LANGUAGE `nome da linguagem usada no corpo`

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

Dentre as linguagens possíveis para o postgresql temos:

SQL

PLPGSQL

C

PERL

TEL

PYTHONU

uso da função:

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

nome_da_função(valor_para_variavel1,valor_para_variavel1,

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

, valor_para_variavelN)

A aspa no nome da linguagem pode ser opcional, depende da versão do Postgresql (no

8.3 ela já é opcional)

Quando definimos que a linguagem de uma função e sql, LANGUAGE SQL, só podemso

empregar comandos da sql em seu corpo.

A definição do corpo da função depende da linguagem para plpgsql, devendo ser

delimitada por aspas simples ' ou cifrão duplo $$. Obedece a seguinte sintaxe:

Uso de ' para delimitar o corpo da função

Uso de '$$ para delimitar o corpo da função

'declare variavel1 tipo_da_varialvel1, variavel2 tipo_da_variavel2,

$$declare variavel1 tipo_da_varialvel1, variavel2 tipo_da_variavel2,

BEGIN INSTRUÇÃO 1 INSTRUÇÃO 2 RETURN VALOR RETORNO END;'

BEGIN INSTRUÇÃO 1 INSTRUÇÃO 2 RETURN VALOR RETORNO END;$$

Obs:

1 – a declaração de variáveis, por meio da palavra reservada declare, é opcional

2 - Para que uma função 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 variáveis que correspondem aos n-valores passados como parâmetros para a

função devem ser referenciadas como $1, $2, $3,

4 – Quando o corpo da função for definido com o uso de aspas simples devemos

delimitar a função com $$ para que o compilador não interprete a aspa simples do corpo

da função como fim da função.

$n

Exemplos:

1 - Função sem parâmetros de entrada

primeiro: definição da função Create function dois() returns integer

as `select 2;’

language sql;

segundo: uso da função Select dois();

2

- função com parâmetros de entrada

primeiro: criação da função

create funcition media(decimal,decimal)

returns decimal as

$$ select ($1+$2)/2; $$

language sql;

segundo: uso da função

caso1

select media(10,8);

caso2

select media(8,9);

3 - Função 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 – Função maior salário de tabela funcionário

Etapas:

4.1 – criar a tabela

create table func(cod integer, nome varchar(30), salário 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 função maior_salario, para exibir o maior salario

create function maior_salario() returns decimal

as 'select Max(salario) from func;' language sql;

4.4 usar a função que retorna o maior salario

select maior_salario();

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

select soma('Sidney ','Silva');

6 – Função 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- Função que disponibilize o maior valor de venda.

create function maiorvenda() returns decimal

as 'select Max(valor) from venda;' language sql;

usando a função:

select maiorvenda();

8- Função que disponibilize o valor total obtido com vendas

create function valortotal() returns decimal

as 'select sum(valor) from venda;'

language sql;

usando a função:

select valortotal();

9- Crie um “store procedure” que disponibilize data da ultima venda

create function dataultimavenda() returns date

as 'select max(data) from venda;'

language sql;

usando a função:

TRIGGER

select dataultimavenda();

Uma função de gatilho, trigger,

é uma ação 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_função (v1,v2, ,vn)

Em gatilho onde tem-se FOR EACH ROW o procedimento em execute procedure é

chamado uma vez para cada linha que a operação modifica. Já se tivermos FOR EACH

STATEMENT ocorrerá somente uma chamada ao procedimento descrito em execute

procedure , não importando quantas linhas sejam modificadas .

Variáveis disponíveis no ambiente de programação - PL

NEW → Tipo de dado RECORD; variável contendo a nova linha do banco de dados, para as operações de INSERT/UPDATE nos gatilhos no nível de linha.

OLD → Tipo de dado RECORD; variável contendo a antiga linha do banco de dados, para as operações de UPDATE/DELETE nos gatilhos no nível de

TG_NAME → Tipo de dado name; variável contendo o nome do gatilho disparado.

TG_WHEN → Tipo de dado text; uma cadeia de caracteres contendo BEFORE ou AFTER, dependendo da definição do gatilho.

TG_LEVEL → Tipo de dado text; uma cadeia de caracteres contendo ROW ou STATEMENT, dependendo da definição do gatilho.

TG_OP → Tipo de dado text; uma cadeia de caracteres contendo INSERT, UPDATE, ou DELETE, informando para qual operação o gatilho foi disparado.

TG_RELID → Tipo de dado oid; o ID de objeto da tabela que causou o disparo do gatilho.

TG_RELNAME → Tipo de dado name; o nome da tabela que causou o disparo do gatilho.

TG_NARGS → Tipo de dado integer; o número de argumentos fornecidos ao procedimento de gatilho na instrução CREATE TRIGGER.

TG_ARGV[] → Tipo de dado matriz de text; os argumentos da instrução CREATE TRIGGER. O contador do índice começa por 0. Índices inválidos (menor que 0 ou maior ou igual a tg_nargs) resultam em um valor nulo.

Exemplos:

1 – Gatilho que após efetuar uma inclusão, alteração ou exclusão 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 função para o gatilho

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

CREATE FUNCTION processa_audit_func() RETURNS TRIGGER AS $$

BEGIN

--

-- Cria uma linha na tabela func_auditoria para refletir a operação

-- realizada na tabela func. Utiliza a variável especial TG_OP

-- para descobrir a operação 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;

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 conexão 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 inserção na tabela func verifica se o nome do

funcionario é nulo e se o salario é nulo ou menor do que zero caso seja não faz a inclusão

e emite uma mensagem

Primeiro – definição da função de gatilho

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

CREATE FUNCTION func_gatilho() RETURNS trigger AS $$

BEGIN -- Verificar se foi fornecido o nome do empregado IF NEW.nome IS NULL THEN RAISE EXCEPTION 'O nome do empregado não pode ser nulo'; END IF; IF NEW.salario IS NULL THEN RAISE EXCEPTION 'O não pode ter um salário nulo', NEW.nome_emp; END IF; -- Quem paga para trabalhar? IF NEW.salario < 0 THEN RAISE EXCEPTION 'O funcionario não pode ter um salário negativo', NEW.nome_emp; END IF;

RETURN NEW; END; $$ LANGUAGE plpgsql;

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

Segundo: criação 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 não pode ser nulo.

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

3

– Gatilho que ao se efetuar uma inserção 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 mudança no preço de venda de um produto armazene os

dados na tabela histórico.

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;