Buscar

Resumo sobre Oracle

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 43 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 43 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 43 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
1 
 
 
 
 
 
 
 
 
 
 
 
 
Material de Apoio 
 
 
 
Oracle 
 
 
 
 
 
 
 
 
 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
2 
ÍNDICE 
 
 
 
1. Introdução............................................................................................................................... 3 
2. Objetivo.................................................................................................................................. 3 
3. Tabelas e colunas (Tables and columns)................................................................................ 3 
4. Sequences (sequências) .......................................................................................................... 6 
5. Tabela DUAL......................................................................................................................... 8 
6. Funções e Operadores de linhas simples................................................................................ 8 
7. SQL e PL/SQL ..................................................................................................................... 11 
8. Estrutura de um Bloco PL/SQL ........................................................................................... 15 
9. Views.................................................................................................................................... 17 
10. Index (índice) ..................................................................................................................... 18 
11. Procedures, Functions e Triggers ....................................................................................... 19 
12. Tratamento de Erros (Exceções) ........................................................................................ 29 
13. Cursor ................................................................................................................................. 34 
 
 
 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
3 
1. Introdução 
 
O Oracle é um sistema gerenciador de banco de dados (SGBD) relacional utilizado 
por muitas empresas hoje em dia. Sua aplicação vem aumentando consideravelmente por 
oferecer confiabilidade (segurança/suporte) e alto desempenho com grandes volumes de 
dados e transações. 
 
2. Objetivo 
 
 Esta apostila tem como objetivo oferecer aos alunos informações para a 
compreensão de funcionalidades básicas do Oracle. 
 
3. Tabelas e colunas (Tables and columns) 
 
Tabelas são mecanismos de armazenamento para dados de um banco de dados 
Oracle. Sua função é armazenar uma série de colunas fixas. As colunas de uma tabela 
descrevem os atributos da entidade que esta sendo estipulado pela tabela. Cada coluna tem 
um nome e características específicas. 
 As características de uma coluna são divididas em duas partes: seu tipo de dado e 
seu tamanho. 
 
CREATE TABLE [schema].tabela 
 (coluna tipo_de_dado 
 [DEFAULT expressão]) 
 
o schema é o mesmo que o nome do 
dono. Na parte prática veremos com 
mais atenção a criação de tabelas. 
 
ALTER TABLE tabela 
 ADD (coluna tipo_de_dado 
 [DEFAULT expressão]) 
acrescenta colunas em uma tabela 
ALTER TABLE tabela 
 MODIFY (coluna tipo_de_dado 
 [DEFAULT expressão]) 
altera colunas em uma tabela 
DROP TABLE tabela apaga a tabela (Não é possível fazer 
rollback desta classe de comandos - 
DDL). 
TRUNCATE TABLE tabela remove todas as linhas de uma tabela 
preservando a sua estrutura. 
RENAME tabela TO novonome renomeia uma tabela. 
COMMENT ON TABLE tabela IS 
‘comentário’ 
adiciona comentário em tabela 
(dicionário de dados: 
USER_TAB_COMMENTS). 
 
 Exemplos. 
 
 Criar uma tabela: 
 
 CREATE TABLE CLIENTE 
 (CLI_COD NUMBER(6) NOT NULL PRIMARY KEY, 
 CLI_NOME VARCHAR2(70) NOT NULL, 
 CLI_SEXO CHAR(1) CHECK (CLI_SEXO IN ('M', 'F')), 
 CLI_DTNASCTO DATE NOT NULL, 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
4 
 CID_COD NUMBER(3), 
 CONSTRAINT FK_CLI_CIDADE FOREIGN KEY (CID_COD) 
REFERENCES CIDADE(CID_COD)); 
 
 DROP TABLE CLIENTE; 
 
 Alterar uma tabela: 
 
 ALTER TABLE CLIENTE ADD (CLI_CPF VARCHAR2(11)); 
 ALTER TABLE CLIENTE RENAME 
COLUMN CLI_DTNASCTO TO CLI_DTNASC; 
 ALTER TABLE CLIENTE DROP COLUMN CLI_CPF; 
 
 Apagar uma tabela: 
 
 DROP TABLE CLIENTE; 
 
Os tipos de dados (Data Types) básicos de dados no Oracle são: 
 
size = tamanho 
Tipo Descrição 
CHAR(size) Aceita dados alfanuméricos. Tamanho (size) fixo, podendo ser 
utilizado de 1 a 2000 caracteres. 
VARCHAR2(size) Aceita dados alfanuméricos. Tamanho variável pelo estipulado em 
(size), podendo variar de 1 a 4000 caracteres. 
VARCHAR(size) Mesmo que o tipo Varchar2 (não é recomendado). Existe para 
manter compatibilidade com versões anteriores. 
DATE Valor de data e hora abrangendo 01/01/4712 a.C. até 31/12/4712 
d.C. 
LONG Similar ao Varchar2, porém o tamanho máximo é de 2 GB. A 
documentação da Oracle não recomenda seu uso. Existe para 
manter compatibilidade com versões anteriores. Sugere como 
alternativa a utilização de CLOB. 
NUMBER(I,D) Valor numérico, onde: I = quantidade total de dígitos 
(inteiros+decimais) e D = quantidade de dígitos decimais 
RAW Usado para dados binários ou dados não interpretados pelo Oracle, 
como uma seqüência de caracteres gráficos, arquivos executáveis, 
arquivos PDF, etc. Tem tamanho máximo de 2000 bytes 
LONG RAW Similar ao Raw, mas com tamanho de até 2 GB 
BLOB Binary Large Object – suporta dados binários com tamanho até 4 GB 
CLOB Large Object – suporta dados caracteres com tamanho até 4 GB 
BFILE Utilizado como apontador para um arquivo binário em um servidor de 
arquivos – tamanho até 4 GB 
 
 Existem diversos outros tipos aceitos pelo Oracle, mas que não foram abordados 
aqui por não fazerem parte do escopo da disciplina. 
 
As tabelas do usuário SYS são chamadas de tabelas de dicionário de dados. Elas 
provêem um catálogo do sistema que o banco de dados usa para sua própria administração. 
 Tabelas se relacionam umas com as outras através das colunas que as mesmas têm 
em comum. O banco de dados pode reforçar esta relação via integridade referencial. O 
Oracle denomina esta ligação de constraint (constrangimento). 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
5 
3.1. Table Constraint (restrição de tabelas) 
 
O Oracle usa constaints para prevenir entrada de dados inválidos em tabelas. 
Podemos usar constraints para fazer as seguintes operações: 
• reforçar regras no nível de tabela sempre que uma linha é inserida, atualizada ou 
apagada. 
• prevenir a deleção de uma tabela se existem dependentes em outras tabelas. 
• prover regras para as ferramentas do Oracle, como o SQL Developer. 
 
Podem ser: 
NOT NULL impede que um valor nulo seja inserido nesta coluna. 
UNIQUE KEY especifica uma coluna ou uma série de colunas que não podem ter 
valores repetidos ao longo da tabela. 
PRIMARY KEY identificador único de cada linha em uma tabela. 
FOREIGN KEY estabelece e reforça uma chave estrangeira entre uma coluna e a 
tabela relacionada. 
CHECK estabelece uma condição que deve ser verdadeira. 
 
 
Exemplos 
 
CREATE TABLE EMPREGADOS( 
 EMP_COD NUMBER(6) PRIMARY KEY, 
 DEP_COD NUMBER(2) NOT NULL, 
 EMP_NOME VARCHAR2(60), 
 EMP_SALARIO NUMBER(10,2), 
CONSTRAINT CONST_EMPREGADO UNIQUE(NOME)); 
 
Adicionando uma constraint 
 
ALTER TABLE EMPREGADOS 
ADD CONSTRAINT CONST_DEPARTAMENTO_FK 
 FOREIGN KEY (DEP_COD) REFERENCES DEPARTAMENTOS(DEP_COD); 
 
Deletando uma constraint 
 
ALTER TABLE EMPREGADOS 
DROP CONSTRAINT CONST_DEPARTAMENTO_FK; 
 
Desabilitando uma constraint 
 
ALTER TABLE EMPREGADOS 
DISABLE CONSTRAINT CONST_DEPARTAMENTO_FK; 
 
Habilitando uma constraint 
 
ALTER TABLE EMPREGADOS 
ENABLE CONSTRAINTCONST_DEPARTAMENTO_FK; 
 
OBS: As constraints são armazenadas na tabela USER_CONSTRAINTS do dicionário de 
dados. 
 
Outros exemplos: 
 
“nome da constraint” 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
6 
CREATE TABLE EMPREGADOS 
(CODIGO NUMBER(10) PRIMARY KEY, 
 NOME CHAR(40) NOT NULL, 
 DEP_COD NUMBER(2) DEFAULT 10, 
 SALARIO NUMBER(7,2) CHECK (SALARIO < 180), 
 NASC DATE, 
 RG CHAR(9) UNIQUE, 
 FOREIGN KEY (DEP_COD) REFERENCES DEPARTAMENTOS(DEP_COD) 
 ) TABLEPACE USERS; 
 
Note que cada coluna tem o seu tamanho e o tipo de dados associado, bem como 
algumas colunas possuem as seguintes constraints 
 
PRIMARY KEY 
NOT NULL, 
DEFAULT 10 
CHECK (SALÁRIO < 180) 
UNIQUE 
 
A constraint FOREIGN KEY nos obriga a ter uma tabela DEPTO, cuja coluna 
DEP_COD tenha o valor que estamos inserindo nesta linha neste momento. 
 
 Outros exemplos: 
 
 ALTER TABLE CLIENTE DROP CONSTRAINT FK_CLI_CIDADE; 
ALTER TABLE CLIENTE ADD 
CONSTRAINT FK_CLI_CIDADE FOREIGN KEY 
(CID_COD) REFERENCES CIDADE; 
ALTER TABLE CLIENTE ADD CONSTRAINT NN_CLI_CPF CLI_CPF 
VARCHAR2(11) NOT NULL; 
 ALTER TABLE CLIENTE ADD CONSTRANIT PK_CLIENTE 
PRIMARY KEY (CLI_COD); 
 
 
4. Sequences (sequências) 
 
Uma seqüência ou sequence é usada para gerar uma lista de números seqüências 
para as colunas numéricas das tabelas de um banco de dados, recomendada 
principalmente para chaves primárias. As seqüências simplificam a programação de 
aplicações pois geram automaticamente e sem degradação de performance, valores 
seqüências para linhas de uma ou mais tabelas, portanto não acessam o disco, não ocorrem 
locks implícitos ou explícitos em suas estruturas e, assim a serialização é reduzida, pois dois 
ou mais comandos podem utilizá-las ao mesmo tempo. 
Os números seqüências gerados pelo Oracle são inteiros de 38 dígitos e são 
definidos em um banco de dados. A definição de uma seqüência mostra diversas 
informações como o nome da seqüência, se a geração dos números é ascendente ou 
descendente, o intervalo entre os números gerados, e outras informações. As definições de 
todas as seqüências de um banco são armazenadas em uma tabela do dicionário de dados. 
Os números seqüências são usados pelos comandos SQL para gerar um novo 
número seqüencial ou usar o número atual. Os números seqüências são gerados 
independentemente das tabelas mas podemos usar um gerador de números seqüências 
para mais de uma tabela. 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
7 
Resumindo: 
• automaticamente gera números únicos; 
• é um objeto compartilhável; 
• é tipicamente usada para criar um valor para uma chave primaria; 
• substitui código em aplicações 
• aumenta a velocidade para acessar valores seqüenciais armazenados na 
memória (“cacheados”). 
 
Sintaxe: 
 
CREATE SEQUENCE sequence 
 [INCREMENT BY n] 
 [START WITH n] 
 [(MAXVALUE n|NOMAXVALUE)] 
 [(MINVALUE n|NOMINVALUE)] 
 [(CYCLE|NOCYCLE)] 
 [(CACHE n|NOCACHE)]; 
 
INCREMENT BY especifica o intervalo entre os números da sequence - padrão 1 
START WITH n especifica o primeiro valor da sequence - padrão 1 
MAXVALUE n especifica o valor máximo para a sequence atingir 
NOMAXVALUE sem valor máximo 
MINVALUE n especifica o valor mínimo da sequence 
NOMINVALUE sem valor mínimo 
CYCLE começa a gerar do começo quando o limite for alcançado 
NOCYCLE não começa a gerar do começo quando o limite for alcançado 
CACHE n especifica quantos valores o Oracle Server irá pré-alocar na memória 
para disponibilidade imediata - padrão 20 valores. 
NOCACHE não pré-aloca nada, fazendo consultas ao dicionário de dados a cada 
incremento da sequence. 
 
Usando uma sequence: 
 
CURRVAL Retorna o valor corrente de uma sequence. Considera somente o 
valor da sessão/conexão ativa. Somente acessível após o primeiro 
NEXTVAL da sessão/conexão. 
NEXTVAL Retorna o próximo valor de uma sequence e faz o seu incremento. 
Considera a instância do banco para que o incremento nunca se 
repita para diferentes ssões/conexões. 
 
Exemplo - gravando dados em uma tabela com chave primária: 
 
CREATE SEQUENCE SEQ_CLIENTE 
START WITH 1 
INCREMENT BY 1 
NOMAXVALUE 
NOMINVALUE 
NOCYCLE 
NOCACHE; 
 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
8 
Situação 1: 
 
INSERT INTO CLIENTE (CLI_COD,CLI_NOME) 
VALUES (SEQ_CLIENTE.NEXTVAL,'TESTE'); 
 
INSERT INTO CLIENTE_FONE (CLI_COD, FONE_COD, FONE_NUMERO) 
VALUES (SEQ_CLIENTE.CURRVAL, 1, '(18) 3333-4567'); 
 
INSERT INTO CLIENTE_FONE (CLI_COD, FONE_COD, FONE_NUMERO) 
VALUES (SEQ_CLIENTE.CURRVAL, 2, '(18) 4444-5566'); 
 
Situação 2: 
 
CREATE OR REPLACE PROCEDURE INSERE_CLIENTE 
 (P_CLI_COD OUT CLIENTE.CLI_COD%TYPE, 
 P_CLI_NOME IN CLIENTE.CLI_NOME%TYPE) 
IS 
BEGIN 
 SELECT SEQ_CLIENTE.NEXTVAL INTO P_CLI_COD FROM DUAL; 
 INSERT INTO CLIENTE(CLI_COD,CLI_NOME) 
 VALUES(P_CLI_COD,P_CLI_NOME); 
END; 
 
5. Tabela DUAL 
 
Tabela do usuário SYS com acesso público para ser utilizado em instruções “select” 
que necessitam retornar uma única linha, sem necessidade de acesso a atributos de outras 
tabelas. 
 Exemplo: 
 
 -- retorna a data do sistema 
 SELECT SYSDATE FROM DUAL; 
 
-- realiza a operação matemática 
SELECT (145.6*85.1/4) AS CONTA FROM DUAL; 
 
-- exibir o usuário conectado no banco 
SELECT USER FROM DUAL; 
 
6. Funções e Operadores de linhas simples 
 
 No Oracle, como em todos os outros SGBD’s, há uma série de funções pré-definidas 
para serem utilizadas no intuito de transformar dados a serem recuperados ou manipulados 
com comandos SQL. Essas funções podem: 
 
• manipular itens de dados; 
• aceitar argumentos e retornar um valor; 
• agir sobre cada linha retornada; 
• retornar um resultado por linha; 
• modificar o tipo de dado 
• podem ser aninhados 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
9 
 
Algumas das funções mais utilizadas: 
 
Funções Gerais 
LOWER converte uma string em minúscula 
UPPER converte uma string em maiúscula 
INITCAP Retorna a string com o primeiro caractere de cada 
palavra em maiúsculo e os caracteres restantes 
em minúsculo 
CONCAT Concatenação de strings - equivalente a || 
SUBSTR(coluna/expressão,m[,n]) retorna caracteres especificados a partir da 
posição m até a posição n da coluna/expressão. 
LENGTH(coluna/expressão) retorna o número de caracteres (tamanho) da 
coluna/expressão 
INSTR 
(str1,str2,p_ini,ocorrencia,’string’) 
retorna a posição em que a string2 está contida 
de string1. 
p_ini: posição de string1 a partir da qual será 
iniciada a busca – opcional – default 1 
ocorrência: indica o número da ocorrência – se 
retorna na 1a. ocorrência encontrada, na 2a., e 
assim por diante – opcional – default 1. 
LPAD(string1,n,string2) 
 
Retorna string1 preenchida à esquerda até o 
comprimento de n com os caracteres de string2. 
RPAD(string1,n,string2) 
 
Retorna string1 preenchida à direita até o 
comprimento de n com os caracteres de string2. 
ROUND(coluna/expressão,n) arredonda a coluna/expressão para n casas 
decimais. 
TRUNC(coluna/expressão,n) trunca a coluna/expressão em n casas decimais e 
se n for omitido, pega somente a parte inteira da 
expressão 
NVL(coluna/expressão,n) converte um valor nulo na expressão n 
Ex: NVL(salário,’não estipulado’) 
DECODE(coluna/expressão, 
pesquisa1, resultado1[, pesquisa2, 
resultado2,...,][default]) 
decifra a coluna/expressão e compara com 
pesquisaN, devolvendo como resultado o 
resultadoN, se nenhum for encontrado segue o 
default 
MOD(m,n) retorna o resto da divisão 
Funções de data e hora 
SYSDATE retorna a data e a hora do sistema 
data + numero resulta em data + numero dias (data) 
date - numero resulta em data - numero (data) 
date - date número de dias (inteiro) 
date + numero/24 adiciona um número de horas a uma data (data) 
MONTHS_BETWEEN(data1,data2) Retorna o número de meses entre data1 e data2 
ADD_MONTHS(d,x) Retorna a datad mais x meses 
NEXT_DAY(data,dia_semana) A partir da data informada, retorna a data do 
próximo dia da semana especificado. 
Onde dia_semana; 
1–domingo, 2-segunda,.....,6-sábado 
LAST_DAY(data) Retorna a data do último dia do mês 
ROUND(data,formato) arredonda a data para o formato especificado 
(opcional) ou para o menor valor possível. 
TRUNC trunca a data, para o formato especificado 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
10 
(opcional) ou para o menor valor possível. 
Funções de conversão 
TO_CHAR(x,formato) converte x em um tipo de caractere, formato 
opcional 
TO_DATE(y,formato) converte y para data 
TO_NUMBER(x) converte x para tipo numérico 
 
 O tratamento e manipulação do tipo DATE no Oracle exige alguns cuidados 
especiais, pois este tipo armazena sempre data e hora simultaneamente num mesmo 
atributo ou variável. Para isso, é indispensável a utilização das funções TO_CHAR e 
TO_DATE, em ambas pode ser especificado uma máscara de formatação de data e hora. 
Na tabela abaixo são apresentados os mais comuns: 
 
DD Dia: 01, 02…31 
MM Mês: 01...12 
YY Ano de 2 dígitos: 07,08 
YYYY Ano de 4 dígitos: 2007, 2008 
HH24 Hora no padrão 24 hs: de 00 a 23 
MI Minutos: 00 a 59 
SS Segundos: 00 a 59 
d Dia da semana (1-domingo a 6-sábado) 
 
 Existem vários outros formatos que podem ser verificados nos arquivos de referência 
no diretório público. 
 Algumas situações serão apresentadas para melhor entendimento. 
 
SELECT NOT_NUM, 
 TO_CHAR(NOT_DATA,'DD/MM/YYYY HH24:MI:SS') AS DATA 
FROM NOTA 
WHERE NOT_DATA BETWEEN 
 TO_DATE('01/01/2000 00:00:00','DD/MM/YYYY HH24:MI:SS') AND 
 TO_DATE('091231235959', 'YYMMDDHH24MISS'); 
 
Neste caso note que para exibir o atributo NOT_DATA (definido como “date” na 
tabela) foi utilizada a função TO_CHAR para formatar o modo de exibição. Caso não tivesse 
sido usada a função, seria exibida a data no formato padrão do “client” do Oracle. 
Outro detalhe está presente na cláusula WHERE quando há a comparação do 
atributo NOT_DATA. Tem-se que comparar DATE com DATE, por isso transformar a string 
entre aspas em DATE com a função TO_DATE. 
 
-- SOMAR 3 HORAS EM UMA DATA 
SELECT TO_CHAR(SYSDATE+(1/24)*3,’DD/MM/YYYY HH24:MI’) AS DATA 
FROM DUAL; 
 
-- QUANTOS DIAS HÁ ENTRE 2 DATAS 
SELECT TO_DATE('01/01/08','DD/MM/YY')-TO_DATE('01/05/05','DD/MM/YY') 
FROM DUAL; 
 
-- INSERT EM UMA TABELA COM ATRIBUTO DATE 
INSERT INTO NOTA(NOT_NUM, CLI_COD, NOT_DATA, NOT_TOTAL) 
VALUE(150,1,TO_DATE('01/01/08 HH24:MI','DD/MM/YY 10:30'),5230); 
 
 Mais referências podem ser encontradas no diretório public. 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
11 
7. SQL e PL/SQL 
 
Structured Query Language (Linguagem estruturada de consulta) a SQL permite que 
você se comunique com o banco de dados com as seguintes vantagens: 
1.Eficiência; 
2.Facilidade de aprendizado e uso; 
3.Funcionalidade total - permite definir, manipular e recuperar dados em tabelas. 
 
 PL/SQL - Procedural Language que estende os recursos da SQL através do uso de 
lógica de aplicação. 
 
7.1. Declarações SQL 
 
Select Recuperação de dados (DRS) 
Insert 
Update 
Delete 
Linguagem de manipulação de dados 
(DML) 
Create 
Alter 
Drop 
Rename 
Truncate 
Linguagem de definição de dados (DDL) 
Commit 
Rollback 
Savepoint 
Controles de Transações 
Grant 
Revoke 
Linguagem de controle de dados (DCL) 
 
7.2. Benefícios da PL/SQL 
 
 Com a PL/SQL podemos realizar toda a camada de aplicação lógica internamente no 
banco de dados, ficando a cargo da estação somente a camada de interface com o usuário. 
1. Aumento de performance através da redução de tráfico de rede; 
2. Agrupamento de lógicas relacionadas em blocos; 
3. Aninhar blocos menores em maiores para construir programas mais poderosos; 
4. Quebrar um problema complexo em blocos menores para facilitar a 
administração; 
5. Colocar código reusável em bibliotecas; 
6. Alta portabilidade (pode migrar para qualquer host); 
7. Posso declarar identificadores; 
8. Estrutura de controle procedural (pascal, c); 
9. Pode manipular erros; 
 
Qualquer rotina de um programa PL/SQL é baseada em blocos. Um programa 
PL/SQL pode ser composto por um ou mais blocos, os quais podem ocorrer 
seqüencialmente (um depois do outro) ou aninhados (um dentro do outro). 
 Serão apresentados mais detalhes mais à frente. 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
12 
7.3. Sintaxe 
7.3.1. Select 
 
SELECT * FROM tabela; seleciona todos os elementos da tabela 
SELECT 
coluna1,coluna2,...,colunan 
FROM tabela; 
seleciona as colunas mencionadas da 
tabela 
SELECT (coluna1+300)+100, 
coluna2* 2 FROM tabela; 
seleciona as colunas mencionadas com 
operadores matemáticos que têm a 
seguinte precedência: * / + - para mudar a 
preferência tenho que usar parênteses. 
SELECT coluna1*1.08 AS “Novo 
salário” FROM tabela; 
posso dar um apelido as colunas 
associando um alias ao mesmo. As aspas 
duplas preservam a formatação interna 
dos caracteres. 
SELECT nome||’ ‘||sobrenome 
FROM tabela; 
|| é o operador de concatenação. 
SELECT DISTINCT salário FROM 
tabela; 
a clausula distinct elimina as linhas 
duplicadas na consulta. 
 
7.3.2. Restringindo e ordenando dados 
 
SELECT * 
FROM tabela 
WHERE nome= ‘JOÃO’; 
seleciona todos os elementos da tabela 
cujo nome seja exatamente ‘JOÃO’. 
Operadores de comparação = (igual) 
> (maior) 
>= (maior ou igual) 
< (menor) 
<= (menor ou igual) 
<> (diferente) 
 
SELECT nome,salário 
FROM tabela 
WHERE cargo<>‘diretor’ and 
salário > 10000; 
posso colocar tantas cláusulas restritivas 
quantas eu quiser adicionando AND, OR 
ou NOT - operadores lógicos.Têm a 
seguinte precedência: 
NOT 
AND 
OR 
Outros operadores de comparação BETWEEN ... AND... - entre dois valores 
(muito usado para datas) 
IN(lista) - coloco todos os elementos que 
quero comparar 
LIKE – como associado ao % - que 
substitui qualquer expressão - e ao _ 
(underline) - que substitui qualquer 
caractere - faz buscas por expressões 
parciais. 
IS NULL - compara com valores nulos dos 
campos. 
SELECT nome||’ ‘||sobrenome a cláusula order by ordena a consulta, 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
13 
FROM tabela ORDER BY nome 
[DESC][ASC]; 
trazendo os dados de forma ordenada em 
forma descendente DESC - ou 
ascendente ASC (padrão). Podem ser 
usadas múltiplas colunas na ordenação 
 
7.4. Mostrando dados de várias tabelas 
 
SELECT 
tabela1.coluna1,tabela2.coluna2 
FROM tabela1,tabela2 
WHERE 
tabela1.chave1 = tabela2.chave2 
Quando dados de mais de uma tabela no 
banco de dados são requeridos, podem 
ser juntados com a cláusula WHERE ao 
lado. Geralmente isto se dá com chaves 
primárias e chaves estrangeiras. 
SELECT 
tabela1.coluna1,tabela2.coluna2 
FROM tabela1,tabela2 
A SQL ao lado devolve um produto 
cartesiano das duas tabelas (mostra para 
cada registro da 1a todos os registros da 2a 
) 
Equijoin Envolve duas colunas iguais/correlatas em 
ambas as tabelas - geralmente chave 
primária e chave estrangeira 
Non-equijoin Duas colunas diferentes compõem a 
consulta, como mostrar os salários da 
tabela A que estão entre dois valores da 
tabela B. 
Outer join 
SELECT tabela1.coluna1, 
tabela2.coluna2 
FROM tabela1 , tabela2 
 WHERE tabela1.codigo(+) = 
tabela2.codigo; 
Retorna registros que não 
necessariamente encontraram 
correspondência. No Exemplo ao lado 
pegamos os dados da tabela1 que não 
têm correspondente na tabela2 e os 
exibimos mesmo assim com valor nulo. 
 
Self join 
SELECT unique e1.cargo, e1.nome 
 FROM empregados e1, 
empregados e2 
WHERE e1.chefe = e2.emp_codigo; 
Podemos ter uma tabela relacionada com 
ela mesmo e extrair os dados baseados 
nesta informação. 
EMPREGADOS 
EMP_COD, NOME, CHEFE 
 
7.5. Agregando dados usando funções de agrupamento 
 
 As funções de grupo buscam resumos de operações, tais como totalda folha, saldo, 
média, etc... 
AVG Média (ignora valores nulos) 
COUNT Conta o número de registros que 
satisfazem o critério especificado. 
MAX pega o maior valor (ignora valores nulos) 
MIN pega o menor valor (ignora valores nulos) 
STDDEV desvio padrão (ignora valores nulos) 
SUM soma os valores (ignora valores nulos) 
VARIANCE calcula a variância (ignora valores nulos). 
GROUP BY 
 
agrupa os valores de uma consulta por 
esta condição. Todos os itens da consulta 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
14 
SELECT 
departamento,AVG(salário) 
FROM empregados 
GROUP BY departamento 
têm que estar agrupados ou usando 
funções de agrupamento. 
HAVING 
 
SELECT 
departamento,AVG(salário) 
FROM empregados 
GROUP BY departamento 
HAVING AVG(salário) > 1000 
ORDER BY departamento 
 
Esta cláusula é usada para especificar 
quais grupos serão mostrados. 
 
7.6. Subqueries 
 
Podemos nos deparar com a seguinte ordem: Mostre todos os salários que sejam 
maiores que o do empregado ‘Jose’. 
 A SQL que recupera os dados do banco de dados tem que passar como condição de 
busca o salário do ‘Jose’ para a SQL que recupera os dados dos outros funcionários. 
 
SELECT departamento,nome,salario 
FROM empregados 
WHERE salario > (SELECT salario 
 FROM empregados 
 WHERE nome = ‘Jose’); 
 
Para usar a subqueries temos algumas regras básicas: 
 
• Encapsule as subqueries entre parênteses; 
• coloque as subqueries do lado direito da comparação; 
• não coloque ORDER BY em uma subquerie (Oracle 8 ou inferior); 
• use operadores de linha única (=,>,<) com consultas de linha única; 
• use operadores de múltiplas linhas (in, exists) com subqueries de múltiplas 
linhas. 
 
7.7 Controlando Transações 
 
 O servidor Oracle assegura a consistência dos dados baseado em transações. 
Transações nos proporcionam mais flexibilidade e controle quando estamos mudando 
dados. 
 As chaves de transações são os comandos: 
 
COMMIT finaliza a transação corrente, fazendo 
todas as atualizações pendentes e 
transformando-as em permanentes. 
ROLLBACK finaliza a transação corrente descartando 
todas as mudanças realizadas. 
SAVEPOINT marca um ponto de inicio para uma dada 
transação, nomeando-a: 
SAVEPOINT a; 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
15 
8. Estrutura de um Bloco PL/SQL 
 
 PL/SQL é uma linguagem estruturada em blocos significando que programas podem 
ser divididos em blocos lógicos. Constitui-se de três sessões: 
 
Declarativa contém todas as variáveis, constantes, 
exceções definidas pelo usuário que 
estão referenciadas nas sessões de 
execução 
Opcional 
Executável contém as declarações SQL para 
manipulação de dados no banco de 
dados e instruções PL/SQL para 
manipulação de dados no bloco. 
Obrigatória 
Exception Handling 
(manipulação de exceções) 
Especifica a ação a tomar quando erros 
e condições anormais ocorrem na 
sessão executável. 
Opcional 
 
 
Tipos de blocos 
 
Anonymous Procedure Function 
[DECLARE] 
 
BEGIN 
 -- comandos 
[EXCEPTION] 
 
END; 
PROCEDURE nome IS 
 
BEGIN 
 -- comandos 
[EXCEPTION] 
 
END; 
FUNCTION nome 
RETURN tipo_de_dado 
IS 
 
BEGIN 
 -- comandos 
 RETURN valor; 
[EXCEPTION] 
 
END; 
 
8.1. Estruturas de Controle 
 
 Podemos controlar o fluxo de um bloco PL/SQL com algumas estruturas de controles 
que existem na maioria das linguagens que conhecemos. 
 
Nota: Toda instrução PL/SQL é finalizada com ponto-e-vírgula (;). 
 
Atribuição ( := ) 
 
( := ) - dois pontos igual 
 variável := expressão; 
 vnome := ‘jose’; 
IF THEN ELSE 
 
IF condição THEN 
sequencia_de_intruções; 
ELSIF condição THEN 
sequencia_de_intruções; 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
16 
ELSE 
sequencia_de_intruções; 
END IF; 
 
 A única observação é que a sintaxe precisa ser exata e não temos ferramentas de 
interação para analisar onde está o erro precisamente, ainda mais se o mesmo ocorrer 
dentro desta estrutura. 
 
LOOP 
 
 PL/SQL nos fornece um número de facilidades para estrutura de loop para repetir 
uma seqüência de três maneiras básicas: Loop Básico, Loop FOR e Loop WHILE. 
 
LooP Básico: 
 
DECLARE 
 VAR_COD EMPREGADO.COD_EMPREGADO%TYPE := 100; 
 VAR_CONTADOR NUMBER(2) :=1; 
BEGIN 
 LOOP 
 INSERT INTO ITEM(COD_EMPREGADO,ORDEM) 
 VALUES(VAR_COD,VAR_CONTADOR); 
 VAR_CONTADOR := VAR_CONTADOR+1; 
 EXIT WHEN VAR_CONTADOR > 10; 
 END LOOP; 
END; 
 
Loop FOR: 
 
DECLARE 
 VAR_COD EMPREGADO.COD_EMPREGADO%TYPE := 100; 
 VAR_CONTADOR NUMBER(2); 
BEGIN 
 FOR VAR_CONTADOR IN 1..10 LOOP 
 INSERT INTO ITEM(COD_EMPREGADO,ORDEM) 
 VALUES(VAR_COD,VAR_CONTADOR); 
 END LOOP; 
END; 
 
Loop WHILE: 
 
DECLARE 
VAR_COD EMPREGADO.COD_EMPREGADO%TYPE := 100; 
VAR_CONTADOR NUMBER(2) :=1; 
BEGIN 
WHILE VAR_CONTADOR < 10 LOOP 
 INSERT INTO ITEM(COD_EMPREGADO,ORDEM) 
 VALUES(VAR_COD,VAR_CONTADOR); 
 VAR_CONTADOR := VAR_CONTADOR+1; 
END LOOP; 
END; 
 
 Posso aninhar os loops à vontade e há ainda um diferencial importante que é o fato 
de podermos nomear um loop e sair dele com “EXIT nome“. 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
17 
CASE 
 
 Sintaxe 1: 
 
 CASE VAR_TESTE 
 WHEN VALOR1 THEN ...INSTRUÇÕES...; 
 WHEN VALOR2 THEN ...INSTRUÇÕES...; 
 ELSE ...INSTRUÇÕES...; 
 END CASE; 
 
 Sintaxe 2: 
 
 CASE 
 WHEN VAR_TESTE_1 = VALOR1 THEN 
...INSTRUÇÕES...; 
 WHEN VAR_TESTE_1 < VALOR2 THEN 
...INSTRUÇÕES...; 
 ELSE 
...INSTRUÇÕES...; 
 END CASE; 
 
 
 Sintaxe 3 (case com “select”): 
 
SELECT CASE 
 WHEN CLI_COD='01' THEN 
 'CODIGO 1' 
 WHEN CLI_COD = '02' THEN 
 'CODIGO 2' 
 ELSE 
 'OUTRO CODIGO' 
 END AS LOCAL 
 FROM CLIENTE; 
 
 
9. Views 
 
 Devemos usar uma view para: 
 
• restringir o acesso a dados; 
• fazer queries complexas ficarem simples; 
• permitir a independência de dados; 
• para apresentar diferentes visões do mesmo dado. 
 
Criando uma view: 
 
CREATE [OR REPLACE] [FORCE] [NOFORCE] VIEW visão 
AS subquerie 
 [WITH CHECK OPTION [CONSTRAINT constriant]] 
[WITH READ ONLY] 
 
OR REPLACE se já houver substitua; 
FORCE cria independente da existência das tabelas; 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
18 
 
NO FORCE cria se a tabela existir (default); 
WITH CHECK OPTION especifica que somente linhas acessíveis à view 
podem ser atualizadas ou inseridas; 
WITH READ ONLY assegura que nenhuma operação DML pode ser 
feita sobre esta view. 
 
Exemplo: 
 
CREATE OR REPLACE VIEW V_CLIENTES (CODIGO, NOME, TOTAL) 
 AS SELECT C.CLI_COD, C.CLI_NOME, SUM(N.NOT_TOTAL) AS TOTAL 
 FROM CLIENTE C, NOTA N 
 WHERE C.CLI_COD = N.CLI_COD 
 GROUP BY C.CLI_COD, C.CLI_NOME; 
 
10. Index (índice) 
 
 Este tópico somente aborda sintaxe e algumas particularidades para a criação de 
índices que, sucintamente, são estruturas auxiliares que contém a chave do índice 
(composta de um ou mais atributos da tabela) de forma ordenada e o endereço do registro 
correspondente na tabela e é utilizado para otimizar consultas ao banco de dados. 
 Exemplo: se utilizamos muito buscas por data da nota fiscal, então aconselha-se a 
termos um índice pela data da nota fiscal referente à tabela de nota fiscal; ou então para 
consultas por nome do cliente. 
 
 SELECT * 
 FROM NOTA N 
 WHERE N.NOT_DATA BETWEEN (SYSDATE-30) AND SYSDATE; 
 
 Chave do índice: NOT_DATA 
 
 SELECT * 
 FROM CLIENTE C 
 WHERE CL.CLI_NOME LIKE ‘MARIA%’; 
 
 Chave do índice: CLI_NOME 
 
 Enfim, é preciso um aprofundamento maior no assunto para que questões 
fundamentais sejam assimiladas e tenha-se a compreensão exata da necessidade dos 
índices. 
 
Sintaxe: 
 
CREATEINDEX NOME_INDICE 
ON TABELA (COLUNA_1,COLUNA_2,...,COLUNA_N) TABLESPACE X; 
 
Cria o índice da tabela nas colunas, sendo que a ordem é a que foi digitada. 
 
Guia para criar índices: 
• se a coluna é usada freqüentemente em clausulas WHERE; 
• se a coluna contém uma grande faixa de valores; 
• se a coluna contém uma grande quantidade de valores nulos; 
• se duas ou mais colunas são usadas freqüentemente juntas em clausulas 
WHERE; 
Chave do índice 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
19 
• se a tabela for grande e a maioria das consultas recuperar de 2 a 4% das linhas. 
 
Guia para não criar um índice: 
• se a tabela for pequena; 
• se a coluna não for freqüentemente usada como condição em consultas; 
• se a maioria das consultas recuperar mais de 4% das linhas; 
• se a tabela for atualizada constantemente ( o banco vai sofrer para fazer a 
manutenção). 
 
Removendo índices: 
 
DROP INDEX índice; 
 
11. Procedures, Functions e Triggers 
 
Procedures e functions são coleções de comandos SQL e PL/SQL. 
São objetos do banco de dados que nos permitem armazenar blocos de instruções 
para executar determinadas tarefas. 
 
Atenção: não confundir objeto de banco de dados (procedure, 
tables,indexes,sequences, etc...) com objeto de Orientação a Objetos. O Oracle também 
suporta a criação de classes e objetos e todos os recursos da Orientação a Objetos; mas 
para isto são necessários comandos e instruções específicos. 
 
Características 
 
1. Armazenados de forma compilada no banco de dados (todo o texto ou fonte das 
procedures e functions) 
 
2. Podem chamar outras procedures e functions ou serem chamadas 
 
3. Podem ser chamadas por usuários em ambiente Cliente/Servidor (Delphi, VB) ou 
Web (asp, php) 
 
 Procedures e functions são semelhantes, a única diferença é que as functions podem 
retornar valores por elas próprias. Já nas procedures a única forma de termos retorno de 
valor é definindo uma variável de saída, o que pode inviabilizar sua utilização em alguns 
casos. 
 
Utilização 
 
 1. Definir uma central de funções de negócios 
 exemplo: criar pedidos / eliminar cliente 
 
 2. Armazenar atividades em lotes (Job Batch) no banco de dados 
 exemplo: fechamento mensal 
 
 3. Encapsular uma transação 
 exemplo: reprocessar custo médio ou estoque de produtos 
 
 4. Canalizar as alterações de uma tabela em um único local. 
exemplo: todas as alterações de salário e departamento do 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
20 
empregado é feita por uma única transação. 
 
 5. Criar códigos genéricos (comuns ou compartilhados) 
 exemplo: manter as aplicações em um único banco de dados 
 
6. Implementar restrições de segurança para dados protegidos diretamente pelo 
próprio gerenciador. 
exemplo: somente determinados usuários terão direito de executar um 
determinado procedimento/função. 
 
Comandos válidos 
 
 1. SQL DML ou PL/SQL 
 
2. Chamada de outros procedimentos e funções armazenados no banco (remotos ou 
não) 
 
Comandos inválidos 
 
1. DDL (exceto em SQL dinânico) 
 
2. SQL Dinâmico (em versões anteriores à 8 e sem a utilização de execute 
immediate) 
 
3. COMMIT, ROLLBACK e SAVEPOINT para procedimentos e funções que serão 
chamados por uma Database Trigger e por procedures remotas 
 
11.1. Erros de Compilação 
 
 A compilação de PL/SQL é realizada pelo mecanismo Oracle PL/SQL. Erros de 
sintaxe ocorridos durante a compilação são armazenados no banco de dados. 
 
 Para ver os erros: 
 
 1. Use no SQL * Plus, o comando SHOW ERRORS; 
 
 2. Selecione os erros através das visões (views): 
 . USER_ERRORS 
 . ALL_ERRORS 
 . DBA_ERRORS 
 
 Para ter acesso às visões ALL_ERRORS e DBA_ERRORS é necessário que os 
usuários tenham permissão para tanto. Já a visão USER_ERRORS é acessível aos 
usuários que tem permissão de acesso de visão ao catálogo (dicionário de dados). 
 
 O SHOW ERRORS exibirá: 
 . NAME nome do objeto 
 . TYPE tipo do objeto (procedure,function,package,etc) 
 . LINE número da linha em que ocorreu o erro 
 . POSITION coluna da linha em que ocorreu o erro 
 . TEXT descrição do erro 
 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
21 
11.2. Armazenamento no banco de dados 
 
 O Oracle armazena em seu dicionário de dados o código fonte e o compilado de 
cada procedure, function, trigger ou package: 
 
 1. Compila os comandos PL/SQL do código fonte 
 
 2. Armazena os dados do procedimento: 
a) Nome do objeto 
b) Código fonte 
c) Caminho de acesso (parse tree) 
d) Código compilado 
e) Informações sobre dependência (referência cruzada) 
 
Nota: comandos SQL em procedimentos não são armazenados de forma compilada 
(parsed). 
 
 Visões do dicionário de dados sobre procedimentos, funções, etc: 
 . USER_SOURCE 
 . ALL_SOURCE 
 . DBA_SOURCE 
 
 Colunas relevantes: 
 . OWNER (não tem em USER_SOURCE) 
 . NAME 
 . TYPE 
 . LINE 
 . TEXT 
 
 Exemplo: 
 
SELECT TEXT 
FROM USER_SOURCE 
WHERE NAME = 'NOME_DO_OBJETO'; 
 
11.3. Descrição (describe) 
 
 Podemos visualizar as informações de estrutura de procedures, functions e packages 
através do comando DESCRIBE. 
 Sintaxe: 
 
DESCRIBE NOME_DO_OBJETO; 
ou 
DESC NOME_DO_OBJETO; 
 
11.4. Dependências 
 
Quando criamos procedures, functions ou triggers que em seu bloco de instruções é 
feito uso ou chamada de outras procedures ou functions, estes objetos que chamaram estes 
outros ficam dependentes deles. Ou seja, se numa procedure A chamo uma function B, 
temos que a procedure A é dependente a function B, de tal forma que se forem feitas 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
22 
modificações na function B e estas modificações resultarem em erro que a invalidem, então 
a procedure A também é invalidada. Para que a procedure A seja revalidada, tem-se que 
revalidar primeiro a function B e depois a procedure A. Isto é possível através da 
recompilação destes objetos. 
 Um procedimento é dependente de: 
 
1. Objetos de banco de dados que tem referência (dependência direta), como 
procedures, functions, tables, views, synonyms e sequences 
 
2. Objetos que outros objetos dependem dele (dependência indireta). Exemplo: uma 
procedure utiliza uma view de uma table, assim esta procedure tem dependência 
indireta desta table. 
 
O Oracle verifica as dependências automaticamente. Quando um objeto do 
banco de dados é modificado e o mesmo possui objetos dependentes, estes são marcados 
para serem recompilados na coluna STATUS da tabela USER_OBJECTS. 
Objeto dependente deve ser recompilado se o objeto por ele referenciado 
for alterado. A recompilação dos dependentes é feita automaticamente em rempo de 
execução. 
 Podemos obter informações das dependências através das views: 
 . USER_DEPENDENCIES 
 . ALL_DEPENDENCIES 
 . DBA_DEPENDENCIES 
 
11.5. Recompilação 
 
 Procedures e functions podem ser recompilados manualmente pelo desenvolvedor 
ou automaticamente pelo RDBMS. 
 
 Recompilação manual, sintaxe: 
 
ALTER PROCEDURE [FUNCTION] 
[SCHEMA] NOME_DO_OBJETO COMPILE; 
 
11.6. Procedures 
 
Sintaxe de criação 
 
CREATE [OR REPLACE] PROCEDURE [SCHEMA.] NOME_DA_PROCEDURE 
 ( ARGUMENTO_1 [IN/OUT/IN OUT] TIPO_DO_DADO, 
 ARQUMENTO_2 [IN/OUT/IN OUT] TIPO_DO_DADO, 
 ... ) 
IS [AS] 
 ...DECLARAÇÃO DE VARIÁVEIS... 
 VARIAVEL_1 TIPO_DO_DADO; 
BEGIN 
 INSTRUÇÕES PL/SQL... 
 ... 
END; 
/ 
SHOW ERRORS; 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
23 
 
Opção Descrição 
OR REPLACE Depois de criada uma procedure, se esta opção não for especificada 
numa nova compilação, dará uma mensagem de erro mostrando que a 
esta procedure já existe. O comando REPLACE troca a procedure 
especificada e suas instruções internas pela que está sendo 
compilada. 
SCHEMA Ou usuário dono do objeto procedure, se nada for epecificado será 
criado com ousuário corrente como dono. 
IN Identifica se o parâmetro é de entrada – é a especificação default se 
nada for informado. Os parâmetros IN não podem ser seu conteúdo 
alterado dentro da procedure. 
OUT Identifica se o parâmetro é de saída. Os parâmetros de saída podem 
ser alterados dentro da procedure, não sendo possível receber 
passagem de valores externos. 
IN OUT Identifica que o parâmetro é de entrada e de saída. Isto significa que 
além de uma variável com esta especificação poder receber valores 
externos por parâmetro, esta também pode ser modificada dentro da 
procedure e ter seu valor recuperado no meio externo 
(aplicação/programa). 
SHOW ERRORS Exibe os erros da procedure, se houver. 
 
Exemplo 1: 
 
 Criar uma procedure que receba como parâmetro de entrada o código de um 
funcionário e retorne em uma parâmetro/variável de saída o valor total dos vales retirados 
por este funcionário. 
 
CREATE OR REPLACE PROCEDURE CALCULA_VALES 
 (P_FUN_COD IN FUNCIONARIO.FUN_COD%TYPE, 
 P_TOTAL OUT NUMBER) 
IS 
BEGIN 
 SELECT SUM(VALOR) INTO P_TOTAL 
 FROM VALES_FUNC 
 WHERE FUN_COD = P_FUN_COD; 
END; 
/ 
SHOW ERRORS; 
Testando a procedure no SQL*PLUS: 
 
-- declarando uma variável para receber o parâmetro de saída 
SQL> VARIABLE V_TOTAL NUMBER; 
 
-- executando a procedure 
SQL> EXECUTE CALCULA_VALES(387,:V_TOTAL); 
 
-- exibindo o conteúdo da variável que armazenou o retorno da ---- 
-- procedure 
SQL> PRINT V_TOTAL; 
 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
24 
Sintaxe para apagar uma procedure: 
 
 SQL> DROP PROCEDURE NOME_DA_PROCEDURE; 
 
11.7. Functions 
 
Sintaxe de criação: 
 
CREATE [OR REPLACE] FUNCTION [SCHEMA.] NOME_DA_FUNCTION 
 ( ARGUMENTO_1 [IN/OUT/IN OUT] TIPO_DO_DADO, 
 ARQUMENTO_2 [IN/OUT/IN OUT] TIPO_DO_DADO, 
 ... ) RETURN TIPO_DE_DADO 
IS [AS] 
 ...DECLARAÇÃO DE VARIÁVEIS... 
 VARIAVEL_1 TIPO_DO_DADO; 
BEGIN 
 INSTRUÇÕES PL/SQL... 
 ... 
 RETURN(...); 
END; 
/ 
SHOW ERRORS; 
Opção Descrição 
OR REPLACE Depois de criada uma function, se esta opção não for especificada 
numa nova compilação, dará uma mensagem de erro mostrando 
que a esta function já existe. O comando REPLACE troca a function 
especificada e suas instruções internas pela que está sendo 
compilada. 
SCHEMA Ou usuário dono do objeto function, se nada for epecificado será 
criado com o usuário corrente como dono. 
IN Identifica se o parâmetro é de entrada – é a especificação default se 
nada for informado. Os parâmetros IN não podem ser seu conteúdo 
alterado dentro da function. 
OUT Identifica se o parâmetro é de saída. Os parâmetros de saída 
podem ser alterados dentro da function, não sendo possível receber 
passagem de valores externos. 
IN OUT Identifica que o parâmetro é de entrada e de saída. Isto significa 
que além de uma variável com esta especificação poder receber 
valores externos por parâmetro, esta também pode ser modificada 
dentro da function e ter seu valor recuperado no meio externo 
(aplicação/programa). 
SHOW 
ERRORS 
Exibe os erros da procedure, se houver. 
 
 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
25 
Exemplo 1: 
 
 Criar uma function que receba como parâmetro de entrada o número de uma nota 
fiscal e retorne o valor total dos produtos desta nota. 
 
CREATE OR REPLACE FUNCTION RET_TOTAL_PROD 
 (P_NF_NUM IN NOTA.NF_NUM%TYPE) RETURN NUMBER 
IS 
 V_TOTAL NUMBER; 
BEGIN 
 SELECT SUM(VALOR_UNIT*QUANT) INTO V_TOTAL 
 FROM ITENS_NOTA 
 WHERE NF_NUM = P_NF_NUM; 
 
 RETURN(V_TOTAL); 
END; 
/ 
SHOW ERRORS; 
Testando a function no SQL*PLUS: 
 
SQL> SELECT RET_TOTAL_PROD(5421) FROM DUAL; 
 
 
Sintaxe para apagar uma function: 
 
SQL> DROP FUNCTION NOME_DA_FUNCTION; 
 
 
 
11.8. Triggers 
 
 Um Database Trigger é um bloco PS/SQL associado a uma tabela específica. Ele é 
executado implicitamente quando é disparado um comando que altera o conteúdo de uma 
tabela. 
 Um Trigger é composto por quatro partes: 
 
Trigger type BEFORE, AFTER – statment (comando) ou row (linha) 
Triggering event INSERT, UPDATE ou DELETE 
Trigger restriction WHEN cláusula (opcional) 
Trigger action Bloco PL/SQL 
 
 Cada tabela (table) pode ter um Trigger de cada tipo, totalizando então 12 Triggers 
por tabela: 
 . INSERT – UPDATE - DELETE 
 . BEFORE – AFTER 
 . FOR STATMENT – FOR EACH ROW (mais utilizado - recomendado) 
 
 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
26 
Sintaxe: 
 
CREATE [OR REPLACE] TRIGGER [SCHEMA.] NOME_DO_TRIGGER 
[BEFORE/AFTER][INSERT <OR> UPDATE <OF COLUMNS> <OR> DELETE] 
ON NOME_DA_TABELA 
REFERENCING [OLD AS NOME_OLD][NEW AS NOME_NEW] 
FOR [EACH ROW / STATEMENT] 
[WHEN CONDIÇÃO] 
DECLARE 
 VARIAVEL_1 TIPO_DO_DADOS; 
 ...DECLARAÇÃO DE VARIÁVEIS... 
BEGIN 
 ... 
 INSTRUÇÕES PL/SQL 
 ... 
END; 
/ 
SHOW ERRORS; 
 
Opção Descrição 
OR REPLACE Depois de criada uma trigger, se esta opção não for especificada 
numa nova compilação, dará uma mensagem de erro mostrando 
que a esta trigger já existe. O comando REPLACE troca a trigger 
especificada e suas instruções internas pela que está sendo 
compilada. 
SCHEMA Ou usuário dono do objeto trigger, se nada for epecificado será 
criado com o usuário corrente como dono. 
BEFORE/AFTER Especifica se o trigger vai disparado antes ou depois do evento 
INSERT/UPDATE/D
ELETE 
Indica em quais eventos o trigger será disparado. No caso de 
update ainda há a opção de especificar qual a coluna que deverá 
haver mudança para disparar o trigger. 
ON NOME_TABELA Indica sobre qual tabela o trigger estará vinculado 
REFERENCING Geralmente é omitido, utilizado para nomear as referências OLD e 
NEW disponíveis no trigger 
FOR EACH ROW Indica se o trigger será disparado após a alteração de cada linha 
da tabela 
FOR EACH 
STATEMENT 
Indica se o trigger será disparado após o término do comando de 
alteração da tabela (pouco utilizado) 
WHEN CONDIÇÃO Pode-se nesta opção especificar uma condição para o disparo do 
trigger 
SHOW ERRORS Exibe os erros da procedure, se houver. 
 
 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
27 
Exemplo 1: 
 
CREATE OR REPLACE TRIGGER TG_FUNC_SAL 
BEFORE INSERT OR UPDATE OF FUN_SAL 
ON FUNCIONARIOS 
FOR EACH ROW 
DECLARE 
 V_MINSAL NUMBER; 
 V_MAXSAL NUMBER; 
BEGIN 
 SELECT MINSAL, MAXSAL INTO V_MINSAL, V_MAXSAL 
 FROM FUNC_SALARIOS 
 WHERE DEPTO = :NEW.DEPTO; 
 
 IF :NEW.FUN_SAL < V_MINSAL OR :NEW.FUN_SAL > V_MAXSAL THEN 
 RAISE_APPLICATION_ERROR(-20500,’Salário fora da 
faixa’); 
 END IF; 
END; 
 
Um Database Trigger e uma Procedure têm muitas coisas em comum. 
 
Similaridades: 
1. Feitos através de comandos SQL e PL/SQL 
2. Usam área SQL compartilhadas 
3. O SGBD verifica automaticamente as dependências 
 
Diferenças: 
1. Um trigger está associado a uma tabela 
2. Um trigger é chamado implicitamente, a procedure não 
3. COMMIT, ROOLBACK e SAVEPOINT não são permitidos em triggers e em 
procedures chamadas por eles. 
4. Não há GRANT (privilégio) para executar um trigger 
 
A execução de um trigger segue a seguinte sequência: 
 
1. INSERT, UPDATE, DELETE são passados para o SGBD 
2. Executa o Trigger Before em nível de comando (statement) 
3. Para cada linha afetada com comando: 
3.1. Executa o trigger Before em nível de linha (row) 
3.2. Altera a linha, verifica a integridade referencial 
3.3. Executa o trigger After em nível de linha (row) 
4. Completa a verificação da integridade referencial 
5. Executa o trigger After em nível de comando (statement) 
6. Retorna para a aplicação 
 
 
 
Expressões 
 
Para referenciar os valores novos e velhos das colunas no trigger, usa-se os prefixos 
OLD e NEW. 
 
Exemplo: IF :NEW.FUN_SAL < :OLD.FUN_SAL THEN ... 
 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
28 
Nota: 
 
1. NEW e OLD são variáveis válidas somente para triggers 
2. NEW e OLD - ambas disponíveisno comando UPDATE 
3. OLD vale NULL no comando INSERT 
4. NEW vale NULL no comando DELETE 
5. Pode-se mudar NEW para NOVO (ou qualquer outro nome) e OLD para VELHO 
(ou qualquer outro nome) utilizando a opção REFERENCING 
 
Predicados Condicionais 
 
 Para identificar qual o tipo de operação (insert,update,delete) que disparou a trigger, 
utilizamos: 
 
1. IF INSERTING... 
2. IF UPDATING... 
3. IF DELETING… 
 
 
11.9. Atenção 
 
 Um erro muito comum em stored procedures e triggers é a ocorrência, no bloco 
executável, de instruções “select” sem a cláusula “into”. Todo “select” nestes casos tem que 
possuir a cláusula “into”, atribuindo os valores das colunas de uma tabela para variáveis; e 
este “select...into” pode retornar somente 1 linha. Se retornar 0 linha ou mais de 1 linha, 
ocorre um erro. 
 
Exemplo: 
 
CREATE OR REPLACE FUNCTION RET_CIDADE 
 (P_CID_COD CIDADE.CID_COD%TYPE) RETURN VARCHAR2 
IS 
 V_CID_NOME CIDADE.CID_NOME%TYPE; 
BEGIN 
 SELECT CID_NOME INTO V_CID_NOME 
 FROM CIDADE 
 WHERE CID_COD = P_CID_COD; 
 RETURN(V_CID_NOME); 
END; 
 
 No exemplo exposto, a restrição na chave primária não permite o erro de múltiplas 
linhas retornadas para dentro de uma variável, fica somente sujeito ao erro de nenhum dado 
encontrado se o código passado como parâmetro não existir. 
 É apresentado a seguir recursos para o tratamento destes erros. 
 
 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
29 
 
12. Tratamento de Erros (Exceções) 
 
 O tratamento de erros em PL/SQL ocorre em tempo de execução. Os erros em 
tempo de compilação são detectados pelo mecanismo da PL/SQL e informados ao usuário. 
Erros de sintaxes ou referências a objetos inexistentes são exemplos de exceções de 
compilação. 
 
DECLARE 
 A NUMBER:=1; 
 B NUMBER:=0; 
 X NUMBER; 
BEGIN 
 X := A/B; 
 
EXCEPTION 
 WHEN OTHERS THEN -- qualquer erro 
 ... tratamento/instruções 
 
END; 
 
Neste exemplo o erro será: ORA-01476: o divisor é igual a zero 
 
 
12.1 Exceções definidas pelo usuário 
 
 Os desenvolvedores de rotinas PL/SQL têm a possibilidade de criar erros 
personalizados que não se referenciam aos erros próprios do Oracle. 
 Exemplo: 
 
CREATE OR REPLACE PROCEDURE ALTERA_CIDADE 
 (P_CID_COD CIDADE.CID_COD%TYPE, 
 P_CID_NOME CIDADE.CID_NOME%TYPE, 
 P_CID_UF CIDADE.CID_UF%TYPE) 
IS 
 V_CONT NUMBER; 
 V_MEU_ERRO EXCEPTION; 
BEGIN 
 SELECT COUNT(*) INTO V_CONT 
 FROM CIDADE 
 WHERE CID_COD = P_CID_COD; 
 IF VCONT=0 THEN 
 RAISE V_MEU_ERRO; 
 ELSE 
 UPDATE CIDADE 
 SET CID_NOME = P_CID_NOME, 
 CID_UF = P_CID_UF 
 WHERE CID_COD = P_CID_COD; 
 END IF; 
EXCEPTION 
 WHEN V_MEU_ERRO THEN 
 RAISE_APPLICATION_ERROR(-20001,'CIDADE NÃO ENCONTRADA...'); 
END; 
 
Bloco de 
tratamento de 
erros 
Declara uma variável do tipo exception 
RAISE – desvia a execução para o 
bloco de tratamento de erros, para a 
variável correspondente. 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
30 
 
 
 
 
12.2 Exceções predefinidas 
 
 O Oracle possui várias exceções predefinidas que correspondem aos erros mais 
comuns. Na tabela abaixo são apresentados alguns deles. 
 
Erro Oracle Exceções Descrição 
ORA-0001 DUP_VAL_ON_INDEX Violação de restrição exclusiva 
ORA-0051 TIMEOUT_ON_RESOURCE Tempo de espera esgotado 
ORA-1403 NO_DATE_FOUND Não foram encontrados dados 
ORA-1001 INVALID_CURSOR Operação de cursor ilegal 
ORA-1722 INVALID_NUMBER Número inválido 
ORA-1017 LOGIN_DENIED Nome do usuário/senha inválido 
ORA-6501 PROGRAM_ERROR Erro interno do PL/SQL 
ORA-1476 ZERO_DIVIDE Divisão por zero 
ORA-6511 CURSOR_ALREADY_OPEN Tentativa de abertura de um cursor que já está aberto 
ORA-1422 TOO_MANY_ROWS Uma instrução SELECT..INTO 
corresponde mais que uma linha 
 
RAISE_APPLICATION_ERROR (número_erro,mensagem) 
 
 Função pré-definida para o programador criar suas próprias mensagens de 
erros. Esta função aborta a execução do bloco/rotina correspondente. 
 
Número_erro: valor entre –20000 e –20999 
Mensagem: texto de até 512 caracteres. 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
31 
 
Exemplo: 
 
CREATE OR REPLACE FUNCTION RET_CIDADE 
 (P_CID_COD CIDADE.CID_COD%TYPE) RETURN VARCHAR2 
IS 
 V_CID_NOME CIDADE.CID_NOME%TYPE; 
BEGIN 
 BEGIN 
 SELECT CID_NOME INTO V_CID_NOME 
 FROM CIDADE 
 WHERE CID_COD = P_CID_COD; 
 EXCEPTION 
 WHEN NO_DATA_FOUND THEN 
 V_NOME:= '**NÃO ENCONTRADO**'; 
 WHEN TOO_MANY_ROWS THEN 
 V_NOME:= '**MUITAS LINHAS ENCONTRADAS**'; 
 WHEN OTHERS THEN 
 V_NOME:= '**ALGUM ERRO OCORREU**'; 
 END; 
 RETURN(V_CID_NOME); 
END; 
 
 
 
12.3 When Others 
 
 Esta cláusula é executada em todas as exceções levantadas nas rotinas PL/SQL e 
deve ser sempre a última cláusula (handler) do bloco. 
 Exemplo: 
 
CREATE OR REPLACE FUNCTION RET_SALARIO 
 (P_FUN_CODIGO FUNCIONARIO.FUN_CODIGO%TYPE) RETURN NUMBER 
IS 
 V_FUN_SAL FUNCIONARIO.FUN_SAL%TYPE; 
BEGIN 
 
 SELECT FUN_SAL INTO V_FUN_SAL 
 FROM FUNCIONARIO 
 WHERE FUN_CODIGO = P_FUN_CODIGO; 
 
 RETURN(V_FUN_SAL); 
 
EXCEPTION 
 WHEN NO_DATA_FOUND THEN 
 RAISE_APPLICATION_ERROR(-20001,’CODIGO DE FUNCIONARIO NÃO 
 ENCONTRADO’); 
 WHEN OTHERS THEN 
 RAISE_APPLICATION_ERROR(-20002,’ALGUM OUTRO ERRO OCORREU...’); 
END; 
 
 Pode-se construir blocos dentro de outros blocos e assim por diante, para que se 
tenha o funcionamento esperado. 
 
 
 
Se neste “select” não encontrar 
nenhuma linha, então dá um erro 
de NO_DATA_FOUND, se 
houver qualquer outro erro, é 
capturado pelo WHEN OTHERS. 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
32 
Exemplo: 
 
 BEGIN 
 BEGIN 
 EXCEPTION 
 WHEN . . . THEN 
 INSERT...; 
 IF . . . THEN. . . END IF; 
 WHEN . . . THEN 
 BEGIN 
 EXCEPTION 
 END; 
 END; 
 EXCEPTION 
 END; 
 
 
12.4 SqlCode e SqlErrm 
 
 São funções predifinidas que retornam o código do erro atual e o texto da mensagem 
do erro atual, consecutivamente. 
 São muito utilizados no tratamento de exceções “WHEN OTHERS” para informar o 
erro ocorrido. 
 Exemplo: 
 
CREATE OR REPLACE PROCEDURE INCLUI_CLIENTE 
(P_CLI_COD CLIENTE.CLI_COD%TYPE, 
 P_CLI_NOME CLIENTE.CLI_NOME%TYPE, 
 P_MSG OUT VARCHAR2) 
IS 
BEGIN 
 BEGIN 
 P_MSG := ‘OK’; 
 INSERT INTO CLIENTE (CLI_COD, CLI_NOME) 
 VALUES(P_CLI_COD, P_CLI_NOME); 
 EXCEPTION 
 WHEN OTHERS THEN 
 P_MSG := ‘ERRO..CODIGO: ’||TO_CHAR(SQLCODE)||’ MENSAGEM:’ 
 ||SQLERRM; 
 END; 
END; 
 
 
12.5 Exception_Init 
 
 Existe a possibilidade de associar um erro do Oracle a uma exceção nomeada 
(nome), ou seja, podemos associar um código de erro do Oracle a um nome. 
 
Sintaxe: 
 
 PRAGMA_EXCEPTION_INIT(nome_do_erro,número_do_erro_oracle) 
 
 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
33 
Exemplo: 
 
CREATE OR REPLACE PROCEDURE EXCLUI_CIDADE 
 (P_CID_COD CIDADE.CID_COD%TYPE, 
 P_ERRO OUT VARCHAR2, 
 P_MSG OUT VARCHAR2) 
IS 
 
 V_CONT NUMBER; 
 V_ERRO1 EXCEPTION; 
 V_ERRO2 EXCEPTION; 
 
 -- EXCEPTION_INIT pragma 
 
 PRAGMA EXCEPTION_INIT(V_ERRO2,-2292); 
-- integrity constraint violated - child record found 
 
BEGIN 
 
 BEGIN 
 
 P_ERRO := 'N'; 
 P_MSG := 'OK'; 
 
 SELECT COUNT(*) INTO V_CONT 
 FROM CIDADE 
 WHERE CID_COD = P_CID_COD; 
 
 IF V_CONT = 0 THEN 
 RAISE V_ERRO1; 
 END IF; 
 
 DELETE 
 FROM CIDADE 
 WHERE CID_COD = P_CID_COD; 
 
 COMMIT; 
 
 EXCEPTION 
 WHEN V_ERRO1 THEN 
 P_ERRO := 'S'; 
 P_MSG := 'CÓDIGO NÃO ENCONTRADO....'; 
 WHEN V_ERRO2THEN 
 P_ERRO := 'S'; 
 P_MSG := 'NÃO FOI POSSÍVEL APAGAR. HÁ REGISTRO 
RELACIONADOS COM ESTE CODIGO...'; 
 END; 
 
END; 
 
 
 
Se durante o delete ocorrer o erro 
-2292, a exceção é capturada em 
V_ERRO2 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
34 
13. Cursor 
 
Cursor é um artifício utilizado em PL/SQL para ter acesso a um conjunto de linhas 
resultantes de uma operação de banco de dados. 
O Oracle sempre executa uma declaração SQL associando um cursor individual, ou 
nome, para ele; o cursor controla todas as fases do processo. 
 Realiza intimamente todas as questões do banco de dados sem considerar o 
processamento da declaração SQL, o Oracle adquire antes a necessidade do cursor 
implícito e manuseia-os automaticamente. 
 No entanto, para processar consultas explicitamente em ordem, declara cursores 
explicitamente e controla-os manualmente no bloco PL/SQL. 
 A seleção de linhas que satisfaz o critério de procura de uma consulta consiste de 
zero, uma ou mais linhas. 
 Quando uma consulta retornar mais de uma linha, declare e utilize um cursor 
explícito. 
 
13.1 Cursor Explícito 
 
 Cursores explícitos podem processar mais de uma linha retornada pela consulta, 
linha a linha. São criados e utilizados pelos programadores, desenvolvedores e DBA’s, 
geralmente em stored procedures e triggers, para realizar operações que necessitem de 
uma estrutura que assuma o resultado de uma instrução “select”. 
 
 Para utilizar um cursor explícito deve-se: 
 
a. declarar o cursor (declare) 
 
DECLARE 
 CURSOR NOME_DO_CURSOR IS 
 DECLARAÇÃO_SELECT; 
 
Onde: NOME_DO_CURSOR é uma declaração PS/SQL 
DECLARAÇÃO_SELECT é uma declaração “SELECT” sem a cláusula 
“INTO” 
 
Nota: Não inclua a cláusula “INTO” dentro da declaração do cursor, pois ele 
aparece depois dentro da declaração “FETCH”, implicitamente. 
Se a declaração “SELECT” utiliza qualquer variável, é correto declará-
la(s) antes da declaração do cursor. 
 
b. abrir o cursor (open) 
 
OPEN NOME_DO_CURSOR; 
 
Onde: NOME_DO_CURSOR é o nome de um cursor declarado previamente. 
 
c. buscar dados do cursor (fetch) 
 
FETCH NOME_DO_CURSOR INTO VARIAVEL1, VARIAVEL2,... 
 
Onde: NOME_DO_CURSOR é o nome do cursor declarado previamente. 
 VARIAVEL é uma variável de saída para armazenar resultados. 
 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
35 
Nota: Inclua o mesmo número de variáveis dentro da cláusula “INTO” da 
declaração “FETCH” como colunas de saída na declaração “SELECT”, 
assim como a compatibilidade dos seus tipos. 
 As variáveis correspondem ao posicionamento das colunas. 
 
d. fechar o cursor (close) 
 
CLOSE NOME_DO_CURSOR; 
 
 Onde: NOME_DO_CURSOR é o cursor previamente declarado. 
 
Nota: Não tente buscar dados de um cursor uma vez que ele esteja fechado. 
 
 Para buscar linha a linha de um cursor, é necessário determinar quando entrar e sair 
de um “LOOP” pela inspeção de um atributo do cursor. 
 
 
Atributos de Cursor Descrição 
%ISOPEN atributo booleano que avalia se o cursor está aberto 
%NOTFOUND Atributo booleano que avalia se o mais recente “fetch” não 
retornou nenhuma linha 
%FOUND Atributo booleano que avalia se o mais recente “fetch” retornou 
alguma linha 
%ROWCOUNT Atributo numérico que retorna o número total de linhas que foram 
processadas pelo “fetch” e não o total que será retornado pelo 
cursor explícito. 
Nota: 
• não use atributos de cursor diretamente dentro de uma declaração SQL 
• busque linhas somente quando o cursor estiver aberto. 
 
Exemplo 1: 
 
DECLARE 
 CURSOR C_ALUNOS IS 
 SELECT ALU_COD, DT_TRANCOU 
 FROM ALUNOS 
 WHERE DT_TRANCOU < TO_DATE('01/01/2000', 'DD/MM/YYYY'); 
 
V_ALU_COD ALUNOS.ALU_COD%TYPE; 
V_DT_TRANCOU ALUNOS.DT_TRANCOU%TYPE; 
BEGIN 
OPEN C_ALUNOS; 
 
LOOP 
 FETCH C_ALUNOS INTO V_ALU_COD, V_DT_TRANCOU; 
 
 EXIT WHEN C_ALUNOS%NOTFOUND OR C_ALUNOS%ROWCOUNT=5; 
 
 INSERT INTO TRANCADOS (ALU_COD, DT_TRANCOU) 
 VALUES (V_ALU_COD, V_DT_TRANCOU); 
END LOOP; 
 
CLOSE C_ALUNOS; 
COMMIT; 
END; 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
36 
 
 
Existe um caminho mais curto para buscar linhas de um cursor utilizando a estrutura “FOR 
LOOP”: 
 
FOR NOME_DO_REGISTRO IN NOME_DO_CURSOR LOOP 
 DECLARAÇÃO 1; 
DECLARAÇÃO 2; 
... 
END LOOP; 
 
Onde: NOME_DO_REGISTRO é o nome de um registro declarado implicitamente. 
 NOME_CO_CURSOR é o nome do cursor previamente declarado. 
 
Exemplo 2: 
 
DECLARE 
 V_NUM_PEDIDO PEDIDO_ITEM.NUM_PEDIDO%TYPE; 
 
 CURSOR C_ITEM IS 
 SELECT PROD_COD, SUM(QUANT*VALOR) AS TOTAL 
 FROM PEDIDO_ITEM 
 WHERE NUM_PEDIDO = V_NUM_PEDIDO 
 GROUP BY PROD_COD; 
BEGIN 
 V_NUM_PEDIDO := 10; 
 FOR VREG IN C_ITEM LOOP -- open, fetch e declaração de VREG 
 -- implícito 
 
 INSERT INTO ACUMULADO (PROD_COD, TOTAL) 
 VALUES (VREG.PROD_COD, VREG.TOTAL); 
 
 END LOOP; /*close implícito*/ 
 
 COMMIT; 
END; 
 
 
Neste exemplo poderia ter sido declarada a variável VREG como 
VREG.C_ITEM%ROWTYPE, passando assim a assumir a estrutura de registro (linha) do 
cursor. 
 
Outro recurso interessante para ser usado em um cursores é a cláusula 
“FOR UPDATE” e “CURRENT OF”. 
 
Exemplo 3: 
 
CREATE OR REPLACE PROCEDURE ATRIBUI_DESCONTOS 
(P_CUR_COD CURSOS.CUR_COD%TYPE) 
IS 
 CURSOR C_ALUNOS(P_CUR_COD) IS 
 SELECT ALU_CPF, ALU_DESCTO 
 FROM ALUNOS WHERE CUR_COD = P_CUR_COD 
FOR UPDATE OF ALU_DESCTO; 
 V_CONT NUMBER; 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
37 
BEGIN 
 FOR VREG IN C_ALUNOS LOOP 
 IF V_REG.ALU_DESCTO = 0 THEN 
 SELECT COUNT(*) INTO V_CONT 
 FROM FUNCIONARIOS 
 WHERE FUN_CPF = V_REG.ALU_CPF; 
 IF V_CONT <> 0 THEN 
 UPDATE ALUNOS 
 SET ALU_DESCTO = 50 
 WHERE CURRENT OF C_ALUNOS; 
 END IF; 
 END IF; 
 END LOOP; 
 COMMIT; 
END; 
Nota: é importante destacar que a cláusula “FOR UPDATE” faz com que os registros 
(linhas) da tabela que o cursor envolve sejam “locados/bloqueados” quando o cursor é 
aberto; e permanecem assim até que o mesmo seja fechado e após um “commit” ou 
“rollback” se foram feitas modificações nestas linhas da tabela. 
 
Exemplo 4: 
 
No SQL/PLUS: 
 
SET SERVEROUTPUT ON; 
 
DECLARE 
 CURSOR C_CLIENTE IS 
 SELECT C.CLI_NOME, D.CID_NOME 
 FROM CLIENTE C, CIDADE D 
 WHERE C.CID_COD = D.CID_COD; 
 
 VNOME CLIENTE.CLI_NOME%TYPE; 
 VCIDADE CIDADE.CID_NOME%TYPE; 
 
BEGIN 
 OPEN C_CLIENTE; 
 LOOP 
 FETCH C_CLIENTE INTO VNOME, VCIDADE; 
 EXIT WHEN C_CLIENTE%NOTFOUND; 
 DBMS_OUTPUT.PUT_LINE(VNOME||' - '||VCIDADE); 
 END LOOP; 
 CLOSE C_CLIENTE; 
END; 
 
Exemplo 5 (outra forma de loop no cursor): 
 
CREATE OR REPLACE PROCEDURE DESATIVA_CLIENTES 
IS 
BEGIN 
 FOR VCLI IN (SELECT CLI_COD 
 FROM CLIENTE WHERE CLI_ATIVO='N') LOOP 
 INSERT INTO CLIENTES_INATIVOS (CLI_COD, DATA) 
 VALUES (VCLI.CLI_COD, SYSDATE); 
 DELETE FROM CLIENTE WHERE CLI_COD = VCLI.CLI_COD; 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
38 
 END LOOP; 
 COMMIT; 
END; 
 
13.2 Cursor Implícito 
 
 O cursor implícito é chamado cursor SQL, porque ele armazena as informações 
referentes ao processamento da última declaração SQL não associada a um cursor 
explícito. Todas as instruções SQL são executadas dentro de uma área de contexto e, 
portanto, têm um cursor (implícito) que aponta para essa área. Diferentemente dos cursores 
explícitos, o cursor SQL não é aberto ou fechado pelo programa. A PL/SQL implicitamente 
abre o cursor SQL, processa a instrução SQL nele e em seguida fecha o cursor. 
 Este cursor é utilizado para processar as instruções INSERT, UPDATE, DELETE E 
SELECT...INTO. Pelo fato de o cursor SQL ser aberto e fechado pelo mecanismo PL/SQL, 
os comandos OPEN, FETCH E CLOSE não são relevantes.Entretanto, os atributos de 
cursor podem ser aplicados no cursor SQL. 
 Embora SQL%NOTFOUND possa ser utilizada com instruções SELECT...INTO, 
não é realmente útil fazer isso, pois uma instrução SELECT...INTO levantará o erro do 
Oracle (ORA-1403: no data found) quando ela não corresponder a nenhuma linha. 
Esse erro faz com que o controle passe imediatamente para a seção de tratamento de 
exceção do bloco, evitando a verificação em SQL%NOTFOUND. 
Veremos nos exemplos a seguir as situações apresentadas. 
 
Atributos de Cursor Descrição 
SQL%ISOPEN atributo booleano – sempre avalia para “FALSE” 
SQL%NOTFOUND Atributo booleano que avalia se a mais recente declaração SQL 
não afetou nenhuma linha 
SQL%FOUND Atributo booleano que avalia se o mais recente declaração SQL 
afetou uma ou mais linhas 
SQL%ROWCOUNT Atributo numérico que retorna o número total de linhas que foram 
processadas pela declaração SQL mais recente. 
 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
39 
Exemplo 1: 
 
CREATE OR REPLACE PROCEDURE ALTERA_CIDADE 
 (P_CID_COD CIDADE.CID_COD%TYPE, 
 P_CID_NOME CIDADE.CID_NOME%TYPE, 
 P_CID_UF CIDADE.CID_UF%TYPE, 
 P_ERRO OUT VARCHAR2, 
 P_MSG OUT VARCHAR2) 
 
IS 
 V_CID_COD CIDADE.CID_COD%TYPE; 
BEGIN 
 
 P_ERRO := 'N'; 
 P_MSG := 'OK'; 
 
 UPDATE CIDADE 
 SET CID_NOME = P_CID_NOME, 
 CID_UF = P_CID_UF 
 WHERE CID_COD = P_CID_COD; 
 
 IF SQL%NOTFOUND THEN -- CURSOR IMPLICITO 
 P_ERRO := 'S'; 
 P_MSG := 'CÓDIGO NÃO ENCONTRADO...'; 
 ELSE 
 P_MSG := 'CIDADE ALTERADA COM SUCESSO...'; 
 COMMIT; 
 END IF; 
 
END; 
 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
40 
 
Exemplo 2: 
 
CREATE OR REPLACE PROCEDURE CONSULTA_CIDADE 
 (P_CID_COD CIDADE.CID_COD%TYPE, 
 P_CID_NOME OUT CIDADE.CID_NOME%TYPE, 
 P_CID_UF OUT CIDADE.CID_UF%TYPE) 
IS 
BEGIN 
 
 BEGIN 
 SELECT CID_NOME, CID_UF INTO P_CID_NOME, P_CID_UF 
 FROM CIDADE 
 WHERE CID_COD = P_CID_COD; 
 
 -- se o código da cidade não existir, não chega na verificação 
 -- abaixo, dá erro no select e vai imediatamente para a seção 
 -- de tratamento de erros 
 
 IF SQL%NOTFOUND THEN 
 P_CID_NOME := 'CIDADE NÃO ENCONTRADA...'; 
 P_CID_UF := 'XX'; 
 END IF; 
 
 EXCEPTION -- bloco de tratamento de erros da PL/SQL - Oracle 
 WHEN NO_DATA_FOUND THEN 
 P_CID_NOME := 'CIDADE NÃO ENCONTRADA...'; 
 P_CID_UF := 'XX'; 
 END; 
 
END; 
 
 
13.3 Ref Cursor 
 
 Ref cursor ou cursor de referência é um tipo de variável de cursor que assume a 
estrutura de um “SELECT” como se fosse uma tabela, com múltiplas colunas e múltipas 
linhas; sua principal vantagem é poder ser um parâmetro de saída de uma procedure ou 
uma function. Este é um recurso muito interessante para ser utilizado em consultas (select). 
Complementando, uma variável de cursor é um tipo de referência. Ela pode referir-se a 
posições de memória diferentes à medida que o programa é executado. 
 Os exemplos até aqui abordaram cursores estáticos que sempre estão associados a 
somente uma instrução “select”. Variáveis de cursor (ref cursor) podem conter diferentes 
valores em tempo de execução. 
 
 TYPE nome_do_tipo IS REF CURSOR [RETURN tipo_de_retorno] 
 
Onde: 
nome_do_tipo é o nome do novo tipo de referência 
tipo_de_retorno é um tipo de registro que indica os tipos da lista “select” que 
por fim retornarão pela variável de cursor. 
 
 
 
 
 
Este bloco 
fica sem 
utilidade 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
41 
Exemplo 1 – declarando como um tipo específico (estático): 
 
DECLARE 
 -- utilizando %rowtype 
 TYPE TP_CIDADE IS REF CURSOR 
 RETURN CIDADE%ROWTYPE; 
 
 -- definindo um novo tipo de registro 
 TYPE TP_REGISTRO IS RECORD 
 (cli_nome cliente.cli_nome%type, 
 cid_nome cidade.Cid_nome%type); 
 
V_VAR1 TP_REGISTRO; 
 
-- criando uma variável de cursor que utiliza o tipo registro 
-- que foi criado 
TYPE TP_MEU_REFCURSOR IS REF CURSOR RETURN TP_REGISTRO; 
 
 V_MEU_CURSOR TP_MEU_REFCURSOR; 
 
 
Exemplo 2 – Fazendo um LOOP em um Ref Cursor: 
 
CREATE OR REPLACE PROCEDURE TESTE_CLIENTES 
IS 
 TYPE T_MEU_TIPO IS REF CURSOR; 
 C_CLIENTE T_MEU_TIPO; 
 VCLI_COD NUMBER(6); 
BEGIN 
 OPEN C_CLIENTE FOR SELECT CLI_COD FROM CLIENTE; 
 LOOP 
 FETCH C_CLIENTE INTO VCLI_COD; 
 EXIT WHEN C_CLIENTE%NOTFOUND; 
 INSERT INTO CLIENTE_TESTE (CLI_COD) VALUES (VCLI_COD); 
 END LOOP; 
 CLOSE C_CLIENTE; 
 COMMIT; 
END; 
 
 Para utilizarmos o Ref Cursor para declarar uma variável a ser utilizada como 
parâmetro de saída em uma procedure ou function, a principal funcionalidade no escopo em 
questão, tem-se que criar uma package criando e definindo um nome para um tipo “ref 
cursor”: 
 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
42 
Exemplo 3: 
 
Passo 1 – É necessária a criação do tipo “ref cursor”. Como trata-se de um cursor variável 
que pode representar diferentes estruturas e resultados de instruções “select”, basta criar 
um único tipo para ser utilizado em todo o banco de dados. Não há a necessidade de criar 
um tipo para cada variável ou parâmetro de stored procedure que tiver que ser declarada. 
 
CREATE OR REPLACE PACKAGE PK_REF_CURSOR AS 
 TYPE TP_REF_CURSOR IS REF CURSOR; 
END PK_REF_CURSOR; 
/ 
 
Passo 2 – Cria-se uma procedure ou function que tenha como parâmetro de saída uma 
variável do tipo ref cursor definido na package: 
 
CREATE OR REPLACE PROCEDURE RETORNA_PRODUTOS 
 (P_PRO_DESC IN PRODUTO.PRO_DESC%TYPE, 
 P_SAIDA OUT PK_REF_CURSOR.TP_REF_CURSOR) AS 
BEGIN 
 OPEN P_SAIDA FOR 
 SELECT PRO_COD, PRO_DESC, PRO_PRVENDA 
 FROM PRODUTO 
 WHERE PRO_DESC LIKE '%'||P_PRO_DESC||'%' 
 ORDER BY PRO_DESC; 
END; 
Para testar no Sql/Plus: 
-- cria uma variável PL/SQL dentro do SQL/PLUS para receber o -
-- resultado do parâmetro de saída 
VARIABLE RETORNO REFCURSOR; 
EXECUTE RETORNA_PRODUTOS(‘A’,:RETORNO); 
PRINT RETORNO; 
 
 
 
 
Universidade do Oeste Paulista 
Faculdade de Informática de Presidente Prudente 
 
43 
Referências Bibliográficas 
 
URMAN, Scott; tradução: Edson Furmankiewicz. Oracle 9i Programação PL/Sql. Rio 
de Janeiro: Elsevier, 2002.

Continue navegando

Outros materiais