Você está na página 1de 50

__________________________________________________________________________________________

NDICE
ASSUNTO:

PAG

1. CONCEITO....................................................................................................................... 81
2. ESTRUTURA....................................................................................................................81
3. ARQUITETURA................................................................................................................82
4. COMPONENTES DA LINGUAGEM.................................................................................82
IDENTIFICADORES................................................................................................................ 82
PALAVRAS RESERVADAS.................................................................................................... 82
LITERAIS................................................................................................................................ 82
COMENTRIOS:..................................................................................................................... 83

5. DECLARAES..............................................................................................................83
TIPOS DE VARIAVEIS............................................................................................................ 83
VARIVEIS SIMPLES................................................................................................. 83
ATRIBUTOS ESPECIAIS............................................................................................ 84
PROBLEMA PROPOSTO........................................................................................... 85
RESOLUO 1:...........................................................................................................85
RESOLUO 2............................................................................................................86

VARIVEIS COMPOSTAS.......................................................................................... 86
PROBLEMA PROPOSTO........................................................................................... 88
RESOLUO:..............................................................................................................88

CONSTANTES........................................................................................................... 88
CONVERSO DE TIPO DE VARIVEL.................................................................................89
EXEMPLOS DE DECLARAES.......................................................................................... 89
VARIVEIS ESPECIAIS............................................................................................. 89
ATRIBUTOS PARA CURSOR.....................................................................................90
PROBLEMA PROPOSTO........................................................................................... 91
RESOLUO:..............................................................................................................91

6. ATRIBUIES..................................................................................................................92
7. FUNES PR-DEFINIDAS............................................................................................92
CONTROLE DE ERROS......................................................................................................... 92
SQLCODE.................................................................................................................. 92
SQLERRM.................................................................................................................. 92
NUMRICAS........................................................................................................................... 93
ABS............................................................................................................................ 93
CEIL............................................................................................................................ 93
COS............................................................................................................................ 93
COSH......................................................................................................................... 93
EXP............................................................................................................................ 93
FLOOR....................................................................................................................... 93
LN............................................................................................................................... 93
LOG............................................................................................................................ 94
MOD........................................................................................................................... 94
POWER...................................................................................................................... 94
ROUND....................................................................................................................... 94
SIGN........................................................................................................................... 94
SIN.............................................................................................................................. 94
SINH........................................................................................................................... 94
SQRT.......................................................................................................................... 94
TAN............................................................................................................................. 95
TANH.......................................................................................................................... 95
__________________________________________________________________________________________

__________________________________________________________________________________________
TRUNC....................................................................................................................... 95
CARACTERES........................................................................................................................ 95
ASCII.......................................................................................................................... 95
CHR............................................................................................................................ 95
CONCAT..................................................................................................................... 95
INITCAP...................................................................................................................... 95
INSTR......................................................................................................................... 95
LENGTH..................................................................................................................... 96
LOWER....................................................................................................................... 96
LPAD........................................................................................................................... 96
LTRIM......................................................................................................................... 96
REPLACE................................................................................................................... 96
RPAD.......................................................................................................................... 96
RTRIM........................................................................................................................ 96
SOUNDEX.................................................................................................................. 97
SUBSTR..................................................................................................................... 97
TRANSLATE............................................................................................................... 97
UPPER....................................................................................................................... 97
DATAS..................................................................................................................................... 97
ADD_MONTHS........................................................................................................... 97
LAST_DAY.................................................................................................................. 97
MONTHS_BETWEEN................................................................................................. 97
NEW_TIME................................................................................................................. 98
NEXT_DAY................................................................................................................. 98
SYSDATE................................................................................................................... 98
ROUND....................................................................................................................... 98
TRUNC....................................................................................................................... 98
CONVERSO......................................................................................................................... 99
CHARTOROWID........................................................................................................ 99
HEXTORAW............................................................................................................... 99
RAWTOHEX............................................................................................................... 99
ROWIDTOCHAR........................................................................................................ 99
TO_CHAR................................................................................................................... 99
MISCELNEA....................................................................................................................... 100
DECLARE................................................................................................................. 100
GREATEST............................................................................................................... 101
LEAST...................................................................................................................... 101
NVL........................................................................................................................... 101
UID........................................................................................................................... 101
USER........................................................................................................................ 101
USERENV................................................................................................................ 101
VSIZE....................................................................................................................... 101
PROBLEMA PROPOSTO:........................................................................................ 102
RESOLUO.............................................................................................................102

8. COMANDOS................................................................................................................... 103
LABELS................................................................................................................................ 103
EXIT....................................................................................................................................... 103
IF THEN ELSE...................................................................................................................... 104
LOOP.................................................................................................................................... 105
PROBLEMA PROPOSTO:........................................................................................ 106
RESOLUO.............................................................................................................106

WHILE LOOP........................................................................................................................ 107


PROBLEMA PROPOSTO:........................................................................................ 107
RESOLUO:............................................................................................................107

FOR LOOP............................................................................................................................ 108


GOTO.................................................................................................................................... 109
NULL..................................................................................................................................... 109
PROBLEMA PROPOSTO:........................................................................................ 109
RESOLUO:............................................................................................................110

__________________________________________________________________________________________

__________________________________________________________________________________________

9. COMUNICAO COM O SQL.......................................................................................110


OPEN CURSOR.................................................................................................................... 110
CURSOR LOOP.................................................................................................................... 111
PROBLEMA PROPOSTO:........................................................................................ 111
RESOLUO:............................................................................................................112

10. TRATAMENTO DE ERROS..........................................................................................112


EXCEES PR-DEFINIDAS..............................................................................................113
PROBLEMA PROPOSTO:........................................................................................114
RESOLUO:............................................................................................................114

EXCEES DEFINIDAS PELOS USURIOS......................................................................115


RAISE....................................................................................................................... 115
PRAGMA EXCEPTION_INIT....................................................................................115
RAISE_APPLICATION_ERROR...............................................................................116
PROPAGAO DA EXCEO.................................................................................116
SQLERRM................................................................................................................ 117

11. SUBPROGRAMAS.......................................................................................................117
PROCEDURES..................................................................................................................... 118
DECLARAES FORWARD................................................................................................ 119
STORED SUBPROGRAMS.................................................................................................. 120
CHAMADAS DE UM STORED PROGRAM..............................................................120
CRIANDO UM STORED SUBPROGRAM................................................................120

12. DATABASE TRIGGERS...............................................................................................121


13. PACKAGES..................................................................................................................123
CRIANDO UM PACKAGE..................................................................................................... 123
VANTAGENS DO USO DE PACKAGES...............................................................................124
REFERNCIAS A PACKAGES............................................................................................. 125

14. MENSAGENS EM STORED PROCEDURES E TRIGGERS........................................125


EXEMPLO............................................................................................................................. 125
PROCEDURES E FUNES............................................................................................... 125
DISABLE PROCEDURE........................................................................................... 125
ENABLE PROCEDURE............................................................................................ 126
GET_LINE PROCEDURE......................................................................................... 126
GET_LINES PROCEDURE......................................................................................126
NEW_LINE PROCEDURE........................................................................................ 126
PUT PROCEDURE................................................................................................... 127
PUT_LINE................................................................................................................. 127
EXEMPLO................................................................................................................ 127

__________________________________________________________________________________________

__________________________________________________________________________________________

GUIA DE REFERENCIA DE PL/SQL COM BASE ORACLE


1. CONCEITO
A PL/SQL uma linguagem procedural do ORACLE, extenso ao SQL. Este captulo da apostila tem
o objetivo de dar uma viso geral da linguagem e suas potencialidades. Atravs de exemplos simples
veremos a aplicabilidade da linguagem. No fim do captulo esto transcritos os principais comandos e
sua sintaxe. 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.

2. ESTRUTURA
A PL/SQL uma estrutura em blocos, ou seja, as unidades bsicas (procedures, funes, etc.)
podem conter qualquer nmero de sub-blocos. Um bloco permite que se faam declaraes
associadas ao bloco e que deixam de existir quando o bloco termina.
Cada bloco composto basicamente de 3 partes:
DECLARE
<declaraes> ______________ opcional
BEGIN
<lgica> ___________________ obrigatria
EXCEPTION
<erros> _____________ opcional
END;
A ordem das partes lgica, ou seja, primeiro deve-se efetuar as declaraes, para depois utilizar (na
lgica) as variveis criadas. As excees ocorridas durante a execuo podem ser resolvidas na parte
referente a erros.
Exemplo:
DECLARE
w_salario
NUMBER(5);
BEGIN
SELECT vl_sal INTO w_salario FROM func
WHERE cd_mat = 150
FOR UPDATE OF;
IF w_salario < 800
THEN
UPDATE func
SET salario = w_salario * 1.3
WHERE cd_mat = 150;
ELSE
UPDATE func
SET vl_sal = w_salario * 1.15
WHERE cd_mat = 150;
END IF;
COMMIT;
END;

__________________________________________________________________________________________
81

__________________________________________________________________________________________

3. ARQUITETURA
O mdulo executvel da PL/SQL pode ser instalado no RDBMS ou em softwares aplicativos tais
como: SQL*REPORT, SQL*FORMS, SQL*MENU. Estes dois ambientes (RDBMS e aplicativos) so
independentes. No ambiente instalado, a PL/SQL aceita como entrada qualquer bloco ou
subprograma escrito na linguagem. Quando a instalao feita no RDBMS, possvel a incluso de
rotinas em PL/SQL nos aplicativos das host languages. possvel ainda, a compilao separada de
subprogramas e armazenamento na base de dados ORACLE, que sero lidos a tempo de execuo.
Um Subprograma explicitamente criado usando uma ferramenta do ORACLE chamado de stored
subprogram, que uma vez compilado e armazenado no dicionrio de dados, poder ser chamado por
qualquer nmero de aplicaes conectadas base de dados.
Ex.: no SQL *PLUS
SQL> execute teste (DILSON)

4. COMPONENTES DA LINGUAGEM
IDENTIFICADORES
Consiste de uma letra opcionalmente seguida de nmeros, $, _ ou #. As letras podem ser
minsculas ou maisculas.
Ex.:

Legais
money$$$tree
ab###
novo_teste_

Ilegais
teste&teste
cd_depto
nmfunc

PALAVRAS RESERVADAS
Palavras que possuam um significado especial para a SQL.
Ex.:

BEGIN
END

LITERAIS
uma representao explcita
identificador.
Ex.:
Numricos
030
6
-14
+32767
12.0
.5
2E5
-9.5E-3

de um nmero, caracter, string ou boleano, no representado por um


Caracteres
Z
%
7
.
.
z
(

Strings
10-NOV-91
hello,world

Boleanos
TRUE
FALSE

__________________________________________________________________________________________
82

__________________________________________________________________________________________

COMENTRIOS:
O incio do comentrio marcado por dois hfens em qualquer ponto da linha. O restante da linha
considerado comentrio. Para comentrios que ultrapassem uma linha, pode-se usar a notao /*
(inicio) e */(fim).
Ex.:
SELECT vl_sal INTO w_salario obtm o salrio atual
/* calculo da
bonificao */
IF w_salario > 50000

5. DECLARAES
TIPOS DE VARIAVEIS
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.
SUBTIPOS So associados aos tipos com uma restrio, que indiquem um subconjunto de
valores.
VARIVEIS SIMPLES
BINARY INTEGER numrico, para armazenamento de valores inteiros de -2**31 a (2**31) - 1
sintaxe:

binary_integer

subtipos:

natural
positive

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

NUMBER numrico, para armazenamento de valores em ponto flutuante com preciso de at 38


dgitos.
sintaxe:

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

subtipos:

dec
decimal
double precision
float
integer
int
numeric
real
smallint

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

CHAR alfanumrico de tamanho fixo com at 32767 caracteres.


sintaxe:

char [ (<comprimento>) ]

subtipo:

string

idem a char

LONG alfanumrico de tamanho varivel com comprimento de at 32760.


sintaxe:

long

__________________________________________________________________________________________
83

__________________________________________________________________________________________
VARCHAR2 alfanumrico de tamanho varivel com comprimento de at 32767.
sintaxe:

varchar2 [(<comprimento>) ]

subtipo:

varchar

idem a varchar2

RAW para armazenamento de dados binrios (tam.mx. at 32767).


sintaxe:

raw (<comprimento>)

LONG RAW para armazenamento de dados binrios at o tamanho de 32760.


sintaxe:

long raw

BOOLEAN valores boleanos (true, false, ou null).


DATE armazenamento de datas.
sintaxe:

date

ROWID valores de rowiddo Oracle (em hexadecimal).


sintaxe:

rowid

formato:

BBBBBBBBB.RRRR.FFFF
onde:
BBBBBBBBB - bloco dentro do arquivo (database file)
RRRR
- row dentro do bloco ( primeira row 0)
FFFF
- nmero do arquivo (database file)

ATRIBUTOS ESPECIAIS
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.
%TYPE este atributo copia os atributos de uma varivel, constante ou coluna do database.
particularmente usado quando declaramos variveis que pertenam as colunas do database.
sintaxe:

<varivel>/<constante>/<coluna>%TYPE

Ex.:
DECLARE
W_CODIGO
NUMBER(3)
W_CODIGO2 W_CODIGO%TYPE; - varivel de tipo idntico a cdigo
W_COD_DEP DEPTO.CD_DEPTO%TYPE
/* varivel de tipo idntico varivel da base de dados cd_depto */

__________________________________________________________________________________________
84

__________________________________________________________________________________________
%ROWTYPE este atributo gera um tipo de registro que representa uma linha da tabela. O registro
pode armazenar uma linha de dados selecionados da tabela ou recebidos de um cursor (fetched).
sintaxe:

<tabela>/<cursor>%ROWTYPE

Ex.:
DECLARE
W_DEP_ROW
DEPTO%ROWTYPE;
W_MAT
NUMBER(3);
CURSOR W_C1 Ls
SELECT CD_DEPTO,NM_DEPTO
FROM DEPTO;
W_C1_ROW WC1%ROWTYPE;

- varivel do tipo row


- cursor com apenas 2 colunas
- colunas da tabela
- possui as mesmas colunas de
W_C1

BEGIN
SELECT * INTO W_DEP_ROW
FROM depto
WHERE cd_mat = W_MAT;
IF W_DEP_ROW.CD_DEPTO = 00

- contm todos os dados lidos FROM


- da linha da tabela
- a referncia a cada campo THEN
- feita com o uso da varivel de
tipo ROWTYPE

PROBLEMA PROPOSTO
Suponhamos a existncia de uma tabela (RESULTADO) com o layout (VALOR N (30), ORDEM N(5)).
Deseja-se preench-la a partir da tabela funcionrio, com a matrcula do funcionrio (ordem) e a
expresso trunc(nr_git*vl_sal/nr_cargo) na coluna valor.
RESOLUO 1:
DECLARE
w_reg_func
FUNC%ROWTYPE;
CURSOR w_c1 lS
SELECT * FROM func ORDER BY cd_mat;
BEGIN
OPEN w_c1;
LOOP
FETCH w_c1 INTO w_reg_func;
EXIT WHEN w_c1%NOTFOUND;
INSERT INTO resultado (ordem,valor)
VALUES (w_reg_func.cd_mat,
trunc(w_reg_func.nr_git * w_reg_func.vl_sal / w_reg_func.nr_cargo));
ENDLOOP;
CLOSE w_c1;
END;

__________________________________________________________________________________________
85

__________________________________________________________________________________________
RESOLUO 2
DECLARE
CURSOR w_c1 lS
SELECT cd_mat, nr_git, vl_sal, nr_cargo FROM func;
w_reg_func
w_c1%ROWTYPE;
BEGIN
OPEN w_c1;
LOOP
FETCH w_c1 INTO w_reg_func;
EXIT WHEN w_c1%NOTFOUND;
INSERT INTO resultado (ordem,valor)
VALUES (w_reg_func.cd_mat,
trunc(w_reg_func.nr_git * w_reg_func.vl_sal / w_reg_func.nr_cargo));
END LOOP;
CLOSE w_c1;
END
VARIVEIS COMPOSTAS
TABLE - tabelas na 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}
[NOT NULLl] INDEX BY BINARY_INETGER

Ex.:
DECLARE
TYPE tab IS TABLE OF char(10)
INDEX BY BINARY_INTEGER;
teste
TAB;
teste (1) := 1234567890;
teste (-1) := -1234567890;
RECORD - Permite a criao de um item estruturado.
sintaxe:

TYPE <nome> IS RECORD


(<campo1>{<tipo campo>/<tabela>.<coluna>%TYPE}[NOT NULL],
<campo2>{<tipo campo>/<tabela>.<coluna>%TYPE}[NOT NULL] ...)

__________________________________________________________________________________________
86

__________________________________________________________________________________________
Ex.:
DECLARE
TYPE registro IS RECORD
(depto
CHAR(03) NOT NULL,
nome
DEPTO. NM_DEPTO%TYPE);
outro_reg
reg_teste

REGISTRO;
REGISTRO;

...........
REG_TESTE.DEPTO := A00;
SELECT cd_depto, nm_depto INTO outro_reg FROM DEPTO
WHERE cd_depto = D11;
Ex.:
DECLARE
TYPE tab is table of CHAR(2) INDEX BY BINARY_INTEGER;
TYPE registro IS RECORD (a1 TAB, a2 CHAR(1));
teste

REGISTRO;

BEGIN
teste.a1 (1) := aa;
teste.a1 (2) := bb;
teste.a1 (3) := cc;

__________________________________________________________________________________________
87

__________________________________________________________________________________________
PROBLEMA PROPOSTO
Deseja-se saber, para cada cargo, a quantidade de funcionrios por departamento. O nome do cargo
deve ser apresentado no resultado.
RESOLUO:
DECLARE
TYPE t_cargo IS TABLE OF char(25)
INDEX BY BINARY_INTEGER;
TYPE t_codigo IS TABLE OF number(3)
INDEX BY BINARY_INTEGER;
cargo
T_CARGO;
cod_cargo
T_CODIGO;
CURSOR w_c1 IS
SELECT func.cd_depto, nr_cargo, nm_depto, count(*) conta
FROM func, depto
WHERE func.cd_depto = depto.cd_depto
GROUP BY func.cd_depto, nm_depto, nr_cargo;
w_c1_row
w_c1%ROWTYPE;
BEGIN
cod_cargo(1) := 42;
cargo(1) := OPERADOR
cod_cargo(2) := 43;
cargo(2) := DIGITADOR
.
.
.
OPEN w_c1;
LOOP
FETCH w_c1 INTO w_c1_row;
EXIT WHEN w_c1%NOTFOUND;
FOR i IN 1..12 LOOP
IF cod_cargo(i) =w_c1_row.nr_cargo
THEN
INSERT INTO saida
(valor, texto, qtd)
VALUES
(w_c1_row.cd_depto, to_char(w_c1_row.nr_cargo)ll ll
cargo(i),w_c1_row.conta);
EXIT;
END IF;
END LOOP;
END LOOP;
END;
CONSTANTES
A declarao de uma constante semelhante declarao de uma varivel, exceto que devemos
adicionar a palavra chave CONSTANT e, imediatamente, associar um valor inicial. Seu valor no
poder ser alterado durante o programa.
sintaxe:

<nome da constante> CONSTANTE<tipo> :=/DEFAULT <valor inicial>;

Ex.:
DECLARE
W_TESTE
W_TESTE1

CONSTANT REAL := 3.14159;


CONSTANT REAL DEFAULT := 3.14159;

__________________________________________________________________________________________
88

__________________________________________________________________________________________

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

EXEMPLOS DE DECLARAES
DECLARE
W_DATA
W_CONTADOR
W_CODIGO
W_TESTE
W_CODIGO2
W_COD_DEP

DATE;
SMALLINT := 0;
CHAR(O3)NOT NULL := A00
CONSTANT REAL := 3.14159;
W_CODIGO%TYPE := B01
DEPTO.CD_DEPTO%TYPE

W_DEP_ROW DEPTO%ROWTYPE
CURSOR W_C1 IS
SELECT cd_depto, nm_depto
FROM DEPTO;
W_C1_ROW
W_C1%ROWTYPE

- varivel de tipo data


- varivel iniciada com zero
- varivel c/ restrio
- /* constante de tipo real - o valor
inicial obrigatrio */
- varivel de tipo idntico a cdigo
- varivel de tipo idntico a varivel da
da base de dados cd_depto
- varivel tipo row
- cursor c/ 2 colunas da tabela
- possui as mesmas colunas de w_c1

BEGIN
SELECT *
INTO W_DEP_ROW
FROM DEPTO
WHERE cd_depto = A00;
IF W_DEP_ROW.cd_DEPTO = A00
THEN
W_CONTADOR := WHERE_CONTADOR + 1;
END IF;
END
VARIVEIS ESPECIAIS
EXCEPTION - nomeia uma exceo definida pelo usurio.
sintaxe:

<nome da exceo> EXCEPTION

Ex.:
DECLARE
erro_matrcula

EXCEPTION;

CURSOR - declara um cursor.

__________________________________________________________________________________________
89

__________________________________________________________________________________________
sintaxe:
CURSOR <nome cursor>[(<parmetro> <tipo>[,<parmetro <tipo>...])]
RETURN<tipo>/<varivel%TYPE/<table.column>%TYPE/<table>%rowtype
IS <comando SELECT >;
onde:
1. A clusula RETURN define o tipo de dado do resultado de um cursor.
2. Pode-se usar o atributo %ROWTYPE para representar uma linha em uma tabela da base.
3. Pode-se usar %TYPE para representar o tipo de uma varivel, constante ou coluna da
base.
4. Um cursor deve estar associado a um comando SELECT com mesmo nmero, tipo e
ordem de elementos selecionados que os da clusula RETURN.
Ex.:
DECLARE
CURSOR w_c1 IS SELECT cd_mat, vl_sal FROM func;
CURSOR w_c2 (dat_ini DATE) IS
SELECT cd_mat, nm_func FROM func
WHERE de_nasc > dat_ini;
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 row.
%FOUND - indica se o ltimo FETCH retornou uma linha ou no, para cursores explcitos. E se
alguma row foi afetada pelo ltimo comando INSERT, UPDATE ou DELETE para cursores
implcitos.
sintaxe:

<cursor> %FOUND
SQL%FOUND

Ex.:
LOOP
FETCH w_c1 INTO w_c1_row;
IF w_c1%FOUND
THEN
%NOTFOUND - indica se o ltimo FETCH retornou uma row ou no, para cursores explcitos. E se
alguma row foi afetada pelo ltimo comando INSERT, UPDATE ou DELETE para cursores
implcitos.
sintaxe:

<cursor>%NOTFOUND
SQL%NOTFOUND

Ex.:
LOOP
FETCH w_c1 INTO w_c1_row;
IF w_c1%NOTFOUND
THEN
EXIT;
...
END LOOP;

__________________________________________________________________________________________
90

__________________________________________________________________________________________
%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

Ex.:
IF NOT (w_c1%ISOPEN)
THEN
...
%ROWCOUNT - indica o nmero de rows lidas para o cursor associado (para cursores explcitos)
ou o nmero de rows 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 row.
sintaxe:

<cursor>%ROWCOUNT
SQL %ROWCOUNT

Ex.:
LOOP
FETCH w_c1 INTO w_c1_row;
IF w_c1% ROWCOUNT
THEN
...
PROBLEMA PROPOSTO
Deseja-se calcular e emitir a folha de pagamento de uma empresa. Em funo da necessidade de se
emitir vrios relatrios sobre o clculo efetuado, ser gerada uma tabela intermediria com os
resultados para posterior impresso.
RESOLUO:
DECLARE
CURSOR w_c1 IS SELECT cd_mat, vl_sal, vl_sal * .10 fgts FROM func;
w_c1_row
w_c1 %ROWTYPE;
w_vl_lim
NUMBER(15,2) :=&1;
w_vl_ir
NUMBER(15,2) := 0;
w_vl_inss
NUMBER(15,2) := 0
tabela invlida
EXCEPTION;
PROCEDURE ir (val_sal IN NUMBER, val_ir OUT NUMBER) IS
BEGIN
IF val_sal < 300.00 THEN
val_ir := 0;
ELSIF val_sal BETWEEN 300.01 AND 1000.00 THEN
val_ir := val_sal *10;
ELSIF val_sal BETWEEN 1000.01 AND 3000.00 THEN
val_ir := val_sal *20;
ELSE
val_ir := val_sal *30;
END IF;
END;
FUNCTION inss (val_sal IN NUMBER, val_lim IN NUMBER) RETURN NUMBER
IS
val_inss
NUMNER(15,2);

__________________________________________________________________________________________
91

__________________________________________________________________________________________
BEGIN
val_inss := val_sal *.08;
IF val_inss := > val_lim THEN
val_inss := val_lim;
END IF;
RETURN val_inss;
END inss;
BEGIN
DELETE FROM folha;
COMMIT;
OPEN w_c1;
LOOP
FETCH w_c1 INTO w_c1_row;
EXIT WHEN w_c1%NOTFOUND;
ir(w_c1_row.vl_sal, w_vl_ir);
w_vl_inss := inss(w_c1_row.vl_sal,w_vl_lim);
INSERT INTO folha (cd_mat, vl_sal, vl_ir, vl_inss, vl_fgts)
VALUES (w_c1_row.cd_mat, w_c1_row.vl_sal, w_vl_ir, w_vl_inss,
w_c1_row.fgts);
END LOOP;
CLOSE w_c1;
COMMIT;
END;

6. ATRIBUIES
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.
Ex.:
sim_no
boolean;
...
sim_no := (contador > 500);
IF sim_no IS NULL
THEN

- verifica se uma varivel tem o valor = NULL

7. FUNES PR-DEFINIDAS
A PL/SQL permite a utilizao de diversas funes pr-definidas para manipulao dos dados. Podese us-las onde expresses do mesmo tipo so permitidas.

CONTROLE DE ERROS
SQLCODE
Funo numrica que retorna o cdigo do erro associado ltima exceo.
Definio:
Ex.:

FUNCTION SQLCODE RETURN NUMBER


<varivel> := SQLCODE;

SQLERRM
Funo string que retorna a mensagem de erro associado ao ltimo SQLCODE.

__________________________________________________________________________________________
92

__________________________________________________________________________________________
Definio:
Ex.:

FUNCTION SQLERRM [(error_number NUMBER)] RETURN CHAR


<varivel> := SQLERRM(-1023);

NUMRICAS
ABS
Retorna o valor absoluto do argumento.
Definio:
Ex.:

FUNCTION ABS (<n> NUMBER) RETURN NUMBER


<varivel> := ABS (<varivel2>);

CEIL
Retorna o menor inteiro maior ou igual ao argumento.
Definio:
Ex.:

FUNCTION CEIL(<n> NUMBER) RETURN NUMBER


<varivel> := CEIL (<varivel2>);

COS
Retorna o coseno do argumento, que deve ser expresso em radianos.
Definio:
Ex.:

FUNCTION COS (<n> NUMBER) RETURN NUMBER


<varivel> := COS (<varivel2>);

Obs.: se <n> estiver em graus, basta que seja dividido por 57.29578 para ser convertido para
radianos.
COSH
Retorna o coseno hiperblico do argumento.
Definio:
Ex.:

FUNCTION COSH (<n> NUMBER) RETURN NUMBER


<varivel> := ABS (<varivel2>);

EXP
Retorna e elevado n-esima potncia, onde e (~2.71828) a base do logaritmo neperiano.
Definio:
Ex.:

FUNCTION EXP (<n> NUMBER) RETURN NUMBER


<varivel> := EXP (<varivel2>);

FLOOR
Retorna o maior inteiro menor ou igual ao argumento.
Definio:
Ex.:

FUNCTION FLOOR(<n> NUMBER) RETURN NUMBER


<varivel> := FLOOR (<varivel2>);

LN
Retorna o logaritmo natural do argumento, que deve ser maior que zero.
Definio:
Ex.:

FUNCTION LN (<n> NUMBER) RETURN NUMBER


<varivel> := LN (<varivel2>);

__________________________________________________________________________________________
93

__________________________________________________________________________________________
LOG
Retorna o logaritmo de <n> na base <m>, sendo que <m> deve ser maior que 1 e <n> deve ser maior
que 1 e <n> deve ser maior que zero.
Definio:
Ex.:

FUNCTION LOG (<n> NUMBER) RETURN NUMBER


<varivel> := LOG (<varivel2>);

MOD
Retorna o resto da diviso de <m> por <n>. Se <n> for zero, <m> retornado.
Definio:
Ex.:

FUNCTION MOD (<n> NUMBER) RETURN NUMBER


<varivel> := MOD (<varivel2>), (<varivel3>);

POWER
Retorna o nmero <m> elevado <n>-sima potncia. Se <m> for negativo, <n> deve ser inteiro.
Definio:
Ex.:

FUNCTION POWER (<n> NUMBER) RETURN NUMBER


<varivel> := POWER (<varivel2>);

ROUND
Retorna <m> arredondado para <n> casas decimais. Se <n> for omitido, zero ser assumido.
Definio:
Ex.:

FUNCTION ROUND (<n> NUMBER) RETURN NUMBER


<varivel> := ROUND (<varivel2>), (<varivel3>);

SIGN
Retorna 1 se o argumento for negativo, 0 se igual a zero ou 1 se o argumento for maior que zero.
Definio:
Ex.:

FUNCTION SIGN (<n> NUMBER) RETURN NUMBER


<varivel> := SIGN (<varivel2>);

SIN
Retorna o seno de <n>, que deve ser expresso em radianos.
Definio:
Ex.:

FUNCTION EXP (<n> NUMBER) RETURN NUMBER


<varivel> := SIN (<varivel2>);

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.
Definio:
Ex.:

FUNCTION SINH (<n> NUMBER) RETURN NUMBER


<varivel> := SINH (<varivel2>);

SQRT
Retorna a raiz quadrada do argumento, que no pode ser negativo.
Definio:
Ex.:

FUNCTION SQRT (<n> NUMBER) RETURN NUMBER


<varivel> := SQRT (<varivel2>);

__________________________________________________________________________________________
94

__________________________________________________________________________________________
TAN
Retorna a tangente de <n>, que deve ser expresso em radianos.
Definio:
Ex.:

FUNCTION TAN (<n> NUMBER) RETURN NUMBER


<varivel> := TAN (<varivel2>);

TANH
Retorna a tangente hiperblica do argumento.
Definio:
Ex.:

FUNCTION TANH (<n> NUMBER) RETURN NUMBER


<varivel> := TANH (<varivel2>);

TRUNC
Retorna o nmero <m> truncado para <n> casas decimais. Se o <n> for omitido, zero ser assumido.
Definio:
Ex.:

FUNCTION TRUNC (<n> NUMBER) RETURN NUMBER


<varivel> := TRUNC (<varivel2>);

CARACTERES
ASCII
Retorna o cdigo ASCII correspondente string informada no argumento.
Definio:
Ex.:

FUNCTION ASCII (<str> VARCHAR2) RETURN NUMBER


<varivel> := ASCII (<varivel2>);

CHR
Retorna a string correspondente representao numrica informada como argumento. o contrario
da funo ASCII.
Definio:
Ex.:

FUNCTION CHR (<n> NUMBER) RETURN CHR


<varivel> := CHR (<varivel2>);

CONCAT
Retorna uma string que o resultado da concatenao de <str1> (na frente) com <str2>.
Definio:
Ex.:

FUNCTION CONCAT (<str1> VARCHAR2,<str2> VARCHAR2) RETURN VARCHAR2


<varivel> := CONCAT (<varivel2>,<varivel3>);

INITCAP
Retorna a primeira letra de cada palavra do argumento em letra maiscula e as demais em
minsculas.
Definio:
Ex.:

FUNCTION INITCAP (<str> VARCHAR2) RETURN VARCHAR2


<varivel> := INITCAP (<varivel2>);

INSTR
Retorna a posio da <n>-sima ocorrncia de <str2> dentro de <str1>, comeando na posio
<pos>.

__________________________________________________________________________________________
95

__________________________________________________________________________________________
Definio:
Ex.:

FUNCTION INSTR (<str1> VARCHAR2,<str2> VARCHAR2) [<pos> NUMBER [,<n>


NUMBER ]]) RETURN NUMBER
<varivel> := INSTR (<varivel2>, <variavel3>,<pos>,<n>);

LENGTH
Retorna o nmero de caracteres da string <str>. Se o argumento um item definido como CHAR, o
comprimento incluir os brancos. Se <str> for null, o resultado da funo ser NULL.
Definio:
Ex.:

FUNCTION LENGTH (<str> VARCHAR2) RETURN NUMBER


<varivel> := LENGTH (<varivel2>);

LOWER
Retorna o argumento com todas as letras minsculas.
Definio:
Ex.:

FUNCTION LOWER (<str> VARCHAR2) RETURN VARCHAR2


<varivel> := LOWER (<varivel2>);

LPAD
Completa esquerda, com os caracteres <pad> para que o tamanho da string resultado seja <len>.
Definio:
RETURN
Ex.:

FUNCTION LPAD (<str>

VARCHAR2,<len> NUMBER [,<pad> VARCHAR2])

VARCHAR2
<varivel> := LPAD (<varivel2>, <comprimento>,*);

LTRIM
Retira , da esquerda para direita, os caracteres <set> at que seja encontrado um caracter diferente
de <set>.
Definio:
Ex.:

FUNCTION LTRIM (<str> VARCHAR2 [, <set> VARCHAR2]) RETURN VARCHAR2


<varivel> := LTRIM (<varivel2>, <varivel3>);

REPLACE
Retorna <str1> com cada ocorrncia de <str2> substituda por <str3>. Se <str3> no for informado,
todas as ocorrncias se <str2> sero removidas. Se nem <str2> nem <str3> forem informadas a
funo retornar NULL.
Definio:
Ex.:

FUNCTION REPLACE (<str1> VARCHAR2,<str2> VARCHAR2[,<str3> VARCHAR2])


RETURN VARCHAR2
<varivel> := REPLACE (<varivel1>, <varivel2>,<varivel3);

RPAD
Completa, direita, com os caracteres <pad> para que o tamanho da string resultado seja <len>.
Definio:

FUNCTION RPAD (<str> VARCHAR2,<len> NUMBER [,<pad> VARCHAR2])


RETURN VARCHAR2
(<n> NUMBER) RETURN NUMBER
Ex.:
<varivel> := RPAD (<varivel2>, < tamanho>,*);
RTRIM
Retira , da direita para esquerda, os caracteres <set> at que seja encontrado um caracter diferente
de <set>.

__________________________________________________________________________________________
96

__________________________________________________________________________________________
Definio:
Ex.:

FUNCTION RTRIM (<str> VARCHAR2 [, <set> VARCHAR2]) RETURN VARCHAR2


<varivel> := RTRIM (<varivel2>, <varivel3>);

SOUNDEX
Retorna um string que represente o som de <str>.
Definio:
Ex.:

FUNCTION SOUNDEX (<str> VARCHAR2) RETURN VARCHAR2


<varivel> := SOUNDEX (<varivel2>);

SUBSTR
Retorna uma parte da string <str>, a partir da posio <pos> por <len> caracteres. Se l<len> for
omitido, retorna o restante da string.
Definio:
Ex.:

FUNCTION SUBSTR (<str> VARCHAR2, <pos> NUMBER [,<len> NUMBER])


RETURN VARCHAR2
<varivel> := SUBSTR (<varivel2>, <posio inicial>, <tamanho>);

TRANSLATE
Retorna <str>, substituindo cada um dos caracteres presentes em <set1> pelo caracter
correspondente em <set2>. Se <set1> tiver mais caracteres que <set2>, e esses caracteres
estiverem presentes em <str>, sero removidos do resultado.
Definio:
Ex.:

FUNCTION TRANSLATE (<str> VARCHAR2, <set1> VARCHAR2,<set3> CHAR)


RETURN VARCHAR2
<varivel> := TRANSLATE (<varivel2>, ABCDEF, GHIJKL);

UPPER
Retorna o argumento com todas as letras maisculas.
Definio:
Ex.:

FUNCTION UPPER (<str> VARCHAR2) RETURN VARCHAR2


<varivel> := UPPER (texto);

DATAS
ADD_MONTHS
Retorna a data <dte> adicionada de <n> meses. <n. deve ser um inteiro e pode ser negativo.
Definio:
Ex.:

FUNCTION ADD_MONTHS (<dte> DATE, <n>NUMBER) RETURN DATE


<varivel> := ADD_MONTHS (v_dt_nasc,4);

LAST_DAY
Retorna a data do ltimo dia do ms de <dte>.
Definio:
Ex.:

FUNCTION LAST_DAY (<dte> DATE) RETURN DATE


<varivel> := LAST_DAY (<v_dt_adm>);

MONTHS_BETWEEN
Retorna o nmero de meses entre <dte1> e <dte2>.
Definio:
FUNCTION MONTHS_BETWEEN (<dte1> DATE,<dte2> DATE) RETURN DATE
Ex.:
<varivel> := MONTHS_BETWEEN (sysdate, v_dt_nasc) /12;

__________________________________________________________________________________________
97

__________________________________________________________________________________________
NEW_TIME
Converte a data e hora que est no meridiano <zon1>, para a data e hora no meridiano <zon2>.
Definio:
Ex.:

FUNCTION NEW_TIME (<dte> DATE,<zon1> VARCHAR2, <zon2> VARCHAR2)


RETURN DATE
<varivel> := NEW_TIME (v_dt_nasc, AST,GMT);

ABREVIATURAS PARA MERIDIANOS


AST,ADT
GMT
PST, PDT

Atlantic Standard ou Daylight Time


Greenwitch
Pacific Standard ou Daylight Time

NEXT_DAY
Retorna a data do primeiro dia da semana nomeado por <day> que seja posterior a <dte>.
Definio:
Ex.:

FUNCTION NEXT_DAY (<dte> DATE,<day> VARCHAR2) RETURN DATE


<varivel> := NEXT_DAY (sysdate, moday);

SYSDATE
Retorna a data e hora correntes.
Definio:
Ex.:

FUNCTION SYSDATE RETURN DATE


<varivel> := SYSDATE ;

ROUND
Retorna <dte> arredondado para o formato especificado.
Definio:
Ex.:

FUNCTION ROUND (<dte> [,<fmt>]) RETURN DATE


<varivel> := ROUND (sysdate,ww);

TRUNC
Retorna uma data no formato especificado por <fmt>, representado <dte> truncada na unidade
correspondente.
Definio:
Ex.:

FUNCTION TRUNC (<dte> DATE [, <fmt> VARCHAR2 ) RETURN DATE


<varivel> := TRUNC (sysdate,ww);

FORMATOS PARA ROUND E TRUNC


CC
SYYY, YYYY, YEAR, SYEAR, YYY, YY, Y
Q
MONTH, MON, MM
WW
WHERE
DDD, DD, J
DAY, DY, D
HH, HH12, HH24
MI

Sculo
Ano
Quarto de ano
Ms
Incio da semana do ano
Incio da semana do ms
Dia
ltimo Sbado
Hora
Minuto

__________________________________________________________________________________________
98

__________________________________________________________________________________________

CONVERSO
CHARTOROWID
Converte a string <str> do tipo CHAR ou VARCHAR2 para ROWID.
Definio:
Ex.:

FUNCTION CHARTOROWID (<str> CHAR) RETURN ROWID


<varivel> := CHARTOROWID (00000000E.0000007);

HEXTORAW
Converte uma string hexadecimal do tipo CHAR ou VARCHAR2 para RAW.
Definio:
Ex.:

FUNCTION HEXTORAW (<str> CHAR) RETURN RAW


FUNCTION HEXTORAW (<str> VARCHAR2) RETURN RAW
<varivel> := HEXTORAW (F6);

RAWTOHEX
Converte um valor binrio em uma string hexadecimal do tipo VARCHAR2.
Definio:
Ex.:

FUNCTION RAWTOHEX (<bin> RAW) RETURN VARCHAR2


<varivel> := RAWTOHEX (<varivel do tipo raw);

ROWIDTOCHAR
Converte o valor binrio de <bin> para uma string hexadecimal de 18 bytes.
Definio:
Ex.:

FUNCTION ROWIDTOCHAR (<bin> ROWID) RETURN VARCHAR2


<varivel> := ROWIDTOCHAR (<varivel do tipo rowid);

TO_CHAR
Converte um valor numrico ou data para o formato especificado.
Definio:

Ex.:

FUNCTION TO_CHAR (<dte> DATE [,<fmt> VARCHAR2 [,<nls1>]])


RETURN VARCHAR2
FUNCTION TO_CHAR (<n> NUMBER) [,<fmt> VARCHAR2[,<NLS2>]])
RETURN VARCHAR2
<varivel> := TO_CHAR(5678.32, 9.999.99, nls_numeric_characters =, .);

FORMATOS NUMRICOS PARA TO CHAR E TO NUMBER


9
0
$
B
MI
S
PR
D
G
,
.
V

9999
0999
$999
B999
999MI
S999
999PR
99D99
99G99
99,99
99.99
999V99

E
RN,rn

9.99EEEE
RN

A quantidade de 9s determina o comprimento


Completa com zeros esquerda em vez de brancos
Prefixa o valor com o smbolo $
Substitui o valor 0 por branco
Mostra - aps um valor negativo
Coloca um - ou um + antes do nmero.
Mostra um valor negativo entre <>
Inclui o caracter decimal
Inclui o caracter separador de milhar
Mostra uma , na posio correspondente.
Mostra um . decimal na posio correspondente.
Multiplica o valor por 10<n>, onde <n> corresponde ao nmero de
9s aps V
Notao cientfica
Maiscula ou minscula para numerais romanos

__________________________________________________________________________________________
99

__________________________________________________________________________________________
FORMATOS DE NLS
NLS_DATE_LANGUAGE = <language> ________________para <nls1>
NLS_NUMERIC_CHARACTERS = <d> <g>,
NLS_CURRENCY = <text>
NLS_ISSO_CURRENCY = <text> ____________ para <nls2>
Onde:
<d>
<g>
<text>

caracter decimal
separador de milhar
smbolo monetrio

TO_DATE
Converte uma string ou um nmero para o formato data.
Definio:
Ex.:

FUNCTION TO_DATE (<str> VARCHAR2[,<fmt> VARCHAR2 [,<nls1>]])


RETURN DATE
<varivel> := TO_DATE (12/01/84, dd/mm/yy)

FORMATOS DE DATA PARA TO_CHAR E TO_DATE


CC, SCC
SYYY, YYYY, YEAR, SYEAR, YYY, YY, Y
Q
MONTH
MON
MM
WW
WHERE
WHERE
DDD
DD
D
DAY
DY
J
HH, HH12, HH24
MI
SS

Sculo
Ano
Quarto de ano
Ms por extenso
Ms abreviado para trs letras
Ms (numrico)
Semana do ano
Semana do ms
Incio da semana do ms
Dia do ano
Dia do ms
Dia da semana
Nome do dia
Dia abreviado p/ 3 letras
Dia em data Juliana
Hora
Minuto
Segundo

TO_NUMBER
Converte <str> para o valor numrico correspondente.
Definio:
Ex.:

FUNCTION TO_NUMBER (<str> VARCHAR2 [, <nls2> ]])


RETURN NUMBER
<varivel> := TO_NUMBER (5.678,32, 9.999,99, nls_numeric_characters = , .);

MISCELNEA
DECLARE
S permitido em comandos SQL.

__________________________________________________________________________________________
100

__________________________________________________________________________________________
GREATEST
Retorna a maior <expr> da lista de valores. Todas as expresses aps a primeira so convertidas
para o tipo de dado da primeira antes da comparao ser feita.
Definio:
Ex.:

FUNCTION GREATEST (<expr1>, <expr2>,...)


<varivel> := GREATEST (aaaa, bbb, cccc);

LEAST
Retorna a menor <expr> da lista de valores. Todas as expresses aps a primeira so convertidas
para o tipo de dado da primeira antes da comparao ser feita.
Definio:
Ex.:

FUNCTION LEAST (<expr1>, <expr2>,...)


<varivel> := LEAST(aaaa, bbb, cccc);

NVL
Se <expr1> for null, retorna <expr2>. Se <expr1> no for null, retorna <expr1>.
Definio:

FUNCTION NVL ((<expr1>, <expr2>,) RETURN <ret>


Onde: <ret> ser de tipo igual a <expr1> e <expr2>

Ex.:

<varivel> := NVL (v_nr_gir,0);

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

FUNCTION UID RETURN NUMBER


<varivel> := UID;

USER
Retorna o username corrente.
Definio:
Ex.:

FUNCTION USER RETURN VARCHAR2


<varivel> := USER;

USERENV
Retorna informaes sobre o user e a sesso.
Definio:
Ex.:

FUNCTION USERENV (<str> VARCHAR2) RETURN VARCHAR2


<varivel> := USERENV (terminal);

Valores de <str>
entryid
sessionid
terminal
language

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

VSIZE
Retorna o nmero de bytes usado para armazenar a representao interna de <expr>.
Definio:
Ex.:

FUNCTION VSIZE (<exp> DATE l NUMBER l VARCHAR2) RETURN NUMBER


<varivel> := VSIZE (sysdate);

__________________________________________________________________________________________
101

__________________________________________________________________________________________
PROBLEMA PROPOSTO:
Gravar na tabela RESULTADO a quantidade de funcionrios por departamento, convertendo o cdigo
do departamento da seguinte forma:

departamentos AXX
departamentos BXX
e assim por diante

somar 100 ao nmero do departamento


somar 200 ao nmero do departamento

RESOLUO
DECLARE
CURSOR w_c1 IS SELECT cd_depto,count(*) total FROM func GROUP BY cd_depto;
W_c1_row
w_c1%ROWTYPE
w_cd_depto
number(3);
w_str_depto
varchar(1);
BEGIN
OPEN w_c1;
LOOP
FETCH w_c1 INTO w_c1_row;
IF w_c1%NOTFOUND
THEN
CLOSE w_c1;
EXIT;
ENDIF;
W_str_depto := SUBSTR (w_c1_row.cd_depto, 1, 1);
IF w_str_depto = ATHEN w_cd_depto := 100;
ELSIF w_str_depto = B THEN w_cd_depto :=200;
ELSIF w_str_depto = C THEN w_cd_depto :=300;
ELSIF w_str_depto = D THEN w_cd_depto :=400;
ELSIF w_str_depto = E THEN w_cd_depto :=500;
END IF;
w_cd_depto := w_cd_depto+ TO_NUMBER(SUBSTR(w_c1_row.cd_depto,2,2));
INSERT INTO RESULTADO (ordem, campo) VALUES
(w_cd_depto,w_c1_row.total);
END LOOP;
END;

__________________________________________________________________________________________
102

__________________________________________________________________________________________

8. COMANDOS
LABELS
Identifica um comando ou conjunto de comandos. Utilizado para desvios e para qualificao.
Deve existir um comando aps o LABEL.
sintaxe:

<<label>>

Ex.:
<<externo>>
FOR i IN 1..10 LOOP
IF externo.i
THEN
...
ENDIF;
<<Interno>>
FOR i IN 1..10 LOOP
IF inetrno i
THEN
...
ENDIF
EXIT externo WHEN... encerra ambos os loops
END LOOP;
END LOOP externo;
<<fim>>
-- este comando ilegal porque END no
End;
-- um comando executvel

EXIT
Encerra um loop.
sintaxe:

EXIT [ <label>] [WHEN <condio>]

Ex.:
LOOP
FETCH w_c1 INTO w_c1_row;
IF w_c1%FOUND
THEN
calc_ir....
....
INSERT
ELSE
EXIT;
ENDIF
END LOOP;

__________________________________________________________________________________________
103

__________________________________________________________________________________________

IF THEN ELSE
A seqncia de comandos s ser executada se a condio for verdadeira.
sintaxe:
IF <condio>
THEN
<seqncia de comandos>
END IF;
ou
IF <condio>
THEN
<seqncia de comandos>
ELSE
<seqncia de comandos>
END IF;
ou
IF <condio>
THEN
<seqncia de comandos>
ELSIF <condio>
THEN
<seqncia de comandos>
ELSE
<seqncia de comandos
END IF;
<condio>
[NOT] <expresso boleana> [[AND I OR ] <expresso boleana>]
<expresso boleana>]
<literal boleano> I
<varivel boleana> I
<chamada de funo boleana> I
(<expresso boleana>) I
<expresso PLSQL> <operador relacional> <expresso PLSQL> I
<expresso PLSQL> IS [NOT] NULL I
<expresso PLSQL> [NOT] LIKE <pattern> I
<expresso PLSQL> [NOT] BETWEEN
<expresso PLSQL> AND <expresso PLSQL> I
<expresso PLSQL> [NOT] IN (<expresso PLSQL>[,
<expresso PLSQL>]) I
<expresso PLSQL> { <nome cursor> I SQL}
{%NOTFOUND I %FOUND I%ISOPEN}

__________________________________________________________________________________________
104

__________________________________________________________________________________________
Ex.:
IF val_sal < 300.00
THEN
Val_ir := 0;
ELSIF val_sal BETWEEN 300.01 AND 1000.00+
THEN
val_ir := val_sal * .10;
ELSEIF val_sal BETWEEN 1000.01 and 3000.00
THEN
val_ir := val_sal * .20;
ELSE
val_ir := val_sal * .30;
END IF;

LOOP
A seqncia de comandos executada num nmero infinito de vezes ou at que seja encontrado um
comando EXIT ou a condio de WHEN seja satisfeita.
sintaxe:
[<< <label> >>]
LOOP
<sequencia de comandos>
END LOOP
ou
LOOP
<sequencia de comandos>
IF ....
THEN
EXIT; -- encerra o loop
END IF;
END LOOP;
ou
LOOP
<sequencia de comandos>
EXIT WHEN
-- encerra o loop
END LOOP;
Ex.:
OPEN w_c1;
LOOP
FETCH
WHERE_C1 INTO w_c1_row;
EXIT WHEN w_c1%NOTFOUND;
calc_ir(w_c1_row.vl_sal,w_vl_lim);
...
END LOOP;
CLOSE w_c1;

__________________________________________________________________________________________
105

__________________________________________________________________________________________
PROBLEMA PROPOSTO:
Preencher a tabela TABDEP (nome, cdigo, salrio, mdia, totsal, totmd) com os valores abaixo
obtidos na tabela de departamento:

nome
cdigo
salrio
mdia
totsal
totmd

nome do departamento
cdigo do departamento
somatrio dos salrios do departamento correspondente
mdia salarial do departamento correspondente
total de salrios da tabela de funcionrios
mdia da tabela de funcionrios total

RESOLUO
DECLARE
w_tot_sal
number(10,2);
w_tot_med
number(10,2);
CURSOR w_ c1 IS
SELECT nm_depto, depto.cd_depto, SUM(vl_sal)soma, AVG(vl_sal) media
FROM func, depto
WHERE func.cd_depto = depto.cd_depto
GROUP BY nm_depto, depto.cd_depto;
w_c1_row
w_c1%ROWTYPE;
BEGIN
SELECT SUM(vl_sal) INTO w_tot_sal FROM func;
SELECT AVG(vl_sal) INTO w_tot_med FROM func;
OPEN w_c1;
LOOP
FETCH w_c1 INTO w_c1_row;
IF w_c1%NOTFOUND
THEN
CLOSE w_c1
EXIT;
END IF;
INSERT INTO tabdep (nome, cdigo, salrio, mdia, totsal, totmed)
VALUES
(w_c1_row.nm_depto, w_c1_row.cd_depto, w_c1_row.soma,
w_c1_row.media, w_tot_sal, w_tot_med);
END LOOP;
END;

__________________________________________________________________________________________
106

__________________________________________________________________________________________

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;
Ex.:
OPEN w_c1;
FETCH w_c1 INTO w_c1_row;
WHILE w_c1%FOUND LOOP
...
INSERT INTO folha
END LOOP;
CLOSE w_c1;
PROBLEMA PROPOSTO:
Preencher a tabela TABDEP (nome, cdigo, salrio, mdia, totsal, totmd) com os valores abaixo
obtidos na tabela de departamento

nome
cdigo
salrio
mdia
totsal
totmd

nome do departamento
cdigo do departamento
somatrio dos salrios do departamento correspondente
mdia salarial do departamento correspondente
total de salrios da tabela de funcionrios
mdia da tabela de funcionrios total

Obs.:
Este problema o mesmo anterior.
RESOLUO:
DECLARE
w_tot_sal
number(10,2);
w_tot_med
number(10,2);
CURSOR w_c1 IS
SELECT nm_depto, depto.cd_depto, SUM,(vl_sal)soma,AVG(vl_sal)media
FROM func, depto
WHERE func.cd_depto = depto.cd_depto
GROUP BY nm_depto, depto.cd_depto;
W_c1_row
w_c1%ROWTYPE;
BEGIN
SELECT SUM(vl_sal) INTO w_tot_sal FROM func;
SELECT AVG(vl_sal) INTO w_tot_med FROM func;
OPEN w_c1;
FETCH w_c1 INTO w_c1_row;
WHILE w_c1%FOUND LOOP
INSERT INTO tabdep (nome, cdigo, salrio, mdia, totsal, totmed)
VALUES
(w_c1_row.nm_depto, w_c1_row.cd_depto, w_c1_row.soma, w_c1_row.media,
w_tot_sal, w_tot_med);
FETCH w_c1 INTO w_c1_row;
END LOOP;
END;

__________________________________________________________________________________________
107

__________________________________________________________________________________________

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.
sintaxe:
[<< <label> >>]
FOR <contador> IN [REVERSE] <inferior>..<superior> LOOP
<seqncia da comandos>
END LOOP;
Ex.:
FOR i IN 1..3 LOOP
<seqncias de comandos>
END LOOP;
Vezes := i +1

<seqncia de comandos>
executa 3 vezes
o comando vezes invlido, pois i s
existe no escopo do comando FOR

FOR i IN incio..fim LOOP


<seqncia de comandos>
END LOOP;

<seqncia de comandos>
<executada n vezes dependendo
do valor de incio e fim

Fim := 1;
FOR i IN 3..fim LOOP
<seqncia de comandos>
END LOOP;

<seqncia de comados>
no ser executada

FOR IN REVERSE 1..3 LOOP


<seqncia de comandos>
END LOOP;

<seqncia de comandos>
ser executado 3 vezes
i ter o valor inicial de 3

<<incio>>
FOR i IN 1..25 LOOP
FOR i IN 1..10 LOOP
IF incio.i > 15
THEN...
END LOOP;
END LOOP INCIO;

a varivel usada em um loop


automaticamente declarada pela PL/SQL
no exemplo foram criadas
duas variveis i
a referncia ao nvel
externo feita atravs
do label

<<incio>>
FOR i IN 1..25 LOOP
FOR i IN 1..10 LOOP
..
EXIT incio WHEN
END LOOP;
END LOOP incio;

esta forma de interrupo


do loop (exit <label> when..)
encerra os dois nveis
de loops

__________________________________________________________________________________________
108

__________________________________________________________________________________________

GOTO
Desvia incondicionalmente para um label, o qual deve ser dentro do scopo e deve preceder um
comando ou um bloco da PL/SQL.
sintaxe: GOTO << <label> >>
Ex.:
BEGIN

GOTO inclui;

desvio para o comando INSERT

<<inclui>>
INSERT INTO func
END;
BEGIN

<<altera>>
BEGIN
UPDATE func

END;
GOTO altera;

<<fim>>
END;

o desvio pode ser para traz

este label porque END


no um comando executavl

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;

Ex.:
BEGIN

<<fim>>
NULL;

o comando null resolve


o problema anterior

END;
PROBLEMA PROPOSTO:
Preencher a tabela TABDEP (nome, cdigo, salrio, mdia, totsal, totmd) com os valores abaixo
obtidos na tabela de departamento:

nome
cdigo
salrio
mdia
totsal
totmd

nome do departamento
cdigo do departamento
somatrio dos salrios do departamento correspondente
mdia salarial do departamento correspondente
total de salrios da tabela de funcionrios
mdia da tabela de funcionrios total

Obs: Este problema o mesmo anterior.

__________________________________________________________________________________________
109

__________________________________________________________________________________________
RESOLUO:
DECLARE
w_tot_sal
number(10,2)
w_tot_med
number(10,2)
CURSOR w_c1 IS
SELECT nm_depto, depto.cd_depto, SUM(vl_sal) soma, AVG(vl_sal)media
FROM func, depto
WHERE func.cd_depto = depto.cd_depto;
GROUP BY nm_depto, depto.cd_depto;
w_c1_row
w_c1% ROWTYPE;
BEGIN
SELECT SUM(vl_sal) INTO w_tot_sal FROM func:
SELECT AVG(vl_sal) INTO w_tot_med FROM func;
OPEN w_c1;
<<ler>>>
FETCH w_c1 INTO w_c1_row;
IF w_c1%FOUND
THEN
INSERT INTO tabdep (nome, cdigo, salrio, mdia, totsal, totmd)
VALUES
(w_c1row.nm_depto, w_c1_row.cd_depto,w_c1_row.soma),
w_c1_row.media, w_tot_sal, w_tot_med);
GOT ler;
END IF;
END;

9. COMUNICAO COM O SQL


Por ter uma extenso do SQL, a PL*SQL permite a utilizao de quase todos os comandos SQL.
Foram excludos desta lista dos comandos de DDL (ALTER, CREATE, RENAME,...) e os de DDL
(GRANT, REVOKE,...).
Consideramos que a sintaxe dos comandos SQL j de conhecimento dos leitores e no sero
repetidos nesta apostila.

OPEN CURSOR
Executa o query associado com uma declarao explcito de cursor.
sintaxe:

OPEN <cursor> [(<parmetro> [, <parmetro> ...])]

Ex.:
DECLARE
CURSOR
w_c2 (matrcula NUMBER) IS
SELECT nm_func, cd_mat
FROM func
WHERE cd_mat <= matrcula;
BEGIN
OPEN w_c2 (350);
....
END;

__________________________________________________________________________________________
110

__________________________________________________________________________________________

CURSOR LOOP
Implicitamente declara uma rea para receber a row, abre um cursor, l cada row e fecha o cursor
quando todas as rows tiverem sido processadas.
sintaxe:

[<< <label> >>]


FOR <RECORD> IN <cursor> [(<parmetro> [,<parmetro> ...])] LOOP
<seqncia de comandos>
END LOOP;

Ex.:
DECLARE
CURSOR w_c2 IS SELECT cd_mat, vl_sal, vl_sal * .10 fgts
FROM func;
...
BEGIN
DELETE FROM folha;
COMMIT;
FOR w_c2_row IN w_c2 LOOP
calc_ir(w_c2_row.vl_sal, w_vl_ir);
w_vl_inss := calc_inss(w_c2_row.vl_sal, w_vl_lim);
INSERT INTO folha
(cd_mat, vl_sal, vl_ir, vl_inss, vl_fgts)
VALUES
(w_c2_row.cd_mat, w_c2_row.vl_sal,
w_vl_ir, w_vl_inss, w_c2_row.fgts);
END LOOP;
COMMIT;
END;
PROBLEMA PROPOSTO:
Preencher a tabela TABDEP (nome, cdigo, salrio, mdia, totsal, totmd) com os valores abaixo
obtidos na tabela de departamento:

nome
cdigo
salrio
mdia
totsal
totmd

nome do departamento
cdigo do departamento
somatrio dos salrios do departamento correspondente
mdia salarial do departamento correspondente
total de salrios da tabela de funcionrios
mdia da tabela de funcionrios total

Obs: Este problema o mesmo anterior.

__________________________________________________________________________________________
111

__________________________________________________________________________________________
RESOLUO:
DECLARE
w_tot_sal
number(10,2)
w_tot_med
number(10,2)
CURSOR w_c1 IS
SELECT nm_depto, depto.cd_depto, SUM(vl_sal) soma, AVG(vl_sal)media
FROM func, depto
WHERE func.cd_depto = depto.cd_depto;
GROUP BY nm_depto, depto.cd_depto;
BEGIN
SELECT SUM(vl_sal) INTO w_tot_sal_ FROM func;
SELECT AVG(vl_sal) INTO w_tot_med_ FROM func;
FOR w_c1row IN w_c1 LOOP
INSERT INTO tabdep (nome, cdigo, salrio, mdia, totsal, totmd)
VALUES
(w_c1row.nm_depto, w_c1_row.cd_depto,w_c1_row.soma,
w_c1_row.media, w_tot_sal, w_tot_med);
END LOOP;
END;

10.

TRATAMENTO DE ERROS

Em PL/SQL uma warning ou error condition chamada uma exception. Existem algumas excees
j definidas pelo Oracle com minemnico para referncia. Para as demais, podem ser dados nome
pelo usurio, como veremos neste captulo.
Quando um erro ocorre, uma exception setada, isto , a seqncia de execuo do programa
interrompida e o controle transferido para a rea de tratamento de execuo 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.

__________________________________________________________________________________________
112

__________________________________________________________________________________________

EXCEES PR-DEFINIDAS
Nome da Exceo
CURSOR_ALREADY_OPEN

Oracle Error
ORA-06511

SQLCODE
-6511

DUP_VAL_ON_INDEX

ORA-00001

-1

INVALID_CURSOR

ORA-01001

-1001

INVALID_NUMBER

ORA-01722

-1722

LOGIN_DENIED

ORA-01017

-1017

NO_DATA_FOUND

ORA-01403

+100

NOT_LOGGED_ON

ORA-01012

-1012

PROGRAM_ERROR

ORA-06501

-6501

STORANGE_ERROR

ORA-06500

-6500

TIME_ON_RESOURSE

ORA-00051

-51

TOO_MARY_ROWS

ORA-014222

-1422

TRANSACTION_BACKED_O
UT

ORA-00061

-61

VALUE_ERROR

ORA-06502

-6502

ZERO_DIVIDE

ORA-01476

-1476

Condio de Erro
setada se for executado um
OPEN para um cursor j aberto.
setada se for tentada uma
incluso de uma coluna com valor
duplicado em uma tabela que
possui um ndice unique nesta
coluna.
setada se for feita uma
operao ilegal com um cursor.
Por exemplo: CLOSE em um
cursor no aberto.
setada se algum comando SQL
tentou uma converso de uma
string para nmero e esta
converso falha porque a string
no representa um nmero.
setada se for feita uma tentativa
de
logon
com
um
username/password invlido.
setada se num SELECT INTO
nenhuma row foi retornada ou se
foi feita uma referncia a uma row
no inicializada em uma tabela
PL/SQL.
setada se uma programa
PL/SQL tenata fazer acesso ao
database sem efetuar um logon.
setada se ocorrer um problema
interno.
setada se PL/SQL sai da
memria ou se a memria estiver
corrompida.
setada se ocorrer timeout
enquanto o ORACLE estiver
aguardando por um recurso.
setada se um comando
SELECT INTO retormar mais que
uma row.
setada quando a parte remota
de
uma
transao

desmanchada. A transao local


deve ser desmanchada tambm.
setada se uma operao
aritmtica, converso, constraint
error, truncation ocorrer.
setada se houver ocorrido uma
diviso por zero.

__________________________________________________________________________________________
113

__________________________________________________________________________________________
Ex.:
DECLARE

BEGIN
SELECT
SELECT
SELECT
EXCEPTION
WHEN NO_DATA_FOUND THEN

END;
PROBLEMA PROPOSTO:
Fazer um programa para crtica dos dados informados atravs de parmetros:

salrio deve estar entre R$ 1500 e R$ 2000 mensais. Na base gravado o salrio atual.
departamento deve existir na tabela de departamentos.
grau de instruo deve estar entre 15 e 20.
ramal deve iniciar com 2.
sexo deve ser F ou M.

RESOLUO:
DECLARE
w_salario
number(7,2) := &1;
w-depto
char(3) := &2;
w_git
number(2) := &3;
w_ramal
number(4) := &4;
w_nome
char(8) := &5;
w_sexo
char(1) := &6;
e_salario
exception;
e_salario
exception;
e_depto
exception;
e_git
exception;
e_ramal
exception;
e_sexo
exception;
w_aux
number(3) := );
BEGIN
IF w_salario < 1500 OR w_salario > 2000 THEN
RAISE e_salario;
END IF;
select count(*) into w_auxi FROM depto WHERE cd_depto = w_depto;
IF w_aux = o THEM
RAISE e_depto;
END IF;
IF w_git < 15 OR w_git > 20 THEM
RAISE e_git;
END IF;
IF SUBSTR(TO_CHAR (nr_ramal),1,1) <> 2 THEM
RAISE e_ramal;
END IF;
IF w_sexo <> F' AND w_sexo <> M THEM
RAISE e_sexo;
END IF;
SELECT MAX(cd_mat) INTO w_aux FROM func;
INSERT INTO func (cd_mat, vl_sal, cd_depto, nr _ramal, in_sexo, nm _func, nr _git)
VALUES (w_aux + 1, w_sal * 12, w_depto, w_ramal, w_sexo. w_func, w_git);
EXCEPTION
WHEN e_sexo THEM

__________________________________________________________________________________________
114

__________________________________________________________________________________________
RAISE_APPLICATION_ERROR (-20001, SEXO INVALIDO);
WHEN e_ramal THEM
RAISE_APPLICATION_ERROR (-20003, GRAU DE INSTRUCAO
INVALIDO);
WHEN e_depto THEM
RAISE_APPLICATION_ERROR (-20004, DEPARTAMENTO INVALIDO);
WHEN e_salario THEN
RAISE_APPLICATION_ERROR (-20005, SALARIO INVALIDO);
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR (-20999, SQLERRM(SQLCODE));
END;

EXCEES DEFINIDAS PELOS USURIOS


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

RAISE <exceo>

Ex.:
DECLARE
erro_soma EXCEPTION;

BEGIN
IF
THEN
RAISE erro_soma;
END IF;
EXCEPTION
WHEN erro_soma THEN

WHEN OTHERS THEN

END;
Obs.: O desvio de execuo do programa transferido para a exceo OTHERS quando o erro
ocorrido no foi tratado em outras excees mais especficas. uma opo para diminuio da
lista de exceptions.
PRAGMA EXCEPTION_INIT
Associa um nome de exceo com um nmero de SQLCODE. Isto permite que se faam testes se
erro mais especficos em vez de usar OTHERS.
sintaxe:

PRAGMA EXCEPTION_INIT (<nome da exceo>,<nmero>)

__________________________________________________________________________________________
115

__________________________________________________________________________________________
Ex.:
DECLARE
sem_privilegio EXCEPTION;
PRAGMA EXCEPTION_INIT (sem_privilegio, -1031);
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.
BEGIN

EXCEPTION
WHEN sem_privilegio THEN

END;
RAISE_APPLICATION_ERROR
uma procedure que permite ao usurio enviar mensagens de um subprograma ou database trigger.
sintaxe:

RAISE_APPLICATION_ERROR (<nmero>,<mensagem>);

Ex.:
CREATE TRIGGER checa_salario

DECLARE

BEGIN

IF (:new.vl_sal <salario_minimo OR :new.vl_sal > salrio_maximo)


THEN
RAISE_APPLICATION_ERROR (-20225, Salrio fora de faixa);

END IF;
END;
Obs.: <nmero> deve variar de -20000 a -20999 e a <mensagem> deve possuir at 512 bytes de
comprimento.
PROPAGAO DA EXCEO
Quando uma exceo setada, se PL/SQL no encontrar um tratamento para ela no bloco correto ou
subprograma, a exceo se propaga. Isto , 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).
Ex.:
BEGIN

BEGIN
IF
x=1
ELSIF
x=2
ELSE
END IF;

EXCEPTION
WHEN A THEN

END;

THEN RAISE A;
THEN RAISE B;
RAISE C;

__________________________________________________________________________________________
116

__________________________________________________________________________________________
A
EXCEPTION
WHEN B THEN

END;

A exceo A tratada no bloco mais interno. Aps seu tratamento o programa continua no
comando A.
A exceo B se propaga para o bloco mais externo, tratada e o programa termina
normalmente.
A exceo COMANDO SQL: se propaga para o bloco mais externo, no e tratada e o erro
passa para o ambiente, isto , o programa abortado.

SQLERRM
String procedure para traduzir um SQLCODE.
sintaxe:

SQLERRM (<sqlcode>)

Ex.:
DECLARE
msg
CHAR(100)
BEGIN
FOR num IN 1..9999 LOOP
msg := SQLERRM (num * -1);
INSERT INTO tab_erro VALUES (msg);
END LOOP;
END;

11.

SUBPROGRAMAS

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 funes. 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 exceo.
Os subprogramas podem ser definidos em qualquer ferramenta ORACLE que suporte PL/SQL.
Podem ser declaradas dentro de blocos, procedures, funes e packages. Os subprogramas devem
ser declarados no fim da parte declarativa, aps todos os outros objetos do programa.
Ex.:
DECLARE
w_vl_lim
NUMBER(15,2) := &1;

PROCEDURE calc_ir (val_sal IN NUMBER, val_ir OUT NUMBER) IS


BEGIN

END calc_ir;
FUNCTION calc_inss (val_sal IN NUMBER, val_lim IN NUMBER)
RETURN NUMBER IS
val_inss
NUMBER(15,2);
BEGIN

__________________________________________________________________________________________
117

__________________________________________________________________________________________

BEGIN

END;

PROCEDURES
As procedures so subprogramas que executam uma ao especfica.
sintaxe:

onde:

PROCEDURE <nome da procedure> [(<parmetro>[,<parmetro>,])] IS


BEGIN
<comandos>
[EXCEPTION
<tratamento das excees>]
END <nome da procedure>];

parmetro possui a seguinte sintaxe:


<nome da varivel> [IN | OUT |IN OUT] <tipo> [{:= | DEFAULT} <valor>]
Quando [IN | OUT ] no for especificado, ser assumido IN.

Ex:
PROCEDURE calc_ir (val_sal IN NUMBER, val_ir OUT NUMBER) IS
BEGIN
IF val_sal < 300.00
THEN
val_ir := 0;
ELSIF val_sal BETWENN 300.01 AND 1000.00
THEN
val_ir := val_sal * .10;
ELSIF val_sal BETWEEN 1000.01 AND 3000.00
THEN
val_ir := val_sal *.20;
ELSE
val_ir := val_sal *.30;
END calc_ir;
FUNCTIONS
Uma funo um subprograma que calcula um valor. Funes e procedures so estruturalmente
iguais, exceto que as funes possuem uma clusula RETURN que especifica o tipo de retorno da
funo.
sintaxe:

onde:

FUNCTION <nome da funo> [(<parmetro>[,<parmetro>,])]


RETURN <tipo da funo> IS
[<variveis locais>]
BEGIN
<comando>
[EXCEPTION
<tratamento das excees>]
END <nome da funo>];

parmetros possui a seguinte sintaxe:


<nome da varivel> [IN | OUT | IN OUT] <tipo> [{:=| DEFAULT} <valor>]
Quando [IN | OUT ] no for especificado, ser assumido IN.

__________________________________________________________________________________________
118

__________________________________________________________________________________________
Ex.:
FUNCTION calc_inss (val_sal IN NUMBER, val_lim IN NUMBER)
RETURN NUMBER IS
val_inss
NUMBER(15,2);
BEGIN
val_inss := val_sal * .08;
IF val_inss > val_lim
THEN
val_inss := val_lim;
END IF;
RETURN val_inss;
END calc_inss;

DECLARAES FORWARD
A PL/SQL exige que se declare um subprograma antes de chama-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 um ;.


Ex:
DECLARE
w_vl_lim
NUMBER(15,2) := &1;

PROCEDURE calc_ir(val_sal IN NUMBER, val_ir OUT NUMBER); -- declarao


forward
FUNCTION calc_inss (val_sal IN NUMBER, val_lim IN NUMBER)
RETURN NUMBER IS
val_inss
NUMBER(15,2);
BEGIN

RETURN val_inss;
END calc_inss;
PROCEDURE calc_ir (val_sal IN NUMBER, val_ir OUT NUMBER) IS
BEGIN

END calc_ir;
BEGIN

END;

__________________________________________________________________________________________
119

__________________________________________________________________________________________

STORED SUBPROGRAMS
No ORACLE possvel armazenar um subprograma PL/SQL na base da dados aps a compilao.
Vrias vantagens so adquiridas com este procedimento, tais como:
Produtividade
Performance

Memria
Integridade

Segurana

Vrios programas podem fazer rotinas previamente gravadas na base de


dados, diminuindo a redundncia de codificao.
Subprogramas podem reduzir a necessidade de calls nas aplicaes. Por
exemplo, para executar 10 comandos SQL individuais, 10 calls so
necessrias, porm para executar um subprograma contendo dez comandos
SQL, apenas um call necessrio.
Subprogramas rem a vantagem de compartilhar memria. Ou seja, somente
uma cpia de um subprograma necessita ser carregado na memria para
execuo por mltiplos usurios.
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.
Pode haver um aumento na segurana, uma vez que o DBA pode restringir o
acesso a determinadas operaes, fornecendo autorizao somente atravs de
subprogramas.

CHAMADAS DE UM STORED PROGRAM


Local
De outro
subprograma
De um programa
de aplicao
(HOST)
De uma ferramenta
ORACLE

Sintaxe:
<nome da procedure> (<parmetro>);
EXEC SQL EXECUTE
BEGIN <nome da procedure> (<parmetro)); END;
END-EXEC;
EXECUTE <nome da procedure> (<parmetro>);
(SQL*PLUS)
ou
BEGIN <nome da procedure> (<parmetro>); END;

CRIANDO UM STORED SUBPROGRAM


sintaxe:

CREATE [OR REPLACE]


PROCEDURE <nome da procedure>[(<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 subprograma definido dentro de um programa PL/SQL.

__________________________________________________________________________________________
120

__________________________________________________________________________________________

12.

DATABASE TRIGGERS

Um DATABASE TRIGGER um programa PL/SQL armazenado em um banco ORACLE, associado


com uma tabela especfica. O ORACLE ir disparar a execuo do DATABASE TRIGGER
automaticamente quando uma determinada operao SQL afeta a tabela.
Deste forma, pode-se usar um DATABASE TRIGGER para:

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

Pode-se 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> e as mesmas sintaxes para AFTER). Um
DATABASE TRIGGER composto de 3 partes:

evento
constraint (opcional)
ao

Quando o evento ocorre, o trigger disparado e um bloco PL/SQL annimo executa a ao.
Deve-se observar que os DATABASE TRIGGERS executam com os privilgios do OWNER e no do
usurio corrente.
sintaxe:

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>
[OLD [AS] <nome> | NEW [AS] <nome>]}
FOR EACH ROW [WHEN (<condio>)]] <bloco PL/SQL/>

__________________________________________________________________________________________
121

__________________________________________________________________________________________
Ex.:
CREATE TRIGGER checa_salario
BEFORE UPDATE OF vl_sal, nr_git ON FUNC
FOR EACH ROW WHEN (NEW.nr_git < 56)
DECLARE
salario_minimo
NUMBER(5) := 0;
salario_maximo
NUMBER(5) := 0;
faixa
EXCEPTION;
negativo
EXCEPTION;
excede
EXCEPTION;
BEGIN
SELECT MIN(vl_sal), MAX(vl_sal)
INTO salario-minimo, salario_maximo
FROM folha
WHERE nr_git = :new.nr_git;
IF (:NEW.vl_sal < salario_minimo OR
:NEW.vl_sal > salario_maximo)
THEN
RAISE faixa
ELSIF (:NEW.vl_sal < OLD.vl_sal)
THEN
RAISE negativo;
ELSIF (:New.vl_sal > 1.1 * :OLD.vl_sal)
THEN
RAISE excede;
END IF;
EXCEPTION
WHEN faixa THEN
RAISE_APPLICATION_ERROR(-20225, Salrio fora da faixa);
WHEN negativo THEN
RAISE_APPLICATION_ERROR(-20230, Incremento negativo);
WHEN excede THEN
RAISE_APPLICATION_ERROR(-20235, Incremento excede 10%);
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20999, SQLERRM(SQLCODE));
END;

__________________________________________________________________________________________
122

__________________________________________________________________________________________

13.

PACKAGES

Um package um objeto que grupa logicamente subprogramas, objetos e tipos PL/SQL. Packages
so compostos de duas partes: A especificao e o corpo do pacote. A especificao a interface
com as aplicaes. Nela so declarados os tipos, variveis, constantes, excees, cursores e
subprogramas. No corpo do pacote concluda a definio dos cursores e subprogramas e feita a
implementao da especificao.
Um package no pode ser chamado, receber parmetro nem ser aninhado (declarado dentro de outro
package).
sintaxe:

PACKAGE <nome do pacote> IS


<declaraes>
END [<nome do pacote>];

parte da especificao

PACKAGE BODY <nome do pacote> IS


<corpo dos subprogramas>
[BEGIN
<comandos de inicializao>]
END [<nome do pacote>];

corpo do pacote

A parte de especificao so declaraes pblicas, visveis pelas aplicaes. O corpo implementa


detalhes e declaraes privadas que so invisveis pelas aplicaes. O corpo seria uma caixa preta.

CRIANDO UM PACKAGE
Um pacote pode ser criado internamente no SQL*PLUS ou no SQL*DBA usando-se os comandos
CREATE PACKAGE e CREATE PACKAGE BODY.
sintaxe:

CREATE [OR REPLACE]


PACKAGE <nome do pacote> AS/IS
<declaraes>
END <nome do pacote>
CREATE [OR REPLACE]
PACKAGE BODY <nome do pacote> AS/IS
<corpo dos subprogramas<
[BEGIN
<inicializaes>]
END <nome do pacote>

__________________________________________________________________________________________
123

__________________________________________________________________________________________
Ex:
CREATE PACKAGE funcionario AS
TYPE func_reg_type IS RECORD )cd_depto_mat NUMBER, vl_sal NUMBER);
CURSOR salario (mat NUMBER) RETURN func_reg_type;
PROCEDURE admisso
(nome CHAR, grau NUMBER, sal NUMBER, depto CHAR);
PROCEDURE demisso (mat NUMBER);
END funcionario;
CREATE PACKAGE BODY funcionario As
CURSOR salario (mat NUMBER) RETURN func_reg_type IS
SELECT cd_mat, vl_sal FROM func
WHERE cd_mat = mat
ORDER BY vl_sal DESC;
PROCEDURE admisso
(nome CHAR, grau NUMBER, sal NUMBER, depto CHAR) IS
BEGIN
INSERT INTO func
(nm_func, nr_git, vl_sal, cd_mat, cd_depto)
VALUES
(nome, grau, sal, cd_mat_seq.NEXTVAL, depto);
END admisso;
PROCEDURE demisso (mat NUMBER) IS
BEGIN
DELETE FROM func WHERE cd_mat = mat;
END demisso;
END funcinario;
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

VANTAGENS DO USO DE PACKAGES


Packages oferecem vrias vantagens:
Modularidade
Desenho da aplicao

Segurana

Funcionalidade
Performance

Packages permitem que se encapsule logicamente tipos, objetos e


subprogramas relacionados.
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 armazenado a referncia ao pacote pode ser compilada tambm.
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 do body do package. Eles so usados dentro do prprio
pacote e no precisam ficar visveis a quem usar os pacotes.
Variveis pblicas e cursores empacotados podem ser compartilhados
por todas as procedures que executarem no ambiente.
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

__________________________________________________________________________________________
124

__________________________________________________________________________________________

REFERNCIAS A PACKAGES
Para fazer uma referncia aos tipos, objetos e subprogramas declaradas dentro da especificao de
packages deve-se usar a seguinte notao:
<nome de package>. <tipo>
<nome de package>. <objeto>
<nome de package>. <subprograma>
Pode-se 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).

14.

MENSAGENS EM STORED PROCEDURES E TRIGGERS

Podemos enviar mensagens a partir de procedures ou packags usando package DBMS_OUTPUT.


Este package possui duas procedures PUT e PUT_LINE, que faro com que a mensagem seja
armazenada em um buffer que pode ser mostrado quando o trigger, procedure ou package for
executado.
Estas mensagens podero ser mostradas com o uso da procedure GET_LINE ou com o uso do
comando SET SERVER OUTPUT ON no SQL*PLUS ou SQL*DBA, caso contrrio estas mensagens
sero ignoradas.
Este package pode ser especialmente til para depurao.

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 ou SQL*DBA com a opo SERVER UOTPUT setada para ON, para
executar o trigger e depurar as mensagens includas.

PROCEDURES E FUNES
Veremos, agora cada uma das procedures e funes contidas no package DBMS_OUTPUT:
DISABLE PROCEDURE
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 SERVER UOTPUT no SQL*PLUS ou
SQL*DBA.
sintaxe: DISABLE;

__________________________________________________________________________________________
125

__________________________________________________________________________________________
ENABLE PROCEDURE
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) as 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.
So permitidas mltiplas chamadas ENABLE. No necessria a chamda a esta procedure quando
utilizamos a opo SQL*DBA ou SQL*PLUS. Se existirem mltiplas chamadas a esta procedure, o
maior valor dentre os especificados. O tamanho mximo 1.000.000 e o mnimo 2.000 bytes.
sintaxe: ENABLE (buffer_size in integer);
GET_LINE PROCEDURE
Esta procedure recupera uma linha da informao do buffer, excluindo o caracter newline final. O
tamanho mximo da linha 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 (no existem
linhas no buffer).
sintaxe: GET_LINE(line out varchar2, status out integer);
GET_LINES PROCEDURE
Esta procedure recupera um array de linhas e pode ser usada no lugar de 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, PU_LINR ou
NEW_LINE.
Cada linha no array pode ter at 255 bytes de comprimento.
Sntaxe: GET_LINES (lines out chararr, numlines in out integer);
NEW_LINE PROCEDURE
Esta procedure coloca uma marca de fim da 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: NEW_LINE;

__________________________________________________________________________________________
126

__________________________________________________________________________________________
PUT PROCEDURE
Esta procedure especifica a informao que desejamos armazenar no buffer. Devemos usar esta
procedure para adicionar pedaos de informao ao buffer. As procedures 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 recebido uma mensagem de erro.
Sintaxe: 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).
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.
EXEMPLO
O package DBMS_OUTPUT , normalmente, usado para depurao de stored procedures e
tringgers, como veremos no exemplo abaixo:
CREATE FUNCTION depto_sal (p_cd_depto IN CHAR) RETURN NUMBER IS CURSOR func_cursor
IS
SELECT vl_sal FROM func WHERE cd_depto = p_cd_depto;
v_total_sal
NUMBER(11,2) := 0;
v_conta
NUMBER(10) := 1;
func_rec
func_cursor%ROWTYPE;
BEGIN
FOR func_rec IN func_cursor LOOP
v_total_sal := v_total_sal + func_rec.vl_sal;
PUT_LINE (loop NO. = || TO_CHARY(v_conta) || ; salrio = ||
TO_CHAR(v_conta_sal));
v_conta := v_conta + 1;
END LOOP;
PUT_LINE (Total de salrios = || TO_CHAR(v_total_sal));
RETURN v_total_sal;
END depto_sal;

__________________________________________________________________________________________
127

Você também pode gostar