Escolar Documentos
Profissional Documentos
Cultura Documentos
NDICE - i
NDICE - ii
NDICE - iii
NDICE - iv
NDICE - v
NDICE - vi
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
INTRODUO - 2
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
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
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]
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
CHAR [ (<comprimento>) ]
SUBTIPOS
STRING [ (<comprimento>) ]
idem a CHAR
NUMBER
Numrico, para armazenamento de valores em ponto flutuante com preciso de at 38
dgitos.
SINTAXE
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
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
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
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;
BOOLEAN
Para armazenamento de valores boleanos (true, false ou null)
SINTAXE
BOOLEAN
INTRODUO - 9
ROWID
FORMATO:
BBBBBBBB.RRRR.FFFF, onde :
BBBBBBBB.......
RRRR...............
FFFF.................
DATE
Para armazenamento de datas.
SINTAXE
DATE
INTRODUO - 10
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
%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 /
INTRODUO - 12
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
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
INTRODUO - 15
INTRODUO - 16
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
INTRODUO - 18
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
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
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
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
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
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
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
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
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
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
FUNES PR-DEFINIDAS - 29
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
FUNES PR-DEFINIDAS - 31
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
FUNES PR-DEFINIDAS - 33
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>)
FUNES PR-DEFINIDAS - 34
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
TRUNC
Retorna uma data no formato especificado por <fmt>, representando <d> truncada na
unidade correspondente.
SINTAXE: TRUNC(<d>,<fmt>)
Sculo
Quarto de ano
Ms
WW..................................................................
W.....................................................................
Dia (DEFAULT)
Hora
MI.....................................................................
Minuto
FUNES PR-DEFINIDAS - 36
FUNES PR-DEFINIDAS - 37
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
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.........
0.........
$.........
B.........
MI.......
PR......
,..........
...........
V.........
E.........
Notao cientifica.
DATE..
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
FUNES PR-DEFINIDAS - 40
FUNES PR-DEFINIDAS - 41
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>)
FUNES PR-DEFINIDAS - 42
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
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
FUNES PR-DEFINIDAS - 45
PROCESSAMENTO REPETITIVO - 47
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.
PROCESSAMENTO REPETITIVO - 48
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.
PROCESSAMENTO REPETITIVO - 49
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
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
PROCESSAMENTO REPETITIVO - 52
PROCESSAMENTO REPETITIVO - 53
%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
<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
PROCESSAMENTO REPETITIVO - 56
PROCESSAMENTO REPETITIVO - 57
PROCESSAMENTO REPETITIVO - 58
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
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
PROCESSAMENTO REPETITIVO - 61
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
nome do departamento
codigo do departamento
somatrio dos salrios do departamento correspondente
mdia salarial do departamento correspondente
PROCESSAMENTO REPETITIVO - 63
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
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
PROCESSAMENTO REPETITIVO - 66
opcional
obrigatria
opcional
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.
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.
RAISE
Causa uma exceo.
SINTAXE
RAISE <exceo>
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
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.
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 /
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
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
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.
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.
SUBPROGRAMAS EM PL/SQL - 80
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
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
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
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
MEMRIA
INTEGRIDADE
SEGURANA
SUBPROGRAMAS EM PL/SQL - 84
SINTAXE
De outro
subprograma
De um programa
de aplicao
(HOST)
EXEC SQL
EXECUTE BEGIN
<nome da procedure> (<parmetro> . . .);
END;
END-EXEC;
No SQL*PLUS
No PL/SQL
SUBPROGRAMAS EM PL/SQL - 85
SUBPROGRAMAS EM PL/SQL - 86
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
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
SUBPROGRAMAS EM PL/SQL - 89
SUBPROGRAMAS EM PL/SQL - 90
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:
TRIGGERS E PACKAGES - 91
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
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.
TRIGGERS E PACKAGES - 92
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
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.
SINTAXE
ALTER TRIGGER
<nome trigger>
ENABLE
DISABLE
COMPILE
TRIGGERS E PACKAGES - 94
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
DESENHO DA
APLICAO
SEGURANA
FUNCIONALIDAD
E
PERFORMANCE
TRIGGERS E PACKAGES - 95
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
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
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
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
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.
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).
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.
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);
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.
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 /
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 /
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 /
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 /
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 /
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 /
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 /
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 /
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;
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 /
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 /
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.
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;
...
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.
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.
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.
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 /
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.