Escolar Documentos
Profissional Documentos
Cultura Documentos
PL SQL Reduzida
PL SQL Reduzida
Estrutura do Curso
1. Introduo a PL/SQL
2. Conceitos Bsicos de PL/SQL
3. Variveis e Dados de Programa
4. Controle Condicional e Seqencial
5. Loops
6. Registros em PL/SQL
7. Tabelas PL/SQL
8. SQL em PL/SQL
9. Funes de SQL integradas
10. Cursores
11. Procedimentos e Funes
12. Packages
13. Triggers
14. Tratamento de Erros
15. Testes e Depurao
16. PL/SQL Dinmico
17. Entrada e Sada em Arquivos
18. Desempenho e Otimizao
PL/SQL
Procedural Language extensions to SQL. Usamos esta linguagem no Oracle Server
e em aplicaes-cliente (p.e. Oracle Forms). Adiciona construes de programao no
existentes na linguagem de banco de dados padro. Permite a combinao de comandos
SQL com construes procedurais.
Ambientes de Execuo
Servidor
Oracle 7: PL/SQL verso 2
Oracle 8: PL/SQL verso 8
SQL* Plus (modo interativo)
Cliente
Oracle Developer (Forms , Reports e
Procedure Builder)
Utilizam compiladores PL/SQL prprios
Existem no banco de dados: Number, Char, Long, Long Raw, Raw, Rowid, Varchar2, Date.
Binary_Integer: Utilizado para armazenar inteiros com sinal. Com intervalo de:
-2147483647 .. 2147483647
Subtipos:
Natural (de 0 .. 2147483647)
Positive (de 1 .. 2147483647)
Tipos de Dados Numricos
Utilize NUMBER para armazenar nmeros
(inclusive ponto-flutuante)
Preciso Mxima: 38 dgitos
1.0E- 129 at 9.999E125
Caracteres
CHAR
Subtipos: Character e string.
especifica que a varivel tem um tamanho fixo pode-se especificar o tamanho mximo (1
at 32767) se o tamanho no for especificado, o valor padro 1 (um).
espaos em branco so adicionados ao final da varivel, se esta armazenar uma cadeia de
caracteres de tamanho menor que o mximo.
VARCHAR2 e VARCHAR
armazenam cadeias de caractere de tamanho varivel.
pode-se especificar o tamanho mximo (1 at 32767)
VARCHAR2 e VARCHAR so sinnimos (visando a compatibilidade com bancos de
dados ANSI ).
Recomendao da Oracle: utilize VARCHAR2
LONG
armazenam cadeias de caractere de tamanho varivel, de at 32760 caracteres.
recomendao: utilize VARCHAR2.
RAW
armazena dados binrios de at 32767 bytes o PL/SQL no tenta interpretar os dados
LONG RAW
armazena dados binrios de at 32760 bytes
Row id
No database Oracle, ROWID uma pseudocoluna, pertencente a toda tabela.
Internamente gerado, ocupando 6 bytes. ROWID em PL/SQL um subtipo do CHAR
com tamanho fixo.
BBBBBBB.RRRR.FFFF
bloco no database file, linha no bloco e
database file
Booleano (BOOLEAN)
Tipo de dados lgico (no existe correspondente no servidor Oracle). Pode assumir os
valores TRUE, FALSE ou NULL.
Data-hora (DATE)
Uma varivel do tipo DATE armazena tanto informaes sobre data quanto sobre hora.
Valor de tamanho fixo, que ocupa 7 bytes.
DATE armazena as seguintes informaes: sculo, ano, ms, dia, hora, minuto e segundo
Datas vlidas para uma varivel data esto entre 1 jan de 4712 AC a 31 dez de 4712 DC.
Podem ser feitas operaes aritmticas sobre um valor do tipo DATE.
Converso entre Tipos
Sempre que o PL/SQL efetua uma operao envolvendo um ou mais valores, ele primeiro
converte os dados para o formato correto para a operao.
Converso Explcita
usada uma funo de converso pr-definida
Converso Implcita
sempre que necessrio, o PL/SQL tenta converter os valores para efetuar a operao
Valores Nulos em PL/SQL
NULL nunca igual a qualquer outra coisa
IF nome = NULL THEN ... -- ERRADO
Quando usados uma funo utilizando um valor nulo, geralmente recebemos como
resultado um outro valor nulo.
nome := NULL;
IF LENGTH(nome) = 0 THEN -- No funciona
Maneira correta da comparao:
<identificador> IS NULL
<identificador> IS NOT NULL
Combinao IF-THEN
Exemplos
IF :empresa.total > media
THEN
aplicar_desconto(:empresa.empresa_id);
END IF;
IF relatorio_pedido
THEN
imprime_relatorio(relatorio_id);
END IF;
Exemplo
IF :cliente.total_pedido > max _permitido
THEN
pedido_excedente := TRUE;
ELSE
pedido_excedente := FALSE;
END IF;
Exemplo
IF salario < 10000
THEN
bonus:= 2000;
ELSIF salario < 20000
THEN
bonus:= 1500;
ELSIF salario < 40000
THEN
bonus:= 1000;
ELSE
bonus:= 500;
END IF;
Comando GOTO
Desvio incondicional para um rtulo definido no programa.
GOTO nome_rotulo;
...
<<nome_rotulo>>
...
Pelo menos um comando deve existir aps a definio de um rtulo.
O rtulo deve ser nico no escopo.
Rtulo destino deve estar no mesmo escopo que o comando GOTO.
IF, BEGIN, Loop, mdulo.
Rtulo destino deve estar na mesma parte do bloco PL/SQL que o comando GOTO.
ex.: um GOTO na seo executvel no pode
desviar para a seo de exceptions..
O cdigo resultante com o uso do GOTO pode tornar-se complexo e desestruturado,
dificultando a manuteno.
Comando NULL
Melhorar a clareza do programa
IF : report.selection = DETAIL
THEN
exec_detail_report ;
ELSE
NULL;
END IF;
Tirar o efeito de uma exception
Loops
Conceitos
Um loop permite que um mesmo cdigo seja executado repetidamente.
Loop Simples
Loop FOR (p/ nmeros e cursores)
Loop WHILE
Na maioria dos casos, uma lgica que requer um loop pode usar qualquer das trs
construes existentes.
Loop Simples
LOOP
<comandos>
END LOOP;
O teste para terminao feito dentro do loop
EXIT
EXIT WHEN <condio>
LOOP
<comandos>
END LOOP;
O teste para terminao feito dentro do loop
EXIT
EXIT WHEN <condio>
Quando usar
no existe a certeza de quantas vezes o loop ser executado
o loop deve executar pelo menos uma vez
Loop FOR
FOR numrico
FOR < indice_loop > IN [REVERSE] <menor>..<maior>
LOOP
<comandos>
END LOOP;
O loop termina quando o cdigo executado o nmero de vezes correspondente ao
intervalo informado. Aps cada execuo do bloco, o PL/SQL verifica se o valor atual do
ndice excede a diferena entre o maior e menor nmero informado na faixa.
FOR numrico
Quando usar:
cdigo dentro do loop ser executado um nmero fixo de vezes, sem ser necessria uma
interrupo
Regras
no declare o ndice usado no loop
no mude o valor das variveis usadas para informar a faixa de valores (a faixa
analisada no incio do loop), muito menos o valor do ndice
no use o comando EXIT dentro do loop FOR
Loop WHILE
WHILE <condio>
LOOP
<comandos>
END LOOP;
Executa at que a condio seja falsa.
Antes de cada execuo do bloco dentro loop,
o PL/SQL avalia a condio informada.
Quando usar
no temos certeza de quantas vezes devemos
executar o corpo do loop
desejamos interromper o loop de acordo com
uma condio
no necessariamente temos que executar o loop
pelo menos uma vez
Registros em PL/SQL
Conceitos
Um registro em PL/SQL bastante similar estrutura de linhas em uma tabela.
Um registro uma estrutura de dados composta. O registro como um todo no tem um
valor. Cada componente ou campo que o possui.
Tipos de Registro
Baseado em Tabela
cada campo corresponde a uma coluna em uma tabela, inclusive com o mesmo nome
Baseado em Cursor
cada campo corresponde a uma coluna ou expresso no comando SELECT de um
cursor
Definido pelo Programador
cada campo definido explicitamente (nome e tipo) atravs do comando TYPE
Declara o de um Registro
Baseado em Tabelas
<nome_reg> <nome_tabela>%ROWTYPE;
DECLARE
empresa_reg empresa%ROWTYPE;
Baseado em Cursores
<nome_reg> <nome_cursor>%ROWTYPE;
DECLARE
empresa_reg empresa_cur%ROWTYPE;
TYPE <nome_tipo> IS RECORD
( <nome_campo1> <tipo_dado1>,
<nome_campo2> <tipo_dado2>,
...
<nome_campoN> <tipo_dadoN> )
TYPE cliente_regtipo IS RECORD
(cliente_id NUMBER(5),
cliente_nome cliente.nome%TYPE,
total_vendas NUMBER(15,2) );
Tabelas PL/SQL
Definio
Como um array, uma tabela PL/SQL uma coleo ordenada de elementos de um mesmo
tipo. Uma tabela PL/SQL no tem limites de tamanho, pode ser incrementada
dinamicamente.
O ndice de acesso da tabela no precisa ser um nmero sequencial. Por exemplo, podese usar uma srie como nmero do empregado (como 7369, 7499, 7521, 7566, )
Definindo uma Tabela PL/SQL
TYPE table_type_name IS TABLE OF
datatype [NOT NULL]
[INDEX BY BINARY_INTEGER];
onde table_type_name um tipo especificado pelo usurio.
Na verso 8 a clusula INDEX BY opcional.
Exemplos
CLOSE c1;
END;
Atributos de Tabela: COUNT
Retorna o nmero de elementos na tabela.
...
IF ename_tab.COUNT = 50 THEN
...
END;
Atributos de Tabela: DELETE
Este atributo tem 3 formas:
tabela.DELETE remove todos os elementos da tabela;
tabela.DELETE(n) remove o elemento n da tabela;
tabela.DELETE(m,n) remove o range m .. n.
uma instruo completa por si s; no chamada como parte de uma expresso
Atributos de Tabela:
EXISTS
Retorna TRUE se existir uma linha com ndice i na tabela, caso contrrio retorna
FALSE.
IF sal_tab.EXISTS(i) THEN
sal_tab(i) := sal_tab(i) + 500;
ELSE
RAISE salary_missing;
END IF;
...
Atributos de Tabela: FIRST e LAST
Retornam o ndice da primeira e da ltima linha da tabela, respectivamente.
...
FOR i IN emp_tab.FIRST .. emp_tab.LAST LOOP
...
END LOOP;
A primeira linha a que tem o ndice mais baixo e a ltima, o mais elevado.
Atribut os de Tabela: NEXT e PRIOR
Retornam o ndice do elemento seguinte ou anterior da tabela, respectivamente.
DECLARE
...
i BINARY_INTEGER;
BEGIN
..
i := any_tab.FIRST;
WHILE i IS NOT NULL LOOP
... process any_tab(i)
i := any_tab.NEXT(i);
END LOOP;
END;
SQL em PL/SQL
Instrues de SQL
Podem dividir-se em seis categorias:
DML: linguagem de manipulao de dados
DDL: linguagem de definio de dados
Controle de transaes
Controle de sesses
Controle do sistema
SQL incorporado (para pr- compiladores)
Num programa PL/SQL s podem ser usadas as seguintes instrues:
DML: select, insert, update, delete
Controle de transaes: commit, rollback, savepoint
Existe uma alternativa para o uso de instrues DDL em PL/SQL
A package DBMS_SQL, disponvel a partir da verso 2.1 permite a criao de SQL
dinmico
DML: Select
Busca informaes do banco de dados para variveis PL/SQL
SELECT emp.ename
INTO v_ename
FROM emp
WHERE emp.empno = 7902;
Deve retornar somente uma linha. A clusula INTO s usada em blocos PL/SQL
DML: Insert
Insere uma linha na tabela
INSERT INTO emp
(empno, ename, job, mgr, hiredate, sal, comm,
deptno)
VALUES
(1, 'ALBERT', 'SALESMAN', 7698, SYSDATE,
string2 IN VARCHAR2
[ , pos_ini IN NUMBER := 1
[ , nth_ocorrencia IN NUMBER := 1] ] )
RETURN NUMBER
INSTR( Estou procurando uma palavra , uma ) => 18
FUNCTION LPAD(string1 IN VARCHAR2,
tamanho_pad IN NUMBER
[ , string_pad IN VARCHAR2] )
RETURN VARCHAR2
LPAD( 55 , 10, 0) = > 0000000055
LPAD( 12345678 , 5, 0 ) = > 12345
Exemplos
FUNCTION LTRIM(string1 IN VARCHAR2
[ , trim_string IN VARCHAR2] )
RETURN VARCHAR2
LTRIM( Eu gosto de pizza ) => Eu gosto de pizza
FUNCTION SUBSTR(string_in IN VARCHAR2,
pos_ini IN NUMBER
[ , tam_substr_in IN
NUMBER] )
RETURN VARCHAR2
SUBSTR( Eu gosto de pizza , 4, 5) => gosto
SUBSTR( Eu gosto de pizza , -1) => a
Funes para Datas
Exemplos
LAST_DAY(data_in IN DATE) RETURN DATE
LAST_DAY(SYSDATE) - SYSDATE => nmero de dias at o final do ms.
NEXT_DAY(data_in IN DATE, nome_dia IN VARCHAR2)
RETURN DATE
NEXT_DAY( 01-JAN-1997 , MONDAY) => 06-JAN-1997
Funes Numricas
Outras Funes
Exemplos
FUNCTION SQLCODE RETURN INTEGER
FUNCTION SQLERRM RETURN VARCHAR2
EXCEPTION
WHEN OTHERS THEN
MESSAGE( Error | | TO_CHAR(SQLCODE) | | : | | SQLERRM);
Funes de Converso
Funo TO_CHAR
FUNCTION TO_CHAR(param IN {DATE/NUMBER} ,
[ , formato IN VARCHAR2
[ , nls_language IN
VARCHAR2] ] )
RETURN VARCHAR2
TO_CHAR(SYSDATE, Month DD, YYYY) =>March 10,1997
TO_CHAR(564.70, $999.9 ) => $564.7
TO_CHAR(564.70, $0000999.9 ) => $0000564.7
Funo TO_DATE
FUNCTION TO_DATE(param IN {VARCHAR2|NUMBER}
[ , formato IN VARCHAR2
[ , nls_language IN VARCHAR2 ] ] )
RETURN DATE
TO_DATE( 123198 , MMDDYY) => 31- DEC-1998
TO_DATE( 16/7/94 , DD/MM/YY) = > 16- JUL-1994
Funo TO_NUMBER
FUNCTION TO_NUMBER(string_in IN
CHAR|VARCHAR2}
[ , formato IN VARCHAR2
[ , nls_language VARCHAR2] ] )
RETURN NUMBER
TO_NUMBER( 123.23 ) => 123.23
TO_NUMBER( abcdef ) => ERRO
Funes de Grupo
Somente para SELECT com GROUP BY
Cursores
Conceitos
Um cursor pode ser encarado como um ponteiro para a tabela virtual no banco de dados
representada pelo comando SELECT associado.
Ex.:
CURSOR empregado_cur IS
SELECT * FROM empregado;
OPEN empregado_cur;
FETCH empregado_cur INTO empregado_rec;
CLOSE empregado_cur;
Operaes em Cursores
OPEN
abre o cursor, faz o parse e o bind da consulta associada, identificando o resultado
o cursor posicionado antes da primeira linha.
FETCH
busca a linha corrente do cursor e o posiciona na prxima
CLOSE
fecha o cursor e libera a memria alocada.
Tipos de Cursores
Cursores Estticos
sempre referenciam um comando SQL, que conhecido em tempo de compilao.
Variveis Cursores
a varivel referencia um objeto cursor e pode referenciar diferentes comandos SQL em
ocasies diferentes. Nova feature do PL/SQL.
Implcitos
o PL/SQL utiliza um cursor implcito sempre que um comandos SQL executado
diretamente no cdigo, desde que o cdigo no utilize um cursor explcito usados em cada
UPDATE, INSERT ou DELETE so menos eficientes que cursores explcitos
mais suscetveis a erro.
Explcitos
comando SELECT explicitamente definido na seo de declarao, sendo um nome
associado a ele usados quando desejamos recuperar mais de uma linha de resultado
no existem para comandos de UPDATE, INSERT e DELETE
Declarao
CURSOR nome_cursor [ ( [ parmetro [ ,
parmetro ...] ) ]
[ RETURN especificao_retorno ]
IS comando_SELECT;
Variveis em um Cursor
Nome do Cursor no uma varivel. No PL/SQL, a lista de itens no SELECT pode
conter colunas, variveis do PL/SQL e variveis associadas (p.e. Oracle Forms).
DECLARE
bonus NUMBER := 100;
CURSOR empregado_cur IS
SELECT empregado_id, salario + bonus,
:revisao.avaliacao
FROM empregado
WHERE dt_contrat < ADD_MONTHS(SYSDATE, -36);
Precedncia de um Identificador
Em um cursor, existe precedncia do nome da coluna sobre o nome de uma varivel
PL/SQL.
PROCEDURE melhorar_SQL
IS salario NUMBER := 1000;
CURSOR dobrar_sal_cur IS
SELECT salario + salario
FROM empregado
WHERE dt_contrat < ADD_MONTHS(SYSDATE,- 36);
BEGIN
A clasula RETURN
Somente pode ser usada para cursores que esto contidos em um package.
A clasula RETURN pode ser feita com as seguintes estruturas:
Um record definido a partir de uma tabela,
usando %ROWTYPE
Um record definido a partir de um record pr-definido pelo progamador
Exemplo de Uso da clasula RETURN
Primeiro a definio da Package
PACKAGE empresa IS
CURSOR empresa_cur (id IN NUMBER)
RETURN empresa%ROWTYPE;
END empresa;
Depois a definio da Package Body
PACKAGE body empresa IS
CURSOR empresa_cur (id IN NUMBER)
RETURN empresa%ROWTYPE IS
SELECT * FROM empresa
WHERE empresa_id = id;
END empresa;
Porque colocar cursor numa Package?
Uma package uma coleo de objetos logicamente relacionados. Agrupando os cdigos,
torna-se mais fcil a identificao e uso dos cdigos pelo programador. Cursores em
packages so essencialmente caixas pretas. O programador no precisa saber como um
cursor recuperado.
Abrindo Cursores
OPEN <nome_cursor> [ (parmetro [ , parmetro ...] ) ] ;
O comando OPEN no recupera linhas. Todos os fetches refletiro os dados exatamente
como da ocasio em que o cursor foi aberto. Recuperando Dados de Cursores
FETCH <nome_cursor> INTO <registro_ou_lista_variveis>
Exemplo:
FETCH empresa_cur INTO empresa_reg;
FETCH max_sal_cur INTO max_sal;
FETCH empr_cur INTO empr_nome(1),
dt_contrat,
:depto.min_ salario;
Fechando Cursores
CLOSE <nome_cursor>
Libera rea de memria (SGA). Libera todo bloqueio (lock) causado pelo cursor. Existe um
limite mximo de cursores que podem ser abertos no SGBD Oracle.
Um cursor automaticamente fechado quando o seu escopo abandonado.
Atributos de Cursores
%FOUND
OPEN pedido_cur;
FETCH pedido_cur INTO pedido_id, empresa_id;
IF pedido_cur %FOUND THEN
:pedido.num_pedidos := :pedido.num_pedidos + 1;
END IF;
...
%NOTFOUND
Oposto ao %FOUND
Muito utilizado para terminao de loops
EXIT WHEN empresa_cur%NOTFOUND;
%ROWCOUNT
DECLARE
CURSOR emp_cur IS
SELECT nome, salrio FROM empregado
ORDER BY salario DESC;
Exemplo
DECLARE
TYPE empresa_curtipo IS REF CURSOR
RETURN empresa%ROWTYPE;
empresa_curvar empresa_curtipo;
BEGIN
OPEN empresa_curvar FOR SELECT *
FROM empresa;
...
Definindo uma Varivel Cursor
TYPE ref_type_name IS REF CURSOR
RETURN return_type;
onde ref_type_name o nome da varivel especificada para uso subsequente e
return_type deve representar um record ou uma row na tabela.
Exemplo:
DECLARE
TYPE DeptCurTyp IS REF CURSOR
RETURN dept%ROWTYPE;
Em uma Stored Procedure
CREATE PACKAGE emp_data AS
TYPE GenericCurTyp IS REF CURSOR;
TYPE EmpCurTyp IS REF CURSOR
RETURN emp%ROWTYPE;
PROCEDURE open_emp_cv
(emp_cv IN OUT EmpCurTyp,
choice IN NUMBER);
END emp_data;
CREATE PACKAGE BODY emp_data AS
PROCEDURE open_emp_cv
(emp_cv IN OUT EmpCurTyp,
choice IN NUMBER) IS
BEGIN
IF choice = 1 THEN
OPEN emp_cv FOR SELECT * FROM emp
WHERE comm IS NOT
NULL;
ELSIF choice = 2 THEN
OPEN emp_cv FOR SELECT * FROM emp
WHERE sal > 2500;
Modularizao
Processo de quebrar grandes blocos de cdigo em pequenos pedaos (mdulos)
torna o cdigo:
mais reutilizvel
mais fcil de gerenciar
mais legvel
mais confivel
Estruturas para Modularizao (PL/SQL):
Procedimento
Bloco que efetua uma ou mais aes, sendo possvel a passagem de informaes, tanto
para dentro quanto para fora do procedimento
Funo
Retorna um nico valor; podemos passar informaes para a funo atravs de
parmetros
Bloco annimo
Bloco PL/SQL que efetua uma ou mais tarefas;
usado para controlar o escopo dos
identificadores e manuseio de exceptions
Package
coleo de procedimentos, funes, tipos e variveis;
no exatamente um mdulo, mas est relacionado ao assunto.
Estrutura do Bloco PL/SQL (Reviso)
Procedimentos
Estrutura
PROCEDURE <nome> [ (parmetro [ ,parmetro ...] ) ] IS
[comandos de declarao]
BEGIN
<comandos>
[ EXCEPTION <comandos para manuseio de exceptions> ]
END [nome] ;
Chamada
um procedimento chamado da mesma maneira que um comando PL/SQL
aplicar_desconto(nova_empr_id, 15.00);
Cabealho
nome do procedimento e lista de parmetros
PROCEDURE aplicar_desconto(empr_id_in IN empresa.empr_id%TYPE, desconto_in IN
NUMBER)
Corpo
cdigo necessrio para a execuo do procedimento
PROCEDURE nada IS
BEGIN
NULL;
END;
Exemplo de Procedure
PROCEDURE raise_salary (emp_id INTEGER, increase REAL) IS
current_salary REAL;
salary_missing EXCEPTION;
BEGIN
SELECT sal INTO current_salary FROM emp
WHERE empno = emp_id;
IF current_salary IS NULL THEN
RAISE salary_missing;
ELSE
UPDATE emp SET sal = sal + increase
WHERE empno = emp_id;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO emp_audit VALUES (emp_id, No such number );
WHEN salary_missing THEN
INSERT INTO emp_audit VALUES (emp_id, Salary is null );
END raise_salary;
Funes
Estrutura
FUNCTION nome [ (parmetro [ , parmetro...] ) ]
RETURN tipo_retornado IS [comandos de declarao]
BEGIN
comandos
[ EXCEPTION comandos para manuseio de exceptions]
END [nome]
Chamada
uma funo chamada como parte de um comando, sempre que uma expresso pode ser
usada
vendas_95 := total_vendas( Marisol , 1995);
DECLARE
vendas_95 NUMBER DEFAULT
total_vendas( Marisol , 1995);
IF total_vendas( Marisol , 1995)
THEN ...
Cabealho
nome da funo, lista de parmetros e tipo do retorno
FUNCTION total_vendas(nome_in IN
empresa.nome%TYPE, ano_in pedido.ano%TYPE)
RETURN NUMBER;
Corpo
cdigo necessrio para a execuo da funo
FUNCTION nada RETURN BOOLEAN IS
BEGIN
RETURN TRUE;
END;
Declarao RETURN
Encerra a execuo da funo e retorna o valor para o programa que a chamou.
Um subprograma pode conter vrias declaraes RETURN. Em procedures a declarao
RETURN no deve conter uma expresso. Em funes a declarao RETURN deve conter
uma expresso que executada no momento da execuo da declarao.
Exemplo de Funo
FUNCTION sal_ok (salary REAL, title REAL) RETURN BOOLEAN IS
min_sal REAL;
max_sal REAL;
BEGIN
SELECT losal, hisal INTO min_sal, max_sal
FROM sals
WHERE job = title;
RETURN (salary >= min_sal) AND (salary <= max_sal);
END sal_ok;
Parmetros
Modo de troca de informaes entre o mdulo e o bloco PL/SQL que o chamou.
Quando declaramos um parmetro, nunca especificamos restries quanto ao
tamanho do tipo de dado.
PROCEDURE mostra_empresa(nome IN VARCHAR2) IS
permitida a utilizao de %TYPE e %ROWTYPE na declarao de parmetros
Modo de Passagem de Parmetros
IN
somente para leitura
OUT
somente para escrita (o mdulo pode atribuir um valor ao parmetro, que ser passado ao
bloco PL/SQL que o chamou)
IN OUT
usado para leitura e escrita
Passagem de Parmetros
PROCEDURE combine_formate_nomes (prim_nome IN OUT VARCHAR2,
ult_nome IN OUT VARCHAR2,
nome_comp OUT VARCHAR2,
formato IN VARCHAR2 := ULTIMO PRIMEIRO)
-- O parmetro formato no precisa obrigatoriamente ser informado
IS
BEGIN
IF formato = ULTIMO PRIMEIRO THEN
nome_comp := ult_nome | | , | | prim_nome
ELSIF formato = PRIMEIRO ULTIMO THEN
nome_comp := prim_nome | | | | ult_nome;
END IF;
END;
Como o PL/SQL faz a associao dos parmetros?
Notao Posicional
associa o valor ao parmetro correspondente implicitamente atravs da posio
Notao por Nome Explicitamente
associa um valor a um parmetro explicitamente atravs do seu nome
vendas_97 := total_vendas(nome_in => Cia. JK,
ano_in => 1997);
vendas_97 := total_vendas(ano_in => 1997,
nome_in => Cia. JK);
Stored Procedures/Functions
Uma stored procedure ou stored function uma unidade de programa PL/SQL que:
tem um nome
pode receber e retornar valores
fica armazenada no dicionrio de dados
pode ser usada por vrios usurios
CREATE PROCEDURE recupera_emp_reg
(emp_numero IN emp.empno%TYPE,
emp_reg OUT emp%ROWTYPE) AS
BEGIN
SELECT empno, ename, job, mgr, hiredate, sal, comm, deptno
INTO emp_ret
FROM emp
WHERE empno = emp_numero;
END;
Exemplo:
Mdulo Local
Procedimento ou funo definido da seo de declarao de um bloco PL/SQL.
No pode ser chamado por nenhum outro mdulo PL/SQL definido fora do bloco ao
qual o mesmo pertence.
Vantagens
reduz o tamanho do mdulo, eliminando
cdigos repetitivos
torna o cdigo mais legvel
DECLARE
rent REAL;
PROCEDURE raise_rent (increase IN OUT REAL) IS
BEGIN
rent := rent + increase;
...
END raise_rent;
...
BEGIN
...
raise_rent(rent); indeterminate
Dependncias dos Subprogramas
Subprogramas so dependentes dos objetos que referenciam.Caso algum destes objetos
forem alterados por uma operao DDL, o subprograma fica com status INVALID e deve
ser recompilado.
ALTER {PROCEDURE | FUNCTION} nome COMPILE;
Determinao de dependncia (no INIT.ORA)
Timestamp
Assinatura
Privilgios de Acesso
Para poder executar um subprograma necessrio ter o privilgio EXECUTE para
o objeto. Um subprograma executado utilizando os privilgios explcitos do seu owner,
sem considerar privilgios de roles.
Packages
Conceitos
Uma package um conjunto de objetos PL/SQL que so empacotados com uma
sintaxe especial de BEGIN-END. Podemos colocar em uma package:
cursores
variveis nomes de exceptions
comandos TYPE
procedimentos e funes
Vantagens de utilizarmos packages:
information hiding
projeto orientado a objetos
projeto top-down
persistncia de objetos
melhor performance
Interface
END [nome_package] ;
Corpo
contm implementao de mdulos, cursores e outros objetos
PACKAGE BODY nome_package IS
[ declaraes de variveis e tipos ]
[ especificaao de comandos SELECT de cursores ]
[ especificao do corpo de mdulos ]
[ BEGIN
comandos executveis ]
[ EXCEPTION
exception handlers ]
END [nome_package] ;
Exemplo Package - Especificao
CREATE PACKAGE emp_actions AS specification
TYPE EmpRecTyp IS RECORD (emp_id INTEGER, salary REAL);
CURSOR desc_salary RETURN EmpRecTyp;
PROCEDURE hire_employee (ename VARCHAR2,
job VARCHAR2,
mgr NUMBER,
sal NUMBER,
comm NUMBER,
deptno NUMBER);
PROCEDURE fire_employee (emp_id NUMBER);
END emp_actions;
Exemplo Package - Body
CREATE PACKAGE BODY emp_actions AS
CURSOR desc_salary RETURN EmpRecTyp IS
SELECT empno, sal FROM emp ORDER BY sal DESC;
PROCEDURE hire_employee (ename VARCHAR2,
job VARCHAR2,
mgr NUMBER,
sal NUMBER,
comm NUMBER,
deptno NUMBER) IS
BEGIN
INSERT INTO emp VALUES (empno_seq.NEXTVAL, ename, job,
mgr, SYSDATE, sal, comm, deptno);
END hire_employee;
Onde Fazer?
na seo de declarao de um bloco PL/SQL dentro de um package
No podemos fazer a sobrecarga de nomes de programas independentes,
muito menos criar dois mdulos independentes com o mesmo nome e
listas de parmetros distintas.
Exemplo:
DECLARE
TYPE DateTabTyp IS TABLE OF DATE
INDEX BY BINARY_INTEGER;
TYPE RealTabTyp IS TABLE OF REAL
INDEX BY BINARY_INTEGER;
hiredate_tab DateTabTyp;
comm_tab RealTabTyp;
indx BINARY_INTEGER;
...
BEGIN
indx := 50;
initialize(hiredate_tab, indx); calls first version
initialize(comm_tab, indx); calls second version
...
END;
Inicializao de Packages
Uma package pode conter um conjunto de instrues a serem executadas somente quando
a mesma carregada para a memria.
CREATE OR REPLACE PACKAGE BODY nome_pack AS
...
BEGIN
-- Cdigo de inicializao
...
END nome_pack;
Dependncias de Packages
O Package Body depende da Package Specification e dos objetos referenciados
A Package Specification no depende de nada
Vises para dependncias no PL/SQL 8.0:
user_dependencies
all_dependencies
dba_dependencies
Utilizao de Stored Functions em instrues SQL
Uma funo independente ou contida numa package pode ser chamada numa
instruo SQL, dependendo das restries de referncia
Restries de Referncia: definem quais tipos de estruturas de dados que a funo
l ou modifica
WNDS (Writes No Database State)
RNDS (Reads No Database State)
WNPS (Writes No Package State)
RNPS (Reads No Package State)
Somente para Stored Functions Parmetros
devem ser somente de entrada
Exerccio III.1
Converta o script criado no exerccio I.2 (razes de uma equao do 2o grau) para
um procedimento. Armazene este procedimento no banco.
Exerccio III.2
Converta o script do exerccio II.1 (trs departamentos com maior folha - soma de
salrios) para um procedimento. Ao invs de mostrar as informaes na
tela, insira-as em uma tabela. Armazene este procedimento no banco
(stored procedure).
Exerccio III.3
Converta o script do exerccio II.2 (clculo do imposto renda) para uma funo, que
Deve resultar em valor TRUE ou FALSE. O trigger somente ser executado para
valores TRUE.
Trigger Action
um bloco PL/SQL que ser executado quando o trigger for acionado.
Tipos de Triggers
ROW TRIGGERS
so executados uma vez para cada linha da tabela afetada pelo comando SQL.
STATEMENT TRIGGERS
so executados apenas uma vez para cada comando SQL que afete a tabelas,
independentemente do nmero de linhas envolvidas.
Acionamento de Triggers
Quando definimos um trigger, podemos especificar quando ele ser acionado:
before row
before statement
after row
after statement
Triggers (Exemplo)
CREATE TRIGGER dummy
BEFORE DELETE OR INSERT OR UPDATE ON emp
FOR EACH ROW
WHEN (new.empno > 0)
DECLARE
/ * variveis, constantes, cursores, etc. * /
BEGIN
/ * bloco PL/SQL * /
END;
Limite de Triggers por Tabela
Um de cada tipo, totalizando at 12 triggers. No entanto no PL/SQL 2.1 uma tabela pode
ter mais de um trigger de cada tipo.
BEFORE UPDATE row AFTER UPDATE row
BEFORE DELETE row AFTER DELETE row
BEFORE INSERT statement AFTER INSERT statement
BEFORE INSERT row AFTER INSERT row
BEFORE UPDATE statement AFTER UPDATE statement
BEFORE DELETE statement AFTER DELETE statement.
Triggers instead-of
Em PL/SQL 8.0, podem ser definidos triggers que sero disparados em vez da instruo
DML que os disparou. Somente para vises a nvel de linha.
Exemplo:
Para eliminar linhas de uma view complexa
Pseudo-regist ros
Disponvel para triggers a nvel de linha
:old
valores originais do registro da tabela
somente para leitura no corpo do trigger
:new
valores do registro que sero inseridos ou
atualizados na base de dados
podem ser atribudos valores (somente
quando before)
Clusula WHEN
Vlida para triggers a nvel de linha. O corpo do trigger ser executado para as linhas que a
condio especificada resultar em TRUE. Os pseudo-registros :old e :new podem ser
utilizados dentro da condio, mas os dois pontos devem ser suprimidos
Predicados de Trigger
Usados em triggers disparados para diferentes tipos de instrues de DML
Funes booleanas que identificam a instruo que disparou o trigger
INSERTING
UPDATING
DELETING
Tratamento de Erros
Conceitos
Uma exception uma situao que no deveria ter ocorrido.
Pode ser causada por:
erro gerado pelo sistema (p.e. out of memory )
erro causado por uma ao do usurio aviso gerado pela aplicao e direcionado ao
usurio
Exception Handlers
Este mecanismo permite separar o cdigo de processamento de erros do resto dos
comandos. Oferece um modelo orientado a eventos. No importa como uma exception foi
gerada, ela ser tratada na mesma seo (exception section).
Desvio do Fluxo
PROCEDURE fluxo
IS
novo_valor VARCHAR2(5);
BEGIN
END;
Tipos de Exceptions
Existem quatro tipos de exceptions:
exceptions do sistema com um nome, geradas devido a um erro no processamento do
SGBD ou do cdigo PL/SQL, definidas pelo programador com um nome geradas devido a
um erro no cdigo; elas so declaradas na seo correspondente
Exceptions do sistema sem um nome
geradas devido a um erro no processamento do SGBD ou do cdigo PL/SQL; somente as
mais comuns possuem um nome. Definidas pelo programador sem um nome.
procedimento RAISE_APPLICATION_ERROR executado
o programador informa um nmero (-20000 a 20999) e uma mensagem de erro;
utilizada para facilitar a comunicao de erros do ambiente cliente-servidor.
Exceptions do sistema com um nome
DECLARE
stmt INTEGER := 1; designates 1st SELECT statement
BEGIN
SELECT ...
stmt := 2; designates 2nd SELECT statement
SELECT ...
stmt := 3; designates 3rd SELECT statement
SELECT ...
...
EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO errors VALUES ( Error in statement || stmt);
...
END;
Exceptions Pr-Definidas
Exception Name Oracle Error SQLCODE Value
CURSOR_ALREADY_OPEN ORA 06511 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
ROWTYPE_MISMATCH ORA 06504 6504
STORAGE_ERROR ORA 06500 6500
TIMEOUT_ON_RESOURCE ORA 00051 51
TOO_MANY_ROWS ORA 01422 1422
VALUE_ERROR ORA 06502 6502
ZERO_DIVIDE ORA 01476 1476
Definidas pelo programador com um nome
Diferente das exceptions pr-definidas, as exceptions definidas pelo programador devem
ser declaradas e devem ser chamadas explicitamente atravs da declarao:
RAISE
Definindo a Exception:
DECLARE
past_due EXCEPTION;
acct_num NUMBER(5);
Exemplo
DECLARE
past_due EXCEPTION;
acct_num NUMBER;
BEGIN
...
DECLARE incio do sub block
past_due EXCEPTION;
acct_num NUMBER;
BEGIN
...
IF ... THEN
RAISE past_due; esta exception no
executada
END IF;
...
END; fim do sub-block
EXCEPTION
WHEN past_due THEN no usada
...
END;
EXCEPTION_INIT pragma
Pragma uma instruo especial ao compilador. A EXCEPTION_INIT pragma indica que o
compilador deve associar um nome a uma exception que possui um nmero
correspondente.
Exemplo
ORA-2292 violated integrity constraining - child
record found
DECLARE
ainda_ha_empreg EXCEPTION;
PRAGMA EXCEPTION_INIT (ainda_ha_empreg, -2292);
BEGIN
DELETE FROM empresa;
EXCEPTION
WHEN ainda_ha_empreg THEN
DBMS_OUTPUT.PUT_LINE
( Ainda existem empregados para a empresa );
END;
Usando raise_application_error
A package DBMS_STANDARD, que vem com o Oracle7, tem algumas facilidades que
ajudam a aplicao a interagir com o Oracle. Por exemplo, a procedure
raise_application_error permite ao programador definir uma mensagem de
erro ao seu modo.
raise_application_error(error_number,
message[, {TRUE | FALSE}]);
Onde error_number um inteiro negativo entre -20000 .. -20999 e message uma string
de caracter com at 2048 bytes. Se o terceiro parmetro TRUE, o erro colocado em
uma pilha de erros. Se o parmetro FALSE (default), o erro substitui todos os erros
anteriores. A chamada a raise_application_error somente pode ser feita de uma stored
procedure. Quando chamada, o subprograma encerrado e o
nmero do erro e a mensagem so retornados.
CREATE PROCEDURE raise_salary (emp_id NUMBER, increase NUMBER)
AS
current_salary NUMBER;
BEGIN
SELECT sal INTO current_salary FROM emp
WHERE empno = emp_id;
IF current_salary IS NULL THEN
/* Issue user defined error message. */
raise_application_error( 20101, Salary is missing );
ELSE
UPDATE emp SET sal = current_salary + increase
WHERE empno = emp_id;
END IF;
END raise_salary;
Seo Exception
EXCEPTION
WHEN exception_name1 THEN handler
sequence_of_statements1
WHEN exception_name2 THEN another
handler
sequence_of_statements2
...
WHEN OTHERS THEN optional handler
sequence_of_statements3
END;
Exemplo de DBMS_OUTPUT
BEGIN
DBMS_OUTPUT.ENABLE(20000);
DBMS_OUTPUT.PUT_LINE( Incio );
...
DBMS_OUTPUT.PUT_LINE( Fim );
END;
Procedure Builder
Ambiente de desenvolvimento de PL/SQL. Serve como depurador de cdigo PL/SQL. No
pode depurar stored procedures, somente chamar PL/SQL Interpreter Visualizador
Mostra o bloco, procedimento ou funo que est sendo executado
Linha de comandos
Permite execuo imediata de instrues de PL/SQL
Facilidades
Depurar sem necessidade de alterar o cdigo
Insero de breakpoints
Visualizao e alterao dos valores das variveis locais
Depurao mais simples
Ambiente de desenvolvimento integrado
PL/SQL Dinmico
DBMS_SQL
A instruo SQL pode ser montada dinamicamente dentro do bloco
Processa trs tipos de instrues:
Sintaxe
FUNCTION EXECUTE (cursor_id IN INTEGER)
RETURN INTEGER;
O retorno corresponde s linhas processadas somente se forem instrues INSERT,
UPDATE ou DELETE.
DBMS_SQL.FETCH_ROWS
Somente usado em consultas. Faz o fetch buscando os dados no servidor. Os dados de
retorno so convertidos nos tipos definidos com DEFINE_COLUMN.
Sintaxe
FUNCTION FETCH_ROWS (cursor_id IN INTEGER)
RETURN INTEGER;
O retorno o nmero de linhas.
DBMS_SQL.EXECUTE_AND_FETCH
Combina as operaes de EXECUTE e a primeira chamada de FETCH_ROWS.
Sintaxe
FUNCTION EXECUTE_AND_FETCH
(cursor_id IN INTEGER, busca_exata IN BOOLEAN DEFAULT FALSE)
RETURN INTEGER;
Se busca_exata for TRUE e a consulta retornar mais de uma linha, abre a exception
TOO_MANY_ROWS. O retorno o nmero de linhas.
DBMS_SQL.VARIABLE_VALUE
Determina o valor de uma varivel de associao, se for modificada pela instruo
(parmetros de sada). Utilizado quando a instruo um bloco PL/SQL.
Sintaxe
PROCEDURE VARIABLE_VALUE
(cursor_id IN NUMBER,
:nome_na_instruo IN VARCHAR2,
valor_variavel OUT tipo_dado);
DBMS_SQL.COLUMN_VALUE
Somente usado em consultas, aps FETCH_ROWS. Devolve realmente os dados.
Variveis devem ser do mesmo tipo definido em DEFINE_COLUMN.
Sintaxe
PROCEDURE COLUMN_VALUE
(cursor_id IN INTEGER,
posio_coluna IN INTEGER,
valor_coluna OUT tipo_dado);
DBMS_SQL.CLOSE_CURSOR
Fecha o cursor. Libera os recursos utilizados pelo cursor.
Sintaxe
PROCEDURE CLOSE_CURSOR
Declarao de Tipos
A especificao para a package UTL_FILE declarada no tipo:
TYPE file_type IS RECORD (id
BYNARY_INTEGER)
Exemplo:
v_filehandle UTL_FILE.FILE_TYPE;
...
v_filehandle := UTL_FILE.FOPEN(...);
...
Exceptions
Exception Name Descrio
INVALID_PATH Localizao ou nome do arquivo invlido
INVALID_MODE Modo de abertura do arquivo invlido.
INVALID_FILEHANDLE Arquivo Invlido.
INVALID_OPERATION Arquivo no pode ser aberto.
READ_ERROR Um erro de sistema operacional ocorreu durante leitura.
WRITE_ERROR Um erro de sistema operacional ocorreu durante a escrita..
INTERNAL_ERROR Um erro no especificado ocorreu no PL/SQL.
FOPEN
Sintaxe:
FUNCTION FOPEN(location IN VARCHAR2,
filename IN VARCHAR2,
open_mode IN
VARCHAR2)
RETURN UTL_FILE.FILE_TYPE;
Parmetros Descrio
location Diretrio
filename Nome do Arquivo
open_mode r ler um texto (GET_LINE)
w escrever um texto
(PUT, PUT_LINE, NEW_LINE, PUTF, FFLUSH)
a adicionar um texto
(PUT, PUT_LINE, NEW_LINE, PUTF, FFLUSH)
Retorno da Funo FOPEN
FOPEN retorna um file handle que deve ser passado para todas as procedures
chamadas posteriormente.
IS_OPEN
Sintaxe:
FUNCTION IS_OPEN(file_handle IN
FILE_TYPE)
RETURN BOOLEAN;
Parmetro Descrio
file_handle Um file handle ativo retornado na funo FOPEN
FCLOSE
Sintaxe:
PROCEDURE FCLOSE (file_handle IN OUT
FILE_TYPE);
Parmetro Descrio
file_handle Um file handle ativo retornado na funo FOPEN
FCLOSE_ALL
Sintaxe:
PROCEDURE FCLOSE_ALL;
GET_LINE
Sintaxe:
PROCEDURE GET_LINE
(file_handle IN FILE_TYPE,
buffer OUT VARCHAR2);
Parmetro Descrio
file_handle Um file handle ativo retornado na funo FOPEN
buffer Um buffer para receber a linha lida do arquivo.
PUT
Sintaxe:
PROCEDURE PUT
(file_handle IN FILE_TYPE,
buffer IN VARCHAR2);
Parmetro Descrio
file_handle Um file handle ativo retornado na funo FOPEN
buffer Um buffer que contm a linha a ser escrita.
NEW_LINE
Sintaxe:
PROCEDURE NEW_LINE
(file_handle IN FILE_TYPE,
lines IN NATURAL := 1);
Parametro Descrio
file_handle Um file handle ativo retornado na funo FOPEN
lines Nmero de linhas de terminao a serem
escritas no arquivo.
PUT_LINE
Sintaxe:
PROCEDURE PUT_LINE
(file_handle IN FILE_TYPE,
buffer IN VARCHAR2);
Parmetro Descrio
file_handle Um file handle ativo retornado na funo FOPEN
buffer Um buffer que contem a linha a ser escrita.
FFLUSH
Sintaxe:
PROCEDURE FFLUSH
(file_handle IN FILE_TYPE);
Parmetro Descrio
file_handle Um file handle ativo retornado na funo FOPEN
Exemplo
PROCEDURE file_to_table
(loc_in IN VARCHAR2, file_in IN VARCHAR2,
table_in IN names_tabtype)
IS
names_file CONSTANT UTL_FILE.FILE_TYPE :=
UTL_FILE.FOPEN (loc_in, file_in, R);
line_counter INTEGER := 1;
BEGIN
LOOP
UTL_FILE.GET_LINE(names_file,
table_in(line_counter));
line_counter := line_counter + 1;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
UTL_FILE.FCLOSE(names_file);
END;
Desempenho e Otimizao
Instncia Oracle
SGA: Sistem Global Area
Shared Pool
Armazena instrues SQL recebidas do BD
Triggers
Manter o cdigo o mais pequeno possvel, atravs de chamadas de subprogramas
armazenados antes da verso 7.3 os triggers no eram armazenados de forma compilada
Otimizao de instrues SQL
Explain Plan
Tabela plan_ table
Pode ser criada localmente atravs de $ORACLE_HOME\ rdbms\admin\utlxplan.sql
No SQL* Plus
SET AUTOTRACE ON
Aps cada instruo faz automaticamente o explain plan
Tkprof
ALTER SESSION SET SQL_TRACE=TRUE
gera um arquivo de log de todas as instrues SQL, no formato ora_nnnnn.trc
Aps todos os comandos efetuados, fechar o arquivo de log, alterando para FALSE
Executar tkprof para formatar o arquivo .trc
Anlise de Resultados
NESTED LOOP
Operao necessria para executar os joins de tabelas
TABLE ACCESS (FULL)
Pesquisa integral, buscando todas as linhas da tabela
TABLE ACCESS (BY ROWID)
Modo mais rpido de buscar uma s linha
INDEX: {UNIQUE | RANGE} SCAN
Tcnicas
Verificar questes de rede. Utilizar PL/SQL no Client sempre que possvel. Evitar
repeties de parse desnecessrias.
Interface matricial Oracle
permite grandes quantidades de dados
enviados pela rede como uma unidade