You are on page 1of 138

PL/SQL BSICO E AVANADO 7.

Relacional Consultoria e Sistemas


Rua da Candelria, 60 10 andar
Tel: (021) 2213-9191
e-mail:luciaaf@relacional.com.br
Copyright 1998
Lcia M. A. Fernandes
Gerente de Treinamento

PL/SQL BSICO E AVANADO 7.3


CAPTULO 1 : INTRODUO AO PL/SQL....................................................................... 1
CONCEITOS.......................................................................................................................... 1
ESTRUTURA ........................................................................................................................ 1
FIM DE LINHA .................................................................................................................. 1
ARQUITETURA.................................................................................................................... 3
COMPONENTES DA LINGUAGEM................................................................................... 3
IDENTIFICADOR .............................................................................................................. 3
PALAVRAS RESERVADAS ................................................................................................ 3
LITERAIS............................................................................................................................ 4
COMENTRIOS ................................................................................................................... 4
VARIVEIS .......................................................................................................................... 5
TIPOS DE VARIVEIS....................................................................................................... 5
%TYPE ............................................................................................................................. 12
CONSTANTES.................................................................................................................. 13
ATRIBUIES.................................................................................................................... 14
CONVERSO DE TIPO DE VARIVEL.......................................................................... 15
ESCOPO DE UMA VARIVEL EM PL/SQL ................................................................... 16
COMANDOS ....................................................................................................................... 17
IF ...................................................................................................................................... 17
SELECT INTO .................................................................................................................. 19
LABEL .............................................................................................................................. 20
GOTO ............................................................................................................................... 20
NULL ................................................................................................................................ 21

NDICE - i

PL/SQL BSICO E AVANADO 7.3


CAPTULO 2 : FUNES PR-DEFINIDAS ................................................................... 22
ESCALARES - CONTROLE DE ERRO............................................................................. 22
SQLCODE ........................................................................................................................ 22
SQLERRM ........................................................................................................................ 22
ESCALARES - NUMRICAS ............................................................................................ 23
ABS ................................................................................................................................... 23
CEIL ................................................................................................................................. 23
FLOOR ............................................................................................................................. 23
LN ..................................................................................................................................... 23
LOG .................................................................................................................................. 23
MOD................................................................................................................................. 24
POWER ............................................................................................................................ 24
ROUND ............................................................................................................................ 24
SIGN ................................................................................................................................. 24
SQRT ................................................................................................................................ 24
SIN .................................................................................................................................... 25
SINH ................................................................................................................................. 25
TAN................................................................................................................................... 25
TANH................................................................................................................................ 25
TRUNC ............................................................................................................................. 25
ESCALARES - ALFANUMRICAS .................................................................................. 27
CHR .................................................................................................................................. 27
CONCAT........................................................................................................................... 27
INITCAP ........................................................................................................................... 27
LOWER............................................................................................................................. 27
LPAD ................................................................................................................................ 27
LTRIM .............................................................................................................................. 28
REPLACE ......................................................................................................................... 28
RPAD................................................................................................................................ 28
RTRIM .............................................................................................................................. 28
SOUNDEX........................................................................................................................ 28
SUBSTR ............................................................................................................................ 30
TRANSLATE ..................................................................................................................... 30
UPPER ............................................................................................................................. 30
ESCALARES - ALFANUMRICAS RETORNANDO VALORES NUMRICOS.......... 32
ASCII ................................................................................................................................ 32
INSTR ............................................................................................................................... 32
LENGTH........................................................................................................................... 32

NDICE - ii

PL/SQL BSICO E AVANADO 7.3


ESCALARES - DATAS....................................................................................................... 34
ADD_MONTHS................................................................................................................ 34
LAST_DAY........................................................................................................................ 34
MONTHS_BETWEEN ...................................................................................................... 34
NEW_TIME ...................................................................................................................... 34
NEXT_DAY....................................................................................................................... 35
ROUND ............................................................................................................................ 35
SYSDATE.......................................................................................................................... 35
TRUNC ............................................................................................................................. 36
ESCALARES - CONVERSO ........................................................................................... 38
CHARTOROWID.............................................................................................................. 38
ROWIDTOCHAR.............................................................................................................. 38
HEXTORAW ..................................................................................................................... 38
RAWTOHEX ..................................................................................................................... 38
TO_CHAR ........................................................................................................................ 39
TO_DATE ......................................................................................................................... 42
TO_NUMBER................................................................................................................... 42
ESCALARES - OUTRAS.................................................................................................... 43
DECODE.......................................................................................................................... 43
GREATEST ....................................................................................................................... 43
LEAST............................................................................................................................... 43
NVL................................................................................................................................... 43
UID................................................................................................................................... 43
USER ................................................................................................................................ 44
USERENV......................................................................................................................... 44
EXEMPLO SIMPLES DE USO DE FUNES EM PL/SQL............................................ 46

NDICE - iii

PL/SQL BSICO E AVANADO 7.3


CAPTULO 3 : PROCESSAMENTO REPETITIVO ........................................................ 47
CURSOR .............................................................................................................................. 47
DECLARE CURSOR ........................................................................................................ 48
OPEN CURSOR ............................................................................................................... 49
FETCH CURSOR ............................................................................................................. 50
CLOSE CURSOR.............................................................................................................. 51
UPDATE PARA CURSOR................................................................................................ 52
DELETE PARA CURSOR ................................................................................................ 53
ATRIBUTOS PARA CURSOR .......................................................................................... 54
TIPO PARA CURSOR ...................................................................................................... 57
CURSOR LOOP ............................................................................................................... 59
OUTROS COMANDOS PARA PROCESSAMENTO REPETITIVO ............................... 60
EXIT.................................................................................................................................. 60
LOOP................................................................................................................................ 60
WHILE LOOP .................................................................................................................. 62
FOR LOOP....................................................................................................................... 64
CAPTULO 4 : TRATAMENTO DE ERROS EM PL/SQL.............................................. 67
EXCEES PR-DEFINIDAS........................................................................................... 68
DEFININDO UMA EXCEPTION....................................................................................... 70
CAUSANDO UMA EXCEPTION CRIADA PELO USURIO ........................................ 70
RAISE ............................................................................................................................... 70
PRAGMA EXCEPTION_INIT............................................................................................ 72
RAISE_APPLICATION_ERROR ....................................................................................... 73
PROPAGAO DA EXCEO ........................................................................................ 74
CAPTULO 5 TABELAS E REGISTROS EM PL/SQL .................................................... 75
TABLE ................................................................................................................................. 75
RECORD.............................................................................................................................. 77
ATRIBUTOS DE UMA TABELA PL/SQL ........................................................................ 78
EXISTS (N) ....................................................................................................................... 78
COUNT............................................................................................................................. 78
FIRST E LAST .................................................................................................................. 78
PRIOR(N) E NEXT(N)...................................................................................................... 78
DELETE, DELETE(N) E DELETE(M,N) ......................................................................... 78

NDICE - iv

PL/SQL BSICO E AVANADO 7.3


CAPTULO 6 : SUBPROGRAMAS EM PL/SQL .............................................................. 80
PROCEDURES .................................................................................................................... 81
FUNCTIONS........................................................................................................................ 82
DECLARAES FORWARD ............................................................................................ 83
STORED SUBPROGRAMS................................................................................................ 84
VANTAGENS.................................................................................................................... 84
CHAMADAS DE UM STORED SUBPROGRAM............................................................. 85
CRIANDO UM STORED SUBPROGRAM....................................................................... 86
DEPENDNCIA REMOTA ................................................................................................ 88
USO DE TABELAS PL/SQL COMO PARMETRO DE SUBPROGRAMAS ................ 89
CAPTULO 7 : TRIGGERS E PACKAGES....................................................................... 91
DATABASE TRIGGERS .................................................................................................... 91
OBJETIVO........................................................................................................................ 91
CARACTERSTICAS ........................................................................................................ 91
SINTAXE .......................................................................................................................... 92
PREDICADOS CONDICIONAIS ..................................................................................... 92
EXEMPLO........................................................................................................................ 93
COMPILANDO TRIGGERS............................................................................................. 94
HABILITANDO, DESABILITANDO E COMPILANDO TRIGGERS............................... 94
PACKAGES......................................................................................................................... 95
VANTAGENS.................................................................................................................... 95
ESPECIFICAO ............................................................................................................ 96
CORPO............................................................................................................................. 96
SINTAXE .......................................................................................................................... 97
EXEMPLO........................................................................................................................ 98
REFERNCIA A PACKAGES .......................................................................................... 99

NDICE - v

PL/SQL BSICO E AVANADO 7.3


CAPTULO 8 : ALGUNS PACKAGES DO ORACLE.................................................... 100
O PACKAGE DBMS_OUTPUT ....................................................................................... 100
ENABLE ......................................................................................................................... 101
DISABLE ........................................................................................................................ 102
PUT ................................................................................................................................ 102
NEW_LINE ..................................................................................................................... 103
PUT_LINE...................................................................................................................... 103
GET_LINE...................................................................................................................... 104
GET_LINES.................................................................................................................... 104
O PACKAGE UTL_FILE .................................................................................................. 107
FOPEN ........................................................................................................................... 108
FCLOSE ......................................................................................................................... 110
FCLOSE_ALL................................................................................................................. 111
GET_LINE...................................................................................................................... 112
PUT ................................................................................................................................ 113
NEW_LINE ..................................................................................................................... 114
PUT_LINE...................................................................................................................... 115
PUTF .............................................................................................................................. 116
FFLUSH ......................................................................................................................... 117
CAPTULO 9 : VARIVEIS CURSOR ............................................................................ 120
CONCEITO........................................................................................................................ 120
VANTAGENS.................................................................................................................... 120
CRIANDO UMA VARIVEL CURSOR ......................................................................... 121
SINTAXE ........................................................................................................................ 121
DECLARANDO VARIVEIS DO TIPO CURSOR ......................................................... 122
USANDO UMA VARIVEL CURSOR........................................................................... 123
ASSOCIANDO UMA VARIVEL CURSOR A UMA QUERY ........................................ 123
OBTENDO DADOS DE UMA VARIVEL CURSOR .................................................... 124
FECHANDO UMA VARIVEL CURSOR...................................................................... 125
PASSANDO VARIVEIS CURSOR COMO PARMETRO ......................................... 126
EM UM PROGRAMA PRINCIPAL ................................................................................ 126
EM PROGRAMAS ARMAZENADOS NA BASE............................................................. 127
RESTRIES PARA VARIVEIS CURSOR ................................................................. 130

NDICE - vi

PL/SQL BSICO E AVANADO 7.3

CAPTULO 1 : INTRODUO AO PL/SQL


CONCEITOS
A PL/SQL uma linguagem procedural do ORACLE, extenso ao SQL.
Com a PL/SQL pode-se usar comandos SQL para manipular os dados da base
ORACLE e fluxos de controle para processar os dados. Pode-se declarar constantes
e variveis; definir subprogramas (procedures ou funes) e controlar erros de
execuo.

ESTRUTURA
A PL/SQL uma linguagem estruturada em blocos. Cada bloco pode conter qualquer
nmero de sub-blocos.
Um bloco permite que se faam declaraes locais ao bloco, que deixam de existir
quando o bloco termina.
Cada bloco composto basicamente de 3 reas :
DECLARE
<declaraes>............
BEGIN
<lgica>.....................
EXCEPTION
<erros>.......................
END;

opcional
obrigatria
opcional

A ordem das partes lgica, ou seja, primeiro devemos efetuar as declaraes, para
depois utilizar (na lgica) as variveis criadas. As excees ocorridas durante a
execuo podem ser tratadas na parte referente a erros.

FIM DE LINHA
A indicao de fim de linha de comando, em PL/SQL, feita com um ponto e vrgula
(;).

INTRODUO - 1

PL/SQL BSICO E AVANADO 7.3

SQL> SELECT vl_sal FROM func WHERE cd_mat = 150;


VL_SAL
----------2907.2
SQL>DECLARE
2
Wrowid
ROWID;
3
Wsal
NUMBER(5);
4 BEGIN
5
SELECT vl_sal, rowid
6
INTO Wsal, Wrowid
7
FROM func
-- obtm o salrio
8
WHERE cd_mat = 150;
9 /*
10 Atualiza os valores de salrio
11 ------------------------------------12 */
13
UPDATE func
14
SET vl_sal = Wsal * 1.3
15 WHERE rowid = Wrowid;
16 -17 END;
18 /
PL/SQL procedure successfully completed.
SQL> SELECT vl_sal FROM func WHERE cd_mat = 150;
VL_SAL
----------3779.1

INTRODUO - 2

PL/SQL BSICO E AVANADO 7.3

ARQUITETURA
O mdulo executvel da PL/SQL pode ser instalado no RDBMS e/ou em softwares
aplicativos tais como: REPORTS 2.5, FORMS 4.5. Estes dois ambientes (RDBMS e
aplicativos) so independentes. No ambiente instalado, a PL/SQL aceita como entrada
qualquer bloco ou subprograma escrito na linguagem.
A instalao no RDBMS permite:
incluso de rotinas em PL/SQL nos aplicativos das host languages (COBOL,
PL/1, ADA, C, etc).
compilao e armazenamento de subprogramas na base de dados ORACLE
(chamados de "stored subprogram's")

COMPONENTES DA LINGUAGEM
IDENTIFICADOR
Consiste de uma letra opcionalmente seguida de nmeros, $, _ ou #. As letras podem
ser minsculas ou maisculas (No Case Sensitive). O tamanho mximo de um
identificador 30 caracteres.
LEGAIS

ILEGAIS

money$$$tree
ab###
novo__teste_

teste&teste
nm func

PALAVRAS RESERVADAS
Palavras que possuam um significado especial para a PL/SQL.
BEGIN
END
EXCEPTION
TYPE
TABLE
No devem ser usadas como identificadores.

INTRODUO - 3

PL/SQL BSICO E AVANADO 7.3

LITERAIS
uma representao explcita de um nmero, caracter, string ou boleano, no
representado por um identificador.
Numricos
030
6
-14
+32767
12.0
.5
2E5
-9.5E-3

Caracteres
z
%
7
.
.
z
(

Strings
10-NOV-91
hello, world !

Boleanos
TRUE
FALSE
NULL

COMENTRIOS
Um comentrio em PL/SQL pode ser marcado de 2 formas:
dois hfens em qualquer ponto da linha torna o restante dela comentrio.
/* (incio) e */ (fim) marcam uma regio que ser ignorada pelo compilador.
SQL> DECLARE
2
Wrowid ROWID;
3
Wsal
NUMBER(5);
4 BEGIN
5
SELECT vl_sal, rowid
6
INTO Wsal, Wrowid
7
FROM func
-- obtm o salrio
8
WHERE cd_mat = 150;
9 /*
10 Atualiza os valores de salrio
11 --------------------------------------12 */
13 UPDATE func
14
SET vl_sal = Wsal * 1.3
15 WHERE rowid = Wrowid;
16 -17 END;
18 /

INTRODUO - 4

PL/SQL BSICO E AVANADO 7.3

VARIVEIS
Cada constante ou varivel possui um tipo que especifica o formato de
armazenamento, restries e intervalo de valores. O dado pode ser simples ou
composto.
SINTAXE
<varivel>

<tipo>

[NOT NULL]

[ {:= | DEFAULT} <valor inicial>]

SUBTIPOS
So subconjuntos de tipos de variveis. Possuem uma restrio sobre o tipo que
caracteriza o subconjunto de valores.

TIPOS DE VARIVEIS
BINARY_INTEGER
Numrico, para armazenamento de valores inteiros de -2**31 a (2**31) - 1
SINTAXE

BINARY_INTEGER
SUBTIPOS

NATURAL.....................
POSITIVE.....................
SQL> DECLARE
2
Wbin
3
Wnat
4
Wpos
5 BEGIN
........
........
........
16 END;
17 /

de 0 a (2**31) - 1
de 1 a (2**31) - 1

BINARY_INTEGER;
NATURAL;
POSITIVE;

INTRODUO - 5

PL/SQL BSICO E AVANADO 7.3


CHAR
Alfanumrico de tamanho fixo com comprimento at 32767 caracteres. Tamanho
default de 1 caracter.
SINTAXE

CHAR [ (<comprimento>) ]
SUBTIPOS

STRING [ (<comprimento>) ]

idem a CHAR

NUMBER
Numrico, para armazenamento de valores em ponto flutuante com preciso de at 38
dgitos.
SINTAXE

NUMBER [ ( <preciso>, <escala> ) ]


SUBTIPOS

DEC [ ( <preciso>, <escala> ) ]..............................


DECIMAL [ ( <preciso>, <escala> ) ]......................
DOUBLE PRECISION [ ( <preciso>, <escala> ) ]...
FLOAT [ ( <preciso>) ]...........................................
INTEGER [ ( <preciso>, <escala> ) ].....................
INT [ ( <preciso>, <escala> ) ]................................
NUMERIC [ ( <preciso>, <escala> ) ].....................
REAL [ ( <preciso>, <escala> ) ]............................
SMALLINT [ ( <preciso>, <escala> ) ]....................

idem a NUMBER
idem a NUMBER
idem a NUMBER
idem a NUMBER
idem a NUMBER
idem a NUMBER
idem a NUMBER
idem a NUMBER
idem a NUMBER

INTRODUO - 6

PL/SQL BSICO E AVANADO 7.3


SQL> DECLARE
2 Wa
number(8,2);
3 Wb
dec(8,2);
4 Wc
decimal(8,2);
5 Wd
double precision(8,2);
6 We
float(8);
7 Wf
int(8,2);
8 Wg
real(8,2);
9 Wh
smallint(8,2);
10 BEGIN
...................
LONG
Alfanumrico de tamanho varivel com comprimento de at 32767.
SINTAXE

LONG [ (<comprimento>) ]
SQL> DECLARE
2 Wlong
LONG(35000);
3 BEGIN
......................
15 END;
16 /
Wlong
LONG(35000);
*
ERROR at line 2:
ORA-06550: line 2, column 17:
PLS-00215: String length constraints must be in range (1 .. 32767)
ORA-06550: line 2, column 17:
PL/SQL: Item ignored

INTRODUO - 7

PL/SQL BSICO E AVANADO 7.3


VARCHAR2
Alfanumrico de tamanho varivel com comprimento de at 32767. A especificao de
comprimento obrigatria.
SINTAXE

VARCHAR2 (<comprimento>)
SUBTIPOS

VARCHAR (<comprimento>)

idem a VARCHAR2

RAW
Para armazenamento de dados binrios (tam. mx at 32767). A especificao de
comprimento obrigatria.
SINTAXE

RAW (<comprimento>)

INTRODUO - 8

PL/SQL BSICO E AVANADO 7.3


LONG RAW
Para armazenamento de dados binrios (tam. mx at 32767). Comprimento default
1.
SINTAXE

LONG RAW [ (<comprimento>) ]

SQL> DECLARE
2 Wchar
3 Wvarc
4 Wraw
5 Wlonr
6 Wchar1
7 Wlong1
8 Wlongr1
9 BEGIN
10
null;
11 END;
12 /

CHAR(32767);
VARCHAR2(32767);
RAW(32767);
LONG RAW(32767);
CHAR;
LONG;
LONG RAW;

PL/SQL procedure successfully completed.

BOOLEAN
Para armazenamento de valores boleanos (true, false ou null)
SINTAXE

BOOLEAN

INTRODUO - 9

PL/SQL BSICO E AVANADO 7.3


ROWID
Para armazenamento de valores de ROWID do banco ORACLE (em hexadecimal).
SINTAXE

ROWID
FORMATO:

BBBBBBBB.RRRR.FFFF, onde :
BBBBBBBB.......
RRRR...............
FFFF.................

bloco dentro do arquivo (database file)


row dentro do bloco (primeira row 0)
nmero do arquivo (database file)

DATE
Para armazenamento de datas.
SINTAXE

DATE

INTRODUO - 10

PL/SQL BSICO E AVANADO 7.3


PLS_INTEGER
Sua magnitude vai de -2147483647 at 2147483647 (mesma do BINARY_INTEGER).
Uma vez que seu conjunto de valores menor que o de um NUMBER ele requer
menor armazenamento. Alm disso ele usa machine arithmetic sendo, por isso,
mais rpido que um NUMBER OU BINARY_INTEGER que usam em suas operaes
library arithmetic.
Apesar do BINARY_INTEGER e do PLS_INTEGER possurem o mesmo intervalo de
valores, eles no so exatamente iguais. Quando um PLS_INTEGER receber um
valor acima de sua capacidade (overflow), associada uma exceo. No caso de
clculos com BINARY_INTEGER a exceo no ser adquirida se o resultado for
associado a uma varivel NUMBER.
recomendvel, portanto, que nas novas aplicaes utilizemos PLS_INTEGER.
SINTAXE

PLS_INTEGER
SQL> DECLARE
2 Wnum
NUMBER;
3 Wbool
BOOLEAN := TRUE;
4 Wdate
DATE := TO_DATE('10/09/97', 'dd/mm/yy');
5 Wrowid
ROWID;
6 Wpls
PLS_INTEGER := -2147483647;
7 Wbin
BINARY_INTEGER := -2147483647;
8 BEGIN
9
Wnum := wbin - 1;
10
Wnum := wpls - 1;
11 END;
12 /
DECLARE
*
ERROR at line 1:
ORA-01426: numeric overflow
ORA-06512: at line 10

INTRODUO - 11

PL/SQL BSICO E AVANADO 7.3

%TYPE
Atravs do %TYPE as variveis PL/SQL e constantes permitem a referncia ao tipo e
estrutura de uma outra varivel sem a necessidade de repetio de sua definio. Na
definio de tabelas e colunas do database podemos agir de forma similar.
O atributo %TYPE copia as propriedades de uma varivel, constante ou coluna do
database. particularmente usado quando declaramos variveis que pertenam s
colunas do database.
SINTAXE
<varivel>/<constante>/<coluna>%TYPE
SQL> DECLARE
2 Wcodigo
3 Wcod2
4 Wcod3
5 Wcodep
6 BEGIN
7
null;
8 END;
9 /

NUMBER(3) NOT NULL := 3;


Wcodigo%TYPE;
Wcodigo%TYPE NOT NULL := 4;
DEPTO.CD_DEPTO%TYPE;

PL/SQL procedure successfully completed.

INTRODUO - 12

PL/SQL BSICO E AVANADO 7.3

CONSTANTES
A declarao de uma constante semelhante declarao de uma varivel, exceto
que devemos adicionar a palavra chave CONSTANT e, imediatamente, associar uma
valor inicial. Seu valor no poder ser alterado durante o programa.
SINTAXE
<nome da constante> CONSTANT <tipo> {:=/DEFAULT} <valor inicial>;
SQL> DECLARE
2 Wcons
CONSTANT REAL := 3.14159;
3 Wconsr
CONSTANT REAL DEFAULT 3.14159;
4 BEGIN
......................
6 END;
7 /
PL/SQL procedure successfully completed.

INTRODUO - 13

PL/SQL BSICO E AVANADO 7.3

ATRIBUIES
Em PL/SQL a atribuio de valor a uma varivel feita com a notao := .
As variveis e constantes so inicializadas cada vez que iniciado o bloco em que
elas esto declaradas.
Por default, as variveis so inicializadas com "NULL". importante, portanto, que
as variveis antes de serem usadas sejam inicializadas.
SQL> VARIABLE msg char(80)
SQL> DECLARE
2 Wpi
CONSTANT REAL := 3.14159;
3 Wvf
boolean;
4 Wnum
number;
5 BEGIN
6
Wvf := (Wnum > 4);
7
IF Wvf THEN
8
Wnum := Wpi + 1;
9
:MSG := 'O novo valor de Wnum 4.14159';
10
ELSE
11
Wnum := 0;
12
:MSG := 'O novo valor de Wnum zero';
13
END IF;
14 END;
15 /
PL/SQL procedure successfully completed.
SQL> PRINT msg
MSG
------------------------------------------------------------O novo valor de Wnum zero

INTRODUO - 14

PL/SQL BSICO E AVANADO 7.3

CONVERSO DE TIPO DE VARIVEL


Pode-se converter de um tipo de varivel para outro explicitamente porm, em muitas
situaes a PL/SQL pode converter o tipo de caracter em outro, implicitamente. Isto
ocorre quando usamos varivel de um tipo onde era esperado outro. A PL/SQL utiliza
uma das seguintes funes para executar esta converso:
TO_CHAR
TO_VARCHAR2
CHARTOROWID
HEXTORAW
TO_BINARY_INTEGER
TO_DATE
TO_NUMBER
ROWIDTOCHAR
RAWTOHEX
SQL> DECLARE
2 Wnum
NUMBER := 12;
3 Wchar
CHAR(5);
4 Wdata
CHAR(20);
5 BEGIN
6
Wchar := Wnum;
7
Wdata := SYSDATE;
8
:msg := Wdata;
9 END;
10 /
PL/SQL procedure successfully completed.
SQL> PRINT msg
MSG
-----------------------------------------------------10-MAY-97

INTRODUO - 15

PL/SQL BSICO E AVANADO 7.3

ESCOPO DE UMA VARIVEL EM PL/SQL


Uma varivel declarada em um bloco deixa de existir quando o bloco termina.
SQL> DECLARE
2 Wnum
NUMBER := 12;
3 Wchar
CHAR(20) := 'Wchar externa';
4 Wunico
NUMBER := 5;
5 BEGIN
6
DECLARE
7
Wnum
NUMBER := 10;
8
Wchar
CHAR(20) := 'Wchar interna';
9
Wtotal
NUMBER;
10
BEGIN
11
Wtotal := Wnum + Wunico;
12
:msg := 'O valor de total ' || to_char(Wtotal);
13
END;
14 END;
15 /
PL/SQL procedure successfully completed.
SQL> PRINT msg
MSG
---------------------------------------------------------------O valor de total 15

INTRODUO - 16

PL/SQL BSICO E AVANADO 7.3

COMANDOS
IF
A seqncia de comandos s ser executada se a condio for verdadeira.
SINTAXE
IF <CONDIO> THEN
<SEQNCIA DE COMANDOS>
END IF;

IF <CONDIO> THEN
<SEQNCIA DE COMANDOS>
ELSE
<SEQNCIA DE COMANDOS>
END IF;

IF <CONDIO> THEN
<SEQNCIA DE COMANDOS>
ELSIF <CONDIO> THEN
<SEQNCIA DE COMANDOS>
ELSE
<SEQNCIA DE COMANDOS>
END IF;

INTRODUO - 17

PL/SQL BSICO E AVANADO 7.3


<CONDIO>
[NOT] <EXPRESSO BOLEANA> [[AND | OR] <EXPRESSO BOLEANA>]
<EXPRESSO BOLEANA>
<LITERAL BOLEANO> |
<VARIVEL BOLEANA> |
<CHAMADA DE FUNO BOLEANA> |
(<EXPRESSO BOLEANA>) |
<EXPRESSO PLSQL> <OPERADOR RELACIONAL> <EXPRESSO PLSQL> |
<EXPRESSO PLSQL> IS [NOT] NULL |
<EXPRESSO PLSQL> [NOT] LIKE <PATTERN> |
<EXPRESSO PLSQL> [NOT] BETWEEN <EXPR. PLSQL> AND <EXPR. PLSQL> |
<EXPRESSO PLSQL> [NOT] IN (<EXPRESSO PLSQL>[,<EXPRESSO PLSQL>]) |
{<NOME CURSOR> | SQL} {%NOTFOUND |%FOUND |%ISOPEN}

SQL> VARIABLE msg CHAR(30)


SQL> ACCEPT teste PROMPT 'Informe o valor de Wvalor: '
Informe o valor de Wvalor: 0
SQL> DECLARE
2 Wvalor
NUMBER := &teste;
3 BEGIN
4
IF Wvalor < 0 THEN
5
:msg := 'Valor menor que zero';
6
ELSIF Wvalor = 0 THEN
7
:msg := 'Valor igual a zero';
8
ELSE
9
:msg := 'Valor maior que zero';
10
END IF;
11 END;
12 /
old 2: Wvalor
NUMBER := &teste;
new 2: Wvalor
NUMBER := 0;
PL/SQL procedure successfully completed.
SQL> PRINT msg
MSG
-------------------------------Valor igual a zero

INTRODUO - 18

PL/SQL BSICO E AVANADO 7.3

SELECT INTO
Seleciona um nmero fixo de rows. A avaliao das variveis feita a tempo de
execuo do comando.
SINTAXE
SELECT <LISTA DE COLUNAS> / *
INTO <LISTA DE VARIVEIS>
FROM <ESPECIFICAO DE TABELA / VIEW>
WHERE <CONDIO DE SELEO>
<LISTA DE VARIVEIS>
Uma ou mais variveis do programa correspondentes s colunas selecionadas.
SQL> DECLARE
2 w_salario NUMBER(5);
3 BEGIN
4
SELECT vl_sal INTO w_salario FROM func
5
WHERE cd_mat = 150
6
FOR UPDATE OF vl_sal;
7
IF w_salario < 800 THEN
8
UPDATE func SET vl_sal = w_salario * 1.3
9
WHERE cd_mat = 150;
10
:msg := 'Valor do novo salrio ' || to_char(trunc(w_salario * 1.3));
11
ELSE
12
UPDATE func SET vl_sal = vl_sal * 1.15
13
WHERE cd_mat = 150;
14
:msg := 'Valor do novo salrio ' || to_char(trunc(w_salario * 1.15));
15
END IF;
16 END;
17 /
PL/SQL procedure successfully completed.
SQL> PRINT msg
MSG
-------------------------------Valor do novo salrio 4345

INTRODUO - 19

PL/SQL BSICO E AVANADO 7.3

LABEL
Identifica (qualifica) um comando ou conjunto de comandos. Utilizado para desvios e
para qualificao. Deve existir um comando aps o LABEL.
SINTAXE
<< <LABEL> >>

GOTO
Desvia incondicionalmente para um "LABEL", o qual deve ser nico dentro do
escopo.
SINTAXE
GOTO << <LABEL> >>
SQL> DECLARE
2 Wvez
NUMBER(5) := 0;
3 Wloop
NATURAL := 0;
4 BEGIN
5
<<inicio>>
6
Wloop := Wloop + 1;
7
IF Wvez > 5 THEN
8
:msg := 'O valor de Wvez = ' || TO_CHAR(Wvez);
9
GOTO fim;
10
ELSE
11
Wvez := Wvez * Wloop + 1;
12
END IF;
13
GOTO inicio;
14
<<fim>>
15
COMMIT;
16 END;
17 /
PL/SQL procedure successfully completed.
SQL> PRINT msg
MSG
-------------------------------O valor de Wvez = 10

INTRODUO - 20

PL/SQL BSICO E AVANADO 7.3

NULL
Este comando explicitamente indica que no h ao a ser feita. Serve para compor
certas situaes em que um comando exigido, mas nenhuma ao realmente
necessria.
SINTAXE
NULL
SQL> DECLARE
2
Wvez
NUMBER(5) := 0;
3
Wloop
NATURAL := 0;
4 BEGIN
5
<<inicio>>
6
Wloop := Wloop + 1;
7
IF Wvez > 5 THEN
8
:msg := 'O valor de Wvez = ' || TO_CHAR(Wvez);
9
GOTO fim;
10
ELSE
11
Wvez := Wvez * Wloop + 1;
12
END IF;
13
GOTO inicio;
14
<<fim>>
15
NULL;
16 END;
17 /
PL/SQL procedure successfully completed.
SQL> PRINT msg
MSG
-------------------------------O valor de Wvez = 10

INTRODUO - 21

PL/SQL BSICO E AVANADO 7.3

CAPTULO 2 : FUNES PR-DEFINIDAS


A PL/SQL permite a utilizao de diversas funes pr-definidas para a manipulao
dos dados. Pode-se us-las onde expresses do mesmo tipo so permitidas.

ESCALARES - CONTROLE DE ERRO


SQLCODE
Retorna o cdigo do erro associado ultima exceo.
SINTAXE: SQLCODE

SQLERRM
Retorna a mensagem de erro associado ao ltimo sqlcode.
SINTAXE: SQLERRM (<cdigo do erro>)
SQL> DECLARE
2 Wcode
NUMBER(10) := &codigo;
3 BEGIN
4
:msg := SQLERRM(wcode);
5 END;
6 /
Enter value for codigo: -1403
old 2: Wcode
NUMBER(10) := &codigo;
new 2: Wcode
NUMBER(10) := -1403;
PL/SQL procedure successfully completed.
SQL> print msg
MSG
-----------------------------------------------------ORA-01403: no data found

FUNES PR-DEFINIDAS - 22

PL/SQL BSICO E AVANADO 7.3

ESCALARES - NUMRICAS
ABS
Retorna o valor absoluto do argumento <n>.
SINTAXE: ABS(<n>)

CEIL
Retorna o menor inteiro maior que ou igual a <n>.
SINTAXE: CEIL(<n>)

FLOOR
Retorna o maior inteiro menor que ou igual a <n>.
SINTAXE: FLOOR(<n>)

LN
Retorna o logaritmo natural do argumento que deve ser maior que zero.
SINTAXE: LN (<n>)

LOG
Retorna o logaritmo de <n> na base <m>, sendo que <m> deve ser maior que 1 e <n>
deve ser maior que zero.
SINTAXE: LOG (<m>, <n>)

FUNES PR-DEFINIDAS - 23

PL/SQL BSICO E AVANADO 7.3

MOD
Retorna o resto da diviso de <m> por <n>.
SINTAXE: MOD(<m>,<n>)

POWER
Retorna <m> elevado a <n> potncia.
SINTAXE: POWER(<m>,<n>)

ROUND
Retorna <n> arredondado para <m> posies direita do ponto decimal. Se <m> for
omitido, 0 ser assumido. <m> pode ser negativo para arredondar os dgitos a
esquerda do ponto decimal. <m> deve ser um inteiro.
SINTAXE: ROUND(<n>[,<m>])

SIGN
Se <n> menor que 0, a funo retorna -1. Se <n> igual a 0, a funo retorna 0. Se
<n> maior que 0, a funo retorna 1.
SINTAXE: SIGN(<n>)

SQRT
Retorna a raiz quadrada de <n>. Se <n> for negativo, retorna NULL. A funo retorna
um resultado real.
SINTAXE: SQRT(<n>)

FUNES PR-DEFINIDAS - 24

PL/SQL BSICO E AVANADO 7.3

SIN
Retorna o seno de <n>, que deve ser expresso em radianos.
SINTAXE: SIN(<n>)
OBS.: Se <n> estiver em graus, basta que seja dividido por 57.29578 para ser
convertido para radianos.

SINH
Retorna o seno hiperblico do argumento.
SINTAXE: SINH(<n>)

TAN
Retorna a tangente de <n>, que deve ser expresso em radianos.
SINTAXE: TAN(<n>)
OBS.: Se <n> estiver em graus, basta que seja dividido por 57.29578 para ser
convertido para radianos.

TANH
Retorna a tangente hiperblica do argumento.
SINTAXE: TANH(<n>)

TRUNC
Retorna <n> truncado para <m> posies decimais. Se <m> for omitido, 0 ser
assumido. <m> pode ser negativo para truncar <m> dgitos a esquerda do ponto
decimal.
SINTAXE: TRUNC(<n>[,<m>])

FUNES PR-DEFINIDAS - 25

PL/SQL BSICO E AVANADO 7.3

SQL> DECLARE
2 Wcos
NUMBER := 0;
3 Wcosh
NUMBER := 0;
4 Wln
NUMBER := 0;
5 Wlog
NUMBER := 0;
6 BEGIN
7
Wcos := round(cos(20 / 57.29578));
8
Wcosh := trunc(cosh(20 / 57.29578));
9
Wln := round(ln(2));
10
Wlog := trunc(log(10, 5));
11
:msg := 'cos = '|| to_char(Wcos) ||
12
' cosh = '|| to_char(Wcosh) ||
13
' ln = '|| to_char(Wln) ||
14
' log = '|| to_char(Wlog);
15 END;
16 /
PL/SQL procedure successfully completed.
SQL> PRINT msg
MSG
-------------------------------------------------cos = 1 cosh = 1 ln = 1 log = 0

FUNES PR-DEFINIDAS - 26

PL/SQL BSICO E AVANADO 7.3

ESCALARES - ALFANUMRICAS
CHR
Retorna o caracter correspondente ao ASCII ou EBCDIC valor de <n>
SINTAXE: CHR(<n>)

CONCAT
Retorna uma string que o resultado da concatenao de <str1> com <str2>.
SINTAXE: CONCAT(<str1>, <str2>)

INITCAP
Retorna <c> com a primeira letra de cada palavra em maiscula e as demais em
minscula.
SINTAXE: INITCAP(<c>)

LOWER
Retorna<c>, com todas as letras minsculas.
SINTAXE: LOWER(<c>)

LPAD
Retorna <c1> completado esquerda para o comprimento <n> com a seqncia de
caracteres em <c2> (default branco).
SINTAXE: LPAD(<c1>,<n>[,<c2>])

FUNES PR-DEFINIDAS - 27

PL/SQL BSICO E AVANADO 7.3

LTRIM
Retorna <c1> sem os caracteres <c2> encontrados esquerda. A busca
interrompida quando for encontrado o primeiro caracter diferente de <c2> (default
branco) .
SINTAXE: LTRIM(<c1>[,<c2>])

REPLACE
Retorna <c> com cada ocorrncia de <s1> substituda por <s2>. Se <s1> e <s2> no
forem informados, a funo retornar NULL.
SINTAXE: REPLACE(<c>,<s1>[,<s2>])

RPAD
Retorna <c1> completado direita para o comprimento <n> com a seqncia de
caracteres em <c2> (default branco)
SINTAXE: RPAD(<c1>,<n>[,<c2>])

RTRIM
Retorna <c1> sem os caracteres <c2> finais direita. A busca interrompida quando
for encontrado o primeiro caracter diferente de <c2> (default branco)
SINTAXE: RTRIM(<c1>[,<c2>])

SOUNDEX
Retorna uma string que represente o som de <c>.
SINTAXE: SOUNDEX(<c>)

FUNES PR-DEFINIDAS - 28

PL/SQL BSICO E AVANADO 7.3


SQL> VARIABLE msg1 CHAR(50)
SQL> VARIABLE msg2 CHAR(50)
SQL> DECLARE
2 Wchr
CHAR(5);
3 Wconcat
VARCHAR2(30);
4 Winitcap
VARCHAR2(15);
5 Wtexto
VARCHAR2(20);
6 Wnome
VARCHAR2(20);
7 Wsobrenome
VARCHAR2(20);
8 BEGIN
9
SELECT nm_func, nm_sobrenome
10
INTO Wnome, Wsobrenome
11
FROM func
12
WHERE cd_mat = 200;
13
Wconcat := CONCAT (Wnome, Wsobrenome);
14
Winitcap := INITCAP (Wsobrenome);
15
Wtexto := LOWER(RTRIM(LTRIM(Wnome))) ||
16
' ' || UPPER(Wsobrenome);
17
:msg1 := Wtexto;
18
:msg2 := CONCAT(CONCAT(Wconcat, ' ---- '), Winitcap);
19 END;
20 /
PL/SQL procedure successfully completed.
SQL> PRINT msg1
MSG1
---------------------------------------------------------------------------davi BARBOSA
SQL> PRINT msg2
MSG2
---------------------------------------------------------------------------DAVIBARBOSA ---- Barbosa

FUNES PR-DEFINIDAS - 29

PL/SQL BSICO E AVANADO 7.3

SUBSTR
Retorna uma parte de <c>, comeando no <n> caracter com comprimento <m>.
SINTAXE: SUBSTR(<c>,<n>[,<m>])

TRANSLATE
Retorna <c>,substituindo todas as ocorrncias de <x> por <y>. O relacionamento
entre os caracteres de <x> e <y> posicional. Caso <y> tenha cumprimento inferior a
<x> os caracteres de <x> sem correspondncia sero omitidos do resultado.
SINTAXE: TRANSLATE(<c>,<x>,<y>)

UPPER
Retorna <c> com todas as letras maisculas.
SINTAXE: UPPER(<c>)

FUNES PR-DEFINIDAS - 30

PL/SQL BSICO E AVANADO 7.3


SQL> VARIABLE msg1 CHAR(50)
SQL> VARIABLE msg2 CHAR(50)
SQL> DECLARE
2 Wchr
CHAR(5);
3 Wtexto1
VARCHAR2(20);
4 Wtexto2
VARCHAR2(20);
5 Wnome
VARCHAR2(20);
6 Wsobrenome
VARCHAR2(20);
7 BEGIN
8
SELECT nm_func, nm_sobrenome
9
INTO Wnome, Wsobrenome
10
FROM func
11
WHERE cd_mat = 300;
12
Wtexto1 := TRANSLATE (Wnome,
13
'ABCDEFGHIJKLMNOP', ';*&^%$#@!-_+=)(');
14
Wtexto2 := REPLACE (Wnome, 'EI', 'XK');
15
Wchr := CHR(90);
16
:msg1 := 'TRANSLATE = ' || Wtexto1 || ' REPLACE = ' || Wtexto2;
17
:msg2 := UPPER(Wsobrenome) || - CHR(90) = ' || Wchr;
18 END;
19 /
PL/SQL procedure successfully completed.
SQL> PRINT msg1
MSG1
------------------------------------------------------------------------------TRANSLATE = $%+!% REPLACE = FELIPE
SQL> PRINT msg2
MSG2
------------------------------------------------------------------------------SARAIVA - CHR(90) = Z

FUNES PR-DEFINIDAS - 31

PL/SQL BSICO E AVANADO 7.3

ESCALARES - ALFANUMRICAS RETORNANDO VALORES NUMRICOS


ASCII
Retorna o nmero de seqncia em ASCII correspondente ao caracter <c>.
SINTAXE: ASCII (<c>)

INSTR
Retorna a posio da <m>-sima ocorrncia de <c2> dentro de <c1>, comeando na
posio <n>.
SINTAXE: INSTR(<c1>,<c2>[,<n>[,<m>]])

LENGTH
Retorna o comprimento de <c>.
SINTAXE: LENGTH(<c>)

FUNES PR-DEFINIDAS - 32

PL/SQL BSICO E AVANADO 7.3


SQL> VARIABLE msg VARCHAR2(40)
SQL> DECLARE
2 Wtexto
VARCHAR2(30);
3 Wnome
VARCHAR2(20);
4 Wsobrenome
VARCHAR2(20);
5 Wposicao
PLS_INTEGER;
6 BEGIN
7
SELECT nm_func, nm_sobrenome
8
INTO Wnome, Wsobrenome
9
FROM func
10
WHERE cd_mat = 100;
11
Wtexto := Wnome || ' ' || Wsobrenome;
12
Wposicao := INSTR(Wtexto, ' ');
13
:msg := 'TEXTO = *' || Wtexto || '* POSICAO = ' || Wposicao;
14 END;
15 /
PL/SQL procedure successfully completed.
SQL> PRINT msg
MSG
--------------------------------------------------------------------------------TEXTO = *TEODORO SIQUEIRA* POSICAO = 8

FUNES PR-DEFINIDAS - 33

PL/SQL BSICO E AVANADO 7.3

ESCALARES - DATAS
ADD_MONTHS
Retorna a data <d> adicionada de <n> meses. <n> deve ser um inteiro e pode ser
negativo.
SINTAXE: ADD_MONTHS(<d>,<n>)

LAST_DAY
Retorna a data do ltimo dia do ms de <d>.
SINTAXE: LAST_DAY(<d>)

MONTHS_BETWEEN
Retorna o nmero de meses entre <d> e <e>
SINTAXE: MONTHS_BETWEEN(<d>, <e>)

NEW_TIME
Retorna a data e hora no meridiano <b>, para a data e hora <d> no meridiano <a>.
SINTAXE: NEW_TIME(<d>,<a>,<b>)

ABREVIATURAS PARA MERIDIANOS


AST, ADT...........
GMT...................
PST, PDT...........
YST, YDT...........

Atlantic standard ou Daylight Time


Greenwich
Pacific Sandard ou Daylight Time
Youkon Standard ou Daylight Time.

FUNES PR-DEFINIDAS - 34

PL/SQL BSICO E AVANADO 7.3

NEXT_DAY
Retorna a data do primeiro dia da semana nomeado por <c> que seja posterior a <d>
SINTAXE: NEXT_DAY(<d>,<c>)

ROUND
Retorna <d> arredondado para o formato especificado.
SINTAXE: ROUND(<d>,[,<fmt>])

SYSDATE
Retorna a data e hora correntes
SINTAXE: SYSDATE

FUNES PR-DEFINIDAS - 35

PL/SQL BSICO E AVANADO 7.3

TRUNC
Retorna uma data no formato especificado por <fmt>, representando <d> truncada na
unidade correspondente.
SINTAXE: TRUNC(<d>,<fmt>)

FORMATOS PARA ROUND E TRUNC


CC, SCC..........................................................

Sculo

SYYY, YYYY, YEAR, SYEAR, YYY, YY, Y...... Ano (meio=01/07)


Q......................................................................

Quarto de ano

MONTH, MON, MM..........................................

Ms

WW..................................................................

Dia da semana de incio do ano

W.....................................................................

Dia da semana de incio do ms

DDD, DD, J......................................................

Dia (DEFAULT)

DAY, DY, D......................................................

mais prximo domingo

HH, HH12, HH24..............................................

Hora

MI.....................................................................

Minuto

FUNES PR-DEFINIDAS - 36

PL/SQL BSICO E AVANADO 7.3


SQL> VARIABLE msg1 VARCHAR2(80)
SQL> VARIABLE msg2 VARCHAR2(80)
SQL> DECLARE
2 Whoje
DATE := SYSDATE + 5.23;
3 Wmes
DATE;
4 Wdia
DATE;
5 Wdif
NUMBER;
6 Wsem
DATE;
7 Wround
DATE;
8 BEGIN
9
Wmes := ADD_MONTHS(Whoje, 3);
10
Wdia := LAST_DAY(Whoje);
11
Wdif := MONTHS_BETWEEN(SYSDATE, '01-may-97');
12
Wsem := NEXT_DAY(SYSDATE, 'Monday');
13
Wround := ROUND(SYSDATE, 'Day');
14
:msg1 := TO_CHAR(SYSDATE, 'dd/mm/yy hh24:mi:ss d') ||'#'||
15
TO_CHAR(Whoje, 'dd/mm/yy hh24:mi:ss d') ||'#'||
16
TO_CHAR(Wmes, 'dd/mm/yy hh24:mi:ss d');
17
:msg2 := TO_CHAR(Wdia, 'dd/mm/yy hh24:mi:ss d') ||'#'||
18
TO_CHAR(Wdif, '990.0099') ||'#'||
19
TO_CHAR(Wsem, 'dd/mm/yy hh24:mi:ss d') ||'#'||
20
TO_CHAR(Wround, 'dd/mm/yy hh24:mi:ss d');
21 END;
22 /
PL/SQL procedure successfully completed.
SQL> PRINT MSG1
MSG1
---------------------------------------------------------------------------------09/06/97 11:21:27 2#14/06/97 16:52:39 7#14/09/97 16:52:39 1
SQL> PRINT MSG2
MSG2
----------------------------------------------------------------------------------------------30/06/97 16:52:39 2# 1.2733#16/06/97 11:21:27 2#08/06/97 00:00:00 1

FUNES PR-DEFINIDAS - 37

PL/SQL BSICO E AVANADO 7.3

ESCALARES - CONVERSO
CHARTOROWID
Converte o valor de <c> para rowid.
SINTAXE: CHARTOROWID(<c>)

ROWIDTOCHAR
Converte valores de ROWID para caracteres.
SINTAXE: ROWIDTOCHAR(<rowid>)
ROWID corresponde ao endereo da linha. Esta pseudo-coluna existe em cada tabela
do ORACLE.
composta das seguintes informaes:
nmero do bloco no arquivo de banco de dados.
nmero da linha no bloco (iniciando em zero).
nmero do arquivo (primeiro arquivo 1).

HEXTORAW
Converte uma string hexadecimal do tipo CHAR ou VARCHAR2 para RAW.
SINTAXE: HEXTORAW(<h>)

RAWTOHEX
Converte um valor binrio em uma string hexadecimal do tipo VARCHAR2.
SINTAXE: RAWTOHEX(<bin>)

FUNES PR-DEFINIDAS - 38

PL/SQL BSICO E AVANADO 7.3

TO_CHAR
Converte um valor numrico ou data para o formato especificado.
SINTAXE 1: TO_CHAR(<n> [,<fmt> [,<nls1>]])
SINTAXE 2: TO_CHAR(<d>, [<fmt> [,<nls2>]])
FORMATOS NUMRICOS PARA TO_CHAR E TO_NUMBER
9.........

A quantidade de 9's determina o comprimento

0.........

Completa o comprimento do formato com zero's.

$.........

Prefixa o valor com o smbolo $.

B.........

Substitui o valor 0 por branco.

MI.......

Mostra - aps um valor negativo.

PR......

Mostra um valor negativo entre <>.

,..........

Mostra uma , na posio correspondente.

...........

Mostra um . decimal na posio.

V.........

Multiplica o valor por 10n, onde n corresponde ao nmero de 9s aps v.

E.........

Notao cientifica.

DATE..

Para datas armazenadas em colunas number (ORACLE V.2). Mostra no


formato mm/dd/yy.

FORMATOS DE NLS
NLS_NUMERIC_CHARACTERS = <d><g>,
NLS_CURRENCY = <text>, NLS_ISO_CURRENCY = <text> ........ <nls1>
NLS_DATE_LANGUAGE = <language>.................................................... <nls2>
Onde:
<d>................
<g>................
<text>.............

caracter decimal
separador de milhar
smbolo monetrio

FUNES PR-DEFINIDAS - 39

PL/SQL BSICO E AVANADO 7.3


FORMATOS DE DATA PARA TO_CHAR E TO_DATE
CC, SCC...............................
SYYY ou YYYY ou YYY......
YY ou Y ou Y,YYY................
YEAR, SYEAR .....................
BC ou AD .............................
Q...........................................
MONTH................................
MON.....................................
MM........................................
WW......................................
W..........................................
DDD......................................
DD........................................
D...........................................
DAY......................................
DY........................................
J............................................

Sculo (S prefixa datas BC com um sinal de "-").


Ano
Ano
Ano por extenso
Indicadores BC ou AD.
Quarto de ano
Nome do ms (9 caracteres)
Nome do ms (3 caracteres)
Ms (numrico)
Semana do ano (numrico)
Semana do ms(numrico)
Dia do ano(1-366)
Dia do ms
Dia da semana(1-7)
Nome do dia(9 caracteres)
Nome do dia(3 caracteres)
Dia em data juliana (nmero de dias desde
01/01/4712 BC).
HH, HH12, HH24.................. Hora
MI......................................... Minuto
SS......................................... Segundo
AM/PM.................................. Indicador AM ou PM.
/., ..................................... Incluso de pontuao
"..." ..................................... Incluso de strings no resultado

FUNES PR-DEFINIDAS - 40

PL/SQL BSICO E AVANADO 7.3


SQL> VARIABLE msg1 CHAR(30)
SQL> VARIABLE msg2 CHAR(30)
SQL> DECLARE
2 Wnum
NUMBER;
3 Wdata
DATE;
4 Wsobrenome
VARCHAR2(20);
5 Wposicao
PLS_INTEGER;
6 BEGIN
7
Wdata := SYSDATE;
8
:msg1 := TO_CHAR(Wdata,'DAY',
9
'NLS_DATE_LANGUAGE = PORTUGUESE');
10 Wnum := 123456.89;
11 :msg2 := TO_CHAR(Wnum, 'L999G999D99',
12
'NLS_NUMERIC_CHARACTERS = ,., NLS_CURRENCY = R$');
13 END;
14 /
PL/SQL procedure successfully completed.
SQL> PRINT msg1
MSG1
-------------------------------------------------------------------------------------------------DOMINGO
SQL> PRINT msg2
MSG2
-------------------------------------------------------------------------------------------------R$123.456,89

FUNES PR-DEFINIDAS - 41

PL/SQL BSICO E AVANADO 7.3

TO_DATE
Converte <c> para o formato interno de data.
SINTAXE: TO_DATE(<c>[,<fmt>])

TO_NUMBER
Converte <c> para o valor numrico correspondente.
SINTAXE: TO_NUMBER(<c>)

SQL> VARIABLE msg1 CHAR(80)


SQL> DECLARE
2 Wdata1
DATE;
3 Wdata2
DATE;
4 BEGIN
5
Wdata1 := TO_DATE('14/06/97 10:00:00', 'dd/mm/yy hh24:mi:ss');
6
Wdata2 := TO_DATE('1997-july-15 10:15PM',
7
'yyyy-month-dd hh12:mipm');
8
:msg1 := TO_CHAR(Wdata1, 'dd/mm/yy hh24:mi:ss d') ||'#'||
9
TO_CHAR(Wdata2, 'dd/mm/yy hh24:mi:ss d');
10 END;
11 /
PL/SQL procedure successfully completed.
SQL> PRINT MSG1
MSG1
-----------------------------------------------------------------------------14/06/97 10:00:00 7#15/07/97 22:15:00 3

FUNES PR-DEFINIDAS - 42

PL/SQL BSICO E AVANADO 7.3

ESCALARES - OUTRAS
DECODE
S permitido em comandos SQL.

GREATEST
Retorna a maior <e> da lista de valores. Todas as expresses aps a primeira so
convertidas para o tipo de dado da primeira antes da comparao ser feita
SINTAXE: GREATEST(<e>,[,<e>] ...)

LEAST
Retorna a menor <e> da lista de valores. Todas as expresses aps a primeira so
convertidas para o tipo de dado da primeira antes da comparao ser feita
SINTAXE: LEAST(<e>,[,<e>] ...)

NVL
Se <e1> for NULL, retorna <e2>. Se <e1> no for NULL, retorna <e1>
SINTAXE: NVL(<e1>, <e2>)

UID
Retorna o valor do inteiro associado a cada username pelo Oracle.
SINTAXE: UID

FUNES PR-DEFINIDAS - 43

PL/SQL BSICO E AVANADO 7.3

USER
Retorna o username corrente.
SINTAXE: USER

USERENV
Retorna informaes sobre o user e a sesso.
SINTAXE: USERENV(<option>)
VALORES DE <OPTION>
ENTRYID..........................
SESSIONID......................
TERMINAL........................
LANGUAGE......................

Identificador da entrada
Identificador da sesso
Identificador do terminal
Identificador da linguagem em uso

VSIZE
S permitido em comandos SQL.

FUNES PR-DEFINIDAS - 44

PL/SQL BSICO E AVANADO 7.3


SQL> VARIABLE msg1 VARCHAR2(80)
SQL> DECLARE
2 Wdata1
DATE := TO_DATE('1997-july-15 10:15PM',
3
'yyyy-month-dd hh12:miam');
4 Wdata2
DATE := NULL;
5 Wresult
DATE;
6 Wenv
VARCHAR2(30);
7 Wsize
NUMBER;
8 BEGIN
9
Wresult := NVL(Wdata2, Wdata1);
10
Wenv := USERENV('LANGUAGE') ||'#'||USERENV('SESSIONID');
11
:msg1 := TO_CHAR(Wresult, 'dd/mm/yy hh24:mi:ss d') ||'#'||Wenv;
12 END;
13 /
PL/SQL procedure successfully completed.
SQL> PRINT MSG1
MSG1
----------------------------------------------------------------------------------15/07/97 22:15:00 3#AMERICAN_AMERICA.WE8DEC#29005

FUNES PR-DEFINIDAS - 45

PL/SQL BSICO E AVANADO 7.3

EXEMPLO SIMPLES DE USO DE FUNES EM PL/SQL


Deseja-se converter o cdigo do departamento (da tabela de departamento) de
alfabtico para numrico, substituindo a letra pelo nmero correspondente.
Por exemplo: deA00 para 100, de B01 para 201 e assim por diante.
SQL> DECLARE
2 Wnum
NUMBER;
3 Wdepto
CHAR(03) := '&depto';
4 BEGIN
5 ------- Primeira Soluo
6
IF UPPER(SUBSTR(Wdepto,1,1)) = 'A' THEN
7
Wnum := 100 + TO_NUMBER(SUBSTR(Wdepto,2,2));
8
ELSIF UPPER(SUBSTR(Wdepto,1,1)) = 'B' THEN
9
Wnum := 200 + TO_NUMBER(SUBSTR(Wdepto,2,2));
10
ELSIF UPPER(SUBSTR(Wdepto,1,1)) = 'C' THEN
11
Wnum := 300 + TO_NUMBER(SUBSTR(Wdepto,2,2));
12
ELSIF UPPER(SUBSTR(Wdepto,1,1)) = 'D' THEN
13
Wnum := 400 + TO_NUMBER(SUBSTR(Wdepto,2,2));
14
ELSIF UPPER(SUBSTR(Wdepto,1,1)) = 'E' THEN
15
Wnum := 500 + TO_NUMBER(SUBSTR(Wdepto,2,2));
16
ELSE Wnum := 0;
18
END IF;
19
:msg1 := 'O novo valor ' || TO_CHAR(Wnum);
20 -------- Segunda Soluo
21
Wnum := (ASCII(UPPER(SUBSTR(Wdepto,1,1))) - 64) * 100 +
22
TO_NUMBER(SUBSTR(Wdepto,2,2));
23
:msg2 := 'O novo valor ' || TO_CHAR(Wnum);
24 END;
25 /
Enter value for depto: C03
old 3: Wdepto
CHAR(03) := '&depto';
new 3: Wdepto
CHAR(03) := 'C03';
PL/SQL procedure successfully completed.
SQL> PRINT msg1
MSG1
--------------------------------------------------------------------------O novo valor 303
SQL> PRINT msg2
FUNES PR-DEFINIDAS - 46

PL/SQL BSICO E AVANADO 7.3

CAPTULO 3 : PROCESSAMENTO REPETITIVO


CURSOR
As linguagens convencionais (COBOL, PL/1, ASSEMBLER, etc.) no esto
preparadas para trabalhar com tabelas.
Sabemos, porm, que o resultado de uma operao relacional sempre uma tabela
(de uma ou mais rows).
A fim de solucionar este problema, foi criado um artifcio que permite a manipulao
do resultado de uma consulta.
Este artifcio o cursor. Com ele se torna possvel a obteno de linhas individuais da
tabela resultante.

PROCESSAMENTO REPETITIVO - 47

PL/SQL BSICO E AVANADO 7.3

DECLARE CURSOR
Este comando tem por objetivo definir um cursor e associ-lo a uma tabela (em
memria) ORACLE.

SINTAXE
CURSOR <nome cursor>
[(<parmetro> <tipo> [,<parmetro <tipo>...])]
RETURN <tipo> |
<varivel%TYPE |
<table.column>%TYPE |
<TABLE>%rowtype
IS <comando SELECT>
O cursor com nome especificado criado quando o programa executado. Uma
tabela resultado determinada pelo comando SELECT do cursor.

<SELECT>
O comando SELECT do cursor possui a mesma sintaxe de um comando SELECT
comum. Se a clusula ORDER BY no for especificada, as rows da tabela resultado
sero obtidas em uma ordem arbitrria. Se a clusula FOR UPDATE no for
especificada as rows da tabela resultado no podero ser atualizadas.

FOR UPDATE OF <NOMES DE COLUNAS>


Permite que o cursor seja referenciado no comando UPDATE (a fim de atualizar a row
apontada pelo cursor).

PROCESSAMENTO REPETITIVO - 48

PL/SQL BSICO E AVANADO 7.3

OPEN CURSOR
Este comando abre um cursor para que ele possa ser usado na obteno de rows da
tabela resultado.
SINTAXE
OPEN <nome do cursor> [(<parmetro> [, <parmetro> . . . ])]

<NOME DO CURSOR>
Nomeia um cursor que foi definido em um comando DECLARE CURSOR
anteriormente codificado no programa de aplicao. Quando o comando OPEN for
executado, o cursor deve estar no estado de closed. A tabela resultado de um cursor
derivada da avaliao de um comando SELECT, usando os valores atuais dos
parmetros especificados no mesmo. O comando OPEN CURSOR ativa o conjunto de
rows e aponta o cursor para o incio do conjunto. O cursor posicionado antes da
primeira linha da tabela resultado. Nenhuma linha , na verdade recuperada, neste
ponto, somente a tempo de FETCH.

[(<PARMETRO> [, <PARMETRO> . . . ])]


Indica os valores dos parmetros declarados. A tempo de OPEN estes valores devem
ser fornecidos para que seja possvel a execuo do comando SELECT.

PROCESSAMENTO REPETITIVO - 49

PL/SQL BSICO E AVANADO 7.3

FETCH CURSOR
Posiciona um cursor na prxima linha da tabela resultado e associa os valores da
linha atual s variveis do programa.
SINTAXE
FETCH <nome do cursor> INTO <varivel> [,<varivel> ...]

<NOME DO CURSOR>
Substitua pelo nome de um cursor anteriormente definido e aberto pelo programa de
aplicao. Se o cursor estiver posicionado sobre ou aps a ltima linha da tabela
resultado, o valor da funo SQLCODE atualizado com o valor +100, o cursor
posicionado aps a ltima linha e os valores no so associados s variveis do
programa. Se o cursor est atualmente posicionado antes de uma linha, o cursor
posicionado sobre aquela linha e os valores desta so associados s variveis do
programa especificadas na clusula INTO.

INTO <VARIVEL>
Cada varivel do programa deve identificar uma varivel simples ou ocorrncia que
esteja descrita no programa de aplicao. O nmero de linhas recuperado
determinado pela dimenso das variveis (nmero ocorrncias)

PROCESSAMENTO REPETITIVO - 50

PL/SQL BSICO E AVANADO 7.3

CLOSE CURSOR
Fecha um cursor. Se uma tabela temporria foi criada quando o cursor foi aberto,
ento esta tabela destruda.
SINTAXE
CLOSE <nome do cursor>

<NOME DO CURSOR>
o nome de uma cursor que tenha sido declarado no programa de aplicao. Quando
o comando CLOSE executado, o cursor deve estar no estado OPEN.

PROCESSAMENTO REPETITIVO - 51

PL/SQL BSICO E AVANADO 7.3

UPDATE PARA CURSOR


Seu objetivo atualizar uma linha previamente selecionada.
SINTAXE
UPDATE <nome de tabela / VIEW>
SET <nome de coluna 1> = <expresso 1>
[,<nome de coluna 2> = <expresso 2> . . . ]
WHERE CURRENT OF <nome cursor>

WHERE CURRENT OF <NOME DO CURSOR>


Esta clusula indica que somente a row em uso ser atualizada. Para que este
comando seja executado necessrio que anteriormente tenha sido executado um
comando SELECT em que a clusula FOR UPDATE OF estivesse presente. Somente
as colunas mencionadas no comando SELECT podem agora ser atualizadas no
comando UPDATE.

PROCESSAMENTO REPETITIVO - 52

PL/SQL BSICO E AVANADO 7.3

DELETE PARA CURSOR


Seu objetivo excluir uma linha previamente selecionada.
SINTAXE
DELETE FROM <nome da tabela / VIEW>
WHERE CURRENT OF <nome do cursor>

WHERE CURRENT OF <NOME DO CURSOR>


Esta clusula indica que a linha em uso ser excluda.

PROCESSAMENTO REPETITIVO - 53

PL/SQL BSICO E AVANADO 7.3

ATRIBUTOS PARA CURSOR


Existem 2 tipos de cursores em PL/SQL: implcito e explcito. A PL/SQL implicitamente
declara um cursor para cada comando SQL que manipule dados, inclusive QUERIES
que retornem uma nica linha.

%FOUND
Indica se o ltimo FETCH retornou uma linha ou no, para cursores explcitos. E se
alguma linha foi afetada pelo ltimo comando INSERT, UPDATE ou DELETE para
cursores implcitos.
SINTAXE

<cursor>%FOUND
SQL%FOUND

%NOTFOUND
Indica se o ltimo FETCH retornou uma linha ou no, para cursores explcitos. E se
alguma linha foi afetada pelo ltimo comando INSERT, UPDATE ou DELETE para
cursores implcitos.
SINTAXE

<cursor> %NOTFOUND
SQL %NOTFOUND

PROCESSAMENTO REPETITIVO - 54

PL/SQL BSICO E AVANADO 7.3


%ISOPEN
Permite que se verifique se um cursor est aberto ou no. No caso de cursores
implcitos o resultado ser sempre FALSE, uma vez que o ORACLE fecha o cursor
aps uma operao.
SINTAXE

<cursor> %ISOPEN
SQL %ISOPEN

%ROWCOUNT
Indica o nmero de linhas lidas para o cursor associado (para cursores explcitos) ou
o nmero de linhas afetadas no ltimo comando INSERT, UPDATE, DELETE ou
SELECT (para cursores implcitos). Aps a abertura do cursor, o valor de
ROWCOUNT zero. O nmero s ser incrementado se o ltimo FETCH retornou
uma linha.
SINTAXE

<cursor> %ROWCOUNT
SQL %ROWCOUNT

PROCESSAMENTO REPETITIVO - 55

PL/SQL BSICO E AVANADO 7.3


SQL> DECLARE
2 CURSOR Wc is
3
SELECT CD_DEPTO, NM_FUNC, CD_MAT, VL_SAL FROM FUNC
3
ORDER BY 4 DESC;
4 Wcr_cd_depto FUNC.CD_DEPTO%TYPE;
5 Wcr_nm_func
FUNC.NM_FUNC%TYPE;
6 Wcr_cd_mat
FUNC.CD_MAT%TYPE;
7 Wcr_vl_sal
FUNC.VL_SAL%TYPE;
8 BEGIN
9
OPEN Wc;
10
<<INICIO>>
11
FETCH Wc into Wcr_cd_depto,
12
Wcr_nm_func,
13
Wcr_cd_mat,
14
Wcr_vl_sal;
15
IF Wc%NOTFOUND THEN
16
GOTO fim;
17
END IF;
18
IF Wc%ROWCOUNT > 10 THEN
19
GOTO fim;
20
END IF;
21
INSERT INTO MAIORES (DEPTO, NOME, MAT, SAL)
22
VALUES (Wcr_cd_depto, Wcr_nm_func, Wcr_cd_mat, Wcr_vl_sal);
23
GOTO inicio;
24
<<FIM>>
25
COMMIT;
26 END;
27 /
PL/SQL procedure successfully completed.

PROCESSAMENTO REPETITIVO - 56

PL/SQL BSICO E AVANADO 7.3

TIPO PARA CURSOR


A fim de facilitar a recepo de informaes de linhas de tabelas, a PL/SQL
As variveis PL/SQL e constantes possuem atributos, que so propriedades que
permitem a referncia ao tipo e estrutura do objeto sem necessidade de repetio de
sua definio. As tabelas e colunas do database possuem atributos similares, que
podemos usar para facilitar a manuteno.
%ROWTYPE
Este atributo gera um tipo de registro que representa uma linha da tabela. O tipo pode
armazenar uma linha de dados selecionados da tabela ou recebidos de um cursor
(FETCHED).
SINTAXE

{<tabela> | <cursor>} %ROWTYPE

PROCESSAMENTO REPETITIVO - 57

PL/SQL BSICO E AVANADO 7.3


PROBLEMA PROPOSTO
Criar uma tabela com o layout abaixo para receber a quantidade de funcionrios por
departamento. O cdigo do departamento dever convertido da mesma forma que no
problema anterior.
SQL> CREATE TABLE resultado
2 (cd_depto
NUMBER,
3 qt_func
NUMBER
4 ) STORAGE (INITIAL 2K NEXT 2K MINEXTENTS 1 MAXEXTENTS 3);
Table created.
SQL> DECLARE
2 Wnum
NUMBER;
3 CURSOR Wc is SELECT cd_depto, count(*) total
4
FROM func GROUP BY cd_depto;
5 Wrow
Wc%ROWTYPE;
6 BEGIN
7
OPEN Wc;
8
<<inicio>>
9
FETCH Wc INTO Wrow;
10
IF Wc%NOTFOUND THEN
11
GOTO fim;
12
END IF;
13
Wnum := TRANSLATE (SUBSTR(Wrow.cd_depto,1,1)),
14
'ABCDEFGHIJKLMNOPQRSTUVWXYZ,
15
'12345123451234512345123451') ||
16
SUBSTR(Wrow.cd_depto,2,2);
17
INSERT INTO resultado (cd_depto, qt_func)
18
VALUES (Wnum, Wrow.total);
19
GOTO inicio;
20
<<fim>>
21
COMMIT;
22 END;
23 /
PL/SQL procedure successfully completed.

PROCESSAMENTO REPETITIVO - 58

PL/SQL BSICO E AVANADO 7.3

CURSOR LOOP
Implicitamente declara uma rea para receber a linha da tabela resultante, abre um
cursor, l cada linha e fecha o cursor quando todas as linhas tiverem sido
processadas.
SINTAXE
[<< <label> >>]
FOR <RECORD> IN <CURSOR> [(<parmetro> [,<parmetro>. . . ])] LOOP
<seqncia de comandos>
END LOOP;
EXEMPLO
SQL> DECLARE
2
CURSOR Wc is SELECT DEPTO.cd_depto, nm_depto,
3
SUM(vl_sal) soma, AVG(vl_sal) media
4
FROM func, depto
5
WHERE func.cd_depto = depto.cd_depto
6
GROUP BY DEPTO.cd_depto, nm_depto;
7 BEGIN
8
FOR Wrow in Wc LOOP
9
INSERT INTO tabdep (nome, codigo, salario, media)
10
VALUES (Wrow.nm_depto, Wrow.cd_depto,
11
Wrow.soma, Wrow.media);
11
END LOOP;
12
COMMIT;
13 END;
14 /
PL/SQL procedure successfully completed.

PROCESSAMENTO REPETITIVO - 59

PL/SQL BSICO E AVANADO 7.3

OUTROS COMANDOS PARA PROCESSAMENTO REPETITIVO


EXIT
Encerra um loop.
SINTAXE
EXIT [<LABEL>] [WHEN <condio>]

LOOP
A seqncia de comandos executada um nmero infinito de vezes ou at que seja
encontrado um comando "EXIT" ou a condio de "WHEN" seja satisfeita
SINTAXE
[<< <label> >>]
LOOP
<seqncia de comandos>
END LOOP
LOOP
<seqncia de comandos>
IF .....
THEN
EXIT; -- encerra o loop
END IF;
END LOOP;
LOOP
<seqncia de comandos>
EXIT WHEN -- encerra o loop
END LOOP;

PROCESSAMENTO REPETITIVO - 60

PL/SQL BSICO E AVANADO 7.3


PROBLEMA PROPOSTO
Repetiremos o mesmo problema anterior, substituindo o comando GOTO pelo LOOP.
SQL> CREATE TABLE resultado
2 (cd_depto
NUMBER,
3 qt_func
NUMBER
4 ) STORAGE (INITIAL 2K NEXT 2K MINEXTENTS 1 MAXEXTENTS 3);
Table created.
SQL> DECLARE
2 Wnum
NUMBER;
3 CURSOR Wc is SELECT cd_depto, count(*) total
4 FROM func GROUP BY cd_depto;
5 Wrow
Wc%ROWTYPE;
6 BEGIN
7
OPEN Wc;
8
LOOP
9
FETCH Wc INTO Wrow;
10
IF Wc%NOTFOUND THEN
11
EXIT;
12
END IF;
13
Wnum := TRANSLATE (SUBSTR(Wrow.cd_depto,1,1)),
14
'ABCDEFGHIJKLMNOPQRSTUVWXYZ,
15
'12345123451234512345123451') ||
16
SUBSTR(Wrow.cd_depto,2,2);
17
INSERT INTO resultado (cd_depto, qt_func)
18
VALUES (Wnum, Wrow.total);
17
END LOOP;
18
COMMIT;
19 END;
20 /
PL/SQL procedure successfully completed.

PROCESSAMENTO REPETITIVO - 61

PL/SQL BSICO E AVANADO 7.3

WHILE LOOP
A seqncia de comandos executada enquanto a condio for verdadeira. Antes de
cada iterao do loop, a condio avaliada. Se for verdadeira, a seqncia de
comandos executada.
SINTAXE
[<< <label> >>]
WHILE <condio> LOOP
<seqncia de comandos>
END LOOP;

PROCESSAMENTO REPETITIVO - 62

PL/SQL BSICO E AVANADO 7.3


PROBLEMA PROPOSTO
Preencher a tabela TABDEP (nome, codigo, salario, media) com os valores abaixo na
tabela de departamentos:
nome............
codigo...........
salario...........
media............

nome do departamento
codigo do departamento
somatrio dos salrios do departamento correspondente
mdia salarial do departamento correspondente

SQL> CREATE TABLE tabdep


2 (nome
VARCHAR2(50),
3 codigo
CHAR(03),
4 salario
NUMBER(12,2),
5 media
NUMBER(12,2)
6 )
7 STORAGE (INITIAL 2K NEXT 2K MINEXTENTS 1 MAXEXTENTS 3)
8 /
Table created.
SQL> DECLARE
2 CURSOR Wc is SELECT depto.cd_depto, nm_depto,
3
SUM(vl_sal) soma, AVG(vl_sal) media FROM func, depto
4
WHERE func.cd_depto = depto.cd_depto
5
GROUP BY depto.cd_depto, nm_depto;
6 Wrow
Wc%ROWTYPE;
7 BEGIN
8
OPEN Wc;
9
FETCH Wc INTO Wrow;
10
WHILE Wc%FOUND LOOP
11
INSERT INTO tabdep (nome, codigo, salario, media)
12
VALUES (Wrow.nm_depto, Wrow.cd_depto,
13
Wrow.soma, Wrow.media);
14
FETCH Wc INTO Wrow;
15
END LOOP;
16
COMMIT;
17 END;
18 /
PL/SQL procedure successfully completed.

PROCESSAMENTO REPETITIVO - 63

PL/SQL BSICO E AVANADO 7.3

FOR LOOP
A seqncia de comandos executada um nmero fixo de vezes estabelecido no
comando. No incio do comando a quantidade de vezes que o mesmo ser executado
j conhecida, uma vez que no se pode alterar o valor de <contador> durante a
iterao.
OBS: O <contador> declarado no prprio comando.
SINTAXE
[<< <label> >>]
FOR <contador> IN [REVERSE] <inferior>..<superior> LOOP
<seqncia de comandos>
END LOOP;
SQL> DECLARE
2 Wvezes
NUMBER := 0;
3 Werro
NUMBER := 0;
4 BEGIN
5
FOR i IN 1..3 LOOP
-- <seqncia de comandos>
6
Wvezes := i + 1;
-- executada 3 vezes
7
END LOOP;
-- o comando Werro invlido, pois i s
8
Werro := i + 1;
-- existe no escopo do comando FOR
9 END;
10 /
Werro := i + 1;
-- existe no escopo do comando FOR
*
ERROR at line 8:
ORA-06550: line 8, column 12:
PLS-00201: identifier 'I' must be declared
ORA-06550: line 8, column 3:
PL/SQL: Statement ignored

PROCESSAMENTO REPETITIVO - 64

PL/SQL BSICO E AVANADO 7.3

SQL> DECLARE
2 Wvezes
NUMBER := 0;
3 Werro
NUMBER := 0;
4 Winicio
NUMBER := 1;
5 Wfim
NUMBER := 4;
6 BEGIN
7
FOR i IN Winicio..Wfim LOOP
-- <seqncia de comandos>
8
Wvezes := Wvezes + 1;
-- executada n vezes dependendo
9
END LOOP;
-- do valor de incio e fim
10 -11
FOR i IN 3..Winicio LOOP
-- <seqncia de comandos>
12
Wvezes := 100;
-- no ser executada
13
END LOOP;
14
:msg := 'Wvezes = ' || TO_CHAR(Wvezes);
15 END;
16 /
PL/SQL procedure successfully completed.
SQL> PRINT msg
MSG
-----------------------------------------------------------------------Wvezes = 4

PROCESSAMENTO REPETITIVO - 65

PL/SQL BSICO E AVANADO 7.3


SQL> DECLARE
2 Wvezes
NUMBER := 0;
3 Werro
NUMBER := 0;
4 Wexterno
NUMBER := 0;
5 Winterno
NUMBER := 0;
6 Winicio
NUMBER := 1;
7 Wfim
NUMBER := 4;
8 BEGIN
9
FOR i IN REVERSE 1..3 LOOP
-- <seqncia de comandos>
10
Wvezes := Wvezes + 1;
-- ser executada 3 vezes
11
END LOOP;
-- i ter o valor inicial de 3
12
<<externo>>
13
FOR i IN 1..4 LOOP
-- no exemplo foram criadas
14
Wexterno := Wexterno + 1;
-- duas variveis i
15
<<interno>>
16
FOR i IN 2..10 LOOP
-- a referncia a cada varivel
17
Winterno := Winterno + 1;
-- externo feita atravs do label
18
EXIT externo WHEN externo.i = interno.i;
19
END LOOP interno;
-- esta forma de interrupo
20
END LOOP externo;
-- encerra os dois nveis de loops
21
:msg := 'Wvezes = ' || Wvezes ||' Wexterno = ' || TO_CHAR(Wexterno);
22 END;
23 /
PL/SQL procedure successfully completed.
SQL> PRINT msg
MSG
-----------------------------------------------------------------------------------------Wvezes = 3 Wexterno = 2

PROCESSAMENTO REPETITIVO - 66

PL/SQL BSICO E AVANADO 7.3

CAPTULO 4 : TRATAMENTO DE ERROS EM PL/SQL


Em PL/SQL uma WARNING ou ERROR CONDITION chamada uma EXCEPTION.
Existem algumas excees j definidas pelo ORACLE com mnemnicos para
referncia.
Para as demais, podem ser dados nome pelo usurio, como veremos neste captulo.
Quando ocorre um erro, uma EXCEPTION setada, isto , a seqncia de execuo
do programa interrompida e o controle transferido para a rea de tratamento de
exceo do programa.
As excees pr-definidas pelo ORACLE so setadas quando a condio de erro
ocorre. As excees criadas pelo programa devero ser setadas explicitamente pelo
verbo RAISE.
DECLARE
<declaraes>.............
BEGIN
<lgica>......................
EXCEPTION
<erros>.......................
END;

opcional
obrigatria
opcional

TRATAMENTO DE ERROS EM PL/SQL - 67

PL/SQL BSICO E AVANADO 7.3

EXCEES PR-DEFINIDAS
NOME DA EXCEO

ORACLE SQLCODE
CONDIO DE ERRO
ERROR
-6511 causada se for executado
CURSOR_ALREADY_OPEN ORA-06511
um OPEN para um cursor j
aberto.
ORA-00001
-1 causada se for tentada
DUP_VAL_ON_INDEX
uma incluso de uma coluna
com valor duplicado em
uma tabela que possui um
ndice nico nesta coluna.
ORA-01001
-1001 causada se for feita uma
INVALID_CURSOR
operao ilegal com um
cursor.
Por
exemplo:
CLOSE em um cursor no
aberto.
ORA-01722
-1722
causada se algum
INVALID_NUMBER
comando SQL tentou uma
converso de uma string
para
nmero
e
esta
converso falha porque a
string no representa um
nmero.
ORA-01017
-1017 causada se for feita uma
LOGIN_DENIED
tentativa de logon com um
username/password
invlido.
ORA-01403
+100 causada se num SELECT
NO_DATA_FOUND
INTO nenhuma row foi
retornada ou se foi feita uma
referncia a uma row no
inicializada em uma tabela
PL/SQL.
ORA-01012
-1012 causada se um programa
NOT_LOGGED_ON
PL/SQL tenta fazer acesso
ao database sem efetuar um
logon.

TRATAMENTO DE ERROS EM PL/SQL - 68

PL/SQL BSICO E AVANADO 7.3


NOME DA EXCEO

ORACLE SQLCODE CONDIO DE ERRO


ERROR
ORA-06501
-6501 causada se ocorrer um
PROGRAM_ERROR
problema interno.
ORA-06500
-6500 causada se PL/SQL sai
STORAGE_ERROR
da memria ou se a
memria
estiver
corrompida.
-51 causada se ocorrer
TIMEOUT_ON_RESOURCE ORA-00051
timeout enquanto o Oracle
estiver aguardando por
um recurso.
ORA-01422
-1422
causada
se
um
TOO_MANY_ROWS
comando SELECT INTO
retornar mais que uma
row.
-61 causada quando a parte
TRANSACTION_BACKED_OU ORA-00061
remota de uma transao
T

desmanchada.
A
transao local deve ser
desmanchada tambm.
ORA-06502
-6502 causada se uma
VALUE_ERROR
operao
aritmtica,
converso,
constraint
error, truncation ocorrer.
ORA-01476
-1476 causada se houver
ZERO_DIVIDE
ocorrido uma diviso por
zero.

TRATAMENTO DE ERROS EM PL/SQL - 69

PL/SQL BSICO E AVANADO 7.3

DEFININDO UMA EXCEPTION


Nomeia uma exceo definida pelo usurio.
SINTAXE
<nome da exceo> EXCEPTION

CAUSANDO UMA EXCEPTION CRIADA PELO USURIO


A PL/SQL permite que sejam definidas excees dentro de um programa. Este tipo de
exceo deve ser setada explicitamente pelo verbo RAISE.

RAISE
Causa uma exceo.

SINTAXE
RAISE <exceo>

TRATAMENTO DE ERROS EM PL/SQL - 70

PL/SQL BSICO E AVANADO 7.3


PROBLEMA PROPOSTO
Fazer um programa para crtica de dados informados atravs de parmetros :
salrio deve estar entre R$1500 e R$2000 mensais.
departamento deve existir na tabela de departamentos
SQL> DECLARE
2 w_salario
NUMBER(7,2) := &sal;
3 w_depto
CHAR(3) := UPPER('&depto');
4 w_nome
CHAR(8) := UPPER('&nome');
5 e_salario
EXCEPTION;
6 w_aux
NUMBER(3) := 0;
7 BEGIN
8
IF w_salario < 1500 OR w_salario > 2000 THEN
9
RAISE e_salario;
10
END IF;
11
SELECT 0 INTO w_aux FROM depto
12
WHERE cd_depto = w_depto;
13
SELECT MAX(cd_mat) INTO w_aux FROM func;
14
INSERT INTO func (cd_mat, vl_sal, cd_depto, nm_func)
16
VALUES (w_aux + 1, w_salario , w_depto, w_nome);
17 EXCEPTION
18
WHEN NO_DATA_FOUND THEN
19
:MSG := 'DEPARTAMENTO INVALIDO';
20
WHEN e_salario THEN
21
:MSG := 'SALARIO INVALIDO';
22
WHEN OTHERS THEN
23
:MSG := SQLERRM(SQLCODE);
24 END;
25 /

Obs.: O desvio de execuo do programa transferido para a exceo OTHERS


quando o erro ocorrido no foi tratado em outras excees mais especficas.

TRATAMENTO DE ERROS EM PL/SQL - 71

PL/SQL BSICO E AVANADO 7.3

PRAGMA EXCEPTION_INIT
Associa um nome de exceo com um nmero de SQLCODE. Isto permite que se
faam testes de erro mais especficos em vez de se usar OTHERS.
SINTAXE
PRAGMA EXCEPTION_INIT (<nome da exceo>, <nmero>)
EXEMPLO
SQL> DECLARE
2 sem_privilegio EXCEPTION;
3 PRAGMA EXCEPTION_INIT (sem_privilegio, -1031);
4 BEGIN
...
20 EXCEPTION
21
WHEN sem_privilegio THEN
...
30 END;
31 /

Obs: O Oracle retorna o erro -1031 se, por exemplo, for feita uma tentativa de alterar
uma tabela em que o usurio s tem autorizao de SELECT

TRATAMENTO DE ERROS EM PL/SQL - 72

PL/SQL BSICO E AVANADO 7.3

RAISE_APPLICATION_ERROR
uma PROCEDURE que permite ao usurio enviar mensagens de um subprograma
ou DATABASE TRIGGER.

SINTAXE
RAISE_APPLICATION_ERROR (<nmero>, <mensagem>);
Onde:
<nmero> - pode variar de -20000 a -20999
<mensagem> - pode possuir at 512 bytes de comprimento.

TRATAMENTO DE ERROS EM PL/SQL - 73

PL/SQL BSICO E AVANADO 7.3

PROPAGAO DA EXCEO
Quando uma exceo causada, se a PL/SQL no encontrar um tratamento para ela
no bloco corrente ou subprograma, a exceo se propaga.
Ou seja, a exceo se reproduz no bloco externo e assim por diante at que a PL/SQL
retorne um erro para o ambiente (abortando o programa).
SQL>DECLARE
2 Wx
NUMBER := &x;
3 a
EXCEPTION;
4 b
EXCEPTION;
5 c
EXCEPTION;
6 BEGIN
7
:msg := 'Inicio ';
8
BEGIN
9
IF Wx = 1 THEN
10
RAISE A;
11
ELSIF Wx = 2 THEN
12
RAISE B;
13
ELSE RAISE C;
14
END IF;
15
EXCEPTION
16
WHEN A THEN
17
:msg := :msg || '- executou when A';
18
END;
19
:msg := :msg || '- seguiu programa';
20 EXCEPTION
21
WHEN B THEN
22
:msg := :msg || '- executou when B';
23 END;
24 /

A exceo A tratada no bloco mais interno. Aps seu tratamento o programa


continua normalmente.
A exceo B se propaga para o bloco mais externo, tratada e o programa termina
normalmente.
A exceo C se propaga para o bloco mais externo, no tratada e o erro passa para
o ambiente, isto , o programa abortado.

TRATAMENTO DE ERROS EM PL/SQL - 74

PL/SQL BSICO E AVANADO 7.3

CAPTULO 5 TABELAS E REGISTROS EM PL/SQL


Em PL/SQL podemos criar reas de memria complexas, formadas por reas de
repetio ou reas estruturadas.

TABLE
Tabelas PL/SQL podem ter somente uma coluna e uma primary key, nenhuma das
quais nomeadas. A declarao cria um tipo de varivel. Deve ser feita uma declarao
de varivel com o tipo criado posteriormente para uso.
SINTAXE
TYPE <nome> IS TABLE OF
{<tipo coluna> | <tabela>.<coluna>%TYPE |
<tabela> %ROWTYPE | <record> }
[NOT NULL] INDEX BY BINARY_INTEGER
EXEMPLOS
1. Definir uma tabela com cada posio de tamanho NUMBER(10).
SQL> DECLARE
2
TYPE arr_num IS TABLE OF NUMBER(10)
3
INDEX BY BINARY_INTEGER;
4 BEGIN
NUMBER(10)

NUMBER(10)

NUMBER(10)

NUMBER(10)

2. Definir uma tabela com cada posio correspondente ao layout da tabela FUNC.
SQL> DECLARE
2
TYPE arr_func IS TABLE OF func%ROWTYPE
3
INDEX BY BINARY_INTEGER;
4 BEGIN

TABELAS E REGISTROS EM PL/SQL - 75

PL/SQL BSICO E AVANADO 7.3

SQL> VARIABLE msg VARCHAR2(60)


SQL> DECLARE
2 TYPE tipotab IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
3 fibo
tipotab;
4 Wtotal
PLS_INTEGER := 2;
5 BEGIN
6
fibo(1) := 1;
7
fibo(2) := 1;
8
FOR i IN 3..30 LOOP
9
fibo(i) := fibo (i-2) + fibo(i-1);
10
Wtotal := Wtotal + fibo(i);
11
END LOOP;
12
:msg := 'O somatrio dos 30 primeiros termos ' || TO_CHAR(Wtotal);
13 END;
14 /
PL/SQL procedure successfully completed.
SQL> PRINT msg
MSG
--------------------------------------------------------------------------O somatrio dos 30 primeiros termos 2178308

TABELAS E REGISTROS EM PL/SQL - 76

PL/SQL BSICO E AVANADO 7.3

RECORD
Permite a criao de uma rea estruturada.
SINTAXE
TYPE <nome> IS RECORD
(<campo1>{<tipo campo>|<tabela>.<coluna>%TYPE}[NOT NULL],
<campo2>{<tipo campo>|<tabela>.<coluna>%TYPE}[NOT NULL]...)

SQL> DECLARE
2 TYPE tiporeg IS RECORD
3 (nome
VARCHAR2(40),
4
depto
VARCHAR2(40));
5 Wreg tiporeg;
6 BEGIN
7
SELECT LTRIM(RTRIM(nm_func)) || ' ' ||
8
LTRIM(RTRIM(nm_sobrenome)), nm_depto
9
INTO Wreg
10
FROM func, depto
11
WHERE func.cd_depto = depto.cd_depto
12
AND func.cd_mat = &mat;
13
:msg := Wreg.depto || ' - ' || Wreg.nome;
14 END;
15 /
Enter value for mat: 120
old 12:
AND func.cd_mat = &mat;
new 12:
AND func.cd_mat = 120;
PL/SQL procedure successfully completed.
SQL> PRINT msg
MSG
--------------------------------------------------------------------------DIRETORIA - SILVIO OLIVA

TABELAS E REGISTROS EM PL/SQL - 77

PL/SQL BSICO E AVANADO 7.3

ATRIBUTOS DE UMA TABELA PL/SQL


EXISTS (N)
Retorna TRUE se o ensimo elemento em uma tabela PL/SQL existe.
OBS.: O teste de existncia controla o recebimento da exceo NO_DATA_FOUND,
que adquirido quando fazemos referncia a um elemento inexistente.

COUNT
Retorna o nmero de elementos que uma tabela PL/SQL possui.

FIRST E LAST
Retorna o primeiro (menor) e o ltimo (maior) nmero de ndice de uma tabela
PL/SQL. Se a tabela estiver vazia, FIRST e LAST retornam NULL. Se a tabela contiver
um nico elemento, FIRST E LAST retornam o mesmo ndice.

PRIOR(N) E NEXT(N)
Retorna o ndice que precede o ndice n, no caso de PIOR e o seguinte, no caso de
NEXT.

DELETE, DELETE(N) E DELETE(M,N)


O formato DELETE remove todos os elementos de uma tabela PL/SQL. DELETE(n)
remove o ensimo elemento e DELETE (m,n) remove todos os elementos no intervalo
m...n. Se m for maior que n ou se m ou n forem null, DELETE no tem efeito.
OBS.: A quantidade de memria alocada por uma tabela PL/SQL pode aumentar ou
diminuir dinamicamente. Conforme os elementos vo sendo removidos, a memria vai
sendo liberada (pgina por pgina).

TABELAS E REGISTROS EM PL/SQL - 78

PL/SQL BSICO E AVANADO 7.3

SQL> DECLARE
2 CURSOR WC is SELECT * FROM func ORDER BY vl_sal;
3 ---- Declarao de Tipos
4 TYPE tipofunc IS TABLE OF func%ROWTYPE
5
INDEX BY BINARY_INTEGER;
6 TYPE registro IS RECORD
7
( salario
number);
8 TYPE tabsal IS TABLE OF registro
9
INDEX BY BINARY_INTEGER;
10 --- Declarao de variveis
11 Wsal
tabsal;
12 Wfunc
tipofunc;
13 Wlinha
func%ROWTYPE;
14 Wvezes
NUMBER := &n;
15 Wtotal
NUMBER := 0;
16 BEGIN
17
OPEN wc;
18
FETCH wc INTO wlinha;
19
WHILE Wvezes > 0 and wc%FOUND LOOP
20
Wfunc(wlinha.cd_mat) := Wlinha;
21
Wvezes := Wvezes - 1;
22
FETCH wc INTO wlinha;
23
END LOOP;
24
FOR i in 1..999 LOOP
25
IF Wfunc.EXISTS(i) THEN
26
Wtotal := Wtotal + Wfunc(i).vl_sal;
27
END IF;
28
END LOOP;
29
:msg := 'Valor Total = ' || Wtotal;
30 END ;
31 /
Enter value for n: 10
old 14: Wvezes
NUMBER := &n;
new 14: Wvezes
NUMBER := 10;
PL/SQL procedure successfully completed.

TABELAS E REGISTROS EM PL/SQL - 79

PL/SQL BSICO E AVANADO 7.3

CAPTULO 6 : SUBPROGRAMAS EM PL/SQL


Subprogramas so blocos PL/SQL com nome, que podem receber parmetros e ser
invocados.
A PL/SQL possui dois tipos de subprogramas chamados PROCEDURES e
FUNCTIONS.
Geralmente usa-se uma PROCEDURE para executar uma ao e uma funo
para calcular um valor.
Da mesma forma que qualquer outro bloco (annimo) PL/SQL, os subprogramas
possuem uma parte declarativa, uma parte executvel e uma parte opcional para
tratamento de erro.
Os subprogramas podem ser definidos em qualquer ferramenta ORACLE que suporte
PL/SQL.
Os subprogramas devem ser declarados no fim da parte declarativa, aps todos os
outros objetos do programa.
EXEMPLO
SQL> DECLARE
2
w_vl_lim
NUMBER(15,2) := &1;
...
5
PROCEDURE calc_ir (val_ir OUT NUMBER) IS
6
BEGIN
...
9
END calc_ir;
10
FUNCTION calc_inss (val_sal IN NUMBER) RETURN NUMBER IS
11
val_inss
NUMBER(15,2);
12
BEGIN
...
13
RETURN val_inss;
14
END calc_inss;
15 BEGIN
...
21 END;
22 /

SUBPROGRAMAS EM PL/SQL - 80

PL/SQL BSICO E AVANADO 7.3

PROCEDURES
As procedures so subprogramas que executam uma ao especfica.
SINTAXE
PROCEDURE <nome da procedure> [(<parmetro>[,<parmetro>,.])] IS
[<variveis locais>]
BEGIN
<comandos>
[EXCEPTION
<tratamento das excees>]
END [<nome da procedure>];
Onde parmetro possui a seguinte sintaxe:
<nome da varivel> [ IN | OUT | IN OUT] <tipo> [{ := | DEFAULT} <valor>]
OBS.: Quando [IN | OUT ...] no for especificado, ser assumido IN.
Na especificao de <tipo> no deve ser informado tamanho.
EXEMPLO
SQL> DECLARE
...
2
PROCEDURE calc_ir (val_sal IN NUMBER, val_ir OUT NUMBER) IS
3
BEGIN
4
IF val_sal < 300.00 THEN
5
val_ir := 0;
6
ELSIF val_sal BETWEEN 300.01 AND 1000.00 THEN
7
val_ir := val_sal * .10;
8
ELSIF val_sal BETWEEN 1000.01 AND 3000.00 THEN
9
val_ir := val_sal * .20;
10
ELSE
11
val_ir := val_sal * .30;
12
END IF;
13
END calc_ir;
14 BEGIN
...
20 END;
21 /

SUBPROGRAMAS EM PL/SQL - 81

PL/SQL BSICO E AVANADO 7.3

FUNCTIONS
Uma funo um subprograma que calcula um valor. Funes e procedures so
estruturalmente iguais, exceto que funes possuem uma clusula RETURN que
especifica o tipo de retorno da funo.
SINTAXE
FUNCTION <nome da funo> [(<parmetro>[,<parmetro>,...])]
RETURN <tipo da funo> IS
[<variveis locais>]
BEGIN
<comandos>
[EXCEPTION
<tratamento das excees>]
END <nome da funo>];
Onde parmetro possui a seguinte sintaxe:
<nome da varivel> [ IN | OUT | IN OUT] <tipo> [{ := | DEFAULT} <valor>]
OBS.: Quando [IN | OUT ...] no for especificado, ser assumido IN.
SQL> DECLARE
...
5
FUNCTION calc_inss (val_sal IN NUMBER, val_lim IN NUMBER)
6
RETURN NUMBER IS
7
val_inss
NUMBER(15,2);
8
BEGIN
9
val_inss := val_sal * .08;
10
IF val_inss > val_lim THEN
11
val_inss := val_lim;
12
END IF;
13
RETURN val_inss;
14
END calc_inss;
15 BEGIN
...
20 END;
21 /

SUBPROGRAMAS EM PL/SQL - 82

PL/SQL BSICO E AVANADO 7.3

DECLARAES FORWARD
A PL/SQL exige que se declare um subprograma antes de us-lo. No caso de
recursividade, porm isto no possvel.
A PL/SQL resolve este problema com uma declarao FORWARD. Esta declarao
pode ser usada para :
definir subprogramas em ordem alfabtica
definir subprogramas recursivos
grupar subprogramas dentro de PACKAGES
Uma declarao FORWARD consiste de uma declarao de subprograma terminada
por ;.
SQL> DECLARE
2 w_vl_lim
NUMBER(15,2) := &1;
...
6
PROCEDURE proc (salario IN NUMBER);
-- declarao forward
7
FUNCTION teste RETURN NUMBER;
-- declarao forward
8
FUNCTION calc_inss (val_sal IN NUMBER,val_lim IN NUMBER)
9
RETURN NUMBER IS
10
val_inss
NUMBER(15,2);
11
BEGIN
...
18
RETURN val_inss;
19
END calc_inss;
20
FUNCTION teste RETURN NUMBER IS
21
Waux
NUMBER;
22
BEGIN
...
25
END teste;
26
PROCEDURE proc (salario IN NUMBER) IS
27
BEGIN
...
33
END proc;
34 BEGIN
...
35 END;
36 /

SUBPROGRAMAS EM PL/SQL - 83

PL/SQL BSICO E AVANADO 7.3

STORED SUBPROGRAMS
No ORACLE possvel armazenar um subprograma PL/SQL na base de dados aps
a compilao.

VANTAGENS
PRODUTIVIDADE Vrios programas podem fazer uso de rotinas previamente
gravadas na base de dados, diminuindo a redundncia de
codificao.
PERFORMANCE

Subprogramas podem reduzir a necessidade de calls nas


aplicaes. Por exemplo, para executar 10 comandos SQL
individuais, 10 calls so necessrios, porm para executar um
subprograma contendo dez comandos SQL, apenas um call
necessrio.

MEMRIA

Subprogramas tem a vantagem de compartilhar memria. Ou


seja, somente uma cpia de um subprograma necessita ser
carregada na memria para execuo por mltiplos usurios.

INTEGRIDADE

A utilizao de librarys diminui a possibilidade de erros na


codificao de rotinas de consistncia, uma vez que s h a
necessidade de se efetuar a validao da rotina uma vez e ela
poder ser usada por qualquer nmero de aplicaes.

SEGURANA

Pode haver uma aumento na segurana, uma vez que o DBA


pode restringir o acesso a determinadas operaes,
fornecendo autorizao somente atravs de subprogramas.

SUBPROGRAMAS EM PL/SQL - 84

PL/SQL BSICO E AVANADO 7.3

CHAMADAS DE UM STORED SUBPROGRAM


LOCAL

SINTAXE

De outro
subprograma

<nome da procedure> (<parmetro> . . . );

De um programa
de aplicao
(HOST)

EXEC SQL
EXECUTE BEGIN
<nome da procedure> (<parmetro> . . .);
END;
END-EXEC;

No SQL*PLUS

EXECUTE <nome da procedure> (<parmetro> . . . );

No PL/SQL

BEGIN <nome da procedure> (<parmetro> . . .); END;

SUBPROGRAMAS EM PL/SQL - 85

PL/SQL BSICO E AVANADO 7.3

CRIANDO UM STORED SUBPROGRAM


SINTAXE
CREATE [OR REPLACE]
PROCEDURE <nome da procedure>[(<parmetro>[,<parmetro>,...])] AS/IS
[<variveis locais>]
BEGIN
<comandos>
[EXCEPTION
<tratamento das excees>]
END [<nome da procedure>];

CREATE [OR REPLACE]


FUNCTION <nome da funo> [(<parmetro>[,<parmetro>,...])]
RETURN <tipo da funo> AS/IS
[<variveis locais>]
BEGIN
<comandos>
[EXCEPTION
<tratamento das excees>]
END [<nome da funo>];
A sintaxe semelhante de um SUBPROGRAM definido dentro de um programa
PL/SQL.
Posteriormente criao do stored subprogram podemos fazer referncia a ela
nos programas de aplicao.

SUBPROGRAMAS EM PL/SQL - 86

PL/SQL BSICO E AVANADO 7.3


UTILIZAO
A utilizao de uma funo criada na base de dados pode ser referenciada em
comandos SQL.
SQL> CREATE FUNCTION nova_data(pdata IN DATE) RETURN CHAR IS
2 BEGIN
3
RETURN (TO_CHAR (pdata,'DD/MM/YYYY HH24:Mi'));
4 END;
5 /
Function created.

SQL> COL nasc FOR A20


SQL> COL adm FOR A20
SQL> SELECT nova_data(dt_nasc) NASC, nova_data(dt_adm) ADM
2 FROM func
3 WHERE ROWNUM < 5;
NASC
-------------------14/08/1953 00:00
02/02/1968 00:00
11/05/1961 00:00
15/09/1955 00:00

ADM
-------------------01/01/1995 00:00
01/10/1993 00:00
05/04/1995 00:00
17/08/1989 00:00

SUBPROGRAMAS EM PL/SQL - 87

PL/SQL BSICO E AVANADO 7.3

DEPENDNCIA REMOTA
Normalmente o ORACLE usa somente o TIMESTAMP para gerenciar dependncias
remotas das bibliotecas de PL/SQL, isto , PACKAGES e programas armazenados na
base.
Quando uma unidade de programa recompilada, o ORACLE associa o TIMESTAMP
do servidor a ela.
A tempo de execuo os subprogramas dependentes em um ambiente cliente ou em
outro servidor so invlidos porque seu TIMESTAMP anterior ao da rotina chamada.
Frequentemente, porm a recompilao no era realmente necessria uma vez que a
parte da especificao (ou seja os parmetros passados) no havia sido modificada.
Agora, o ORACLE pode usar TIMESTAMPS ou SIGNATURES para gerenciar
dependncias remotas.
Quando o ORACLE usa o SIGNATURE (que inclui o nome do programa, nmero, tipo
e modo dos parmetros) de uma unidade de programa remoto, os subprogramas
dependentes sero invlidos somente se a SIGNATURE ou especificao da unidade
foi alterada. Assim, subprogramas dependentes so recompilados somente quando
necessrio.
Para que o ORACLE use SIGNATURE em vez de TIMESTAMP devemos setar o
seguinte parmetro no arquivo de inicializao do ORACLE (INIT.ORA):
REMOTE_DEPENDENCIES_MODE = SIGNATURE
Podemos alterar o parmetro dinamicamente:
ALTER SESSION
SET REMOTE_DEPENDENCIES_MODE = TIMESTAMP

SUBPROGRAMAS EM PL/SQL - 88

PL/SQL BSICO E AVANADO 7.3

USO DE TABELAS PL/SQL COMO PARMETRO DE SUBPROGRAMAS


Uma tabela PL/SQL pode ser usada como retorno de uma funo.
USANDO UMA TABELA LOCAL PARA RECEPO DO PARMETRO
O programa principal deve declarar uma tabela local para que todo o resultado da
funo possa ser retornado e, ento, utilizar os elementos desejados da tabela local.
SQL> DECLARE
2
TYPE tabcargo IS TABLE OF func.nr_cargo% type
3
INDEX BY BINARY_INTEGER;
4
cargo
tabcargo;
5
nr_cargo
func.nr_cargo%type;
6
FUNCTION novo_cargo RETURN tabcargo IS
7
tabnovocargo
tabcargo;
8
BEGIN
...
15
RETURN tabnovocargo;
16
END;
17 BEGIN
...
25
cargo:= novo_cargo;
26
nr_cargo:= cargo(1);
...
35 END;
36 /

SUBPROGRAMAS EM PL/SQL - 89

PL/SQL BSICO E AVANADO 7.3


FAZENDO REFERNCIA DIRETA A UM ELEMENTO DA TABELA
Para fazermos referncia a um elemento da tabela PL/SQL devemos usar o
indexador.
SQL> DECLARE
2
TYPE tabsal IS TABLE OF func.vl_sal%TYPE
3
INDEX BY BINARY_INTEGER;
4
salario
REAL;
5
FUNCTION PROMOCAO (max_sal REAL) RETURN tabsal IS
6
sal_tab
tabsal;
7
BEGIN
...
12
RETURN saltab;
13
END;
14 BEGIN
15
salario:= promocao(500)(3);
...
25 END;
Da mesma forma, nas funes que retornam um registro PL/SQL, podemos fazer
referncia direta a um elemento do registro.
SQL> DECLARE
2
TYPE tabdep IS TABLE OF depto%ROWTYPE
3
INDEX BY BINARY_INTERGER;
4
FUNCTION NewDepto (MaxNum INTEGER) RETURN tabdep IS
5
RegDepto
tabdep;
6
BEGIN
...
10
RETURN RegDepto;
11
END;
12 BEGIN
...
13
IF NewDepto (90) (3).cd_depto=C01 then
...
20 END;
OBS: Como restrio s duas formas de uso acima temos que ela no pode ser
usada para uma funo que no tenha parmetros, uma vez que em PL/SQL no
podemos usar uma lista de parmetros vazia: funo( ) (indice) invlido.

SUBPROGRAMAS EM PL/SQL - 90

PL/SQL BSICO E AVANADO 7.3

CAPTULO 7 : TRIGGERS E PACKAGES


DATABASE TRIGGERS
Um DATABASE TRIGGER um programa PL/SQL armazenado em um banco
ORACLE, associado com uma tabela especfica.
O ORACLE ir executar o DATABASE TRIGGER automaticamente quando uma
determinada operao SQL afetar a tabela.

OBJETIVO
Podemos usar um DATABASE TRIGGER para:

Logar modificaes
Garantir crticas complexas
Gerar o valor de colunas
Implementar nveis de segurana mais complexos
Manter tabelas duplicadas

CARACTERSTICAS
Podemos associar at 12 DATABASE TRIGGERS a cada tabela, um de cada tipo:

BEFORE UPDATE <row>


BEFORE DELETE <row>
BEFORE INSERT <row>
BEFORE INSERT <comando>
BEFORE UPDATE <comando>
BEFORE DELETE <comando>

AFTER UPDATE <row>


AFTER DELETE <row>
AFTER INSERT <row>
AFTER INSERT <comando>
AFTER UPDATE <comando>
AFTER DELETE <comando>

As palavras BEFORE e AFTER indicam se o TRIGGER ser executado antes ou


depois do evento que o causou.

TRIGGERS E PACKAGES - 91

PL/SQL BSICO E AVANADO 7.3

SINTAXE
Um DATABASE TRIGGER composto de 3 partes:
Evento
Restrio (opcional)
Ao
Quando o evento ocorre, o TRIGGER disparado e um bloco PL/SQL annimo
executa a ao.
A sintaxe CREATE OR REPLACE permite que executemos o script com o texto do
trigger tanto para criao quanto para modificao do trigger.
CREATE [OR REPLACE] TRIGGER <nome trigger>
{BEFORE | AFTER}
{ DELETE | INSERT | UPDATE [OF <coluna>[,<coluna>] . . ]
[OR DELETE | INSERT | UPDATE [OF <coluna>[,<coluna>] . .] .}
ON <tabela>
[REFERENCING{OLD [AS] <nome> | NEW [AS] <nome>
Condio
[OLD [AS] <nome> | NEW [AS] <nome>]}
FOR EACH ROW [WHEN (<condio>)]]
<bloco PL/SQL>
Ao

Evento

OBS.: Os DATABASE TRIGGERS executam com os privilgios do OWNER e no do


usurio que causou o evento.

PREDICADOS CONDICIONAIS
Quando criamos um trigger que esteja associado a mais de uma operao DML,
podemos utilizar os predicados condicionais a fim de determinarmos o tipo de
comando DML causador da execuo do trigger.

INSERTING Retorna TRUE se o trigger foi disparado por causa de um


comando INSERT.
UPDATING Retorna TRUE se o trigger foi disparado por causa de um
comando UPDATE.
DELETING Retorna TRUE se o trigger foi disparado por causa de um
comando DELETE.

TRIGGERS E PACKAGES - 92

PL/SQL BSICO E AVANADO 7.3

EXEMPLO
SQL> CREATE TRIGGER checa_salario
2 BEFORE UPDATE OF vl_sal, nr_git ON FUNC
3 FOR EACH ROW WHEN (NEW.nr_git < 56)
4 DECLARE
5
salario_minimo
NUMBER(5) := 0;
6
salario_maximo
NUMBER(5) := 0;
7
faixa
EXCEPTION;
8
negativo
EXCEPTION;
9 BEGIN
10
SELECT MIN(vl_sal), MAX(vl_sal)
11
INTO salario_minimo, salario_maximo
12
FROM folha
13
WHERE nr_git = :new.nr_git;
14
IF (:NEW.vl_sal < salario_minimo OR
15
:NEW.vl_sal > salario_maximo) THEN
16
RAISE faixa;
17
ELSIF (:NEW.vl_sal < :OLD.vl_sal) THEN
18
RAISE negativo;
19
END IF;
20 EXCEPTION
21
WHEN faixa THEN
22
RAISE_APPLICATION_ERROR(-20225, Salrio fora da faixa);
23
WHEN negativo THEN
24
RAISE_APPLICATION_ERROR(-20230, Incremento negativo);
25
WHEN OTHERS THEN
26
RAISE_APPLICATION_ERROR(-20999, SQLERRM(SQLCODE));
27 END;
28 /

TRIGGERS E PACKAGES - 93

PL/SQL BSICO E AVANADO 7.3

COMPILANDO TRIGGERS
Antes da verso 7.3, um TRIGGER era PARSED e compilado toda vez que o
TRIGGER fosse disparado.
A partir da verso 7.3, a verso compilada do TRIGGER armazenada no dicionrio
de dados e ser chamada quando o TRIGGER for executado.
Se o TRIGGER tiver erros de compilao, ainda assim ele ser armazenado, porm
falhar a tempo de execuo.
Esta nova caracterstica ir dar significativo ganho de performance.

HABILITANDO, DESABILITANDO E COMPILANDO TRIGGERS


O comando ALTER TRIGGER possui trs opes ENABLE, DISABLE e COMPILE,
que permitiro :
Que desabilitemos temporariamente um trigger objetivando por exemplo a
carga de dados.
Que compilemos um trigger previamente cadastrado. Se a compilao for bem
sucedida, o trigger torna-se vlido. Por outro lado se a compilao retornar erro,
o trigger torna-se invlido.

SINTAXE

ALTER TRIGGER

<nome trigger>

ENABLE
DISABLE
COMPILE

TRIGGERS E PACKAGES - 94

PL/SQL BSICO E AVANADO 7.3

PACKAGES
Um PACKAGE um objeto que grupa logicamente subprogramas, objetos e tipos
PL/SQL.
So compostos de duas partes:
especificao
corpo do pacote

VANTAGENS
MODULARIDADE

Packages permitem que se encapsule logicamente tipos,


objetos e subprogramas relacionados.

DESENHO DA
APLICAO

Quando uma aplicao desenhada, tudo que necessrio


inicialmente a informao da especificao do package.
Pode-se codificar e compilar a especificao sem o corpo do
package. Uma vez que a especificao tenha sido compilada
e o subprograma armazenado a referncia ao pacote pode
ser compilada tambm.

SEGURANA

Com pacotes pode-se especificar que tipos, objetos e


subprogramas so pblicos ou privados. Os pblicos so
especificados na parte de especificao dos packages. J os
privados so totalmente especificados no corpo do package.
Eles so usados dentro do prprio pacote e no precisam
ficar visveis a quem usar os pacotes.

FUNCIONALIDAD
E

Variveis pblicas e cursores empacotados podem ser


compartilhados por todas as procedures que executarem no
ambiente.

PERFORMANCE

Quando feita a primeira chamada de um package


subprogram pela primeira vez, todo o pacote carregado na
memria. Assim, subsequentes chamadas a outros
subprogramas dentro do pacote no requerem I/O de disco.

TRIGGERS E PACKAGES - 95

PL/SQL BSICO E AVANADO 7.3

ESPECIFICAO
A especificao a interface com as aplicaes. Nela so declarados os tipos,
variveis, constantes, excees, cursores e subprogramas. Para os subprogramas
so feitas, apenas declaraes FORWARD.
Na parte de especificao so feitas declaraes pblicas, visveis pelas
aplicaes.

CORPO
No corpo do pacote concluda a definio dos cursores e subprogramas e feita a
implementao da especificao.
O corpo implementa detalhes e declaraes privadas que so invisveis pelas
aplicaes. O corpo seria uma caixa preta.

TRIGGERS E PACKAGES - 96

PL/SQL BSICO E AVANADO 7.3

SINTAXE
A sintaxe CREATE OR REPLACE permite que executemos o script com o texto do
package tanto para criao quanto para modificao do pacote.

ESPECIFICAO
CREATE [OR REPLACE] PACKAGE <nome do pacote> IS
<declaraes>
END [<nome do pacote>];

CORPO
CREATE [OR REPLACE] PACKAGE BODY <nome do pacote> IS
<corpo dos subprogramas>
[BEGIN
<comandos de inicializao>]
END [<nome do pacote>];
Deve-se observar que somente a especificao do pacote visvel e acessvel pela
aplicao.
Detalhes da implementao que se localizam do BODY so invisveis e inacessveis.
Desta forma pode-se alterar o BODY sem haver necessidade de se recompilar os
programas que usarem os PACKAGES.

TRIGGERS E PACKAGES - 97

PL/SQL BSICO E AVANADO 7.3

EXEMPLO
ESPECIFICAO
SQL> CREATE OR REPLACE PACKAGE funcionario AS
2
TYPE RegFunc IS RECORD (cd_mat NUMBER, vl_sal NUMBER);
3
CURSOR salario (mat NUMBER) RETURN RegFunc;
4
DtNasc
DATE;
4
PROCEDURE admisso (nome CHAR, grau NUMBER,
5
sal NUMBER, depto CHAR);
6
PROCEDURE demisso (mat NUMBER);
7 END funcionario;
8 /
Package created.
CORPO
SQL> CREATE OR REPLACE PACKAGE BODY funcionario AS
2
CURSOR salario (mat NUMBER) RETURN RegFunc IS
3
SELECT cd_mat, vl_sal FROM func
4
WHERE cd_mat = mat
5
ORDER BY vl_sal DESC;
6
PROCEDURE admisso (nome CHAR, grau NUMBER,
7
sal NUMBER, depto CHAR) IS
8
BEGIN
9
INSERT INTO func (nm_func, nr_git, vl_sal, cd_mat, cd_depto)
10
VALUES (nome, grau, sal, cd_mat_seq.NEXTVAL, depto);
11
END admisso;
12
PROCEDURE demisso (mat NUMBER) IS
13
BEGIN
14
DELETE FROM func WHERE cd_mat = mat;
15
END demisso;
16 BEGIN
17
DtNasc := TO_DATE('17/01/1998', 'DD/MM/YYYY');
18 END funcionario;
Package body created.

TRIGGERS E PACKAGES - 98

PL/SQL BSICO E AVANADO 7.3

REFERNCIA A PACKAGES
Para fazer referncia aos tipos, objetos e subprogramas declarados dentro da
especificao de packages devemos usar a seguinte notao:
<nome do package>. <tipo>
<nome do package>. <objeto>
<nome do package>. <subprograma>
Podemos fazer referncia a pacotes de dentro de DATABASE TRIGGERS, STORED
SUBPROGRAMS e blocos PL/SQL dentro de programas e blocos PL/SQL annimos.
A inicializao da parte executvel do PACKAGE feita uma nica vez, na primeira
vez que for feita referncia ao PACKAGE (por sesso).
RESTRIO
Um PACKAGE no pode ser chamado, receber parmetro nem ser aninhado
(declarado dentro de outro PACKAGE).
EXEMPLO
SQL> VARIABLE DtTeste VARCHAR2(30)
SQL> DECLARE
2
wr
funcionario.salario%ROWTYPE;
3 BEGIN
4
OPEN funcionario.salario(&mat);
5
FETCH funcionario.salario into wr;
6
funcionario.admisso ('Teste', 19, wr.vl_sal * 1.2, 'A00');
7
funcionario.demisso (wr.cd_mat);
8
:DtTeste := TO_CHAR(funcionario.DtNasc, 'DD/MM/YYYY');
9
CLOSE funcionario.salario;
10 END;
11 /
Enter value for mat: 120
old 4: OPEN funcionario.salario(&mat);
new 4: OPEN funcionario.salario(120);
PL/SQL procedure successfully completed.

TRIGGERS E PACKAGES - 99

PL/SQL BSICO E AVANADO 7.3

CAPTULO 8 : ALGUNS PACKAGES DO ORACLE


O PACKAGE DBMS_OUTPUT
Este pacote tem a finalidade de permitir o envio de mensagens a partir de procedures,
packages ou triggers.
Este pacote utiliza um buffer em memria para transferncia das mensagens.
Estas mensagens podero ser mostradas com o uso da procedure GET_LINE ou com
o uso do comando SET SERVEROUTPUT ON no SQL*PLUS, caso contrrio estas
mensagens sero ignoradas.
OBS.: Este package pode ser especialmente til para depurao.

ALGUNS PACKAGES DO ORACLE - 100

PL/SQL BSICO E AVANADO 7.3


Veremos, agora cada uma das procedures e funes contidas no package
DBMS_OUTPUT.

ENABLE
Esta procedure habilita chamadas para PUT, PUT_LINE, NEW_LINE, GET_LINE e
GET_LINES.
As chamadas a estas procedures so ignoradas se o package DBMS_OUTPUT no
estiver habilitado.
Deve-se especificar a quantidade de informao (em bytes) a ser armazenada no
buffer.
Se o buffer for excedido, receberemos a seguinte mensagem de erro:
-20000, ORU-10027: Buffer overflow, Limit of buffer_limit bytes.
No necessria a chamada a esta procedure quando utilizamos o SQL*PLUS.
So permitidas mltiplas chamadas ENABLE. Se existirem mltiplas chamadas a
esta procedure, o maior valor dentre os especificados que ser utilizado.
SINTAXE
DBMS_OUTPUT.ENABLE (buffer_size in integer);
Onde:
buffer_size - pode variar de 2.000 a 1.000.000 de bytes.

ALGUNS PACKAGES DO ORACLE - 101

PL/SQL BSICO E AVANADO 7.3

DISABLE
Esta procedure desabilita as chamadas para PUT, PUT_LINE, NEW_LINE, GET_LINE
e GET_LINES e limpa o buffer.
Esta rotina no necessria se estivermos usando a opo SET SERVEROUTPUT
no SQL*PLUS.
SINTAXE
DBMS_OUTPUT.DISABLE;

PUT
Esta procedure especifica a informao que desejamos armazenar no buffer.
Devemos usar esta procedure para adicionar pedaos de informao ao buffer.
As procedure GET_LINE e GET_LINES no retornam uma linha que no tenham sido
terminadas com o caracter newline.
Se o tamanho especificado pelo buffer for excedido, ser recebida uma mensagem de
erro.
SINTAXE
DBMS_OUTPUT.PUT (item VARCHAR2 | NUMBER | DATE);
OBS
Se passarmos como parmetro um number ou date, quando o item for recuperado
ser convertido (com TO_CHAR) para string no formato default.
Se desejarmos um formato particular, devemos passar o parmetro j convertido
(VARCHAR2).

ALGUNS PACKAGES DO ORACLE - 102

PL/SQL BSICO E AVANADO 7.3

NEW_LINE
Esta procedure coloca uma marca de fim de linha no buffer.
Normalmente usamos esta procedure aps uma ou mais chamadas procedure PUT,
para indicar fim de mensagem.
Cada chamada a NEW_LINE gerar uma linha a ser retornada pelo GET_LINE.
SINTAXE
DBMS_OUTPUT.NEW_LINE;

PUT_LINE
Esta procedure especifica a informao que desejamos armazenar no buffer.
Esta procedure armazena, automaticamente, um caracter de fim de linha a cada texto
enviado.
Cada chamada a PUT_LINE gera uma linha a ser recuperada pela procedure
GET_LINE.
SINTAXE
DBMS_OUTPUT.PUT_LINE (item VARCHAR2 | NUMBER | DATE);
EXEMPLO
Suponha que desejssemos depurar um trigger. Neste caso devemos incluir uma ou
mais linhas de mensagens, da seguinte forma:
DBMS_OUTPUT.PUT_LINE (O novo valor || :new.col);
Devemos usar o SQL*PLUS com a opo SET SERVEROUTPUT marcada para ON,
para executar o trigger e depurar as mensagens includas.

ALGUNS PACKAGES DO ORACLE - 103

PL/SQL BSICO E AVANADO 7.3

GET_LINE
Esta procedure recupera uma nica linha da informao no BUFFER, excluindo o
caracter NEWLINE final. O tamanho mximo da linha de 255 bytes.
Todas as linhas no recuperadas sero descartadas quando usadas as procedures
PUT, PUT_LINE ou NEW_LINE.
Se a procedure concluir com sucesso, o status retornado zero, caso contrrio 1
indicando que no existem linhas no buffer.
SINTAXE
DBMS_OUTPUT.GET_LINE (line OUT VARCHAR2, status OUT INTEGER);
Onde:
line - indica a rea de texto correspondente linha. Devemos passar como
parmetro uma varivel para receber a linha.
status - Indica o sucesso ou fracasso da operao.

GET_LINES
Esta procedure recupera um conjunto de linhas e pode ser usada no lugar da
GET_LINE para reduzir o nmero de chamadas ao servidor.
Devemos especificar o nmero de linhas que desejamos recuperar do buffer.
Aps recuperar o nmero de linhas especificado, a procedure retorna o nmero de
linhas realmente recuperado. Se este nmero for menor que o nmero de linhas
requisitado, significa que no existem mais linhas no buffer.
Todas as linhas no recuperadas sero descartadas quando usadas as procedures
PUT, PUT_LINE ou NEW_LINE.
Cada linha no array pode ter at 255 bytes de comprimento.
SINTAXE
DBMS_OUTPUT.GET_LINES (lines OUT CHARARR, num IN OUT INTEGER);

ALGUNS PACKAGES DO ORACLE - 104

PL/SQL BSICO E AVANADO 7.3


EXEMPLO USANDO O SQL*PLUS
O package DBMS_OUTPUT , normalmente, usado para depurao de STORED
PROCEDURES e TRIGGERS.
SQL> CREATE OR REPLACE FUNCTION DeptoSal (p_cd_depto IN CHAR)
2
RETURN NUMBER IS
3
CURSOR func_cursor IS
4
SELECT vl_sal FROM func WHERE cd_depto = p_cd_depto;
5
v_total_sal
NUMBER(11,2) := 0;
6
v_conta
NUMBER(10) := 1;
7 BEGIN
8
FOR func_rec IN func_cursor LOOP
9
v_total_sal := v_total_sal + func_rec.vl_sal;
10
DBMS_OUTPUT.PUT_LINE ('Loop NO. = ' || TO_CHAR(v_conta) ||
11
'; salrio = ' || TO_CHAR(v_total_sal));
12
v_conta := v_conta + 1;
13
END LOOP;
14
DBMS_OUTPUT.PUT_LINE ('Total de salrios = ' ||
15
TO_CHAR(v_total_sal));
16
RETURN v_total_sal;
17 END depto_sal;
18 /

SQL> SET SERVEROUTPUT ON


SQL> DECLARE
2 total
number;
3 BEGIN
4
total := DeptoSal('A00');
5 END;
6 /
Loop NO. = 1; salrio = 5275
Loop NO. = 2; salrio = 9925
Loop NO. = 3; salrio =
Loop NO. = 4; salrio =
Total de salrios =
PL/SQL procedure successfully completed.
As mensagens so apresentadas na linha do SQL*PLUS.

ALGUNS PACKAGES DO ORACLE - 105

PL/SQL BSICO E AVANADO 7.3


EXEMPLO USANDO OUTRO PROGRAMA
Este pacote tambm pode ser usado para passagem de informao entre programas
executando no ambiente Server.
SQL> CREATE OR REPLACE PROCEDURE teste IS
2 linhas
DBMS_OUTPUT.chararr;
3 total
NUMBER;
4 nlin
NUMBER := 3;
5 BEGIN
6
total := DeptoSal ('A00');
7
DBMS_OUTPUT.GET_LINES (linhas, nlin);
8
IF nlin > 0 THEN
9
DBMS_OUTPUT.PUT_LINE(nlin);
10
END IF;
11 END;
12 /
Procedure created.
SQL> EXECUTE teste;
3
PL/SQL procedure successfully completed.

ALGUNS PACKAGES DO ORACLE - 106

PL/SQL BSICO E AVANADO 7.3

O PACKAGE UTL_FILE
O package UTL_FILE possui diversas rotinas capazes de efetuar o acesso, leitura e
gravao em arquivos convencionais.
Obs: Para utilizao deste package o DBA deve acrescentar o parmetro
UTL_FILE_DIR ao arquivo de inicializao INIT.ORA.
Este pacote no declara apenas procedures e funes, so declaradas excees e
tipos tambm.
Devemos observar que este package se acha armazenado na base de dados,
portanto sua execuo realizada pelo Server. Isto significa que a criao e/ou leitura
de arquivos se dar no ambiente em que se acha o banco de dados, o ambiente
Server.

EXCEPTIONS
A especificao do package UTL_FILE declara sete excees. Estas excees sero
usadas de acordo com as rotinas especficas.
Localizao ou nome do arquivo invlido
O parmetro open_mode na rotina FOPEN est
invlido
INVALID_FILEHANDLE...... O handle do arquivo est invlido
INVALID_OPERATION....... O arquivo no pode ser aberto ou operado como
requisitado.
READ_ERROR................... Um erro de sistema operacional ocorreu durante a
operao de leitura.
WRITE_ERROR.................. Um erro de sistema operacional ocorreu durante a
operao de gravao.
INTERNAL_ERROR........... Um erro no identificado ocorreu.
INVALID_PATH..................
INVALID_MODE.................

FUNES E PROCEDURES
Para cada funo ou procedure apresentada sero vistas as excees e tipos
associados.

ALGUNS PACKAGES DO ORACLE - 107

PL/SQL BSICO E AVANADO 7.3

FOPEN
A funo FOPEN abre um arquivo para leitura ou gravao. O PATH do diretrio j
deve existir, uma vez que no feita criao pelo FOPEN.
A funo retorna um file handle que deve ser usado em todas as operaes de I/O
subseqentes no arquivo.
SINTAXE
FUNCTION FOPEN ( Location IN VARCHAR2, Filename IN VARCHAR2,
Open_mode IN VARCHAR2) RETURN UTL_FILE.FILE_TYPE
Onde:
Location - Indica o diretrio do arquivo a ser aberto.
Filename - Indica o nome do arquivo incluindo a extenso. No deve ser
includo o caminho (path).
Open_mode - Indica o modo como o arquivo ser lido. Os valores vlidos
so: r - leitura, w - gravao, a - adicionar ao fim do arquivo.
TYPE
Deve ser declarada uma varivel do tipo UTL_FILE.FILE_TYPE para receber o file
handle.
EXCEPTION
As seguintes excees podem ser obtidas no momento da abertura do arquivo
(FOPEN) :
UTL_FILE.INVALID_PATH,
UTL_FILE.INVALID_MODE,
UTL_FILE.INVALID_OPERATION
EXEMPLO
SQL> DECLARE
2
arq
UTL_FILE.FILE_TYPE;
4 BEGIN
5
arq := UTL_FILE.FOPEN (/home/teste, arq.txt', r);
....
15 END;
16 /

ALGUNS PACKAGES DO ORACLE - 108

PL/SQL BSICO E AVANADO 7.3


IS_OPEN
Testa um file handle para ver se ele identifica um arquivo aberto.
OBS: Esta funo indica apenas se o arquivo est aberto ou no, ou seja se o file
handle vlido ou no. Ela no garante que uma operao de I/O posterior usando o
file handle no venha a receber um erro de sistema operacional.

SINTAXE
FUNCTION IS_OPEN (File_handle IN FILE_TYPE) RETURN BOOLEAN;
Onde:
File_handle - Indica um file handle retornado por um FOPEN.

EXCEPTION
No Tem.

EXEMPLO
SQL> DECLARE
2
arq
UTL_FILE.FILE_TYPE;
4 BEGIN
5
arq := UTL_FILE.FOPEN (/home/teste, arq.txt', r);
...
8
IF UTL_FILE.IS_OPEN(arq) THEN
...
10
END IF;
15 END;
16 /

ALGUNS PACKAGES DO ORACLE - 109

PL/SQL BSICO E AVANADO 7.3

FCLOSE
A procedure FCLOSE fecha um arquivo identificado por um file handle.
OBS: Pode-se receber uma exceo do tipo WRITE_ERROR se existirem buffers de
dados ainda no gravados quando o comando FCLOSE for executado.

SINTAXE
PROCEDURE FCLOSE (File_handle IN OUT FILE_TYPE);
Onde:
File_handle - Indica um file_handle ativo retornado por um FOPEN.

EXCEPTION
As seguintes excees podem ser adquiridas no momento em que o arquivo
fechado (FCLOSE):
UTL_FILE.WRITE_ERROR
UTL_FILE.INVALID_FILEHANDLE

EXEMPLO
SQL> DECLARE
2
arq
UTL_FILE.FILE_TYPE;
4 BEGIN
5
arq := UTL_FILE.FOPEN (/home/teste, arq.txt', r);
...
8
IF UTL_FILE.IS_OPEN(arq) THEN
...
10
END IF;
14
UTL_FILE.FCLOSE (arq);
15 END;
16 /

ALGUNS PACKAGES DO ORACLE - 110

PL/SQL BSICO E AVANADO 7.3

FCLOSE_ALL
Esta procedure fecha todos os file handle abertos na sesso.
OBS: A procedure FCLOSE_ALL no altera o estado de um file handle adquirido
(aberto) pelo usurio. Isto significa que um teste com IS_OPEN poder retornar TRUE
mesmo aps o arquivo ter sido fechado, porm nenhuma operao de leitura ou
gravao ser vlida at que um novo FOPEN seja realizado para aquele file handle.
SINTAXE
PROCEDURE FCLOSE_ALL;
EXCEPTION
A operao pode receber a seguinte exceo:
UTL_FILE.WRITE_ERROR.
EXEMPLO
SQL> DECLARE
2
arq
UTL_FILE.FILE_TYPE;
4 BEGIN
5
arq := UTL_FILE.FOPEN (/home/teste, arq.txt', r);
...
8
IF UTL_FILE.IS_OPEN(arq) THEN
...
10
END IF;
14
UTL_FILE.FCLOSE_ALL;
15 END;
16 /

ALGUNS PACKAGES DO ORACLE - 111

PL/SQL BSICO E AVANADO 7.3

GET_LINE
Esta procedure l uma linha de texto de um arquivo aberto identificado pelo file handle
e coloca o texto no buffer de sada (parmetro).
Se a linha no couber na rea de buffer o programa recebe a exceo
VALUE_ERROR. Se o texto no for lido porque encontrou fim de arquivo, o programa
receber NO_DATA_FOUND.
OBS: O tamanho mximo do texto para leitura de 1022 bytes. A leitura de uma linha
em branco gerar uma string vazia.
SINTAXE
PROCEDURE GET_LINE (file_handle IN FILE_TYPE, buffer OUT VARCHAR2);
EXCEPTION
A operao de leitura pode receber uma das seguintes excees:

UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.INVALID_OPERATION
UTL_FILE.READ_ERROR
NO_DATA_FOUND
VALUE_ERROR

EXEMPLO
SQL> DECLARE
2
arq
UTL_FILE.FILE_TYPE;
3
linha
VARCHAR2(1000);
4 BEGIN
5
arq := UTL_FILE.FOPEN (/home/teste, arq.txt', r);
6
UTL_FILE.GET_LINE (arq, linha);
....
8
IF UTL_FILE.IS_OPEN(arq) THEN
...
10
END IF;
14
UTL_FILE.FCLOSE_ALL;
15 END;
16 /

ALGUNS PACKAGES DO ORACLE - 112

PL/SQL BSICO E AVANADO 7.3

PUT
Esta procedure armazena o texto existente no buffer no arquivo identificado pelo file
handle.
OBS: A linha includa no recebe nenhum caracter de fim de linha. necessria a
execuo do comando NEW_LINE para gerar este caracter quando desejado.
SINTAXE
PROCEDURE PUT (File_handle IN FILE_TYPE, Buffer IN VARCHAR2);
Onde:
File_handle - Indica um file handle ativo retornado pelo FOPEN.
Buffer - Determina a rea de memria que contm o texto a ser gravado
para o arquivo.
EXCEPTION
As seguintes excees podem ser recebidas:
UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.INVALID_OPERATION
UTL_FILE.WRITE_ERROR
EXEMPLO
SQL> DECLARE
2
carta
UTL_FILE.FILE_TYPE;
3
dt_hoje
VARCHAR2(10) := TO_CHAR (SYSDATE, 'dd/mm/yyyy');
4
CURSOR aniv IS SELECT nm_func,
...
9 BEGIN
10
FOR wlinha IN aniv LOOP
11
carta := UTL_FILE.FOPEN ('c:\lucia', wlinha.nm_func || '.txt', 'w');
12
UTL_FILE.PUT (carta, 'Rio, ' || dt_hoje);
...
23
UTL_FILE.FCLOSE(carta);
24
END LOOP;
25 END;
26 /

ALGUNS PACKAGES DO ORACLE - 113

PL/SQL BSICO E AVANADO 7.3

NEW_LINE
Esta procedure grava um ou mais caracteres de fim de linha para o arquivo
identificado por um file handle.
SINTAXE
PROCEDURE NEW_LINE (File handle IN file_type, Lines IN natural :=1)
Onde:
File_handle - Indica um file handle ativo retornado pelo FOPEN
Lines - Determina o nmero de caracteres de fim de linha a serem
gravados no arquivo.
EXCEPTION
As seguintes excees podem ser recebidas no momento da gravao do arquivo:
UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.INVALID_OPERATION
UTL_FILE.WRITE_ERROR
EXEMPLO
SQL> DECLARE
2
carta
UTL_FILE.FILE_TYPE;
3
dt_hoje
VARCHAR2(10) := TO_CHAR (SYSDATE, 'dd/mm/yyyy');
4
CURSOR aniv IS SELECT nm_func,
...
9 BEGIN
10
FOR wlinha IN aniv LOOP
11
carta := UTL_FILE.FOPEN ('c:\lucia', wlinha.nm_func || '.txt', 'w');
12
UTL_FILE.PUT (carta, 'Rio, ' || dt_hoje);
13
UTL_FILE.NEW_LINE (carta, 1);
14
UTL_FILE.PUT (carta, 'Prezado(a) Sr(a). ' || wlinha.nm_func || ',');
15
UTL_FILE.NEW_LINE (carta, 2);
...
23
UTL_FILE.FCLOSE(carta);
24
END LOOP;
25 END;
26 /

ALGUNS PACKAGES DO ORACLE - 114

PL/SQL BSICO E AVANADO 7.3

PUT_LINE
Esta procedure grava o texto presente no buffer para o arquivo. Este comando j
adiciona um caracter de fim de linha ao texto.
SINTAXE
PROCEDURE PUT_LINE (File_handle IN FILE_TYPE, Buffer IN VARCHAR2);
Onde:
File_handle - Indica um file handle ativo retornado pelo FOPEN.
Buffer - Determina o texto a ser gravado no arquivo.
EXCEPTION
As seguintes excees podem ser adquiridas no monento da gravao no arquivo:
UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.INVALID_OPERATION
UTL_FILE.WRITE_ERROR
EXEMPLO
SQL> DECLARE
2
carta
UTL_FILE.FILE_TYPE;
3
dt_hoje
VARCHAR2(10) := TO_CHAR (SYSDATE, 'dd/mm/yyyy');
4
CURSOR aniv IS SELECT nm_func,
...
9 BEGIN
10
FOR wlinha IN aniv LOOP
11
carta := UTL_FILE.FOPEN ('c:\lucia', wlinha.nm_func || '.txt', 'w');
...
16
UTL_FILE.PUT_LINE (carta, 'Parabns por seu aniversrio dia ' ||
17
wlinha.dt_nasc || '.');
...
21
UTL_FILE.PUT_LINE (carta, 'Depto Pessoal.');
...
24
END LOOP;
25 END;
26 /

ALGUNS PACKAGES DO ORACLE - 115

PL/SQL BSICO E AVANADO 7.3

PUTF
uma procedure que trabalha de forma semelhante a um printf (do C), porm com
limitaes. A string de formatao pode conter qualquer texto.
Os caracteres %s e \n possuem um significado especial:
%s - marca um ponto para substituio, no texto, pelo prximo argumento da
lista.
\n - substitudo (de acordo com a plataforma) pelo caracter de fim de linha.
SINTAXE
PROCEDURE PUTF (File_handle IN FILE_TYPE, Format IN VARCHAR2,
[Arg1 IN VARCHAR2, . . . Arg5 IN VARCHAR2]);
Onde:
File_handle - Indica um file handle ativo, retornado por um FOPEN.
Format - Indica uma string que pode conter os caracteres %s e \n.
Arg1. . . Arg5 - de 1 a 5 argumentos para substituio no %s. Se
houveram mais %s que argumentos, o local ser ocupado por uma string
de comprimento zero.
EXCEPTION
As seguintes excees podem ser adquiridas a tempo de gravao:
UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.INVALID_OPERATION
UTL_FILE.WRITE_ERROR
EXEMPLO
SQL> DECLARE
...
9 BEGIN
10
FOR wlinha IN aniv LOOP
11
carta := UTL_FILE.FOPEN ('c:\lucia', wlinha.nm_func || '.txt', 'w');
...
19
UTL_FILE.PUTF (carta, ' de R$ %s no ms atual.', wlinha.vl_sal);
...
25 END;

ALGUNS PACKAGES DO ORACLE - 116

PL/SQL BSICO E AVANADO 7.3

FFLUSH
Esta procedure grava fisicamente todos os dados pendentes para aquele arquivo. O
FFLUSH faz com que os dados no buffer sejam descarregados em disco.
SINTAXE
PROCEDURE FFLUSH (File_handle IN FILE_TYPE);
Onde:
File_handle - Indica um file handle ativo, retornado por um FOPEN.
EXCEPTION
Pode adquirir as seguintes excees no momento da gravao.
UTL_FILE.INVALID_FILEHANDLE
UTL_FILE.INVALID_OPERATION
UTL_FILE.WRITE_ERROR
EXEMPLO
SQL> DECLARE
2
carta
UTL_FILE.FILE_TYPE;
3
dt_hoje
VARCHAR2(10) := TO_CHAR (SYSDATE, 'dd/mm/yyyy');
4
CURSOR aniv IS SELECT nm_func,
...
9 BEGIN
10
FOR wlinha IN aniv LOOP
11
carta := UTL_FILE.FOPEN ('c:\lucia', wlinha.nm_func || '.txt', 'w');
12
UTL_FILE.PUT (carta, 'Rio, ' || dt_hoje);
13
UTL_FILE.NEW_LINE (carta, 1);
...
21
UTL_FILE.PUT_LINE (carta, 'Depto Pessoal.');
22
UTL_FILE.FFLUSH(carta);
23
UTL_FILE.FCLOSE(carta);
24
END LOOP;
25 END;
26 /

ALGUNS PACKAGES DO ORACLE - 117

PL/SQL BSICO E AVANADO 7.3


PROBLEMA PROPOSTO
Deseja-se carregar na tabela Projetos X Atividades as atividades realizadas no ms.
O arquivo com estas informaes possui o layout abaixo:
Informao
Cdigo do projeto................
Cdigo da atividade............
Data de incio......................
Data de fim..........................

Coluna
1a6
7a9
10 a 17 (dd/mm/yy)
18 a 25 (dd/mm/yy)

SQL> DECLARE
2
arq
UTL_FILE.FILE_TYPE;
3
buffer
VARCHAR2(50);
4
wrow
prjatv%ROWTYPE;
5 BEGIN
6
arq := UTL_FILE.FOPEN ('c:\lucia\curso', 'carga.sql', 'r');
7
LOOP
8
UTL_FILE.GET_LINE(arq, buffer);
9
wrow.cd_proj := SUBSTR(buffer,1,6);
10
wrow.cd_ativ := TO_NUMBER(SUBSTR(buffer,7,3));
11
wrow.dt_ini := TO_DATE(SUBSTR(buffer,10,8), 'dd/mm/yy');
12
wrow.dt_fim := TO_DATE(SUBSTR(buffer,18,8), 'dd/mm/yy');
13
INSERT INTO prjatv (cd_proj, cd_ativ, dt_ini, dt_fim)
14
VALUES (wrow. cd_proj, wrow. cd_ativ, wrow. dt_ini, wrow. dt_fim);
15
END LOOP;
16 EXCEPTION
17
WHEN NO_DATA_FOUND THEN
18
COMMIT;
19
UTL_FILE.FCLOSE(arq);
20 END;
21 /

ALGUNS PACKAGES DO ORACLE - 118

PL/SQL BSICO E AVANADO 7.3


PROBLEMA PROPOSTO
O departamento pessoal de uma empresa deseja enviar a seguinte carta aos seus
funcionrios que fazem aniversrio.
Rio, XX / XX / XXXX
Prezado(a) Sr(a). XXXXXX,
Parabns por seu aniversrio dia xx/xx.
Seu presente ser uma bonificao de R$ xxxxxxxx no ms atual.
Depto Pessoal.
SQL> DECLARE
2
carta
UTL_FILE.FILE_TYPE;
3
dt_hoje
VARCHAR2(10) := TO_CHAR (SYSDATE, 'dd/mm/yyyy');
4
CURSOR aniv IS SELECT nm_func,
5
LTRIM(TO_CHAR(vl_sal/5,'999G999D99')) vl_sal,
6
TO_CHAR(dt_nasc, 'dd/mm') dt_nasc FROM func
7
WHERE TO_CHAR(dt_nasc, 'mm') = TO_CHAR(SYSDATE, 'mm')
8
ORDER BY cd_mat;
9 BEGIN
10
FOR wlinha IN aniv LOOP
11
carta := UTL_FILE.FOPEN ('c:\lucia', wlinha.nm_func || '.txt', 'w');
12
UTL_FILE.PUT (carta, 'Rio, ' || dt_hoje);
13
UTL_FILE.NEW_LINE (carta, 2);
14
UTL_FILE.PUT (carta, 'Prezado(a) Sr(a). ' || wlinha.nm_func || ',');
15
UTL_FILE.NEW_LINE (carta, 2);
16
UTL_FILE.PUT_LINE (carta, 'Parabns por seu aniversrio dia ' ||
17
wlinha.dt_nasc || '.');
18
UTL_FILE.PUT (carta, 'Seu presente ser uma bonificao');
19
UTL_FILE.PUTF (carta, ' de R$ %s no ms atual.', wlinha.vl_sal);
20
UTL_FILE.NEW_LINE (carta, 2);
21
UTL_FILE.PUT_LINE (carta, 'Depto Pessoal.');
22
UTL_FILE.FFLUSH(carta);
23
UTL_FILE.FCLOSE(carta);
24
END LOOP;
25 END;
26 /

ALGUNS PACKAGES DO ORACLE - 119

PL/SQL BSICO E AVANADO 7.3

CAPTULO 9 : VARIVEIS CURSOR


CONCEITO
Uma varivel do tipo cursor aponta para a linha corrente da tabela resultado de uma
query que retorne um nmero indefinido de linhas.
Uma varivel do tipo cursor difere de um cursor propriamente dito, pelo fato de no
estar associada a uma query especfica. Desta forma poderemos abrir uma varivel
cursor para qualquer tipo compatvel de query.
Alm disso, possvel associar novos valores a uma varivel cursor e pass-la como
parmetro para subprogramas.
As variveis cursor esto disponveis para cada PL/SQL cliente, isto , podemos
declarar uma varivel cursor num ambiente host (ex: PRO*C) e pass-la como uma
bind variable para o PL/SQL . Nas aplicaes desenvolvidas com as ferramentas
FORMS e REPORTS, pode-se usar as variveis cursor inteiramente no ambiente
cliente.
OBS: Para executar uma multi-row query o ORACLE abre uma rea de trabalho
annima para processar a informao. Para fazer acesso informao podemos usar
um cursor explicito, que nomeia a rea de trabalho ou podemos usar uma varivel
cursor que aponte para a rea de trabalho annima. Diferentemente de um cursor que
sempre se refere mesma rea de trabalho, uma varivel cursor pode fazer
referncia a diferentes reas de trabalho. Desta forma no podemos usar um cursor
onde uma varivel cursor era esperada e vice-versa.

VANTAGENS
A principal vantagem a possibilidade de passar o resultado de uma query entre um
PL/SQL armazenado na base e as vrias aplicaes cliente. Nem o PL/SQL nem
qualquer das aplicaes cliente duplicam ou recebem a query resultante. Eles
simplesmente compartilham um ponteiro para a rea de trabalho resultante da query.
Podemos considerar que houve uma dissociao entre o ponteiro e a rea de
trabalho. So duas entidades independentes. O ponteiro, como varivel, passa a ser
compartilhvel da mesma forma que qualquer outra varivel PL/SQL.

VARIVEIS CURSOR - 120

PL/SQL BSICO E AVANADO 7.3

CRIANDO UMA VARIVEL CURSOR


A criao de uma varivel cursor est subdividida em duas etapas. Na primeira
declaramos o tipo e posteriormente variveis daquele tipo.

SINTAXE
TYPE

Tipo

IS REF CURSOR
RETURN

Tipo de retorno

Onde:
Tipo - Indica o tipo a ser usado nas declaraes subseqentes.
Tipo de retorno - Deve representar um registro (record) ou uma row em
uma tabela da base de dados.
EXEMPLO
SQL> DECLARE
2
-----------------------------------------3
---- DECLARAO DE TIPO ---4
-----------------------------------------5
-6
TYPE CursorDepto IS REF CURSOR; -- sem especificao do retorno
7
TYPE CursorFunc
IS REF CURSOR RETURN func%rowtype;
8
DeptoReg
DEPTO%rowtype;
9
TYPE CursorDepReg IS REF CURSOR RETURN DeptoReg%type;
10
TYPE FuncReg
IS RECORD
11
(
12
cd_mat
NUMBER(3),
13
nm_func
VARCHAR2(15),
14
vl_sal
NUMBER(10,2));
15
TYPE CursorFuncReg IS REF CURSOR RETURN FuncReg;
...

VARIVEIS CURSOR - 121

PL/SQL BSICO E AVANADO 7.3

DECLARANDO VARIVEIS DO TIPO CURSOR


Aps a declarao dos tipos podemos declarar as variveis correspondentes aos tipos
criados.
SQL> DECLARE
2
-----------------------------------------3
---- DECLARAO DE TIPO ---4
-----------------------------------------5
-6
TYPE CursorDepto IS REF CURSOR; -- sem especificao do retorno
7
TYPE CursorFunc
IS REF CURSOR RETURN func%rowtype;
8
DeptoReg
DEPTO%rowtype;
9
TYPE CursorDepReg IS REF CURSOR RETURN DeptoReg%type;
10
TYPE FuncReg
IS RECORD
11
(
12
cd_mat
NUMBER(3),
13
nm_func
VARCHAR2(15),
14
vl_sal
NUMBER(10,2));
15
TYPE CursorFuncReg IS REF CURSOR RETURN FuncReg;
16
------------------------------------------------17
--- DECLARAO DE VARIVEIS --18
------------------------------------------------19
VCDepto
CursorDepto;
20
VCFun
CursorFunc;
21
VCDepReg
CursorDepReg;
22
VCFuncReg
CursorFuncReg;
23 BEGIN
...
24 END;
25 /

OBSERVAES
No podemos declarar variveis CURSOR em um PACKAGE porque a declarao, na
verdade, cria uma ponteiro e no um objeto. Sendo assim no pode ser salva no
banco de dados.

VARIVEIS CURSOR - 122

PL/SQL BSICO E AVANADO 7.3

USANDO UMA VARIVEL CURSOR


ASSOCIANDO UMA VARIVEL CURSOR A UMA QUERY
A associao acontece no momento da abertura do cursor (OPEN).
SINTAXE
OPEN

VARIVEL CURSOR
HOST VARIVEL CURSOR

FOR

COMANDO
SELECT

A query associada a uma varivel cursor pode fazer referncia a uma BIND
VARIABLE e a variveis do PL/SQL, parmetros e funes, mas no pode incluir a
clusula FOR UPDATE.
EXEMPLO
SQL> DECLARE
2
TYPE CursorFunc IS REF CURSOR;
3
VCFunc
CursorFunc;
4
Wtotal
NUMBER:= 0;
5
Wr
Func%ROWTYPE;
6 BEGIN
7
OPEN VCFunc FOR SELECT * FROM func ORDER BY vl_sal;
8
LOOP
...
12
OPEN VCFunc FOR SELECT SUM(vl_sal) FROM func
13
WHERE cd_mat < Wr.cd_mat;
...
20 END;
21 /

OBSERVAES
Quando reabrimos uma varivel cursor j aberta, a QUERY anterior perdida e a
nova executada. O programa no recebe a exceo CURSOR_ALREADY_OPEN,
como ocorreria no caso de um cursor.

VARIVEIS CURSOR - 123

PL/SQL BSICO E AVANADO 7.3

OBTENDO DADOS DE UMA VARIVEL CURSOR


O comando FETCH o responsvel pela recuperao das linhas geradas pela query.
SINTAXE
FETCH

VARIVEL CURSOR
HOST VARIVEL CURSOR

INTO

NOME DE REGISTRO
VARIVEL

EXEMPLO
SQL> DECLARE
2
TYPE CursorFunc IS REF CURSOR;
3
VCFunc
CursorFunc;
4
Wtotal
NUMBER:= 0;
5
Wr
Func%ROWTYPE;
6 BEGIN
7
OPEN VCFunc FOR SELECT * FROM func ORDER BY vl_sal;
8
LOOP
9
FETCH VCFunc INTO Wr;
...
14
FETCH VCFunc INTO Wtotal;
15
CLOSE VCFunc;
...
19
END LOOP;
20 END;
21 /

OBSERVAES
Quando declaramos uma varivel cursor como parmetro formal de um subprograma
que apenas realiza a operao de fetch, podemos especificar o modo IN ou IN OUT
na passagem do parmetro. Porm, se o subprograma tambm abre a varivel cursor,
devemos especificar, obrigatoriamente, o modo IN OUT.

VARIVEIS CURSOR - 124

PL/SQL BSICO E AVANADO 7.3

FECHANDO UMA VARIVEL CURSOR


O comando CLOSE desvincula a varivel cursor da rea de query e recursos
reservados para a rea.
SINTAXE
CLOSE

VARIVEL CURSOR
HOST VARIVEL
CURSOR

EXEMPLO
SQL> DECLARE
2
TYPE CursorFunc IS REF CURSOR;
3
VCFunc
CursorFunc;
4
Wtotal
NUMBER:= 0;
5
Wr
Func%ROWTYPE;
6 BEGIN
7
OPEN VCFunc FOR SELECT * FROM func ORDER BY vl_sal;
8
LOOP
9
FETCH VCFunc INTO Wr;
10
IF Wr.vl_sal > 3000 then
11
CLOSE VCFunc;
12
OPEN VCFunc FOR SELECT SUM(vl_sal) FROM func
13
WHERE cd_mat < Wr.cd_mat;
14
FETCH VCFunc INTO Wtotal;
15
CLOSE VCFunc;
16
DBMS_OUTPUT.PUT_LINE (Wtotal);
17
EXIT;
18
END IF;
19
END LOOP;
20 END;
21 /

VARIVEIS CURSOR - 125

PL/SQL BSICO E AVANADO 7.3

PASSANDO VARIVEIS CURSOR COMO PARMETRO


EM UM PROGRAMA PRINCIPAL
Em um programa principal podemos declarar a varivel cursor e pass-la para uma
subrotina declarada dentro do prprio programa.
EXEMPLO
SQL> DECLARE
2
TYPE CursorFunc IS REF CURSOR RETURN func%ROWTYPE;
3
VCFunc
CursorFunc;
4
FUNCTION Display (P_Func IN OUT CursorFunc)
5
RETURN BOOLEAN IS
6
Wr
Func%ROWTYPE;
7
BEGIN
8
FETCH P_Func INTO Wr;
9
IF P_Func%FOUND THEN
10
DBMS_OUTPUT.PUT_LINE ('mat = ' || Wr.cd_mat);
11
RETURN TRUE;
12
ELSE
13
RETURN FALSE;
14
END IF;
15
END Display;
16 BEGIN
17
OPEN VCFunc FOR SELECT * FROM func
18
WHERE vl_sal > 3000 ORDER BY vl_sal;
19
WHILE Display (VCFunc) LOOP
20
DBMS_OUTPUT.PUT_LINE('Programa Principal');
21
END LOOP;
22 END;
23 /

VARIVEIS CURSOR - 126

PL/SQL BSICO E AVANADO 7.3

EM PROGRAMAS ARMAZENADOS NA BASE


Neste caso podemos fazer apenas a declarao de tipo, uma vez que a varivel no
pode ser armazenada na base.
EXEMPLO
SQL> CREATE OR REPLACE PACKAGE FData AS
2
TYPE CursorFunc is REF CURSOR RETURN func%ROWTYPE;
3
PROCEDURE AbreCursor (PFunc IN OUT CursorFunc);
4
PROCEDURE LeCursor (PFunc IN OUT CursorFunc);
5
PROCEDURE FechaCursor (PFunc IN OUT CursorFunc);
6 END FData;
7 /
8 CREATE OR REPLACE PACKAGE BODY Fdata AS
9
PROCEDURE AbreCursor (PFunc IN OUT CursorFunc) IS
10
BEGIN
11
OPEN PFunc FOR SELECT * FROM func
12
WHERE TO_CHAR(dt_nasc, 'mm') = TO_CHAR(SYSDATE, 'mm');
13
END AbreCursor;
14
PROCEDURE LeCursor (PFunc IN OUT CursorFunc) IS
15
Wfunc
func%ROWTYPE;
16
BEGIN
17
LOOP
18
FETCH PFunc into Wfunc;
19
EXIT WHEN PFunc%NOTFOUND;
20
DBMS_OUTPUT.PUT_LINE('Parabns ' || Wfunc.nm_func);
21
END LOOP;
22
END LeCursor;
23
PROCEDURE FechaCursor (PFunc IN OUT CursorFunc) IS
24
BEGIN
25
Close PFunc;
26
END FechaCursor;
27 END FData;
28 /

VARIVEIS CURSOR - 127

PL/SQL BSICO E AVANADO 7.3


Para usarmos as procedures do pacote devemos criar uma varivel do tipo
correspondente.
SQL> SET SERVEROUTPUT ON
SQL> DECLARE
2
VFunc
FData.CursorFunc;
3 BEGIN
4
FData.AbreCursor(VFunc);
5
FData.LeCursor(VFunc);
6
FData.FechaCursor(VFunc);
7 END;
8 /
Parabns MIGUEL
Parabns MARIA
Parabns WILIAM
PL/SQL procedure successfully completed.

OBSERVAO
Quando declararmos uma varivel cursor com um parmetro formal de um
subprograma que abre a varivel cursor, devemos especificar o modo IN OUT para
que o subprograma possa passar o cursor aberto de volta para o programa chamador.

VARIVEIS CURSOR - 128

PL/SQL BSICO E AVANADO 7.3


Pode-se tambm criar uma procedure fora do package que faa referncia a um tipo
declarado no package.
EXEMPLO
SQL> CREATE OR REPLACE PROCEDURE SalFunc
2
(PFunc IN OUT FData.CursorFunc) AS
3
Wfunc
func%ROWTYPE;
3 BEGIN
4
LOOP
5
FETCH PFunc INTO Wfunc;
6
EXIT WHEN PFunc%NOTFOUND;
7
DBMS_OUTPUT.PUT_LINE (Wfunc.nm_func ||
8
' seu abono de aniversrio de R$' || Wfunc.vl_sal/5);
9
END LOOP;
10 END SalFunc;
11 /
SQL> SET SERVEROUTPUT ON
SQL> DECLARE
2
VFunc
FData.CursorFunc;
3 BEGIN
4
FData.AbreCursor(VFunc);
5
SalFunc(VFunc);
6
FData.FechaCursor(VFunc);
7 END;
8 /
MIGUEL seu abono de aniversrio de R$825
MARIA seu abono de aniversrio de R$426.8
WILIAM seu abono de aniversrio de R$365.4
PL/SQL procedure successfully completed.

VARIVEIS CURSOR - 129

PL/SQL BSICO E AVANADO 7.3

RESTRIES PARA VARIVEIS CURSOR


1. No podemos declarar variveis cursor em um package porque elas no
possuem um estado persistente, isto , no so objetos armazenveis na base
de dados (so ponteiros).
Subprogramas remotos em outros servidores no podem receber valores de variveis
cursor. Desta forma no podemos usar RPCs para passar variveis cursor de um
server para outro.
Se passarmos uma host varivel cursor para um PL/SQL, no poderemos obter linhas
dele (isto , executar um fetch), neste lado do servidor, a menos que a abertura da
varivel tenha sido realizada na mesma chamada ao servidor.
A query associada com uma varivel cursor no pode ser do tipo for update.
2. No podemos usar operadores de comparao para testar variveis cursor
para igualdade, desigualdade ou nulidade. O exemplo abaixo ilegal.
SQL> DECLARE
2
TYPE CursorTemp
IS REF CURSOR RETURN func%rowtype;
3
TYPE CursorFunc
IS REF CURSOR RETURN func%rowtype;
4
PROCEDURE AbreFunc (CFunc IN OUT CursorTemp,
3
CTemp IN OUT CursorFunc) IS
4
BEGIN
...
15
IF CFunc = CTemp THEN
...
20
IF CFunc IS NULL THEN
...
30
END AbreFunc;
31 BEGIN
...
32 END;
33 /

VARIVEIS CURSOR - 130

PL/SQL BSICO E AVANADO 7.3


3. No podemos criar variveis cursor como colunas de uma tabela.
4. No podemos usar o tipo REF CURSOR como elemento de uma tabela
PL/SQL. O exemplo abaixo, portanto, ilegal.
SQL> DECLARE
2
TYPE CursorFunc IS REF CURSOR RETURN func%ROWTYPE;
3
TYPE TabFunc IS TABLE OF CursorFunc
4
INDEX BY BINARY_INTEGER;
...

5. No podemos usar cursores no lugar de variveis cursor e vice-versa. O


exemplo abaixo ilegal.
SQL> DECLARE
2
TYPE CursorFunc IN REF CURSOR RETURN func%rowtype;
3
VCFunc
CursorFunc;
4 BEGIN
...
12
FOR Wfunc IN VCFunc LOOP
...
20
END LOOP;
21 END;
22 /

6. No podemos usar variveis cursor com SQL dinmico.

VARIVEIS CURSOR - 131