Você está na página 1de 46

Banco de Dados II

Programao Procedural em
Banco de Dados

Edvar Bergman Araujo

O que so Stored Procedures?


Stored procedures so programas armazenados
no banco de dados
So trechos de cdigos que realizam tarefas
especficas
Chamadas como comandos
Podem receber parmetros e retornar valores
SQL e linguagens especficas
Possibilidade de executar comandos DML como
SELECT, INSERT, UPDATE e DELETE
Suporte a variveis, comentrios, instrues
declarativas, testes condicionais, desvios e laos.

O que so Stored Procedures?


Cada stored procedure um mdulo
independente de cdigo que pode ser
executado a partir de:

uma outra procedure;


uma Trigger;
de uma aplicao cliente;
como parte de uma instruo SELECT, retornando
valores como se o procedimento fosse uma
subconsulta;

Eles permitem que se manipule diretamente


os dados em banco, sem qualquer
interveno do cliente e sem impor trfego
sobre a rede.

Objetivos de utilizao
Melhorar o desempenho das aplicaes
Reduzir o volume de dados trafegados na
rede
Melhorar a manuteno do software
Melhorar a segurana no acesso aos dados

Vantagens
Stored procedures podem executar operaes
muito mais complexas que uma simples query.
Se mais de uma aplicao ir acessar o banco
de dados, as stored procedures podem
tambm economizar tempo de manuteno e
desenvolvimento j que qualquer aplicao
poder cham-la.
Alterar a stored procedure sem ter que alterar
ou mesmo recompilar cada aplicao cliente.
As alteraes tornam-se imediatamente
disponveis para todos os aplicativos clientes
que o utilizam.

Vantagens
Segurana - Stored procedures tem uma
grande importncia na segurana do banco de
dados uma vez que elas podem acessar
tabelas que o usurio no tem o direito de
faz-lo.
Clientes magros: como a regra de negcio est
no servidor, aplicativos clientes podem ser
menores, exigindo menos recursos do sistema
(disco, memria e CPU) e consequentemente
hardware de menor custo;

Quando utilizar
Se a operao pode ser feita no servidor,
sem a necessidade de obter informaes do
usurio enquanto a operao estiver sendo
processada.
Se a operao requer o processamento de
um grande nmero de linhas, que implicaria
em custos em termos de trfego na rede
para envi-las atravs da rede para a
aplicao cliente.

Quando utilizar
Se a operao uma que deve ser feita
periodicamente ou frequentemente.
tais como um fechamento de fim de ms ou uma
operao de arquivamento.

Se a operao efetuada por vrios


mdulos ou processos diferentes dentro de
sua aplicao ou por aplicaes diferentes.

Linguagens
Especficas de cada SGBD
Oracle: PL/SQL
PostgreSQL: PL/PgSQL
SQL Server: Transact-SQL
DB2: SQL PL
MySQL: PL/MySQL

Desvantagens
Dependncia do SGBD
Falta de Padro

Estrutura de um Bloco PL/SQL


DECLARE (opcional)
Variveis, cursores, excees definidas pelo
usurio

BEGIN (obrigatrio)
Comandos SQL
Comandos PL/SQL

EXCEPTION (opcional)
Aes para executar quando ocorrer um erro

END; (obrigatrio)

Tipos de Blocos
Annimo

Procedure

Funo

[DECLARE]

PROCEDURE name
IS
BEGIN
-- comandos

FUNCTION name
RETURN datatype
IS
BEGIN
-- comandos
RETURN value;

BEGIN
-- comandos
[EXCEPTION]

[EXCEPTION]

[EXCEPTION]
END;
END;

END;

Variveis
Declaradas e inicializadas na seo de
Declarao
Podem ter o contedo alterado no corpo da
Procedure
Linguagem Tipada: quando cria-se uma
varivel, define-se o seu tipo especificando o
formato de armazenamento, restries e faixa
de valores vlidos.
Tipos de dados escalares (os mesmos usados
para definir as colunas das tabelas do Oracle,
com suporte a boolean)
Tipos de dados compostos (registros)

Declarao de Variveis
Sintaxe:
identificador [CONSTANT] datatype [NOT NULL]
[:= | DEFAULT expresso];
Exemplos:
vDataNasc DATE;
vCodDepto NUMBER(2) NOT NULL := 10;
vCidade VARCHAR2(30) := 'Novo Hamburgo';
cComissao CONSTANT NUMBER := 1400;

Atribuindo Valores para Variveis


Sintaxe:
identificador := expresso ;
Exemplos:
vCodDepto := 50;
vCidade
:= 'Porto Alegre';
vDataNasc := TO_DATE('01/05/2013', 'DD/MM/YYYY');

Atributo %TYPE
Utilizado para declarar uma varivel de acordo
com:
uma coluna do banco de dados
outra varivel previamente declarada

A varivel criada ter o mesmo tipo e preciso


da coluna da tabela ou varivel base.
Exemplo:
vNroConta

conta.NRO_CONTA%TYPE;

Comentando o Cdigo
Comente o cdigo para documentar cada fase e
auxiliar na depurao. O comentrio pode ser:
uma nica linha, usando dois hifens (--)
vrias linhas, usando os delimitadores /* e */

Exemplos:
-- Incrementar a varivel vContador
vContador := vContador + 1; -- pode ser utilizado no final
/*
Bloco de comentrio.
Inicia por /* e termina por */
*/

Estrutura de uma Procedure Parmetros


CREATE PROCEDURE Nome_da_Procedure
( nome_parametro1 tipo_parametro1,
nome_parametro2 tipo_parametro2,
...
nome_parametroN tipo_parametroN)

IS
<declarao de variveis e cursores>

BEGIN
<comandos da procedure>

END;

Estrutura de uma FUNCTION


CREATE FUNCTION Nome_da_Funcao
(nome_parametro tipo_parametro)

RETURN <tipo de dados que a funo retorna>


IS
<declarao de variveis locais>

BEGIN
<comandos da funo>
RETURN value;

END;

Comandos SELECT em PL/SQL


Utilizado para recuperar dados do banco de
dados
Sintaxe:
SELECT lista_de_colunas
INTO {variavel1[, variavel2, ...]
| record_name
FROM tabela
WHERE condio;

Comandos SELECT em PL/SQL Exemplo


DECLARE
vSaldo NUMBER(15,2);
vLimite conta.LIMITE%TYPE;
BEGIN
SELECT saldo, limite
INTO vSaldo, vLimite
FROM conta
WHERE nro_conta = 30001;
...
END;

Select into serve


somente qdo retornar f1
linha
Quando for necessrio
trabalhar com mais de 1
linha, necessrio o uso
de Cursores

Comandos SELECT em PL/SQL


Cuidado:
O comando SELECT deve retornar somente uma
linha.
Mais de uma linha ou nenhuma linha causa um
erro.
Excees geradas:
NO_DATA_FOUND (nenhuma linha)
TOO_MANY_ROWS (mais de uma linha)

COMO EVITAR?
BEGIN
...
BEGIN
SELECT saldo, limite
INTO vSaldo, vLimite
FROM conta
WHERE nro_conta = 30001;
EXCEPTION
WHEN NO_DATA_FOUND THEN
vSaldo := 0;
vLimite := 0;
END;
...
END;

Manipulando Dados em PL/SQL


possvel executar comandos DML (INSERT,
UPDATE e DELETE) da mesma forma como
seriam utilizados fora de um bloco PL/SQL

Comando IF
Sintaxe IF simples:
IF condio THEN
comandos;
END IF;

Sintaxe IF com
ELSE:
IF condio THEN
comandos;
ELSE
comandos;
END IF;

Controle de Repeties
O PL/SQL possui algumas estruturas para
controles de repetio:
O LOOP bsico fornece aes repetitivas sem
condies globais;
O FOR loop fornece controle de repeties de
aes baseado em um contador
O WHILE loop fornece controle de repeties de
aes baseado em uma condio
O comando EXIT encerra um loop
O comando CONTINUE interrompe a iterao atual
e vai para a prxima iterao do lao.

LOOP bsico
Sintaxe:
LOOP
--delimitador
comandos;
--comandos
...
--comandos
EXIT [WHEN condio]; --sada do loop
END LOOP;
--delimitador de fim

FOR LOOP
Sintaxe:
FOR contador IN vlr_inicial..valor_final LOOP
comando 1;
comando 2;
...
comando N;
END LOOP;
Obs.: pode-se utilizar a clusula REVERSE,
aps o IN, para que a varivel de controle
varie de um valor maior para um menor.

WHILE LOOP
Sintaxe:
WHILE condicao LOOP
comando 1;
comando 2;
...
comando N;
END LOOP;
Obs.: A condio avaliada no incio de cada
repetio. O loop se encerra quando a
condio for FALSE.

Exemplo
Desenvolver uma funo que retorne o
nmero de cartes de crdito de uma conta
corrente.
Obs.: exemplo simples, apenas com fins
didticos, para demonstrar o funcionamento.

CREATE FUNCTION funcObtemNumeroCartoes


(pNroConta conta.NRO_CONTA%TYPE)
RETURN NUMBER
IS
vCont NUMBER;
BEGIN
SELECT COUNT(*)
INTO vCont
FROM CARTAO
WHERE NRO_CONTA = pNroConta;
RETURN vCont;
END;

Como testar?

SELECT funcObtemNumeroCartoes(30002) AS NRO_CARTOES


FROM DUAL
OU
SELECT C.*,
funcObtemNumeroCartoes(C.NRO_CONTA) AS NRO_CARTOES
FROM CONTA C

Exerccios

1. Desenvolver uma funo que retorne o valor


total aplicado atualizado de uma conta
corrente.
testar:

SELECT C.NRO_CONTA, funcValorTotalAplicado(C.NRO_CONTA) AS


VLR_APLICADO FROM CONTA C;

2. Desenvolver uma funo que retorne a


mdia de gastos com carto de crdito por
um determinado correntista em um perodo.
testar:

SELECT C.nro_conta, funcValorMediaCartoes2(C.NRO_CONTA,


to_date('01/01/2015','dd/mm/yyyy'),to_date('31/03/2015','dd/mm/yyyy')) AS
vlrmediacartoes FROM CONTA C;

Atributo %ROWTYPE
Utilizado para declarar uma varivel
A varivel poder armazenar um
conjunto de colunas
O nmero, tipo e nome das colunas
obtido a partir da tabela ou view de
origem
Exemplo:
vConta conta%ROWTYPE;

Cursores
Oracle utiliza reas de memria para
executar comandos SQL e para
armazenar informaes
Cursores PL/SQL so usados para
nomear uma destas reas e acessar as
informaes armazenadas

Cursores

Result Set

Cursor

7369
7566
7788
7876
7902

Jonas
Marta
Cristina
Carolina
Marcos

DBA
Gerente
Analista
Testador
Programador

Registro Atual

Cursores

No
Sim
DECLARE
DECLARE

OPEN
OPEN

FETCH
FETCH

Cria um

Executa o

Carrega a

SQL e
obtm o
Resul Set

linha atual
para
vairveis

cursor

EMPTY?

CLOSE
CLOSE

Verifica se Libera a
ainda
existem
linhas,
executando
um novo
FETCH

rea de
memria

Cursores
Sintaxe:
CURSOR nome_do_cursor IS
comando_select;

Exemplo:
CURSOR cContas30 IS
SELECT NRO_CONTA, NOME, SALDO, LIMITE
FROM CONTA
WHERE COD_AGENCIA = 30;
vContas30 cContas30%ROWTYPE;

Cursores
BEGIN
...
OPEN cContas30;
LOOP
FETCH cContas30 INTO vContas30;
EXIT WHEN cContas30%NOTFOUND;
...
-- Processa os dados recuperados
...
END LOOP;
CLOSE cContas30;
...
END;

Cursores
Existem 4 atributos para obter informaes
de status de um cursor:
1. %ISOPEN retorna TRUE se o cursor estiver
aberto
2. %NOTFOUND retorna TRUE se o FETCH
mais recente no retornou uma linha
3. %FOUND retorna TRUE se o FETCH mais
recente retornou uma linha
4. %ROWCOUNT retorna o nmero total de linhas
recuperadas at o momento

Cursores FOR loop


O Oracle possui um tipo especial de lao FOR
para ser utilizado com cursores.
A principal vantagem a facilidade de
utilizao, pois:
O cursor aberto automaticamente
Os registros so recuperados um a um, a
cada repetio do lao
O cursor fechado automaticamente
No necessrio declarar a varivel

Cursores FOR loop


Exemplo:
...
FOR vCon30 IN cContas30 LOOP --- OPEN e FETCH implcitos
-- os dados so carregados na varivel vCon30
...
END LOOP; -- CLOSE implcito feito
...

Exerccio
3. Desenvolver uma stored procedure para
calcular as faturas de todos os cartes com
vencimento em um determinado dia (obtido a
partir da data recebida como parmetro).

Calcular o valor total e gravar um registro na tabela


FATURA
Atualizar a tabela de movimentos com o cdigo da
fatura que gerou o desconto
Pegar o dia de vencto
Sugere-se testar usando a data: 05/03/2015

da tabela CARTAO (col


DIA_VENCTO). Ler a
tabela MOVTO_CARTAO,
gerar fatura p\ todos os
cartes com vencto no
dia e cujo campo
COD_FATURA esteja
null. O cdigo da fatura
a ultima fatura + 1

Dica: para obter o dia de uma data, usar:


extract(day from DATA_QUALQUER)
Considerando a data acima, o retorno ser 5.

Como testar?
Em uma janela do SQL Developer
BEGIN
prcGeraFatura(to_date('05/03/2015', 'dd/mm/yyyy'));
END;

DEBUG no SQL Developer


O SQL Developer possui recurso para depurar
Stored Procedures.
Demonstrao prtica de DEBUG no SQL
Developer

Trabalho

Desenvolver o trabalho conforme especificao


disponvel no documento Trabalho de Stored
Procedures.