Você está na página 1de 38

PROGRAMAO

PARA

BANCO DE DADOS


PL/SQL




Prof. Marcos Alexandruk




SUMRIO



1. Conceitos de programao para banco de dados: Introduo ao PL/SQL
2. Declaraes
3. Tipos de dados
4. Constantes e variveis
5. Comandos SQL dentro de um bloco PL/SQL
6. Instrues IF-THEN-ELSE e CASE
7. Instrues LOOP, FOR e WHILE
8. Tratamento de excees
9. Cursores explcitos e implcitos
10. Procedures
11. Functions
12. Triggers
13. Packages
PROGRAMAO PARA BANCO DE DADOS 3


1. CONCEITOS DE PROGRAMAO PARA BANCO DE DADOS: INTRODUO AO PL/SQL

PL/SQL:
Linguagem de programao: Procedural Language/Stuctured Query Language

Principais recursos oferecidos pela linguagem:
Executar comandos SQL para manipular dados nas tabelas
Criar constantes e variveis
Criar cursores para tratar o resultado de uma consulta
Criar registros para guarda o resultado de um cursor ou campo de tabela
Tratar erros
Utilizar comandos de controle (if, if-then-else, case) e repetio (loop, for, while)

Vantagens:
Versatilidade
Portabilidade
Integrao com o SGBD (Sistema Gerenciador de Banco de Dados)
Capacidade procedural (comandos de controle e repetio)
Reduo de trfego de rede

Rotinas PL/SQL podem ser desenvolvidas com diversas ferramentas:
SQL*Plus
SQL*Plus Worksheet
Oracle Forms
etc.

Estrutura de um bloco PL/SQL:

DECLARE

I ni ci al i zaes, decl ar ao de const ant es, var i vei s e cur sor es

BEGI N

Comandos SQL, est r ut ur as de pr ogr amao e out r os bl ocos PL/ SQL

BEGI N

. . .

END;

EXCEPTI ON ( opci onal )

Tr at ament o de excees, emi sso de mensagens

END;



IMPORTANTE:

Para visualizar a sada no SQL*Plus faa a seguinte alterao:

SET SERVEROUTPUT ON

PROGRAMAO PARA BANCO DE DADOS 4


2. DECLARAES

Na rea DECLARE podemos declarar:
constantes
variveis
cursores
estruturas
tabelas

3. TIPOS DE DADOS

3.1. Os tipos de dados simples que podem ser utilizados em declaraes PL/SQL so:

TIPOS DESCRIO
CHAR Alfanumrico, tamanho fixo, limite: 2000 caracteres
CHARACTER Idntico ao CHAR, mantm compatibilidade com outras verses SQL
VARCHAR2 Alfanumrico, tamanho varivel, limite: 4000 caracteres
VARCHAR E STRING Idntico ao VARCHAR2, mantm compatibilidade com outras verses SQL
CLOB
(Character Long Object)
Alfanumrico, tamanho varivel, limite 4 Gb
LONG Alfanumrico, limites: 2 GB, apenas um por tabela
ROWID Armazena os valores dos ROWIDs das linhas das tabelas
BLOB
(Binary Long Object)
Binrio, tamanho varivel, limite: 4 Gb
BFILE
(Binary File)
Armazena uma referncia a um arquivo externo (que dever localizar-se
na mesma mquina do banco de dados, no permite referncia remota)
RAW Hexadecimais, tamanho varivel, limite: 2 Kb
LONG ROW Hexadecimais, tamanho varivel, limite: 2 Gb
NUMBER
Numrico, limite: 38 dgitos
Exemplo: NUMBER (10,2) armazena 10 nmeros (8 inteiros e 2 decimais)

SUBTIPOS:
DECIMAL
DEC
DOUBLEPRECISION
INTEGER
INT
NUMERIC
REAL
SMALLINT
FLOAT
PLS_INTEGER
BINARY_INTEGER Numrico, positivos e negativos, limites: -2147483647 e 2147483647

SUBTIPOS:
NATURAL (limites: 0 e 2147483647)
NATURALN (limites: 0 e 2147483647, no aceita valores nulos)
POSITIVE (limites: 1 e 2147483647)
POSITIVEN (limites: 0 e 2147483647, no aceita valores nulos)
DATE Data e hora (formato padro: DD-MMM-YY
TIMESTAMP Data e hora (com milsimos de segundo)
BOOLEAN Armazena os valores: TRUE, FALSE ou NULL

3.2. Tipos compostos:
RECORD
TABLE

3.3. Tipos referenciados:
REF CURSOR
PROGRAMAO PARA BANCO DE DADOS 5


4. CONSTANTES E VARIVEIS

4.1. CONSTANTES

Para declaraes de constantes, a palavra CONSTANT deve aparecer antes do tipo de
dado e a seguir utiliza-se o operador := para atribuir-lhe um valor.

Exemplo:

DECLARE
pi CONSTANT NUMBER( 9, 7) : = 3. 1415927;
. . .
BEGI N
. . .
END;
/

4.2. VARIVEIS

As variveis so inicializadas de maneira similar s constantes: declarando-se o tipo e
atribuindo-lhe um valor. Variveis no inicializadas explicitamente recebem o valor
NULL. No necessrio inicializar uma varivel com valor NULL. Pode-se aplicar a
restrio NOT NULL a uma varivel. Neste caso ela dever ser inicializada.

Exemplos:

v1 NUMBER( 4) : = 1;
v2 NUMBER( 4) : = DEFAULT 1;
v3 NUMBER( 4) NOT NULL: = 1;

Podemos atribuir valores s variveis de duas maneiras:
Utilizando o operador de atribuio:
t ot al : = quant * val or ;

Utilizando um comando SELECT com a clusula INTO:
SELECT r a_al uno, nome_al uno
I NTO r a, al uno
FROM al uno;

4.2.1. HERANA DE TIPO E TAMANHO

As constantes e variveis podem herdar o tipo de outras variveis, de colunas ou at
da linha inteira de uma tabela. Desta forma, diminuem-se as manutenes oriundas
nas alteraes realizadas nas colunas de tabelas (ex: tamanho da coluna).

Herdando o tipo de uma varivel previamente declarada:
nome_da_var i avel _2 nome_da_var i avel _1%Type;

Herdando o tipo de uma coluna de uma tabela:
nome_da_var i avel nome_da_t abel a. nome_da_col una%Type;

Herdando o tipo de uma linha inteira de uma tabela:
nome_da_var i avel nome_da_t abel a%Rowt ype;

4.2.2. ESCOPO DE VARIVEIS

Variveis definidas dentro de um bloco sero locais para esse bloco e globais para os
sub-blocos. No sero reconhecidas em outros blocos isolados.
PROGRAMAO PARA BANCO DE DADOS 6


5. COMANDOS SQL DENTRO DE UM BLOCO PL/SQL

Comandos DML (SELECT, INSERT, UPDATE e DELETE) podem ser utilizados dentro de
um bloco PL/SQL.
O comando SELECT dever receber obrigatoriamente a clusula INTO para que o
resultado seja armazenado em variveis e dever retornar apenas uma linha. Caso
mais de uma linha seja retornada, apresentar o erro: t oo_many_r ows e se no
retornar nenhuma linha, apresentar o erro: no_dat a_f ound. (veja: TRATAMENTO DE
EXCEES)

Exemplo:

CREATE TABLE ALUNO (
RA NUMBER( 5) ,
NOME VARCHAR2( 40) ) ;

I NSERT I NTO ALUNO VALUES ( 1, ' ANTONI O' ) ;
I NSERT I NTO ALUNO VALUES ( 2, ' BEATRI Z' ) ;

DECLARE
V_RA ALUNO. RA%TYPE;
V_NOME ALUNO. NOME%TYPE;
BEGI N
SELECT RA, NOME
I NTO V_RA, V_NOME
FROM ALUNO
WHERE RA=1;
DBMS_OUTPUT. PUT_LI NE( V_RA | | ' - ' | | V_NOME) ;
END;
/

1 - ANTONI O

Nota: Utilizamos || para concatenao.

Exerccios:

1. Alterar a clusula WHERE acima para: WHERE RA=1 OR RA=2 e verificar o resultado.

O comando SELECT retorna mais de uma linha, por isso exibida a mensagem:

ORA- 01422: a ext r ao exat a r et or na mai s do que o nmer o sol i ci t ado de l i nhas

2. Alterar a clusula WHERE acima para: WHERE RA=3 e verificar o resultado.

O comando SELECT no retorna nenhuma linha, por isso exibida a mensagem:

ORA- 01403: dados no encont r ados

3. Alterar a clusula WHERE acima para: WHERE RA=&RA_DO_ALUNO.

Ent r e o val or par a r a_do_al uno:

4. Inserir os seguintes valores na tabela aluno: ra=5, nome='DANIEL'.

BEGI N
I NSERT I NTO ALUNO ( RA, NOME)
VALUES ( 5, ' DANI EL' ) ;
END;
/

PROGRAMAO PARA BANCO DE DADOS 7


5. Alterar o nome do aluno cujo RA=5 para 'ERNESTO'.

BEGI N
UPDATE ALUNO
SET NOME=' ERNESTO'
WHERE RA=5;
END;
/

6. Excluir da tabela o aluno cujo RA=5.

BEGI N
DELETE FROM ALUNO
WHERE RA=5;
END;
/

PROGRAMAO PARA BANCO DE DADOS 8


6. INSTRUES IF-THEN-ELSE E CASE

6.1. IF-THEN-ELSE

Executa um conjunto de aes de acordo com uma ou mais condies.

I F condi o_1
THEN r el ao_de_comandos_1
[ ELSI F condi o_2
THEN r el ao_de_comandos_2]
[ ELSE r el ao_de_comandos_3]
END I F;

Exemplo 1:

DECLARE
V_1 NUMBER( 2) : = 4;
V_2 VARCHAR2( 5) ;
BEGI N
I F MOD( V_1, 2) = 0
THEN V_2 : = ' PAR' ;
ELSE V_2 : = ' I MPAR' ;
END I F;
DBMS_OUTPUT. PUT_LI NE ( ' O nmer o : ' | | V_2) ;
END;
/

NOTA: MOD(V1,2) divide o valor de V_1 por 2 e retorna o resto da diviso.

Exemplo 2:

CREATE TABLE ALUNO (
RA NUMBER( 9) ,
NOTA NUMBER( 3, 1) ) ;

I NSERT I NTO ALUNO VALUES ( 1, 4) ;

DECLARE
V_RA ALUNO. RA%TYPE : = 1;
V_NOTA ALUNO. NOTA%TYPE;
V_CONCEI TO VARCHAR2( 12) ;
BEGI N
SELECT NOTA
I NTO V_NOTA
FROM ALUNO
WHERE RA = V_RA;
I F V_NOTA <= 5
THEN V_CONCEI TO : = ' REGULAR' ;
ELSI F V_NOTA < 7
THEN V_CONCEI TO : = ' BOM' ;
ELSE V_CONCEI TO : = ' EXCELENTE' ;
END I F;
DBMS_OUTPUT. PUT_LI NE ( ' Concei t o: ' | | V_CONCEI TO) ;
END;
/

6.2. CASE

Retorna determinado resultado de acordo com o valor da varivel de comparao.

[ var i vel : =]
CASE
WHEN expr esso_1 THEN decl ar ao_1
WHEN expr esso_2 THEN decl ar ao_2
. . .
ELSE decl ar ao_n
END;
PROGRAMAO PARA BANCO DE DADOS 9


Exemplo:

DECLARE
V_RA ALUNO. RA%TYPE : = 1;
V_NOTA ALUNO. NOTA%TYPE;
V_CONCEI TO VARCHAR2( 12) ;
BEGI N
SELECT NOTA
I NTO V_NOTA
FROM ALUNO
WHERE RA = V_RA;
V_CONCEI TO : =
CASE
WHEN V_NOTA <= 5 THEN ' REGULAR'
WHEN V_NOTA < 7 THEN ' BOM'
ELSE ' EXCELENTE'
END;
DBMS_OUTPUT. PUT_LI NE ( ' Concei t o: ' | | V_CONCEI TO) ;
END;
/

PROGRAMAO PARA BANCO DE DADOS 10


EXERCCIOS 01:

1. Criar uma tabela conforme segue:

CREATE TABLE ALUNO (
RA NUMBER( 9) ,
DI SCI PLI NA VARCHAR2( 30) ,
MEDI A NUMBER( 3, 1) ,
CARGA_HORA NUMBER( 2) ,
FALTAS NUMBER( 2) ,
RESULTADO VARCHAR2( 10) ) ;

Inserir uma linha deixando a coluna RESULTADO em branco.

I NSERT I NTO ALUNO VALUES ( 1, ' DI SC 1' , 7. 5, 80, 20, ' ' ) ;

Criar um bloco PL/SQL para preencher a coluna resultado conforme o seguinte:

Se o aluno obteve mdia igual ou maior que 7.0 e suas faltas no ultrapassarem 25%
da carga horria da disciplina o resultado ser: APROVADO.

Se o aluno obteve mdia inferior a 7.0 e suas faltas no ultrapassarem 25% da carga
horria da disciplina o resultado ser: EXAME.

Para demais casos o resultado ser: REPROVADO.


2. Criar uma tabela, conforme segue:

CREATE TABLE PRODUTO (
CODIGO NUMBER(2),
DESCRICAO VARCHAR2(20));

Inserir sete produtos diferentes na tabela acima.

Criar um bloco PL/SQL para apresentar um produto diferente para cada dia da
semana.

Nota: A mensagem acima dever ser exibida dinamicamente, conforme a data do
sistema (SYSDATE).

Apresentar a seguinte mensagem:

Hoj e TERA- FEI RA e o pr odut o emof er t a PRODUTO 3.











PROGRAMAO PARA BANCO DE DADOS 11



7. INSTRUES LOOP, FOR E WHILE

FOR

Repete um bloco de comando n vezes, ou seja, at que a varivel contadora atinja o
seu valor final.
A varivel contadora no deve ser declarada na seo DECLARE e deixar de existir
aps a execuo do comando END LOOP.

FOR v_cont ador I N val or _i ni ci al . . val or _f i nal
LOOP
bl oco_de_comandos
END LOOP;

Exemplo 1:

DECLARE
V_AUX NUMBER( 2) : = 0;
BEGI N
FOR V_CONTADOR I N 1. . 10
LOOP
V_AUX : = V_AUX +1;
DBMS_OUTPUT. PUT_LI NE ( V_AUX) ;
END LOOP;
END;
/

Exemplo 2:

DECLARE
V_RA_I NI CI AL ALUNO. RA%TYPE : = 1;
V_RA_FI NAL V_RA_I NI CI AL%TYPE;
V_AUX V_RA_I NI CI AL%TYPE : = 0;
BEGI N
SELECT COUNT( RA)
I NTO V_RA_FI NAL
FROM ALUNO;
FOR V_CONTADOR I N V_RA_I NI CI AL. . V_RA_FI NAL
LOOP
V_AUX : = V_AUX +1;
DBMS_OUTPUT. PUT_LI NE ( ' Tot al de al unos: ' | | V_AUX) ;
END LOOP;
END;
/

WHILE

Repete um bloco de comandos enquanto a condio que segue o comando WHILE for
verdadeira.

Exemplo 1:

DECLARE
V_AUX NUMBER( 2) : = 0;
BEGI N
WHI LE V_AUX < 10
LOOP
V_AUX : = V_AUX +1;
DBMS_OUTPUT. PUT_LI NE ( V_AUX) ;
END LOOP;
END;
/
PROGRAMAO PARA BANCO DE DADOS 12



Exemplo 2:

DECLARE
V_RA_FI NAL ALUNO. RA%TYPE : = 1;
V_AUX V_RA_FI NAL%TYPE : = 0;
BEGI N
SELECT COUNT( RA)
I NTO V_RA_FI NAL
FROM ALUNO;
WHI LE V_AUX < V_RA_FI NAL
LOOP
V_AUX : = V_AUX +1;
DBMS_OUTPUT. PUT_LI NE ( ' Tot al de al unos: ' | | V_AUX) ;
END LOOP;
END;
/

EXIT

Interrompe a execuo de um comando de repetio.

Exemplo 1:

DECLARE
V_AUX NUMBER( 2) : = 0;
BEGI N
FOR V_CONTADOR I N 1. . 15
LOOP
V_AUX : = V_AUX +1;
DBMS_OUTPUT. PUT_LI NE ( V_AUX) ;
EXI T WHEN V_CONTADOR = 10;
END LOOP;
END;
/

Exemplo 2:

DECLARE
V_AUX NUMBER( 2) : = 0;
BEGI N
FOR V_CONTADOR I N 1. . 15
LOOP
V_AUX : = V_AUX +1;
DBMS_OUTPUT. PUT_LI NE ( V_AUX) ;
I F V_CONTADOR = 10
THEN EXI T;
END I F;
END LOOP;
END;
/

LOOP

Executa uma relao de comandos at que uma instruo de sada (EXIT) seja
encontrada.

LOOP
relao_de_comandos
IF condio_de_sada
THEN EXIT;
END LOOP;

PROGRAMAO PARA BANCO DE DADOS 13



Exemplo:

DECLARE
V_AUX NUMBER( 2) : = 0;
BEGI N
LOOP
V_AUX : = V_AUX +1;
DBMS_OUTPUT. PUT_LI NE ( V_AUX) ;
I F V_AUX = 10
THEN EXI T;
END I F;
END LOOP;
END;
/

EXERCCIO

Crie uma tabela chamada CIRCULO com as seguintes colunas:

RAIO NUMBER(2),
AREA NUMBER(8,2)

CREATE TABLE CI RCULO (
RAI O NUMBER( 2) ,
AREA NUMBER( 8, 2) ) ;

Desenvolva um programa em PL/SQL para inserir os raios com valores 1 a 10 e as
respectivas reas na tabela acima.

SOLUO 1: WHILE

DECLARE
PI CONSTANT NUMBER( 9, 7) : = 3. 1415927;
RAI O NUMBER( 2) ;
AREA NUMBER( 8, 2) ;
BEGI N
RAI O : = 1;
WHI LE RAI O <=10
LOOP
AREA : = PI *POWER( RAI O, 2) ;
I NSERT I NTO CI RCULO VALUES ( RAI O, AREA) ;
RAI O : = RAI O+1;
END LOOP;
END;
/

SOLUO 2: FOR

DECLARE
PI CONSTANT NUMBER( 9, 7) : = 3. 1415927;
RAI O NUMBER( 2) : = 1;
AREA NUMBER( 8, 2) ;
BEGI N
FOR CONTADOR I N 1. . 10
LOOP
AREA : = PI *POWER( RAI O, 2) ;
I NSERT I NTO CI RCULO VALUES ( RAI O, AREA) ;
RAI O : = RAI O +1;
END LOOP;
END;
/


PROGRAMAO PARA BANCO DE DADOS 14



LABELS

Utilizados para nomear blocos ou sub-blocos.
Devem localizar-se antes do incio do bloco e preceder pelo menos um comando.
Se no houver necessidade de nenhum comando aps o label, deve-se utilizar o
comando NULL.

<<NOME_DO_LABEL>>
DECLARE
. . .
BEGI N
RELAO_DE_COMANDOS
<<NOME_DO_LABEL>>
RELAO DE COMANDOS
END;

Um label tambm pode ser aplicado a um comando de repetio LOOP.

<<PRI NCI AL>>
LOOP
. . .
LOOP
. . .
- - SAI R DOS DOI S LOOPS
EXI T PRI NCI PAL WHEN . . .
END LOOP;
END LOOP PRI NCI PAL;

GOTO

Utilizado para desviar um fluxo de um bloco PL/SQL para determinado label.

No pode ser utilizado para:

Desviar o fluxo para dentro de um IF;
Desviar o fluxo de um IF para outro;
Desviar o fluxo para dentro de um sub-bloco;
Desviar o fluxo para um bloco externo ao bloco corrente;
Desviar o fluxo de uma EXCEPTION para o bloco corrente e vice-versa.

GOTO nome_do_label

Exemplo 1:

<<PRI NCI PAL>>
DECLARE
V_NOME ALUNO. NOME%TYPE;
BEGI N
SELECT COUNT( RA)
I NTO V_CONTA
FROM ALUNO;
I F V_CONTA = 10
GOTO FI M;
ELSE I NSERT I NTO ALUNO VALUES ( 20, ' SI LVA' ) ;
END I F;
<<FI M>>
DBMS_OUTPUT. PUT_LI NE( ' Fi mdo pr ogr ama' ) ;
END;
/


PROGRAMAO PARA BANCO DE DADOS 15



Exemplo 2:

<<PRI NCI PAL>>
DECLARE
V_NOME ALUNO. NOME%TYPE;
BEGI N
SELECT NOME
I NTO V_NOME
FROM ALUNO
WHERE NOME LI KE ' &NOME_ALUNO' ;
FOR V_CONTADOR I N 1. . 5
LOOP
<<SECUNDARI O>>
DECLARE
V_NOME VARCHAR2( 40) ;
BEGI N
SELECT NOME
I NTO V_NOME
FROM ALUNO
WHERE RA=V_CONTADOR;
I F V_NOME = PRI NCI PAL. V_NOME
THEN DBMS_OUTPUT. PUT_LI NE( ' Est ent r e os 5 pr i mei r os' ) ;
GOTO FI M;
END I F;
END;
END LOOP;
<<FI M>>
DBMS_OUTPUT. PUT_LI NE( ' Fi mdo pr ogr ama' ) ;
END;
/

PROGRAMAO PARA BANCO DE DADOS 16


8. TRATAMENTO DE EXCEES

Excees so erros ou imprevistos que podem ocorrer durante a execuo de um
bloco PL/SQL.
Nesses casos, o gerenciador de banco de dados aborta a execuo e procura uma
rea de excees.
As excees podem ser:

Predefinidas
Definidas pelo usurio

PREDEFINIDAS

Disparadas automaticamente quando, no bloco PL/SQL, uma regra Oracle for violada.
Podem ser identificadas por um nome e um nmero.

EXCEPTI ON
WHEN nome_da_exceo THEN
r el ao_de_comandos;
WHEN nome_da_exceo THEN
r el ao_de_comandos;

ERRO NOME DESCRIO
ORA-00001 DUP_VAL_ON_INDEX
Tentativa de armazenar valor duplicado em uma coluna que
possui chave primria ou nica.
ORA-01012 NOT_LOGGED_ON Tentativa acessar o banco de dados sem estar conectado a ele.
ORA-01403 NO_DATA_FOUND
Ocorre quando um comando SELECT ... INTO no retorna
nenhuma linha.
ORA-01422 TOO_MANY_ROWS
Ocorre quando um comando SELECT ... INTO retorna mais de
uma linha.
ORA-01476 ZERO_DIVIDE Tentativa de dividir qualquer nmero por zero.

Exemplo:

DECLARE
V_RA ALUNO. RA%TYPE;
V_NOME ALUNO. NOME%TYPE;
BEGI N
SELECT RA, NOME
I NTO V_RA, V_NOME
FROM ALUNO
WHERE RA=30;
DBMS_OUTPUT. PUT_LI NE( V_RA | | ' - ' | | V_NOME) ;
EXCEPTI ON
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT. PUT_LI NE ( ' No h nenhumal uno comest e RA' ) ;
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT. PUT_LI NE ( ' H mai s de umal uno comest e( s) RA( s) ' ) ;
WHEN OTHERS THEN
DBMS_OUTPUT. PUT_LI NE ( ' Er r o desconheci do' ) ;
END;

EXERCCIO

Elabore um programa em PL/SQL que faa o seguinte tratamento de exceo:

- Informe tentativa de inserir valor duplicado numa coluna que chave primria.



PROGRAMAO PARA BANCO DE DADOS 17


DECLARE
BEGI N
I NSERT I NTO ALUNO VALUES ( 1, ' ANTONI O' ) ;
EXCEPTI ON
WHEN DUP_VAL_ON_I NDEX THEN
DBMS_OUTPUT. PUT_LI NE ( ' J exi st e umal uno comest e RA' ) ;
END;
/

DEFINIDAS PELO USURIO

Alm dos erros tratados automaticamente pelo Oracle, regras de negcio especficas
podem ser tratadas.
As excees definidas pelo usurio devem ser declaradas e chamadas explicitamente
pelo comando RAISE.

DECLARE
nome_da_exceo EXCEPTI ON;
BEGI N
. . .
I F . . . THEN
RAI SE nome_da_exceo;
END I F;
. . .
EXCEPTI ON
WHEN nome_da_exceo THEN
r el ao_de_comandos
END;
/

Exemplo 1:

DECLARE
V_RA ALUNO. RA%TYPE;
V_NOTA ALUNO. NOTA%TYPE;
V_CONTA NUMBER( 2) ;
CONTA_ALUNO EXCEPTI ON;
BEGI N
SELECT COUNT( RA)
I NTO V_CONTA
FROM ALUNO;
I F V_CONTA = 10 THEN
RAI SE CONTA_ALUNO;
ELSE I NSERT I NTO ALUNO VALUES ( 20, ' SI LVA' ) ;
END I F;
EXCEPTI ON
WHEN CONTA_ALUNO THEN
DBMS_OUTPUT. PUT_LI NE( ' No f oi poss vel i ncl ui r : t ur ma chei a' ) ;
END;
/

Exemplo 2:

DECLARE
V_RA ALUNO. RA%TYPE : = &RA;
V_NOME ALUNO. NOMEA%TYPE : = ' &NOME' ;
BEGI N
I NSERT I NTO ALUNO VALUES ( V_RA, V_NOME) ;
EXCEPTI ON
WHEN DUP_VAL_ON_I NDEX THEN
DBMS_OUTPUT. PUT_LI NE( ' Est e RA j f oi ut i l i zado' ) ;
END;
/
PROGRAMAO PARA BANCO DE DADOS 18


9. CURSORES EXPLCITOS E IMPLCITOS

Cursores so reas compostas de linhas e colunas em memria que servem para
armazenar o resultado de uma seleo que retorna 0 (zero) ou mais linhas.

No PL/SQL os cursores podem ser de dois tipos:

Explcitos
Implcitos

9.1. CURSORES EXPLCITOS

So utilizados para execuo de consultas que possam retornar nenhuma ou mais de
uma linha.
Neste caso o cursor deve ser explicitamente declarado na rea DECLARE.
Para nomear o resultado do cursor necessrio que ele e suas colunas possuam
nomes (alias). Para isso algumas regras devem ser observadas:

O nome do cursor no pode ser igual ao da tabela.
Para dar um nome a uma coluna da seleo, basta colocar o nome do alias logo
aps a definio da coluna ou expresso.

CURSOR nome_do_cursor IS
SELECT coluna1, coluna2 ...
FROM nome_da_tabela;

9.1.1. UTILIZANDO: OPEN, FETCH E CLOSE

Aps sua declarao, o cursor dever ser manipulado com o uso de alguns comandos:

OPEN abre o cursor
FETCH
disponibiliza a linha corrente e posiciona na prxima linha do cursor. As linhas
armazenadas no cursor somente podero ser processadas quando o seu contedo
for transferido para variveis que possam ser manipuladas no PL/SQL
CLOSE fecha o cursor

OBSERVAO: Aps declarar uma varivel como sendo do tipo
nome_do_cursor%rowtype, essa varivel ser um tipo de registro (varivel composta
de diversas subvariveis) cujas subvariveis tero os mesmos nomes, tipos e
tamanhos e estaro na mesma ordem dos campos especificados no comando SELECT
do cursor. O contedo da varivel desse tipo referenciado com
nome_do_registro.nome da subvarivel.

Para cada cursor, quatro atributos podem ser verificados, e seus valores podem ser
alterados a cada execuo de um comando FETCH. Esses atributos so:

nome_do_cursor%FOUND
retorna TRUE caso FETCH consiga retornar alguma linha e FALSE
caso contrrio. Se nenhum FETCH tiver sito executado, ser
retornado NULL
nome_do_cursor%NOTFOUND
retorna FALSE caso FETCH consiga retornar alguma linha e TRUE
caso contrrio. Se nenhum FETCH tiver sido executado, ser
retornado NULL
nome_do_cursor%ROWCOUNT
retorna o nmero de linhas j processadas pelo cursor. Se
nenhum FETCH tiver sido executado, ser retornado 0 (zero)
nome_do_cursor%ISOPEN retona TRUE caso o cursor esteja aberto e FALSE caso contrrio

PROGRAMAO PARA BANCO DE DADOS 19


Exemplo:

DECLARE
CURSOR c_cl i ent e I S
SELECT codi go, nome
FROM cl i ent e;
v_cl i ent e c_cl i ent e%r owt ype;
BEGI N
OPEN c_cl i ent e;
LOOP
FETCH c_cl i ent e
I NTO v_cl i ent e;
EXI T when c_cl i ent e%not f ound;
DBMS_OUTPUT. PUT_LI NE( ' Cl i ent e: ' | | v_cl i ent e. nome) ;
END LOOP;
CLOSE c_cl i ent e;
END;

9.1.2. UTILIZANDO: FOR

O comando FOR ... LOOP, quando aplicado a um cursor, executa automaticamente as
seguintes aes:

Cria a varivel do tipo registro que receber os dados;
Abre (OPEN) o cursor;
Copia as linhas uma a uma (FETCH), a cada interao do comando;
Controla o final do cursor;
Fecha (CLOSE) o cursor.

NOTA: Caso seja necessrio sair do loop do comando FOR durante sua execuo, o
cursor dever ser fechado explicitamente com o comando CLOSE.

Exemplo:

DECLARE
CURSOR c_cl i ent e I S
SELECT codi go, nome
FROM cl i ent e;
BEGI N
FOR v_cl i ent e I N c_cl i ent e
LOOP
DBMS_OUTPUT. PUT_LI NE( ' Cl i ent e: ' | | v_cl i ent e. nome) ;
END LOOP;
END;

NOTA:

As variveis devem ser visveis no ponto da declarao do cursor:

DECLARE
V_RA ALUNO. RA%TYPE;
C_ALUNO I S
SELECT * FROM ALUNO
WHERE RA = V_RA;
CORRETO

DECLARE
C_ALUNO I S
SELECT * FROM ALUNO
WHERE RA = V_RA;
V_RA ALUNO. RA%TYPE;
ERRADO: V_RA no foi declarado antes de ser
referenciado.


PROGRAMAO PARA BANCO DE DADOS 20


EXERCCIOS:

1. Criar a tabela PRODUTO:

CREATE TABLE PRODUTO (
CODIGO NUMBER(4),
VALOR NUMBER(7,2));

Inserir os valores:

I NSERT I NTO PRODUTO VALUES ( 1000, 300) ;
I NSERT I NTO PRODUTO VALUES ( 1001, 500) ;
I NSERT I NTO PRODUTO VALUES ( 2000, 300) ;
I NSERT I NTO PRODUTO VALUES ( 2001, 500) ;

Criar um bloco PL/SQL para atualizar os preos conforme segue:

Produtos com CODIGO inferior a 2000: Acrescentar 10% ao VALOR atual.
Produtos com CODIGO igual ou superior a 2000: Acrescentar 20% ao VALOR atual.


2. Criar a tabela ALUNO:

Observao: Similar ao exerccio 1 da pgina 10. Porm, utiliza cursor.

CREATE TABLE ALUNO (
RA NUMBER( 9) ,
DI SCI PLI NA VARCHAR2( 30) ,
MEDI A NUMBER( 3, 1) ,
CARGA_HORA NUMBER( 2) ,
FALTAS NUMBER( 2) ,
RESULTADO VARCHAR2( 10) ) ;

Inserir uma linha deixando a coluna RESULTADO em branco.

I NSERT I NTO ALUNO VALUES ( 1, ' DI SC 1' , 7. 5, 80, 20, ' ' ) ;
I NSERT I NTO ALUNO VALUES ( 2, ' DI SC 1' , 5. 5, 80, 20, ' ' ) ;
I NSERT I NTO ALUNO VALUES ( 3, ' DI SC 1' , 7. 5, 80, 40, ' ' ) ;

Criar um bloco PL/SQL para preencher a coluna resultado conforme o seguinte:

Se o aluno obteve mdia igual ou maior que 7.0 e suas faltas no ultrapassarem
25% da carga horria da disciplina o resultado ser: APROVADO.
Se o aluno obteve mdia inferior a 7.0 e suas faltas no ultrapassarem 25% da
carga horria da disciplina o resultado ser: EXAME.
Para demais casos o resultado ser: REPROVADO.



PROGRAMAO PARA BANCO DE DADOS 21


9.2. CURSORES IMPLCITOS

Como observamos na seo anterior, cursores explcitos so utilizados para processar
instrues SELECT que retornam mais de uma linha.
Porm, todas as instrues SQL so executadas dentro de uma rea de contexto e,
por isso, tm um cursor (conhecido como cursor SQL) que aponta para esta rea.
A PL/SQL implicitamente abre o cursor SQL, processa a instruo SQL nele e fecha o
cursor.
O cursor implcito utilizado para processar instrues (SELECT INTO, INSERT,
UPDATE e DELETE).
Os comandos OPEN, FETCH e CLOSE no podem ser aplicados a este tipo de cursor.
Os cursores implcitos esperam que apenas uma linha seja retornada. Por isso
excees tais como NO_DATA_FOUND (nenhuma linha satisfaz os critrios de seleo)
ou TOO_MANY_ROWS (mais de uma linha satisfaz o critrio de seleo) devem ser
observadas.
Porm, os atributos %FOUND, %NOTFOUND, %ROWCOUNT e %ISOPEN podem ser
verificados.

Exemplo:

DECLARE
V_CODI GO CLI ENTE. CODI GO%TYPE;
V_NOME CLI ENTE. NOME%TYPE;
BEGI N
V_CODI GO : = ' &CODI GO' ;
V_NOME : = ' &NOME' ;
UPDATE CLI ENTE
SET NOME = V_NOME
WHERE CODI GO = V_CODI GO;
I F SQL%Not Found THEN
DBMS_OUTPUT. PUT_LI NE ( ' No houve al t er ao' ) ;
END I F;
COMMI T;
END;

EXERCCIO:

Criar a tabela CLIENTE com os campos CODIGO, VALOR e ESTADO.
Inserir os registros a seguir:

(1,1000,'SP')
(2,1500,'SP')
(3,1000,'MG')
(4,1500,'MG')

Utilizar PL/SQL com um cursor implcito para conceder desconto de 10% somente se
ESTADO = 'SP' e VALOR > 1000.
Para efetuar a atualizao o usurio dever entrar com o cdigo do cliente (CODIGO).








PROGRAMAO PARA BANCO DE DADOS 22


DECLARE
v_codi go cl i ent e. codi go%TYPE;
v_val or cl i ent e. val or %TYPE;
v_est ado cl i ent e. est ado%TYPE;
BEGI N
v_codi go : =&codi go;
SELECT val or , est ado
I NTO v_val or , v_est ado
FROM cl i ent e
WHERE codi go = v_codi go;
I F val or > 1000 AND est ado = ' SP' t hen
UPDATE cl i ent e
SET val or = v_val or *0. 9
WHERE codi go = v_codi go;
END I F;
END;
/



PROGRAMAO PARA BANCO DE DADOS 23


10. PROCEDURES

Subprogramas que executam uma determinada ao. No retornam valores e,
portanto, no so utilizadas para atribuir valores a variveis ou como argumento em
um comando SELECT.

CREATE OR REPLACE PROCEDURE nome_pr ocedur e
( ar gument o1 modo t i po_de_dados,
ar gument o2 modo t i po_de_dados,
. . .
ar gument oN modo t i po_de_dados)
I S ou AS
var i vei s l ocai s, const ant es, . . .
BEGI N
. . .
END nome_pr ocedur e;

ARGUMENTO

Nome da varivel que ser enviada ou retornada do ambiente chamador para a
procedure. Pode ser passado em um dos trs modos a seguir.

MODO

IN (padro): Passa um valor do ambiente chamador para procedure e este valor
no pode ser alterado dentro da mesma. (Passagem de parmetro por valor)
OUT: Passa um valor da procedure para o ambiente chamador. (Passagem de
parmetro por referncia)
IN/OUT: Passa um valor do ambiente chamador para a procedure. Esse valor pode
ser alterado dentro da mesma e retornar com o valor atualizado para o ambiente
chamador. (Passagem de parmetro por referncia)



PROGRAMAO PARA BANCO DE DADOS 24


REM t est e. sql
CREATE OR REPLACE PROCEDURE t est e (
p_1 I N NUMBER,
p_2 OUT NUMBER,
p_3 I N OUT NUMBER) I S
v_l ocal NUMBER;
BEGI N
DBMS_OUTPUT. PUT_LI NE( ' Recebendo p_1: ' | | p_1) ;
DBMS_OUTPUT. PUT_LI NE( ' Recebendo p_2: ' | | p_2) ; - - I S NULL
DBMS_OUTPUT. PUT_LI NE( ' Recebendo p_3: ' | | p_3) ;
- - Ut i l i zando p_1, p_2 e p_3 par a at r i bui r val or es a v_l ocal :
v_l ocal : = p_1;
DBMS_OUTPUT. PUT_LI NE( ' p_1 gr avando emv_l ocal : ' | | v_l ocal ) ;
v_l ocal : = p_2; - - Vl i do par a Or acl e 7, 7. 3. 4 e 8. 0. 4, 8i ou super i or
DBMS_OUTPUT. PUT_LI NE( ' p_2 gr avando emv_l ocal : ' | | v_l ocal ) ;
v_l ocal : = p_3;
DBMS_OUTPUT. PUT_LI NE( ' p_3 gr avando emv_l ocal : ' | | v_l ocal ) ;
- - At r i bui ndo val or es par a p_1, p_2, p_3:
- - p_1 : = 2; - - Se r et i r ar o coment r i o ocor r er umer r o
p_2 : = 2;
p_3 : = 2;
DBMS_OUTPUT. PUT_LI NE( ' Ret or nando p_1: ' | | p_1) ;
DBMS_OUTPUT. PUT_LI NE( ' Ret or nando p_2: ' | | p_2) ;
DBMS_OUTPUT. PUT_LI NE( ' Ret or nando p_3: ' | | p_3) ;
END t est e;
/

REM cal l _t est e. sql
set ser ver out put on
DECLARE
v_1 NUMBER : = 1;
v_2 NUMBER : = 1;
v_3 NUMBER : = 1;
BEGI N
DBMS_OUTPUT. PUT_LI NE( ' Ant es de chamar pr ocedur e TESTE v_1: ' | | v_1) ;
DBMS_OUTPUT. PUT_LI NE( ' Ant es de chamar pr ocedur e TESTE v_2: ' | | v_2) ;
DBMS_OUTPUT. PUT_LI NE( ' Ant es de chamar pr ocedur e TESTE v_3: ' | | v_3) ;

t est e( v_1, v_2, v_3) ;

DBMS_OUTPUT. PUT_LI NE( ' Aps chamar pr ocedur e TESTE v_1: ' | | v_1) ;
DBMS_OUTPUT. PUT_LI NE( ' Aps chamar pr ocedur e TESTE v_2: ' | | v_2) ;
DBMS_OUTPUT. PUT_LI NE( ' Aps chamar pr ocedur e TESTE v_3: ' | | v_3) ;

END;
/



















PROGRAMAO PARA BANCO DE DADOS 25


Exemplo 1:

REM par amet r os. sql
REM Est a pr ocedur e apr esent a os di f er ent es modos dos par amet r os

CREATE OR REPLACE PROCEDURE par amet r os (
p_I n I N NUMBER,
p_Out OUT NUMBER,
p_I nOut I N OUT NUMBER) I S

v_Local NUMBER : = 0;
BEGI N
DBMS_OUTPUT. PUT_LI NE( ' Dent r o da pr ocedur e PARAMETROS: ' ) ;
I F ( p_I n I S NULL) THEN
DBMS_OUTPUT. PUT( ' p_I n i s NULL' ) ;
ELSE
DBMS_OUTPUT. PUT( ' p_I n = ' | | p_I n) ;
END I F;

I F ( p_Out I S NULL) THEN
DBMS_OUTPUT. PUT( ' p_Out i s NULL' ) ;
ELSE
DBMS_OUTPUT. PUT( ' p_Out = ' | | p_Out ) ;
END I F;

I F ( p_I nOut I S NULL) THEN
DBMS_OUTPUT. PUT_LI NE( ' p_I nOut i s NULL' ) ;
ELSE
DBMS_OUTPUT. PUT_LI NE( ' p_I nOut = ' | | p_I nOut ) ;
END I F;

v_Local : = p_I n; - - Vl i do

- - p_I n : = 7; - - I l egal

p_Out : = 7; - - Vl i do

v_Local : = p_Out ; - - Vl i do par a Or acl e 7, 7. 3. 4 e 8. 0. 4, 8i ou super i or

v_Local : = p_I nOut ; - - Vl i do

p_I nOut : = 8; - - Vl i do

DBMS_OUTPUT. PUT_LI NE( ' Ao f i nal da pr ocedur e PARAMETROS: ' ) ;
I F ( p_I n I S NULL) THEN
DBMS_OUTPUT. PUT( ' p_I n i s NULL' ) ;
ELSE
DBMS_OUTPUT. PUT( ' p_I n = ' | | p_I n) ;
END I F;

I F ( p_Out I S NULL) THEN
DBMS_OUTPUT. PUT( ' p_Out i s NULL' ) ;
ELSE
DBMS_OUTPUT. PUT( ' p_Out = ' | | p_Out ) ;
END I F;

I F ( p_I nOut I S NULL) THEN
DBMS_OUTPUT. PUT_LI NE( ' p_I nOut i s NULL' ) ;
ELSE
DBMS_OUTPUT. PUT_LI NE( ' p_I nOut = ' | | p_I nOut ) ;
END I F;

END par amet r os;
/






PROGRAMAO PARA BANCO DE DADOS 26


REM cal l _par amet r os. sql

set ser ver out put on

DECLARE
v_I n NUMBER : = 1;
v_Out NUMBER : = 2;
v_I nOut NUMBER : = 3;
BEGI N
DBMS_OUTPUT. PUT_LI NE( ' Ant es de chamar pr ocedur e PARAMETROS: ' ) ;
DBMS_OUTPUT. PUT_LI NE( ' v_I n = ' | | v_I n | |
' v_Out = ' | | v_Out | |
' v_I nOut = ' | | v_I nOut ) ;

par amet r os( v_I n, v_Out , v_I nOut ) ;

DBMS_OUTPUT. PUT_LI NE( ' Aps chamar pr ocedur e PARAMETROS: ' ) ;
DBMS_OUTPUT. PUT_LI NE( ' v_I n = ' | | v_I n | |
' v_Out = ' | | v_Out | |
' v_I nOut = ' | | v_I nOut ) ;
END;
/

- - Chamar pr ocedur e PARAMETROS comuml i t er al par a p_I n. I sso val i do.
DECLARE
v_Out NUMBER : = 2;
v_I nOut NUMBER : = 3;
BEGI N
par amet r os( 1, v_Out , v_I nOut ) ;
END;

- - Subst i t ui r v_Out or v_I nOut por uml i t er al , pr ovocar umer r o de compi l ao.
DECLARE
v_Out NUMBER : = 2;
BEGI N
par amet r os( 1, v_Out , 3) ;
END;

- - Subst i t ui r v_Out or v_I nOut por uml i t er al , pr ovocar umer r o de compi l ao.
DECLARE
v_I nOut NUMBER : = 3;
BEGI N
par amet r os( 1, 2, v_I nOut ) ;
END;

Exemplo 2:

REM soma. sql
CREATE OR REPLACE PROCEDURE soma (
p_1 I N NUMBER,
p_2 I N NUMBER,
p_t OUT NUMBER) I S
BEGI N
p_t : = p_1 + p_2;
DBMS_OUTPUT. PUT_LI NE( p_1| | ' +' | | p_2| | ' =' | | p_t ) ;
END soma;
/

REM cal l _soma. sql
DECLARE
v_1 NUMBER : = 1;
v_2 NUMBER : = 2;
v_t NUMBER;
BEGI N
soma( v_1, v_2, v_t ) ;
END;
/


PROGRAMAO PARA BANCO DE DADOS 27


Exemplo 3:

CREATE TABLE pr odut o
( codi go NUMBER( 4) pr i mar y key,
nome VARCHAR2( 20) ,
val or NUMBER( 7, 2) ,
cat egor i a NUMBER( 4) ) ;

I NSERT I NTO pr odut o VALUES ( 1, ' pr odut o1' , 2. 5, 10) ;
I NSERT I NTO pr odut o VALUES ( 2, ' pr odut o2' , 3. 2, 20) ;
I NSERT I NTO pr odut o VALUES ( 3, ' pr odut o3' , 5. 8, 30) ;

CREATE OR REPLACE PROCEDURE aument a_val or
( v_cat egor i a I N pr odut o. cat egor i a%TYPE,
v_per cent ual NUMBER)
I S
BEGI N
UPDATE pr odut o
SET val or = val or *( 1+v_per cent ual / 100)
WHERE cat egor i a = v_cat egor i a;
END aument a_val or ;
/

EXEC aument a_val or ( 10, 25) ;

SELECT * FROM pr odut o;

CD_PRODUTO NM_PRODUTO VL_CUSTO CD_CATEGORI A
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 pr odut o1 3, 13 10
2 pr odut o2 3, 2 20
3 pr odut o3 5, 8 30

EXERCCIO 1:

Criar uma procedure para incluso de dados na tabela produto.

CREATE OR REPLACE PROCEDURE i nser e_pr odut o
( v_codi go I N pr odut o. codi go%TYPE,
v_nome I N pr odut o. nome%TYPE,
v_val or I N pr odut o. val or %TYPE,
v_cat egor i a I N pr odut o. cat egor i a%TYPE)
I S
BEGI N
I NSERT I NTO pr odut o
( codi go, nome, val or , cat egor i a)
VALUES
( v_codi go, v_nome, v_val or , v_cat egor i a) ;
EXCEPTI ON
WHEN DUP_VAL_ON_I NDEX THEN
DBMS_OUTPUT. PUT_LI NE( ' Cdi go de pr odut o j cadast r ado' ) ;
END i nser e_pr odut o;
/

EXEC i nser e_pr odut o ( 4, ' Pr odut o4' , 4. 2, 10)

SELECT * FROM pr odut o;

CD_PRODUTO NM_PRODUTO VL_CUSTO CD_CATEGORI A
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 pr odut o1 2, 5 10
2 pr odut o2 3, 2 20
3 pr odut o3 5, 8 30
4 Pr odut o4 4, 2 10

PROGRAMAO PARA BANCO DE DADOS 28


EXERCCIO 2:

Criar uma procedure para consultar um produto informando o cdigo:

CREATE OR REPLACE PROCEDURE CONSULTA_PRODUTO
( P_CODI GO I N PRODUTO. CODI GO%TYPE)
I S
V_CODI GO NUMBER( 5) ;
V_DESCRI CAO VARCHAR2( 20) ;
V_VALOR NUMBER( 7, 2) ;
V_CATEGORI A NUMBER( 5) ;
BEGI N
SELECT CODI GO, DESCRI CAO, VALOR, CATEGORI A
I NTO V_CODI GO, V_DESCRI CAO, V_VALOR, V_CATEGORI A
FROM PRODUTO
WHERE CODI GO = P_CODI GO;
DBMS_OUTPUT. PUT_LI NE( ' CODI GO = ' | | V_CODI GO) ;
DBMS_OUTPUT. PUT_LI NE( ' DESCRI CAO = ' | | V_DESCRI CAO) ;
DBMS_OUTPUT. PUT_LI NE( ' VALOR = ' | | V_VALOR) ;
DBMS_OUTPUT. PUT_LI NE( ' CATEGORI A = ' | | V_CATEGORI A) ;
EXCEPTI ON
WHEN NO_DATA_FOUND THEN
RAI SE_APPLI CATI ON_ERROR ( - 20500, ' PRODUTO NO ENCONTRADO' ) ;
END CONSULTA_PRODUTO;
/

EXEC consul t a_pr odut o ( 3) ;

EXERCCIO 3:

CREATE TABLE ALUNO (
RA NUMBER( 5) PRI MARY KEY,
NOME VARCHAR2( 20) ,
NOTA1 NUMBER( 3, 1) ,
NOTA2 NUMBER( 3, 1) ,
MEDI A NUMBER( 3, 1) ,
RESULTADO VARCHAR2( 10) ) ;

I NSERT I NTO ALUNO ( RA, NOME, NOTA1, NOTA2) VALUES ( 1, ' ANTONI O' , 9, 7) ;
I NSERT I NTO ALUNO ( RA, NOME, NOTA1, NOTA2) VALUES ( 2, ' BEATRI Z' , 4, 6) ;
I NSERT I NTO ALUNO ( RA, NOME, NOTA1, NOTA2) VALUES ( 3, ' CLAUDI O' , 8, 6) ;

Criar a procedure NOTAS para inserir os outros valores, conforme as seguintes regras:

MEDIA: (NOTA1+NOTA2)/2
RESULTADO: MEDIA >= 7 'APROVADO '; <7 - 'EXAME '

CREATE OR REPLACE PROCEDURE NOTAS I S
CURSOR C_ALUNO I S
SELECT * FROM ALUNO;
V_MEDI A ALUNO. MEDI A%TYPE;
BEGI N
FOR R_ALUNO I N C_ALUNO
LOOP
V_MEDI A : = ( R_ALUNO. NOTA1+R_ALUNO. NOTA2) / 2;
I F V_MEDI A >= 7 THEN
UPDATE ALUNO
SET MEDI A = V_MEDI A, RESULTADO = ' APROVADO'
WHERE RA = R_ALUNO. RA;
ELSE
UPDATE ALUNO
SET MEDI A = V_MEDI A, RESULTADO = ' EXAME'
WHERE RA = R_ALUNO. RA;
END I F;
END LOOP;
END;
/
PROGRAMAO PARA BANCO DE DADOS 29


IMPORTANTE:

O texto de origem (cdigo-fonte) e a forma compilada (p-code) dos subprogramas
(procedures e funes) so armazenados no dicionrio de dados. Quando um
subprograma chamado, o p-code lido a partir do disco e, se necessrio,
executado. Uma vez que tenha sido lido do disco, o p-code armazenado
armazenado na parte compartilhada do pool da SGA (System Global Area), onde,
quando necessrio, pode ser acessado por vrios usurios.
Para verificar o status de uma procedure:
SELECT OBJ ECT_NAME, OBJ ECT_TYPE, STATUS
FROM USER_OBJ ECTS WHERE OBJ ECT_NAME = ' nome_da_pr ocedur e' ;
Para visualizar o cdigo-fonte de uma procedure:
SELECT TEXT FROM USER_SOURCE
WHERE NAME = ' nome_da_pr ocedur e' ORDER BY LI NE;
Para eliminar uma procedure:
SHOWERRORS PROCEDURE nome_da_pr ocedur e;
Para eliminar uma procedure:
DROP PROCEDURE nome_da_pr ocedur e;


PROGRAMAO PARA BANCO DE DADOS 30


11. FUNCTIONS

Subprogramas que executam uma determinada ao e retornam valores. Portanto,
podem ser invocadas por meio de um comando SELECT ou utilizadas em clculos.

CREATE OR REPLACE FUNCTI ON nome_f uncao
( ar gument o1 modo t i po_de_dados,
ar gument o2 modo t i po_de_dados,
. . .
ar gument oN modo t i po_de_dados)
RETURN t i po_de_dado
I S ou AS
var i vei s l ocai s, const ant es, . . .
BEGI N
. . .
END nome_f uncao;

Exemplo:

Criar uma funo que retorne a quantidade de produtos de uma determinada
categoria. Para isso, ela receber o cdigo da categoria que ser totalizado.

CREATE OR REPLACE FUNCTI ON cont a_pr odut o
( p_cat egor i a I N pr odut o. cat egor i a%TYPE)
RETURN number
I S
v_t ot al number ;
BEGI N
SELECT COUNT( *) I NTO v_t ot al FROM pr odut o
WHERE cat egor i a = p_cat egor i a;
RETURN v_t ot al ;
END cont a_pr odut o;
/

SELECT cont a_pr odut o ( 10) FROM dual ;

CONTA_PRODUTO( 10)
- - - - - - - - - - - - - - - - -
2

EXERCCIOS:

1. Criar uma funo para apresentar o fatorial de um nmero a ser informado no
comando SELECT. Lembrete: x! = x * (x-1)!

CREATE OR REPLACE FUNCTI ON f at or i al
( p_n I N NUMBER)
RETURN number
I S
BEGI N
I F p_n = 1 THEN
RETURN 1;
ELSE
RETURN p_n * f at or i al ( p_n- 1) ;
END I F;
END f at or i al ;

SELECT f at or i al ( 3) FROM dual ;
/

FATORI AL( 3)
- - - - - - - - - - -
6

PROGRAMAO PARA BANCO DE DADOS 31


2. Criar uma funo que recebe um nmero de RA de aluno, como uma entrada e
retorna o nome e o sobrenome concatenados.

CREATE TABLE ALUNO (
RA NUMBER,
NOME VARCHAR2( 20) ,
SOBRENOME VARCHAR2( 30) ) ;

I NSERT I NTO ALUNO VALUES ( 1, ' ANTONI O' , ' ALVES' ) ;
I NSERT I NTO ALUNO VALUES ( 2, ' BEATRI Z' , ' BERNARDES' ) ;

CREATE OR REPLACE FUNCTI ON NOME_ALUNO (
P_RA ALUNO. RA%TYPE)
RETURN VARCHAR2 I S
V_NOMECOMPLETO VARCHAR2( 60) ;
BEGI N
SELECT NOME | | ' ' | | SOBRENOME
I NTO V_NOMECOMPLETO
FROM ALUNO
WHERE RA = P_RA;
RETURN V_NOMECOMPLETO;
END NOME_ALUNO;
/

SELECT RA, NOME_ALUNO( RA) " NOME COMPLETO"
FROM ALUNO;

RA NOME COMPLETO
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 ANTONI O ALVES
2 BEATRI Z BERNARDES

IMPORTANTE:

Para verificar o status de uma funo:
SELECT OBJ ECT_NAME, OBJ ECT_TYPE, STATUS
FROM USER_OBJ ECTS WHERE OBJ ECT_NAME = ' nome_da_f uncao' ;
Para visualizar o cdigo-fonte de uma funo:
SELECT TEXT FROM USER_SOURCE
WHERE NAME = ' nome_da_f uncao' ORDER BY LI NE;
Para eliminar uma funo:
SHOWERRORS FUNCTI ON nome_da_f uncao;
Para eliminar uma funo:
DROP FUNCTI ON nome_da_f uncao;

PROGRAMAO PARA BANCO DE DADOS 32


12. TRIGGERS

Blocos PL/SQL disparados automtica e implicitamente sempre que ocorrer um evento
associado a uma tabela (INSERT, UPDATE ou DELETE).

Utilizadas para:

Manuteno de tabelas
Implementao de nveis de segurana mais complexos
Gerao de valores de colunas (Exemplo: gerar o valor total do pedido a cada
incluso, alterao ou excluso na tabela item_pedido)

CREATE OR REPLACE TRI GGER nome_t r i gger
{BEFORE/ AFTER} {I NSERT, UPDATE, DELETE} OF ( nome_col una1, nome_col una2, . . . )
ON nome_t abel a
FOR EACH ROW
REFERENCI NG, OLD AS ANTI GO NEWAS NOVO
WHEN condi o
DECLARE
. . .
BEGI N
. . .
END;

NOTA: A clusula REFERENCING est substituindo as reas de memria OLD e NEW
por ANTIGO e NOVO.

TEMPO

Os tempos de uma trigger podem ser:

BEFORE - antes do evento
AFTER - depois do evento

EVENTO

Os eventos de uma trigger podem ser:

INSERT
UPDATE
DELETE

TIPO

Indica quantas vezes a trigger poder ser disparada. Os tipos podem ser:

Comando: acionada antes ou depois de um comando, independentemente de este
afetar uma ou mais linhas. No permite acesso s linhas atualizadas por meio dos
prefixos :OLD E :NEW. No utiliza a clusula FOR EACH ROW no cabealho de
criao.
Linha: acionada uma vez para cada linha afetada pelo comando ao qual a trigger
estiver associada. Permite o uso dos prefixos :OLD e :NEW no corpo da trigger e
das clusulas REFERENCING e WHEN em seu cabealho. Deve-se incluir a clusula
FOR EACH ROW no cabealho.

Clusula WHEN

Utilizada para restringir as linhas que iro disparar a trigger.

PROGRAMAO PARA BANCO DE DADOS 33


Regras para criao de triggers:

Nmero mximo de triggers possveis para uma tabela: doze (todas as
combinaes possveis entre tempos, eventos e tipos).
No podem ser utilizados os comandos COMMIT e ROLLBACK, inclusive em
procedures e functions chamadas pela trigger.
No podem ser alteradas chaves primrias, nicas ou estrangeiras.
No podem ser feitas referncias a campos do tipo LONG E LONG RAW.

Para testar o evento de chamada da trigger so disponibilizados os seguintes
predicados:

Inserting: retorna TRUE se a trigger foi disparada por um comando INSERT.
Updating: retorna TRUE se a trigger foi disparada por um comando UPDATE.
Deleting: retorna TRUE se a trigger foi disparada por um comando DELETE.

Contedo das reas OLD e NEW (apenas triggers de linha)
EVENTO OLD NEW
INSERT NULL valor inserido
UPDATE valor antes da alterao valor aps a alterao
DELETE valor antes da excluso NULL

Em triggers com clusula de tempo BEFORE possvel consultar e alterar o valor de
:NEW.
Em triggers com clusula de tempo AFTER possvel apenas consultar o valor de
:NEW.

Comandos:

DROP TRI GGER nome_t r i gger
Elimina uma trigger
ALTER TRI GGER nome_t r i gger ENABLE
Habilita uma trigger
ALTER TRI GGER nome_t r i gger DI SABLE
Desabilita uma trigger
ALTER TABLE nome_t abel a ENABLE ALL_TRI GGERS
Habilita todas as triggers de uma tabela
ALTER TABLE nome_t abel a DI SABLE ALL_TRI GGERS
Desabilita todas as triggers de uma tabela

Exemplo:

CREATE TABLE pr odut o
( codi go NUMBER( 4) ,
val or NUMBER( 7, 2) ) ;

CREATE TABLE val or _pr odut o
( codi go NUMBER( 4) ,
val or _ant er i or NUMBER( 7, 2) ,
val or _novo NUMBER( 7, 2) ) ;

CREATE OR REPLACE TRI GGER ver i f i ca_val or
BEFORE UPDATE
OF val or
ON pr odut o
FOR EACH ROW
BEGI N
I NSERT I NTO val or _pr odut o
VALUES
( : OLD. codi go, : OLD. val or , : NEW. val or ) ;
END;
/
PROGRAMAO PARA BANCO DE DADOS 34



I NSERT I NTO pr odut o VALUES ( 1, 2. 5) ;
I NSERT I NTO pr odut o VALUES ( 2, 3. 2) ;
I NSERT I NTO pr odut o VALUES ( 3, 5. 8) ;

UPDATE pr odut o
SET val or = 5. 4
WHERE codi go = 3;

SELECT * FROM val or _pr odut o;

CODI GO VALOR_ANTERI OR VALOR_NOVO
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3 5, 8 5, 4

EXERCCIO:

Incluir na tabela valor_produto os campos:

usuar i o VARCHAR2, ( 30)
dat a_at ual DATE

Alterar a trigger verifica_valor para que tambm sejam includos na tabela
valor_produto a data do sistema no momento da atualizao e o nome do usurio que
realizou a alterao no campo valor.


ALTER TABLE val or _pr odut o
ADD ( usuar i o VARCHAR2( 30) ,
dat a_at ual DATE) ;

CREATE OR REPLACE TRI GGER ver i f i ca_val or
BEFORE UPDATE
OF val or
ON pr odut o
FOR EACH ROW
BEGI N
I NSERT I NTO val or _pr odut o
VALUES
( : OLD. codi go, : OLD. val or , : NEW. val or , user , sysdat e) ;
END;
/



















PROGRAMAO PARA BANCO DE DADOS 35


13. PACKAGES

Objetos do Banco de Dados equivalentes a bibliotecas que armazenam:

procedures
functions
definies de cursores
variveis e constantes
definies de excees

Um package comporto de duas partes:

1. Especificao:
rea onde so feitas as declaraes pblicas. As variveis, constantes, cursores,
excees e subprogramas estaro disponveis para uso externo ao package.
2. Corpo:
rea onde so feitas as declaraes privadas que estaro disponveis apenas
dentro do package e a definio de aes para os subprogramas pblicos e
privados.
O Corpo do package um objeto de dicionrio de dados separado da Especificao
(cabealho). Ele no poder ser compilado com sucesso a menos que a Especificao
j tenha sido compilada.


- - especi f i cacao

CREATE OR REPLACE PACKAGE nome_package I S
PROCEDURE nome_pr ocedur e ( l i st a_de_par amet r os) ;
FUNCTI ON nome_f unct i on ( l i st a_de_par amet r os) ;
Decl ar ao de var i vei s, const ant es, excees e cur sor es pbl i cos
END nome_package;



- - cor po

CREATE OR REPLACE PACKAGE BODY nome_package I S

Decl ar ao de var i vei s, const ant es, excees e cur sor es pr i vados

PROCEDURE nome_pr ocedur e ( l i st a_de_par amet r os)
I S
. . .
BEGI N
. . .
END nome_pr ocedur e;

FUNCTI ON nome_f unct i on ( l i st a_de_par amet r os)
RETURN t i po_de_dado
I S
. . .
BEGI N
. . .
RETURN
END nome_f uncao;
END;




PROGRAMAO PARA BANCO DE DADOS 36


Exemplo 1:

CREATE OR REPLACE PACKAGE pack_1 I S
PROCEDURE pr oc_1;
FUNCTI ON f unc_1 RETURN VARCHAR2;
END pack_1;
/


CREATE OR REPLACE PACKAGE BODY pack_1 I S
PROCEDURE pr oc_1
I S
BEGI N
DBMS_OUTPUT. PUT_LI NE( ' Mensagemda Pr ocedur e' ) ;
END pr oc_1;
FUNCTI ON f unc_1 RETURN VARCHAR2 I S
BEGI N
RETURN( ' Mensagemda Funct i on' ) ;
END f unc_1;
END pack_1;
/


EXEC pack_1. pr oc_1;

SELECT pack_1. f unc_1 FROM DUAL;



Exemplo 2:

CREATE OR REPLACE PACKAGE pack_al uno I S
PROCEDURE adi ci ona_al uno
( v_r a I N al uno. r a%TYPE,
v_nome I N al uno. nome%TYPE ) ;
END pack_al uno;
/


CREATE OR REPLACE PACKAGE BODY pack_al uno I S
PROCEDURE adi ci ona_al uno
( v_r a I N al uno. r a%TYPE,
v_nome I N al uno. nome%TYPE)
I S
BEGI N
I NSERT I NTO al uno
( r a, nome)
VALUES
( v_r a, v_nome) ;
EXCEPTI ON
WHEN DUP_VAL_ON_I NDEX THEN
DBMS_OUTPUT. PUT_LI NE( ' RA j cadast r ado' ) ;
END adi ci ona_al uno;
END pack_al uno;
/


EXEC pack_al uno. adi ci ona_al uno ( 1, ' Ant oni o' ) ;

PROGRAMAO PARA BANCO DE DADOS 37


14. SQL DINMICO

Um bloco PL/SQL no executa comandos DDL (CREATE TABLE, DROP TABLE,
TRUNCATE, etc.). Por isso, o Oracle oferece um recurso conhecido como NDS (Native
Dynamic SQL) que permite, por meio da linguagem PL/SQL, executar dinamicamente
comandos DDL.
SQL dinmico um comando vlido, codificado dentro de uma string e executado
atravs do comando EXECUTE IMMEDIATE.

A procedure abaixo utiliza um comando DDL (CREATE TABLE) e no poder ser criada.

CREATE OR REPLACE PROCEDURE cr i a_t abel a
I S
BEGI N
cr eat e t abl e t est e ( col una1 number ( 5) ) ;
END cr i a_t abel a;
/

Para cri-la devemos utilizar SQL dinmico, conforme segue:

CREATE OR REPLACE PROCEDURE cr i a_t abel a
( nome_t abel a I N VARCHAR2)
I S
comando VARCHAR2( 100) ;
BEGI N
comando : = ' cr eat e t abl e ' | | nome_t abel a| | ' ( col una1 number ( 5) ) ' ;
EXECUTE I MMEDI ATE comando;
END cr i a_t abel a;
/

EXEC cr i a_t abel a ( ' t est e' ) ;

I NSERT I NTO t est e VALUES ( 1) ;
I NSERT I NTO t est e VALUES ( 2) ;
I NSERT I NTO t est e VALUES ( 3) ;


Para eliminar a tabela tambm devemos utilizar SQL dinmico:

CREATE OR REPLACE PROCEDURE l i mpa_t est e
I S
comando VARCHAR2( 100) ;
BEGI N
comando : = ' TRUNCATE TABLE t est e' ;
EXECUTE I MMEDI ATE comando;
END l i mpa_t est e;
/

exec l i mpa_t est e;









PROGRAMAO PARA BANCO DE DADOS 38


BIBLIOGRAFIA

FANDERUFF, D. Dominando o Oracle 9i Modelagem e Desenvolvimento. So Paulo:
Makron Books, 2003.

MORELLI, E. T. Oracle 9i SQL, PL/SQL e Administrao. So Paulo: rica, 2005.

RAMALHO, J. A. A. Oracle 9i. So Paulo: Berkeley, 2002.

URMAN, S. Oracle 9i Programao PL/SQL. Rio de Janeiro: Campus, 2002.

Você também pode gostar