bdII PLPGSQL V 1 1
bdII PLPGSQL V 1 1
bdII PLPGSQL V 1 1
Viso Geral
1
Linguagem Procedural
CREATE [or REPLACE] FUNCTION nome_funcao(par_1 tipo, par_2 tipo ... par_n)
RETURNS [SETOF] [VOID || DATATYPE || ESCALAR] AS
$$
DECLARE
BEGIN
RETURN;
END;
$$ LANGUAGE 'PLpgSQL';
SQL Functions
2
Exemplos de Funes SQL:
$$ LANGUAGE SQL;
select inserirMEcategoriaCurso();
3
CREATE FUNCTION atualizarMEcategoriaCurso(integer, integer, integer) returns
integer AS
$$
UPDATE me_categoriaCurso
set
cargaHorariamin = $2
, cargaHorariamax = $3
where
codCategoria = $1;
select 1;
$$
LANGUAGE SQL;
UPDATE me_historicoPrecoCurso
set
valorMax = valorMax * (1.00 + $1/100.00)
where
dataFim is null;
$$
LANGUAGE SQL;
4
Procedural Language Functions PLpgSQL
CREATE [or REPLACE] FUNCTION nome_funcao(par_1 tipo, par_2 tipo ... par_n)
RETURNS [SETOF] [VOID || DATATYPE || ESCALAR] AS
$$
DECLARE
BEGIN
RETURN;
END;
$$ LANGUAGE 'PLpgSQL';
SELECT nome_funcao(parametros);
ou
SELECT * FROM nome_Funcao(parmetros);
5
Exemplo de Funo
RETURN _qtd;
END;
$$ LANGUAGE plpgsql;
select fn_exemplo_a();
6
Declarao de variveis
...
DECLARE
a integer;
b numeric(5);
c varchar(50;
linha tabela%ROWTYPE; -- declara varivel que ter a mesma estrutura de uma linha
inteira da tabela
d integer NOT NULL DEFAULT:=80; -- varivel inteira que no pode ser nula, recebe por
padro o valor 80
...
Passagem de parmetros
Exemplo:
select fn_exemplo_parametros(100,3)
7
create or replace function fn_exemploTipos(p_codaluno integer) returns varchar(50) as
$$
declare
_aluno me_aluno%rowtype; -- registro do tipo aluno (possui todos as colunas da
tabela me_aluno e ir armazenar uma linha
_matriculaalunoIndicante me_aluno.matriculaAluno%type;
_msg varchar(80);
begin
Condicionais
IF ... THEN
8
Exerccios
Se a velocidade estiver entre 80.01 e 110 ento o motorista deve ser multado em 120,00 e
receber 20 pontos
Se a velocidade estiver entre 110.01 e 140 ento o motorista deve ser multado em 350 e
receber 40 pontos
Se a velocidade estiver eacima de 140 ento o motorista deve ser multado em 680 e receber
60 pontos
O sistema deve considerar somente 90% da velocidade apurada para o clculo da multa.
Aps o clculo o sistema deve incluir a multa na tabela ex_multa (se o contribuinte foi
multado)
-- criao de tabelas
create table ex_motorista
(cnh char(5) primary key
, nome varchar(20) not null
, totalMultas decimal(9,2)
);
9
b) Escreva um outro procedimento que atualize o campo totalMultas da tabela ex_motorista
a partir dos totais apurados para cada motorista autuado na tabela ex_multa.
Ateno:
- motorista sem multa devero possuir valor 0.00 no campo total multa;
- cuidado para no duplicar valores na coluna totalMultas para os casos em
que a rotina for disparada mais de uma vez.
10
PlPgSql Descartando resultados de uma consulta
Exemplo:
-- EXEMPLO QUE DEMONSTRA A UTILIZAO DE PERFORM E FOUND
END IF;
RETURN;
END;
$$
LANGUAGE PLPGSQL;
SELECT FN_DESCARTAR_RESULT( );
11
PlPgSql Tratamento de Erros
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE NOTICE 'MOTORISTA % NO ENCONTRADO EM
MULTAS', BLOCO_A._MOTORISTA.NOME;
WHEN TOO_MANY_ROWS THEN
RAISE EXCEPTION 'MOTORISTA % POSSUI VARIAS
MULTAS', BLOCO_A._MOTORISTA.NOME;
WHEN OTHERS THEN
RAISE NOTICE '%', SQLSTATE ;
RAISE NOTICE '%', SQLERRM;
END;
RETURN;
END;
$$ LANGUAGE PLPGSQL;
12
-- INSERINDO UM MOTORISTA SEM MULTAS
INSERT INTO EX_MOTORISTA VALUES ('369EF', 'ANA');
-- EXECUTANDO OS PROCEDIMENTOS
-- TESTE I : MOTORISTA NO ENCONTRADO
SELECT FN_TRATAR_ERRO('369EC');
13
PlPgSql Chamando uma funo a partir de outra
SELECT
COALESCE(SUM(VALOR)) AS VALOR
INTO
_TOTAL
FROM
EX_MULTA
WHERE
CNH = _CNH;
RETURN _TOTAL;
END;
$$ LANGUAGE PLPGSQL
14
-- PROCEDIMENTO Ii
CREATE OR REPLACE FUNCTION FN_ATUALIZAR_TOTAL_MULTA(_CNH
CHAR(5)) RETURNS VOID AS
$$
BEGIN
RETURN;
END;
$$
LANGUAGE PLPGSQL;
SELECT FN_ATUALIZAR_TOTAL_MULTA('123AB');
15
PlPgSql Utilizando Funes em Consultas
RETURN _MSG;
END;
$$ LANGUAGE PLPGSQL;
SELECT
NOME
, FN_TEXTO_VALOR_MULTA(TOTALMULTAS)
, TOTALMULTAS
FROM
EX_MOTORISTA;
16
PlPgSql Utilizando Cursores e Tabelas Temporrias
RETURN 'FIM';
END;
$$
LANGUAGE PLPGSQL;
SELECT FN_EXEMPLO_TEMP_TABLE( ) ;
-- TENTE EXECUTAR NOVAMENTE ...
SELECT FN_EXEMPLO_TEMP_TABLE( ) ;
17
-- EXEMPLO COM USO DE CURSORES
UPDATE EX_MOTORISTA
SET TOTALMULTAS = (SELECT FN_OBTER_TOTAL_MULTA(_CNH))
WHERE CNH = _CNH;
CLOSE _CURSOR_MOTORISTA;
RETURN;
END;
$$
LANGUAGE PLPGSQL;
SELECT FN_ATUALIZAR_TOTAL_MULTA( );
18
PlPgSql Utilizando Vetores
_cpf[1] := '123456';
_cpf[2] := '789456';
_cpf[3] := '654987';
_cpf[4] := '321654';
_cpf[5] := '852741';
raise notice '%', 'nome: ' || _nome[_cont] || ' cpf: ' || _cpf[_cont];
return;
end;
$$ language 'plpgsql';
select fn_exemploArray();
19
PlPgSql Utilizando SQL Dinmico
_SQL := 'UPDATE EX_MULTA SET ' || _CAMPO || ' = ' || _VALOR || '
WHERE ' || _CHAVE || ' = ' || QUOTE_LITERAL(_VLRCHAVE);
RAISE NOTICE '%', _SQL;
EXECUTE _SQL;
END IF;
RETURN _TOTAL;
END;
$$ LANGUAGE PLPGSQL;
20
PlPgSql Retornando Conjuntos de Consultas
Algumas vezes necessrio retornar uma lista de valores de uma funo. No postgresql
temos que utilizar algumas estratgias para retornar essas listas (tabelas).
return;
end;
$$ language 'plpgsql';
21
Create or replace function fn_lista_turmaVlrMedio(PAR_VLR_MIN DECIMAL(5,2) )
returns setof turma_vlr_medio as
$$
DECLARE
_turmaVlrMedio turma_vlr_medio%rowtype;
BEGIN
FOR _turmaVlrMedio IN
SELECT
codTurma, avg(valor)
FROM
me_matricula
GROUP BY
codTurma
HAVING
avg(valor) > PAR_VLR_MIN LOOP
RETURN NEXT _turmaVlrMedio;
END LOOP;
RETURN;
END;
$$ language 'plpgsql';
22
EXEMPLO MAIS SIMPLES
END;
$$ LANGUAGE PLPGSQL
23
Exerccios:
a) Escreva uma funo que receba um nmero inteiro entre 1 e 7 e retorne o nome do dia da
semana baseado nesse nmero.
1 = domingo
...
7 = sbado
O procedimento deve retornar um erro caso seja passado por parmetro um nmero que no
esteja entre 1 e 7;
- Crie uma tabela chamada me_resumo com os seguintes campos id serial primary key,
ano_mes integer not null, valor decimal(9,2) not null.
- Crie uma funo chamada fn_montaTabelaResumo
Passar para a funo um nmero inteiro por parmetro que corresponde a um ano
ex:. 2009, 2008, 2007 etc...
Preencher a tabela me_resumo com os valores totais recebidos por ms no ano
recebido por parmetro.
Exemplo: ano recebido 2008
na tabela me_resumo
id = 1
ano_mes = 200801
valor = 0.00
id = 2
ano_mes = 200802
valor = 500.00
etc..
- Ao final a rotina deve devolver a listagem dos valores (ano_mes e valor) obtidos para a
tabela me_resumo a partir do ano passado por parmetro.
Execute a rotina vrias vezes para o mesmo ano e para anos diferentes para ter
certeza de que est funcionando.
24
c) Escreva um procedimento que retorne o nome, em letras minsculas, dos alunos
matriculados em turmas que iniciaram em meses cujo valor total de matrcula no ms
(apurado na tabela me_resumo) foram superiores a 3000.00;
d) Escreva um procedimento que permita efetuar a consulta de alunos por um dos seguintes
critrios:
- iniciais do nome
OU
- por iniciais do email
OU
- por matrcula
OU
- por CPF
Lembre-se, a rotina deve funcionar tanto para os casos em que apenas UM parmetro for
passado ou quando dois, trs ou todos forem passados.
25