You are on page 1of 470

Oracle Database: Fundamentos

de PL/SQL

Guia do Aluno

D64254BP10
Edição 1.0
Agosto de 2011
D73724
Autor Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos
reservados.
Brian Pottle
Isenção de Responsabilidade

Revisores e Este documento contém informações de propriedade da Oracle Corporation e está


Colaboradores Técnicos protegido pela legislação de direitos autorais e outras leis de propriedade intelectual,
podendo ser copiado e impresso somente para uso individual em um curso de
Tom Best treinamento Oracle. O documento não pode ser modificado nem alterado de forma
alguma. Exceto em situações que constituam "uso justo" de acordo com a legislação
Christoph Burandt de direitos autorais, não será permitido utilizar, compartilhar, descarregar, carregar,
Yanti Chang copiar, imprimir, executar, reproduzir, publicar, licenciar, divulgar, transmitir nem
distribuir este documento - total ou parcialmente - sem a expressa autorização da
Laszlo Czinkoczki Oracle.
Ashita Dhir
As informações contidas neste documento estão sujeitas a alterações sem aviso
Peter Driver prévio. Se você encontrar algum problema no documento, envie à Oracle Corporation
ou à Oracle do Brasil Sistemas Ltda. uma descrição de tal problema por escrito.
Gerlinde Frenzen Oracle University, 500 Oracle Parkway, Redwood Shores, California 94065 USA. A
Nancy Greenberg Oracle Corporation não garante que este documento esteja isento de erros.

Chaitanya Kortamaddi Aviso de Direitos Restritos


Tim Leblanc
Se esta documentação for entregue / distribuída ao Governo dos Estados Unidos ou
Bryan Roberts a qualquer outra parte que a licencie ou utilize em nome daquele governo, a seguinte
legenda será aplicável:
Abhishek X Singh
Puja Singh U.S. GOVERNMENT RIGHTS
The U.S. Government’s rights to use, modify, reproduce, release, perform, display, or
Lex Van Der Werff disclose these training materials are restricted by the terms of the applicable Oracle
Hilda Simon license agreement and/or the applicable U.S. Government contract.

Manish Pawar Aviso de Marca Comercial

Oracle é uma marca comercial da Oracle Corporation e/ou de suas empresas


Designer Gráfico afiliadas. Outros nomes podem ser marcas comerciais de seus respectivos
proprietários.
Satish Bettegowda

Redatores
Vijayalakshmi Narasimhan
Daniel Milne

Editor
Veena Narasimhan
Índice

I Introdução
Objetivos da Lição I-2
Objetivos do Curso I-3
Esquema Human Resources (HR) Usado Neste Curso I-4
Agenda do Curso I-5
Informações da Conta Usada em Sala de Aula I-6
Apêndices Usados Neste Curso I-7
Ambientes de Desenvolvimento PL/SQL I-8
O que É o Oracle SQL Developer? I-9
Codificando PL/SQL no SQL*Plus I-10
Codificando PL/SQL no Oracle JDeveloper I-11
Documentação de SQL e PL/SQL do Oracle 11g I-12
Sumário I-13
Visão Geral do Exercício I: Conceitos Básicos I-14

1 Introdução à Linguagem PL/SQL


Objetivos 1-2
Agenda 1-3
Sobre a Linguagem PL/SQL 1-4
Arquitetura de Runtime de PL/SQL 1-6
Vantagens da Linguagem PL/SQL 1-7
Estrutura dos Blocos PL/SQL 1-10
Agenda 1-12
Tipos de Blocos 1-13
Estruturas de Programas 1-15
Examinando um Bloco Anônimo 1-17
Executando um Bloco Anônimo 1-18
Agenda 1-19
Habilitando a Saída de um Bloco PL/SQL 1-20
Exibindo a Saída de um Bloco PL/SQL 1-21
Questionário 1-22
Sumário 1-23
Exercício 1: Visão Geral 1-24

iii
2 Declarando Variáveis PL/SQL
Objetivos 2-2
Agenda 2-3
Uso de Variáveis 2-4
Requisitos para Nomes de Variáveis 2-5
Tratando de Variáveis no Código PL/SQL 2-6
Declarando e Inicializando Variáveis PL/SQL 2-7
Delimitadores em Literais de String 2-9
Agenda 2-10
Tipos de Variáveis 2-11
Diretrizes para Declarar e Inicializar Variáveis PL/SQL 2-13
Diretrizes para Declarar Variáveis PL/SQL 2-14
Convenções de Nomeação das Estruturas PL/SQL Usadas Neste Curso 2-15
Tipos de Dados Escalares 2-16
Tipos de Dados Escalares Básicos 2-17
Declarando Variáveis Escalares 2-21
Atributo %TYPE 2-22
Declarando Variáveis com o Atributo %TYPE 2-24
Declarando Variáveis Booleanas 2-25
Variáveis de Tipo de Dados LOB 2-26
Tipos de Dados Compostos: Registros e Conjuntos 2-27
Agenda 2-28
Variáveis de Bind 2-29
Fazendo Referência a Variáveis de Bind 2-31
Usando AUTOPRINT com Variáveis de Bind 2-32
Questionário 2-33
Sumário 2-34
Exercício 2: Visão Geral 2-35

3 Criando Instruções Executáveis


Objetivos 3-2
Agenda 3-3
Unidades Lexicais de um Bloco PL/SQL 3-4
Diretrizes e Sintaxe de Blocos PL/SQL 3-6
Comentando o Código 3-7
Funções SQL no Código PL/SQL 3-8
Funções SQL no Código PL/SQL: Exemplos 3-9
Usando Sequências em Expressões PL/SQL 3-10
Conversão de Tipo de Dados 3-11
Agenda 3-14

iv
Blocos Aninhados 3-15
Blocos Aninhados: Exemplo 3-16
Escopo e Visibilidade da Variável 3-17
Usando um Qualificador com Blocos Aninhados 3-19
Desafio: Determinando o Escopo de Variáveis 3-20
Agenda 3-22
Operadores no Código PL/SQL 3-23
Operadores no Código PL/SQL: Exemplos 3-24
Diretrizes de Programação 3-25
Usando Recuos no Código 3-26
Questionário 3-27
Sumário 3-28
Exercício 3: Visão Geral 3-29

4 Interagindo com o Oracle Database Server: Instruções SQL em Programas


PL/SQL
Objetivos 4-2
Agenda 4-3
Instruções SQL em Blocos PL/SQL 4-4
Instruções SELECT em Blocos PL/SQL 4-5
Recuperando Dados em Blocos PL/SQL: Exemplo 4-9
Recuperando Dados em Blocos PL/SQL 4-10
Ambiguidades de Nomeação 4-11
Convenções de Nomeação 4-12
Agenda 4-13
Usando o Código PL/SQL para Manipular Dados
Inserindo Dados: Exemplo 4-15
Atualizando Dados: Exemplo 4-16
Deletando Dados: Exemplo 4-17
Intercalando Linhas 4-18
Agenda 4-20
Cursor SQL 4-21
Atributos de Cursor SQL para Cursores Implícitos 4-23
Questionário 4-25
Sumário 4-26
Exercício 4: Visão Geral 4-27

5 Criando Estruturas de Controle


Objetivos 5-2
Controlando o Fluxo de Execução 5-3
Agenda 5-4

v
Instrução IF 5-5
Instrução IF Simples 5-7
Instrução IF THEN ELSE 5-8
Cláusula IF ELSIF ELSE 5-9
Valor NULL em Instrução IF 5-10
Agenda 5-11
Expressões CASE 5-12
Expressões CASE: Exemplo 5-13
Expressões CASE Pesquisadas 5-14
Instrução CASE 5-15
Tratando Valores Nulos 5-16
Tabelas Lógicas 5-17
Expressões Booleanas ou Expressão Lógica? 5-18
Agenda 5-19
Controle Iterativo: Instruções de LOOP 5-20
Loops Básicos 5-21
Loop Básico: Exemplo 5-22
Loops WHILE 5-23
Loops WHILE: Exemplo 5-24
Loops FOR 5-25
Loops FOR: Exemplo 5-27
Regras de Loop FOR 5-28
Sugestão de Utilização de Loops 5-29
Loops Aninhados e Labels 5-30
Loops Aninhados e Labels: Exemplo 5-31
Instrução CONTINUE do Código PL/SQL 5-32
Instrução CONTINUE do Código PL/SQL: Exemplo 1 5-33
Instrução CONTINUE do Código PL/SQL: Exemplo 2 5-34
Questionário 5-35
Sumário 5-36
Exercício 5: Visão Geral 5-37

6 Trabalhando com Tipos de Dados Compostos


Objetivos 6-2
Agenda 6-3
Tipos de Dados Compostos 6-4
Registros ou Conjuntos PL/SQL? 6-5
Agenda 6-6
Registros PL/SQL 6-7
Criando um Registro PL/SQL 6-8

vi
Estrutura de Registros PL/SQL 6-9
Atributo %ROWTYPE 6-10
Criando um Registro PL/SQL: Exemplo 6-12
Vantagens do Uso do Atributo %ROWTYPE 6-13
Outro Exemplo do Atributo %ROWTYPE 6-14
Inserindo um Registro com %ROWTYPE 6-15
Atualizando uma Linha de Tabela com um Registro 6-16
Agenda 6-17
Arrays Associativos (Tabelas INDEX BY) 6-18
Estrutura de Array Associativo 6-19
Etapas para a Criação de um Array Associativo 6-20
Criando e Acessando Arrays Associativos 6-21
Usando Métodos da Tabela INDEX BY 6-22
Opção da Tabela de Registros INDEX BY 6-23
Opção da Tabela de Registros INDEX BY: Exemplo 2 6-24
Tabelas Aninhadas 6-25
VARRAY 6-27
Resumo dos Tipos de Conjunto 6-28
Questionário 6-29
Sumário 6-30
Exercício 6: Visão Geral 6-31

7 Usando Cursores Explícitos


Objetivos 7-2
Agenda 7-3
Cursores 7-4
Operações com Cursores Explícitos 7-5
Controlando Cursores Explícitos 7-6
Agenda 7-8
Declarando o Cursor 7-9
Abrindo o Cursor 7-11
Extraindo Dados do Cursor 7-12
Fechando o Cursor 7-15
Cursores e Registros 7-16
Loops de Cursor FOR 7-17
Atributos de Cursores Explícitos 7-19
Atributo %ISOPEN 7-20
%ROWCOUNT e %NOTFOUND: Exemplo 7-21
Loops de Cursor FOR com Subconsultas 7-22
Agenda 7-23

vii
Cursores com Parâmetros 7-24
Agenda 7-26
Cláusula FOR UPDATE 7-27
Cláusula WHERE CURRENT OF 7-29
Questionário 7-30
Sumário 7-31
Exercício 7: Visão Geral 7-32

8 Tratando Exceções
Objetivos 8-2
Agenda 8-3
O Que É uma Exceção? 8-4
Tratando a Exceção: Exemplo 8-5
Fundamentos das Exceções com PL/SQL 8-6
Tratando Exceções 8-7
Tipos de Exceção 8-8
Agenda 8-9
Sintaxe para Interceptar Exceções 8-10
Diretrizes para Interceptar Exceções 8-12
Interceptando Erros Predefinidos do Oracle Server 8-13
Interceptando Erros Não Predefinidos do Oracle Server 8-16
Interceptação de Erro Não Predefinido: Exemplo 8-17
Funções para Interceptar Exceções 8-18
Interceptando Exceções Definidas pelo Usuário 8-20
Propagando Exceções em um Sub-bloco 8-22
Procedure RAISE_APPLICATION_ERROR 8-23
Questionário 8-26
Sumário 8-27
Exercício 8: Visão Geral 8-28

9 Apresentando Procedures e Funções Armazenados


Objetivos 9-2
Agenda 9-3
Procedures e Funções 9-4
Diferenças entre Blocos Anônimos e Subprogramas 9-5
Agenda 9-6
Procedure: Sintaxe 9-7
Criando um Procedure 9-8
Chamando um Procedure 9-10
Agenda 9-11

viii
Função: Sintaxe 9-12
Criando uma Função 9-13
Chamando uma Função 9-14
Especificando Parâmetros para a Função 9-15
Chamando a Função com um Parâmetro 9-16
Questionário 9-17
Sumário 9-18
Exercício 9: Visão Geral 9-19

A Exercícios e Soluções

B Descrição de Tabelas e Dados

C Usando o SQL Developer


Objetivos C-2
O que É o Oracle SQL Developer? C-3
Especificações do SQL Developer C-4
Interface do SQL Developer 1.5 C-5
Criando uma Conexão com o Banco de Dados C-7
Navegando por Objetos de Banco de Dados C-10
Exibindo a Estrutura da Tabela C-11
Procurando Arquivos C-12
Criando um Objeto de Esquema C-13
Criando uma Nova Tabela: Exemplo C-14
Usando a SQL Worksheet C-15
Executando Instruções SQL C-18
Salvando Scripts SQL C-19
Executando Arquivos de Script Salvos: Método 1 C-20
Executando Arquivos de Script Salvos: Método 2 C-21
Formatando o Código SQL C-22
Usando Snippets C-23
Usando Snippets: Exemplo C-24
Depurando Procedures e Funções C-25
Geração de Relatórios de Banco de Dados C-26
Criando um Relatório Definido pelo Usuário C-27
Mecanismos de Pesquisa e Ferramentas Externas C-28
Definindo Preferências C-29
Redefinindo o Layout do SQL Developer C-30
Resumo C-31

ix
D Usando o SQL*Plus
Objetivos D-2
Interação entre SQL e SQL*Plus D-3
Instruções SQL Versus Comandos do SQL*Plus D-4
SQL*Plus: Visão Geral D-5
Efetuando Login no SQL*Plus D-6
Exibindo a Estrutura da Tabela D-7
Comandos de Edição do SQL*Plus D-9
Usando LIST, n e APPEND D-11
Usando o Comando CHANGE D-12
Comandos de Arquivo do SQL*Plus D-13
Usando os Comandos SAVE e START D-14
Comando SERVEROUTPUT D-15
Usando o Comando SPOOL do SQL*Plus D-16
Usando o Comando AUTOTRACE D-17
Resumo D-18

E Usando o JDeveloper
Oracle JDeveloper E-2
Database Navigator E-3
Criando uma Conexão E-4
Navegando por Objetos de Banco de Dados E-5
Executando Instruções SQL E-6
Criando Unidades de Programa E-7
Compilando E-8
Executando uma Unidade de Programa E-9
Eliminando uma Unidade de Programa E-10
Janela Structure E-11
Janela Editor E-12
Application Navigator E-13
Disponibilizando Procedures Java Armazenados E-14
Publicando Java em PL/SQL E-15
Como Posso Obter Mais Informações sobre o JDeveloper 11g? E-16

F Cursores REF
Variáveis de Cursor F-2
Usando Variáveis de Cursor F-3
Definindo os Tipos REF CURSOR F-4
Usando as Instruções OPEN-FOR, FETCH e CLOSE F-7
Exemplo de Extração com o Comando Fetch F-10

Exercícios Adicionais e Soluções

x
Introdução

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.
Objetivos da Lição

Ao concluir esta lição, você será capaz de:


• Abordar as metas do curso
• Descrever o esquema de banco de dados HR usado no
curso
• Identificar os ambientes da interface do usuário
disponíveis que podem ser usados neste curso
• Consultar apêndices, documentação e outros recursos
disponíveis

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Objetivos da Lição
Esta lição apresenta uma visão geral do curso e de seu fluxo. Você conhecerá o esquema do
banco de dados e as tabelas utilizadas no curso. O curso lhe apresenta componentes como SQL,
PL/SQL, recursos de compilação e também ferramentas como o SQL Developer usadas neste
curso.

Oracle Database: Fundamentos de PL/SQL I - 2


Objetivos do Curso

Após concluir este curso, você será capaz de:


• Identificar as extensões de programação que o PL/SQL
fornece ao SQL
• Criar código PL/SQL para estabelecer interface com o
banco de dados
• Desenvolver blocos PL/SQL anônimos que são
executados de forma eficiente
• Usar estruturas de programação PL/SQL e instruções de
controle condicional
• Tratar erros de runtime
• Descrever funções e procedures armazenados

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Objetivos do Curso
Este curso apresenta os conceitos básicos de PL/SQL. Você conhecerá a sintaxe, os blocos e as
estruturas de programação PL/SQL e também as vantagens de fazer a integração do SQL com
essas estruturas. Você aprenderá a criar unidades de programa PL/SQL e a executá-las com
eficiência. Além disso, você aprenderá a usar o SQL Developer como ambiente de
desenvolvimento para PL/SQL. Você também será ensinado a projetar unidades de programa
reutilizáveis, como procedures e funções.

Oracle Database: Fundamentos de PL/SQL I - 3


Esquema Human Resources (HR)
Usado Neste Curso

DEPARTAMENTOS LOCAIS
department_id location_id
department_name street_address
manager_id postal_code
location_id cidade
state_province
country_id
JOB_HISTORY
employee_id
start_date FUNCIONÁRIOS
employee_id
end_date
first_name
job_id
last_name PAÍSES
department_id
email country_id
phone_number country_name
hire_date region_id
job_id
salário
commission_pct
JOBS manager_id
job_id department_id
job_title
min_salary REGIÕES
max_salary region_id
region_name

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Esquema Human Resources (HR) Usado Neste Curso


O esquema Human Resources (HR) faz parte dos Oracle Sample Schemas que podem ser
instalados em um banco de dados Oracle. As sessões de exercícios deste curso utilizam dados
desse esquema HR.
Descrição das Tabelas
• REGIONS contém linhas que representam uma região, como as Américas ou a Ásia.
• A tabela COUNTRIES contém linhas para os países, cada um dos quais associado a uma
região.
• A tabela LOCATIONS contém o endereço específico de determinado escritório, depósito
ou local de produção de uma empresa em determinado país.
• A tabela DEPARTMENTS mostra detalhes dos departamentos onde os funcionários
trabalham. Cada departamento pode ter um relacionamento que representa o gerente do
departamento na tabela EMPLOYEES.
• A tabela EMPLOYEES contém detalhes sobre cada funcionário que trabalha em um
departamento. Alguns funcionários talvez não tenham sido designados a departamento
algum.
• A tabela JOBS contém os tipos de cargos que cada funcionário pode exercer.
• A tabela JOB_HISTORY contém o histórico de cargos dos funcionários. Se um
funcionário mudar de departamento mantendo o mesmo cargo ou mudar de cargo no
mesmo departamento, uma nova linha será inserida nessa tabela com as informações do
cargo antigo do funcionário.
Oracle Database: Fundamentos de PL/SQL I - 4
Agenda do Curso

Dia 1:
I. Introdução
1. Introdução à Linguagem PL/SQL
2. Declarando Variáveis PL/SQL
3. Criando Instruções Executáveis
4. Interagindo com o Oracle Database Server: Instruções
SQL em Programas PL/SQL
5. Criando Estruturas de Controle
Dia 2:
6. Trabalhando com Tipos de Dados Compostos
7. Usando Cursores Explícitos
8. Tratando Exceções
9. Apresentando Procedures e Funções Armazenados

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL I - 5


Informações da Conta Usada em Sala de Aula

• Um ID da conta HR clonado é configurado para você.


• O seu ID da conta é ora41.
• A senha corresponde ao ID da conta.
• Cada máquina possui o seu próprio ambiente completo e
recebe a designação da mesma conta.
• O instrutor possui um ID separado.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL I - 6


Apêndices Usados Neste Curso

• Apêndice A: Exercícios e Soluções


• Apêndice B: Descrições e Dados das Tabelas
• Apêndice C: Usando o SQL Developer
• Apêndice D: Usando o SQL*Plus
• Apêndice E: Usando o JDeveloper
• Apêndice F: Cursores REF
• Apêndice AP: Exercícios Adicionais e Soluções

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL I - 7


Ambientes de Desenvolvimento PL/SQL

A configuração deste curso fornece as seguintes ferramentas


para o desenvolvimento de código PL/SQL:
• Oracle SQL Developer (usado neste curso)
• Oracle SQL*Plus
• Oracle JDeveloper IDE

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Ambientes de Desenvolvimento PL/SQL


A Oracle fornece várias ferramentas que podem ser usadas para criar código PL/SQL. Estas são
algumas das ferramentas de desenvolvimento disponíveis para uso neste curso:
• Oracle SQL Developer: Uma ferramenta gráfica
• Oracle SQL*Plus: Uma aplicação baseada em janelas ou de linha de comandos
• Oracle JDeveloper: Um IDE (Integrated Development Environment) baseado em janelas
Observação: Os exemplos de códigos e de telas apresentados nas observações do curso foram
gerados a partir da saída no ambiente SQL Developer.

Oracle Database: Fundamentos de PL/SQL I - 8


O que É o Oracle SQL Developer?

• O Oracle SQL Developer é uma ferramenta gráfica


gratuita que melhora a produtividade e simplifica as
tarefas de desenvolvimento de banco de dados.
• Você pode se conectar a qualquer esquema de banco de
dados Oracle de destino usando a autenticação de banco
de dados padrão Oracle.
• Você usará o SQL Developer neste curso.
• O Apêndice C contém os detalhes sobre como usar o SQL
Developer.

SQL Developer

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

O que É o Oracle SQL Developer?


O Oracle SQL Developer é uma ferramenta gráfica gratuita projetada para melhorar sua
produtividade e simplificar o desenvolvimento das tarefas diárias de banco de dados. Com
apenas alguns cliques, você poderá criar e manter com facilidade procedures armazenados, testar
instruções SQL e exibir planos do otimizador.
O SQL Developer, a ferramenta visual para o desenvolvimento de banco de dados, simplifica as
seguintes tarefas:
• Pesquisa e gerenciamento de objetos de banco de dados
• Execução de scripts e instruções SQL
• Edição e depuração de instruções PL/SQL
• Criação de relatórios
Você pode se conectar a qualquer esquema de banco de dados Oracle de destino usando a
autenticação padrão de banco de dados Oracle. Quando estiver conectado, você poderá executar
operações em objetos no banco de dados.
Apêndice C
O Apêndice C deste curso fornece uma introdução sobre como usar a interface do SQL
Developer. Consulte o apêndice para obter informações sobre como criar uma conexão com o
banco de dados, interagir com os dados usando SQL e PL/SQL, e muito mais.

Oracle Database: Fundamentos de PL/SQL I - 9


Codificando PL/SQL no SQL*Plus

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Codificando PL/SQL no SQL*Plus


O Oracle SQL*Plus é uma interface de linha de comandos que permite a você submeter
instruções SQL e blocos PL/SQL para execução e receber os resultados em uma janela de
comando ou aplicação.
O SQL*Plus é:
• Fornecido com o banco de dados
• Instalado em um cliente e no sistema do servidor do banco de dados
• Acessado a partir de um ícone ou da linha de comandos
Ao codificar subprogramas PL/SQL usando o SQL*Plus, considere o seguinte:
• Os subprogramas são criados com a instrução CREATE SQL.
• Os subprogramas são executados com um bloco PL/SQL anônimo ou o comando
EXECUTE.
• Se você usar os procedures do pacote DBMS_OUTPUT para exibir texto na tela, deverá
executar primeiro o comando SET SERVEROUTPUT ON na sua sessão.
Observação
• Para ativar o SQL*Plus no ambiente Linux, abra uma janela de terminal e informe o
comando: sqlplus.
• Para obter mais informações sobre como usar o SQL*Plus, consulte o Apêndice D.

Oracle Database: Fundamentos de PL/SQL I - 10


Codificando PL/SQL no Oracle JDeveloper

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Codificando PL/SQL no Oracle JDeveloper


O Oracle JDeveloper permite que os desenvolvedores criem, editem, testem e depurem código
PL/SQL usando uma GUI sofisticada. O Oracle JDeveloper faz parte do Oracle Developer Suite
e também está disponível como um produto separado.
Ao codificar PL/SQL no JDeveloper, considere o seguinte:
• Você deve criar primeiro uma conexão de banco de dados, de modo que o JDeveloper
possa acessar o proprietário de um esquema de banco de dados para os subprogramas.
• Posteriormente, você poderá usar os menus de contexto do JDeveloper na conexão de
banco de dados para criar uma nova estrutura de subprograma usando o Code Editor do
JDeveloper.
• Para chamar um subprograma, use o comando Run no menu de contexto do subprograma
nomeado. A saída é exibida na janela JDeveloper Log Message, conforme mostrado na
parte inferior da tela.
Observação
• O JDeveloper fornece sintaxe com codificação de cores no JDeveloper Code Editor e
relacionada às estruturas e instruções da linguagem PL/SQL.
• Para obter mais informações sobre como usar o JDeveloper, consulte o Apêndice E.

Oracle Database: Fundamentos de PL/SQL I - 11


Documentação do Oracle SQL e PL/SQL

• Oracle Database New Features Guide


• Oracle Database PL/SQL Language Reference
• Oracle Database Reference
• Oracle Database SQL Language Reference
• Oracle Database Concepts
• Oracle Database PL/SQL Packages and Types Reference
• Oracle Database Advanced Application Developer’s Guide 11g
• Oracle Database SQL Developer User’s Guide Release 1.5

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Documentação do Oracle Database 11g


Navegue até http://www.oracle.com/pls/db112/homepage para acessar a biblioteca da
documentação do Oracle Database 11g.
Navegue até http://www.oracle.com/pls/db102/homepage para acessar a biblioteca da
documentação do Oracle Database 10g .

Oracle Database: Fundamentos de PL/SQL I - 12


Sumário

Nesta lição, você aprendeu a:


• Abordar as metas do curso
• Descrever o esquema de banco de dados HR usado no
curso
• Identificar os ambientes da interface do usuário
disponíveis que podem ser usados neste curso
• Consultar apêndices, documentação e outros recursos
disponíveis

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL I - 13


Visão Geral do Exercício I: Conceitos Básicos

Este exercício aborda os seguintes tópicos:


• Iniciando o SQL Developer
• Criando uma nova conexão com o banco de dados
• Navegando nas tabelas do esquema HR
• Definindo uma preferência do SQL Developer

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Exercício I: Visão Geral


Neste exercício, você usará o SQL Developer para executar instruções SQL a fim de examinar
dados no esquema HR. Você também criará um bloco anônimo simples.
Observação: Todos os exercícios criados usam o SQL Developer como ambiente de
desenvolvimento. Embora seja recomendado o uso do SQL Developer, você também pode usar
os ambientes do SQL*Plus ou do JDeveloper, que estão disponíveis neste curso.

Oracle Database: Fundamentos de PL/SQL I - 14


Introdução à Linguagem PL/SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.
Objetivos

Ao concluir esta lição, você será capaz de:


• Explicar a necessidade da linguagem PL/SQL
• Explicar as vantagens da linguagem PL/SQL
• Identificar os diferentes tipos de blocos PL/SQL
• Exibir mensagens em PL/SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Objetivos
Esta lição apresenta a linguagem PL/SQL e as estruturas de programação PL/SQL. Você
também aprenderá as vantagens do código PL/SQL.

Oracle Database: Fundamentos de PL/SQL 1 - 2


Agenda

• Fundamentos das vantagens e da estrutura do código


PL/SQL
• Examinando blocos PL/SQL
• Gerando mensagens de saída em PL/SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 1 - 3


Sobre a Linguagem PL/SQL

PL/SQL:
• Significa a extensão Procedural Language do código SQL
• É a linguagem padrão de acesso a dados da Oracle
Corporation para bancos de dados relacionais
• Integra totalmente as estruturas procedurais com o código
SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Sobre a Linguagem PL/SQL


SQL (Structured Query Language) é a principal linguagem usada para acessar e modificar dados
em bancos de dados relacionais. Existem apenas alguns comandos SQL, portanto você pode
aprendê-los e usá-los facilmente.
Veja um exemplo:
SELECT first_name, department_id, salary FROM employees;
A instrução SQL anterior é simples e direta. No entanto, se você quiser alterar dados obtidos de
modo condicional, enfrentará as limitações do código SQL.
Considere a instrução de uma questão um pouco modificada: Para cada funcionário recuperado,
verifique o ID do departmento e o salário. Dependendo do desempenho do departamento e do
salário do funcionário, você poderá fornecer bônus distintos aos funcionários.
Verificando a questão, você sabe que precisa executar a instrução SQL anterior, coletar os dados
e aplicar lógica aos dados.
• Uma solução é criar uma instrução SQL para que cada departamento ofereça bônus aos
funcionários daquele departamento que concede o bônus. Lembre-se de que é necessário
verificar o componente salary para decidir o valor do bônus. Isso torna o processo um
pouco mais complexo.
• Uma solução mais eficaz deverá incluir instruções condicionais. O código PL/SQL foi
projetado para atender a esses requisitos. Ele fornece uma extensão de programação ao
código SQL existente.
Oracle Database: Fundamentos de PL/SQL 1 - 4
Sobre a Linguagem PL/SQL

PL/SQL:
• Fornece uma estrutura de blocos para as unidades
executáveis do código. A manutenção do código é
facilitada com uma estrutura bem definida.
• Fornece estruturas procedurais, como:
– Variáveis, constantes e tipos de dados
– Estruturas de controle, como instruções condicionais e loops
– Unidades de programa reutilizáveis, que são criadas uma
vez e executadas várias vezes

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Sobre a Linguagem PL/SQL (continuação)


A linguagem PL/SQL define uma estrutura de blocos para a criação de códigos. A manutenção e
a depuração do código são facilitadas com tal estrutura porque é possível entender facilmente o
fluxo e a execução da unidade de programa.
A linguagem PL/SQL dispõe de modernos recursos de engenharia de software, como
encapsulamento de dados, tratamento de exceções, ocultamento de informações e orientação a
objetos. Ela fornece a programação mais avançada ao conjunto de ferramentas e ao Oracle
Server. O código PL/SQL fornece todas estruturas procedurais disponíveis em qualquer 3GL
(linguagem de terceira geração).

Oracle Database: Fundamentos de PL/SQL 1 - 5


Arquitetura de Runtime de PL/SQL
Bloco PL/SQL

procedural

Procedural Statement
Executor

PL/SQL
Mecanismo PL/SQL

SQL

Oracle Server

SQL statement executor

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Arquitetura de Runtime de PL/SQL


O diagrama mostra um bloco PL/SQL que está sendo executado pelo mecanismo PL/SQL. Esse
mecanismo reside:
• No banco de dados Oracle para executar subprogramas armazenados
• No Oracle Forms Client, quando você executa aplicações cliente/servidor, ou no Oracle
Application Server, quando você usa o Oracle Forms Services para executar o Forms na
Web
Independentemente do ambiente de runtime PL/SQL, a arquitetura básica permanece a mesma.
Portanto, todas as instruções PL/SQL são processadas no Procedural Statement Executor, e todas
as instruções SQL devem ser enviadas ao SQL Statement Executor para serem processadas pelo
Oracle Server. O ambiente SQL também pode chamar o ambiente PL/SQL. Por exemplo, o
ambiente PL/SQL é chamado quando uma função PL/SQL é usada em uma instrução SELECT.
O mecanismo PL/SQL é uma máquina virtual residente na memória que processa as instruções
m-code PL/SQL. Quando o mecanismo PL/SQL encontra uma instrução SQL, ocorre uma
alternância de contexto a fim de especificar a instrução SQL para os processos do Oracle Server.
O mecanismo PL/SQL aguarda o término da instrução SQL e o retorno dos resultados para
depois continuar processando as instruções subsequentes do bloco PL/SQL. O mecanismo
PL/SQL do Oracle Forms é executado no cliente para a implementação de cliente/servidor e no
servidor de aplicações para a implementação do Forms Services. Em ambos os casos, as
instruções SQL geralmente são enviadas pela rede para processamento em um Oracle Server.
Oracle Database: Fundamentos de PL/SQL 1 - 6
Vantagens da Linguagem PL/SQL

• Integração de estruturas procedurais com o código SQL


• Melhor desempenho

SQL 1
SQL 2

SQL
IF...THEN
SQL
ELSE
SQL
END IF;
SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Vantagens da Linguagem PL/SQL


Integração de estruturas procedurais com o código SQL: A maior vantagem da linguagem
PL/SQL é a integração das estruturas procedurais com o código SQL. SQL é uma linguagem não
procedural. Quando você executa um comando SQL, o seu comando avisa o servidor de banco
de dados sobre o que fazer. No entanto, você não pode especificar como fazer. O código PL/SQL
integra instruções de controle e instruções condicionais com SQL, proporcionando maior
controle sobre as instruções SQL e sua execução. Anteriormente nesta seção, você viu um
exemplo da necessidade dessa integração.
Melhor desempenho: Sem o código PL/SQL, não seria possível combinar logicamente as
instruções SQL como uma unidade. Caso você tenha projetado uma aplicação que contenha
muitos forms, poderá haver, em cada form, vários forms diferentes com campos. Quando um
form submeter dados, você deverá executar várias instruções SQL. As instruções SQL são
enviadas ao banco de dados uma de cada vez. Isso resulta em vários percursos de ida e volta pela
rede e uma chamada para o banco de dados de cada instrução SQL, aumentando, dessa forma, o
tráfego na rede e reduzindo o desempenho (especialmente em um modelo cliente/servidor).
Com o código PL/SQL, você pode combinar todas essas instruções SQL em uma só unidade de
programa. A aplicação pode enviar o bloco inteiro para o banco de dados, em vez de enviar as
instruções SQL uma de cada vez. Isso reduz drasticamente o número de chamadas do banco de
dados. Como é ilustrado no slide, se a aplicação for predominantemente SQL, você poderá usar
blocos PL/SQL para agrupar as instruções SQL antes de enviá-las ao servidor de banco de dados
Oracle para execução.
Oracle Database: Fundamentos de PL/SQL 1 - 7
Vantagens da Linguagem PL/SQL

• Desenvolvimento de programas em módulos


• Integração com ferramentas Oracle
• Portabilidade
• Tratamento de exceções

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Vantagens da Linguagem PL/SQL (continuação)


Desenvolvimento de programas em módulos: A unidade básica em todos os programas
PL/SQL é o bloco. Os blocos podem estar em sequência ou aninhados em outros blocos. O
desenvolvimento de programas em módulos tem as seguintes vantagens:
• Agrupar logicamente em blocos as instruções relacionadas.
• Aninhar blocos dentro de blocos maiores para criar programas avançados.
• Fragmentar a aplicação em módulos menores. Se estiver projetando uma aplicação
complexa, o código PL/SQL permitirá que você fragmente a aplicação em módulos
menores, gerenciáveis e logicamente relacionados.
• Manter e depurar o código com facilidade.
No código PL/SQL, a modularização é implementada através de procedures, funções e pacotes,
que são abordados na lição “Apresentando Procedures e Funções Armazenados”.
Integração com ferramentas: O mecanismo PL/SQL é integrado às ferramentas Oracle, como
Oracle Forms e Oracle Reports. Quando você usa essas ferramentas, o mecanismo PL/SQL
disponível localmente processa as instruções procedurais e apenas as instruções SQL são
passadas para o banco de dados.

Oracle Database: Fundamentos de PL/SQL 1 - 8


Vantagens da Linguagem PL/SQL (continuação)
Portabilidade: Os programas PL/SQL podem ser executados em qualquer lugar onde seja
executado um Oracle Server, independentemente do sistema operacional e da plataforma. Não é
necessário personalizá-los para cada novo ambiente. Você pode criar pacotes de programas
portáteis e bibliotecas que podem ser reutilizadas em diferentes ambientes.
Tratamento de exceções: O código PL/SQL permite tratar exceções com eficácia. Você pode
definir blocos separados para lidar com as exceções. Você aprenderá mais sobre o tratamento de
exceções na lição “Tratamento de Exceções”.
O código PL/SQL compartilha o mesmo sistema de tipo de dados do código SQL (com algumas
extensões) e utiliza a mesma sintaxe de expressões.

Oracle Database: Fundamentos de PL/SQL 1 - 9


Estrutura dos Blocos PL/SQL

• DECLARE (opcional)
– Variáveis, cursores e exceções definidas pelo usuário
• BEGIN (obrigatório)
– Instruções SQL
– Instruções PL/SQL
• EXCEPTION (opcional)
– Ações a serem executadas
quando ocorrerem exceções
• END; (obrigatório)

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Estrutura dos Blocos PL/SQL


O slide mostra um bloco PL/SQL básico. Um bloco PL/SQL consiste em quatro seções:
• Declarativa (opcional): A seção declarativa começa com a palavra-chave DECLARE e
termina quando a seção executável começa.
• Begin (obrigatório): A seção executável começa com a palavra-chave BEGIN. Esta seção
precisa ter, no mínimo, uma instrução. No entanto, a seção executável de um bloco
PL/SQL pode conter inúmeros blocos PL/SQL.
• Tratamento de exceções (opcional): A seção de exceção é aninhada dentro da seção
executável. Essa seção começa com a palavra-chave EXCEPTION.
• End (obrigatório): Todos os blocos PL/SQL devem terminar com uma instrução END.
Observe que END é seguido de um ponto e vírgula.

Oracle Database: Fundamentos de PL/SQL 1 - 10


Estrutura dos Blocos PL/SQL (continuação)
Em um bloco PL/SQL, as palavras-chave DECLARE, BEGIN e EXCEPTION não são seguidas
de ponto e vírgula. No entanto, a palavra-chave END, todas as instruções SQL e as instruções
PL/SQL devem ser seguidas de um ponto e vírgula.

Seção Descrição Inclusão


Declarativa Contém declarações das variáveis, das constantes, Opcional
(DECLARE) dos cursores e das exceções definidas pelo usuário
que são referenciadas nas seções executável e de
exceção
Executável Contém instruções SQL para obter dados do banco Obrigatória
(BEGIN … de dados; contém instruções PL/SQL para manipular
END) dados no bloco
Exceção Especifica as ações a serem realizadas quando Opcional
(EXCEPTION) ocorrem erros ou condições anormais na seção
executável

Oracle Database: Fundamentos de PL/SQL 1 - 11


Agenda

• Fundamentos das vantagens e da estrutura do código


PL/SQL
• Examinando blocos PL/SQL
• Gerando mensagens de saída em PL/SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 1 - 12


Tipos de Blocos

Procedure Função Anônimo


PROCEDURE name FUNCTION name [DECLARE]
IS RETURN datatype
IS
BEGIN BEGIN BEGIN
--statements --statements --statements
RETURN value;
[EXCEPTION] [EXCEPTION] [EXCEPTION]

END; END; END;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Tipos de Blocos
Um programa PL/SQL inclui um ou mais blocos. Esses blocos podem estar totalmente separados
ou aninhados em outro bloco.
Existem três tipos de blocos que formam um programa PL/SQL:
• Procedures
• Funções
• Blocos anônimos
Procedures: São objetos nomeados que contêm instruções SQL e/ou PL/SQL.
Funções: São objetos nomeados que contêm instruções SQL e/ou PL/SQL. Diferentemente de
um procedure, uma função retorna um valor de um tipo de dados especificado.
Blocos anônimos
Blocos anônimos são blocos não nomeados. Eles são declarados em linha no momento da
aplicação em que eles deverão ser executados, e serão compilados cada vez que a aplicação for
executada. Esses blocos não são armazenados no banco de dados. Eles são passados para o
mecanismo PL/SQL para execução durante o runtime. Os triggers dos componentes do Oracle
Developer consistem nesses blocos.
Se quiser executar novamente o mesmo bloco, você terá de recriá-lo. Você não poderá chamar o
bloco que criou anteriormente porque os blocos são anônimos e não existem mais depois que são
executados.
Oracle Database: Fundamentos de PL/SQL 1 - 13
Tipos de Blocos (continuação)
Subprogramas
Os subprogramas complementam os blocos anônimos. Eles são blocos PL/SQL nomeados
armazenados no banco de dados. Como eles são nomeados e armazenados, você poderá chamá-
los sempre que desejar, dependendo da sua aplicação. Você pode declará-los como procedures
ou funções. Em geral, o procedure é usado para realizar uma ação e a função para calcular e
retornar um valor.
Os subprogramas podem ser armazenados no nível do servidor ou da aplicação. Usando os
componentes do Oracle Developer (Forms, Reports), você pode declarar procedures e funções
como parte da aplicação (um form ou relatório) e chamá-los a partir de outros procedures,
funções e triggers dentro da mesma aplicação, sempre que necessário.

Oracle Database: Fundamentos de PL/SQL 1 - 14


Estruturas de Programa

Estruturas de Servidor
Estruturas de Ferramentas de Banco de Dados
Blocos anônimos Blocos anônimos
Procedures de aplicações Procedures armazenados
ou funções ou funções

Pacotes de aplicações Pacotes armazenados

Triggers de aplicações Triggers de banco de dados

Tipos de objetos Tipos de objetos

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Estruturas de Programa
A tabela a seguir resume várias estruturas de programa PL/SQL que usam blocos PL/SQL
básicos. As estruturas de programa estão disponíveis com base no ambiente em que são
executadas.
Bloco de Descrição Disponibilidade
Programa
Blocos anônimos Blocos PL/SQL não nomeados incorporados a Todos os ambientes PL/SQL
uma aplicação ou executados interativamente

Functions e Blocos PL/SQL nomeados armazenados em uma Componentes de ferramentas do


procedures de aplicação do Oracle Forms Developer ou uma Oracle Developer (por exemplo,
aplicações biblioteca compartilhada podem aceitar Oracle Forms Developer, Oracle
parâmetros e podem ser chamados várias vezes Reports)
pelo nome

procedures ou Blocos PL/SQL nomeados armazenados no Servidor Oracle ou ferramentas do


funções servidor Oracle podem aceitar parâmetros e podem Oracle Developer
armazenados ser chamados várias vezes pelo nome

Pacotes Módulos PL/SQL nomeados que agrupam Servidor Oracle e componentes


(de aplicações ou procedures, funções e identificadores relacionados de ferramentas do Oracle
armazenados) Developer (por exemplo, Oracle
Forms Developer)

Oracle Database: Fundamentos de PL/SQL 1 - 15


Estruturas de Programa (continuação)

Bloco de Descrição Disponibilidade


Programa
Triggers de Blocos PL/SQL associados a uma tabela de banco Servidor Oracle ou qualquer
banco de dados de dados e que serão acionados automaticamente ferramenta Oracle que execute a
se tiverem sido disparados por vários eventos instrução DML

Triggers de Blocos PL/SQL associados a uma tabela de banco Componentes de ferramentas do


aplicações de dados ou a eventos de sistema. Eles serão Oracle Developer (por exemplo,
acionados automaticamente quando disparados por Oracle Forms Developer)
uma instrução DML ou um evento de sistema,
respectivamente.

Tipos de objetos Tipos de dados compostos definidos pelo usuário Servidor Oracle e ferramentas do
que fazem encapsulamento de uma estrutura de Oracle Developer
dados juntamente com funções e procedures
necessários para manipular os dados

Oracle Database: Fundamentos de PL/SQL 1 - 16


Examinando um Bloco Anônimo

Um bloco anônimo no espaço de trabalho do SQL Developer:

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Examinando um Bloco Anônimo


Para criar um bloco anônimo usando o SQL Developer, informe o bloco no espaço de trabalho
(como mostrado no slide).
Exemplo
O bloco do exemplo tem a seção declarativa e a executável. Você não precisa prestar atenção à
sintaxe das instruções contidas no bloco; você aprenderá a sintaxe posteriormente neste curso.
O bloco anônimo obtém o nome (first_name) do funcionário cujo id (employee_id) é
100 e armazena-o em uma variável chamada v_fname.

Oracle Database: Fundamentos de PL/SQL 1 - 17


Executando um Bloco Anônimo

Clique no botão Run Script para executar o bloco anônimo:


Run Script (ou F5)

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Executando um Bloco Anônimo


Para executar um bloco anônimo, clique no botão Run Script (ou pressione F5).
Observação: A mensagem “anonymous block completed” é exibida na janela Script Output
após o bloco ser executado.

Oracle Database: Fundamentos de PL/SQL 1 - 18


Agenda

• Fundamentos das vantagens e da estrutura do código


PL/SQL
• Examinando blocos PL/SQL
• Gerando mensagens de saída em PL/SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 1 - 19


Habilitando a Saída de um Bloco PL/SQL

1. Para habilitar a saída no SQL Developer, execute o


seguinte comando antes de executar o bloco PL/SQL:

SET SERVEROUTPUT ON

2. Utilize um pacote Oracle predefinido e seu procedure no


bloco anônimo:
– DBMS_OUTPUT.PUT_LINE

DBMS_OUTPUT.PUT_LINE(' The First Name of the


Employee is ' || v_fname);

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Habilitando a Saída de um Bloco PL/SQL


No exemplo mostrado no slide anterior, foi armazenado um valor na variável v_fname. No
entanto, o valor não foi impresso.
O bloco PL/SQL não possui funcionalidade incorporada de entrada ou saída. Dessa forma, é
necessário usar pacotes Oracle predefinidos para entrada e saída. Para gerar a saída, faça o
seguinte:
1. Execute este comando:

SET SERVEROUTPUT ON

Observação: Para habilitar a saída no SQL*Plus, execute explicitamente o comando SET


SERVEROUTPUT ON.

2. No bloco PL/SQL, use o procedure PUT_LINE do pacote DBMS_OUTPUT para exibir a


saída. Especifique o valor a ser impresso como um argumento para esse procedure (como
mostrado no slide). Em seguida, o procedure exibe o argumento.

Oracle Database: Fundamentos de PL/SQL 1 - 20


Exibindo a Saída de um Bloco PL/SQL

Pressione F5 para
executar o comando e o
bloco PL/SQL.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Exibindo a Saída de um Bloco PL/SQL


Pressione F5 (ou clique no ícone Run Script) para exibir a saída do bloco PL/SQL. Ao fazer isso,
você:
1. Executa o comando SET SERVEROUTPUT ON
2. Executa o bloco PL/SQL anônimo
A saída é exibida na tab Script Output.

Oracle Database: Fundamentos de PL/SQL 1 - 21


Questionário

Um bloco PL/SQL deve consistir nestas três seções:


• Uma seção declarativa, que começa com a palavra-chave
DECLARE e termina quando a seção executável começa.
• Uma seção executável, que começa com a palavra-chave
BEGIN e termina com END.
• Uma seção de tratamento de exceções, que começa com
a palavra-chave EXCEPTION e é aninhada dentro da
seção executável.

a. Verdadeiro
b. Falso

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Resposta: b
Um bloco PL/SQL consiste em três seções:
• Declarativa (opcional): A seção declarativa começa com a palavra-chave DECLARE e
termina quando a seção executável começa.
• Executável (obrigatória): A seção executável obrigatória começa com a palavra-chave
BEGIN e termina com END. É essencial que esta seção tenha, no mínimo, uma instrução.
Observe que END é seguido de um ponto e vírgula. A seção executável de um bloco
PL/SQL pode, por sua vez, conter inúmeros blocos PL/SQL.
• Tratamento de exceções (opcional): A seção de exceções opcional é aninhada dentro da
seção executável. Essa seção começa com a palavra-chave EXCEPTION.

Oracle Database: Fundamentos de PL/SQL 1 - 22


Sumário

Nesta lição, você aprendeu a:


• Integrar instruções SQL a estruturas de programa PL/SQL
• Descrever as vantagens do código PL/SQL
• Fazer a distinção entre os tipos de blocos PL/SQL
• Exibir mensagens em PL/SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Sumário
A linguagem PL/SQL possui recursos de programação que funcionam como extensões à
linguagem SQL. A linguagem SQL, que não é procedural, torna-se procedural com as estruturas
de programação PL/SQL. As aplicações PL/SQL podem ser executadas em qualquer plataforma
ou sistema operacional em que o Oracle Server seja executado. Nesta lição, você aprendeu a
criar blocos PL/SQL básicos.

Oracle Database: Fundamentos de PL/SQL 1 - 23


Exercício 1: Visão Geral

Este exercício aborda os seguintes tópicos:


• Identificando quais blocos PL/SQL são executados com
sucesso
• Criando e executando um bloco PL/SQL simples

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Exercício 1: Visão Geral


Este exercício reforça os conceitos básicos de PL/SQL abordados nesta lição.
• O exercício 1 é do tipo impresso, no qual você identifica os blocos PL/SQL executados
com sucesso.
• O exercício 2 envolve a criação e a execução de um bloco PL/SQL simples.

Oracle Database: Fundamentos de PL/SQL 1 - 24


Declarando Variáveis PL/SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.
Objetivos

Ao concluir esta lição, você será capaz de:


• Reconhecer identificadores válidos e inválidos
• Listar os usos de variáveis
• Declarar e inicializar variáveis
• Listar e descrever vários tipos de dados
• Identificar as vantagens da utilização do atributo %TYPE
• Declarar, usar e exibir variáveis de bind

2-2 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Objetivos
Você já aprendeu sobre blocos PL/SQL básicos e suas seções. Nesta lição, você conhecerá os
identificadores válidos e inválidos. Você aprenderá a declarar e inicializar variáveis na seção
declarativa de um bloco PL/SQL. A lição descreve os vários tipos de dados. Você conhecerá
também o atributo %TYPE e suas vantagens.

Oracle Database: Fundamentos de PL/SQL 2 - 2


Agenda

• Apresentando variáveis
• Examinando tipos de dados de variável e o atributo %TYPE
• Examinando variáveis de bind

2-3 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 2 - 3


Uso de Variáveis

As variáveis podem ser usadas para:


• Armazenamento temporário de dados
• Manipulação dos valores armazenados
• Reutilização

SELECT
first_name,
department_id
INTO Jennifer v_fname
v_fname,
v_deptno
FROM …
10 v_deptno

2-4 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Uso de Variáveis
Com o código PL/SQL, você pode declarar variáveis e depois usá-las em instruções procedurais
e códigos SQL.
As variáveis são usadas principalmente para o armazenamento de dados e a manipulação de
valores armazenados. Considere a instrução PL/SQL no slide. A instrução recupera
first_name e department_id da tabela. Se precisar manipular first_name ou
department_id, você precisará armazenar o valor recuperado. As variáveis são usadas para
armazenar temporariamente o valor. Os valores armazenados nessas variáveis podem ser usados
para processar e manipular os dados. As variáveis podem armazenar qualquer objeto PL/SQL,
como variáveis, tipos, cursores e subprogramas.
Reutilização é outra vantagem da declaração de variáveis. Após as variáveis serem declaradas,
você poderá usá-las repetidamente em uma aplicação, fazendo referência a elas diversas vezes
em várias instruções.

Oracle Database: Fundamentos de PL/SQL 2 - 4


Requisitos para Nomes de Variáveis

Um nome de variável:
• Deve começar com uma letra
• Pode conter letras ou números
• Pode conter caracteres especiais (como $, _ e #)
• Não pode conter mais de 30 caracteres
• Não deve conter palavras reservadas

2-5 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Requisitos para Nomes de Variáveis


As regras para nomeação de uma variável estão listadas no slide.

Oracle Database: Fundamentos de PL/SQL 2 - 5


Tratando Variáveis no Código PL/SQL

As variáveis são:
• Declaradas e inicializadas (opcionalmente) na seção
declarativa
• Valores novos designados e usados na seção executável
• Transmitidas como parâmetros para subprogramas
PL/SQL
• Usadas para armazenar a saída de um subprograma
PL/SQL

2-6 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Tratando Variáveis no Código PL/SQL


Você pode usar variáveis das seguintes formas:
• Declará-las e inicializá-las na seção declarativa: Você pode declarar variáveis na parte
declarativa de qualquer bloco, subprograma ou pacote PL/SQL. As declarações alocam
espaço de armazenamento para um valor, especificam o seu tipo de dados e nomeiam o
local de armazenamento para que você possa fazer referência a ele. As declarações
também podem designar um valor inicial e impor a constraint NOT NULL na variável. Não
são permitidas referências futuras. É necessário declarar uma variável antes de fazer
referência a ela em outras instruções, incluindo outras instruções declarativas.
• Use-as e atribua novos valores a elas na seção executável: Na seção executável, o valor
existente da variável pode ser substituído por um novo valor.
• Especifique-as como parâmetros para os subprogramas PL/SQL: Os subprogramas
podem utilizar parâmetros. Você pode especificar variáveis como parâmetros para os
subprogramas.
• Use-as para armazenar a saída de um subprograma PL/SQL: As variáveis podem ser
usadas para armazenar o valor que é retornado por uma função.

Oracle Database: Fundamentos de PL/SQL 2 - 6


Declarando e Inicializando Variáveis PL/SQL

Sintaxe:
identifier [CONSTANT] datatype [NOT NULL]
[:= | DEFAULT expr];

Exemplos:
DECLARE
v_hiredate DATE;
v_deptno NUMBER(2) NOT NULL := 10;
v_location VARCHAR2(13) := 'Atlanta';
c_comm CONSTANT NUMBER := 1400;

2-7 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Declarando e Inicializando Variáveis PL/SQL


Você deve declarar todos os identificadores PL/SQL na seção declarativa para poder fazer
referência a eles no bloco PL/SQL. Você tem a opção de designar um valor inicial a uma
variável (conforme mostrado no slide). Não é necessário designar um valor a uma variável para
declará-la. Se você fizer referência a outras variáveis em uma declaração, certifique-se de que
elas já tenham sido declaradas separadamente em uma instrução anterior.
Na sintaxe:
identifier É o nome da variável
CONSTANT Restringe a variável para que seu valor não possa mudar (constantes devem
ser inicializadas.)
data type É um tipo de dados escalar, composto, de referência ou LOB (Este curso
aborda apenas tipos de dados escalares, compostos e LOB).
NOT NULL Restringe a variável de modo que ela contenha um valor (variáveis NOT
NULL devem ser inicializadas).
expr É uma expressão PL/SQL que pode ser uma expressão literal, outra variável
ou uma expressão contendo operadores e funções.
Observação: Além das variáveis, também é possível declarar cursores e exceções na seção
declarativa. Você será ensinado a declarar cursores na lição “Usando Cursores Explícitos” e
aprenderá sobre as exceções na lição “Tratamento de Exceções”.

Oracle Database: Fundamentos de PL/SQL 2 - 7


Declarando e Inicializando Variáveis PL/SQL

DECLARE
v_myName VARCHAR2(20);
BEGIN
1
DBMS_OUTPUT.PUT_LINE('My name is: '|| v_myName);
v_myName := 'John';
DBMS_OUTPUT.PUT_LINE('My name is: '|| v_myName);
END;
/

DECLARE
v_myName VARCHAR2(20):= 'John';
2 BEGIN
v_myName := 'Steven';
DBMS_OUTPUT.PUT_LINE('My name is: '|| v_myName);
END;
/

2-8 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Declarando e Inicializando Variáveis PL/SQL (continuação)


Examine os dois blocos de código no slide.
1. No primeiro bloco, a variável v_myName é declarada, mas não inicializada. Um valor
John é designado à variável na seção executável.
- Os literais de string devem ser delimitados por aspas simples. Caso a sua string tenha
aspas como em “Today’s Date”, então ela deverá ser 'Today''s Date'.
- O operador de designação é: “:=”.
- O procedure PUT_LINE é chamado pela especificação da variável v_myName. O
valor da variável é concatenado com a string 'My name is:'.
- A saída desse bloco anônimo é:

2. No segundo bloco, a variável v_myName é declarada e inicializada na seção declarativa.


v_myName armazena o valor John após a inicialização. Esse valor é manipulado na
seção executável do bloco. A saída desse bloco anônimo é:

Oracle Database: Fundamentos de PL/SQL 2 - 8


Delimitadores em Literais de String

DECLARE
v_event VARCHAR2(15);
BEGIN
v_event := q'!Father's day!';
DBMS_OUTPUT.PUT_LINE('3rd Sunday in June is :
'|| v_event );
v_event := q'[Mother's day]';
DBMS_OUTPUT.PUT_LINE('2nd Sunday in May is :
'|| v_event );
END;
/

Saída
resultante

2-9 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Delimitadores em Literais de String


Se a sua string contiver um apóstrofo (idêntico a uma aspa simples), será necessário usar aspas
duplas, como neste exemplo:
v_event VARCHAR2(15):='Father''s day';
A primeira aspa simples funciona como o caractere de escape. Isso tornará a sua string
complicada, especialmente se houver instruções SQL como strings. Você pode especificar como
delimitador qualquer caractere que não esteja presente na string. O slide mostra como usar a
notação q' para especificar o delimitador. O exemplo usa ! e [ como delimitadores. Considere
o seguinte exemplo:
v_event := q'!Father's day!';
Compare-o com o primeiro exemplo mostrado nesta página. Inicie a string com q' se desejar
usar um delimitador. O caractere seguinte à notação é o delimitador usado. Informe a string após
especificar o delimitador, feche o delimitador e feche a notação com uma aspa simples. O
exemplo a seguir mostra como usar [ como um delimitador:
v_event := q'[Mother's day]';

Oracle Database: Fundamentos de PL/SQL 2 - 9


Agenda

• Apresentando variáveis
• Examinando tipos de dados de variável e o atributo %TYPE
• Examinando variáveis de bind

2 - 10 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 2 - 10


Tipos de Variáveis

• Variáveis PL/SQL:
– Escalar
– Referência
– LOBs (large objects)
– Composta
• Variáveis não PL/SQL: Variáveis de bind

2 - 11 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Tipos de Variáveis
Toda variável PL/SQL tem um tipo de dados, que especifica um formato de armazenamento,
constraints e uma faixa válida de valores. A linguagem PL/SQL suporta várias categorias de
tipos de dados, incluindo os tipos escalares, de referência, LOBs (large objects) e compostos.
• Tipos de dados escalares: Os tipos de dados escalares armazenam um único valor. O
valor depende do tipo de dados da variável. Por exemplo, a variável v_myName do
exemplo da seção “Declarando e Inicializando Variáveis PL/SQL” (desta lição) é do tipo
VARCHAR2. Portanto, v_myName pode armazenar um valor de string. O código PL/SQL
também suporta variáveis booleanas.
• Tipos de dados de referência: Os tipos de dados de referência armazenam valores,
chamados ponteiros, que apontam para um local de armazenamento.
• Tipos de dados LOB: Os tipos de dados LOBs armazenam valores, chamados
localizadores, que especificam a localização de objetos grandes (como imagens gráficas)
que são armazenados fora da tabela.
• Tipos de dados compostos: Os tipos de dados compostos estão disponíveis quando você
utiliza variáveis PL/SQL de conjunto e de registro . Conjuntos e registros PL/SQL
contêm elementos internos que você pode tratar como variáveis individuais.
As variáveis que não são PL/SQL contêm variáveis de linguagem host declaradas em programas
pré-compiladores, campos de tela em aplicações Forms e variáveis de host. Você conhecerá as
variáveis de host posteriormente nesta lição.
Para obter mais informações sobre LOBs, consulte PL/SQL User’s Guide and Reference.

Oracle Database: Fundamentos de PL/SQL 2 - 11


Tipos de Variáveis

TRUE 15-JAN-09

Branca de Neve
Há muito tempo,
em um reino muito distante,
vivia uma princesa chamada
Branca de Neve. . .

Atlanta
256120.08

2 - 12 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Tipos de Variáveis (continuação)


O slide ilustra os seguintes tipos de dados:
• TRUE representa um valor booleano.
• 15-JAN-09 representa uma DATE.
• A imagem representa um BLOB.
• O texto do callout pode representar um tipo de dados VARCHAR2 ou um CLOB.
• 256120.08 representa um tipo de dados NUMBER com precisão e escala.
• A bobina do filme representa um BFILE.
• O nome da cidade Atlanta representa um tipo de dados VARCHAR2.

Oracle Database: Fundamentos de PL/SQL 2 - 12


Diretrizes para Declarar e Inicializar
Variáveis PL/SQL
• Siga convenções de nomeação consistentes.
• Use identificadores significativos para as variáveis.
• Inicialize variáveis que sejam designadas como NOT NULL
e CONSTANT.
• Inicialize as variáveis com o operador de designação (:=)
ou a palavra-chave DEFAULT:
v_myName VARCHAR2(20):='John';

v_myName VARCHAR2(20) DEFAULT 'John';

• Declare um identificador por linha para obter melhor


legibilidade e manutenção de código.

2 - 13 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Diretrizes para Declarar e Inicializar Variáveis PL/SQL


Estas são algumas diretrizes a serem seguidas quando você declara variáveis PL/SQL.
• Siga convenções de nomeação consistentes — por exemplo, use name para representar
uma variável e c_name para representar uma constante. De modo similar, para nomear
uma variável, você pode usar v_fname. O segredo é aplicar a convenção de nomeação de
modo consistente para facilitar a identificação.
• Use identificadores significativos e adequados para as variáveis. Por exemplo, considere o
uso de salary e sal_with_commission em vez de salary1 e salary2.
• Se você usar a constraint NOT NULL, deverá atribuir um valor quando declarar a variável.
• Na declaração de constantes, a palavra-chave CONSTANT deve preceder o especificador de
tipo. A declaração a seguir nomeia uma constante do tipo NUMBER e designa o valor de
50.000 à constante. Uma constante deve ser inicializada na sua declaração; caso contrário
haverá um erro de compilação. Após inicializar uma constante, não é possível alterar o seu
valor.
sal CONSTANT NUMBER := 50000.00;

Oracle Database: Fundamentos de PL/SQL 2 - 13


Diretrizes para Declarar Variáveis PL/SQL

• Evite usar nomes de colunas como identificadores.


DECLARE
employee_id NUMBER(6);
BEGIN
SELECT employee_id
INTO employee_id
FROM employees
WHERE last_name = 'Kochhar';
END;
/

• Use a constraint NOT NULL se a variável precisar


armazenar um valor.

2 - 14 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Diretrizes para Declarar Variáveis PL/SQL


• Inicialize a variável em uma expressão com o operador de designação (:=) ou com a
palavra reservada DEFAULT. Se você não designar um valor inicial, a nova variável
conterá NULL por default até que você designe um valor. Para designar ou redesignar um
valor a uma variável, crie uma instrução de atribuição PL/SQL. No entanto, é
recomendável inicializar todas as variáveis.
• Dois objetos podem ter o mesmo nome somente se estiverem definidos em blocos
diferentes. Se eles coexistirem, será possível qualificá-los com labels e usá-los.
• Evite usar nomes de colunas como identificadores. Se as variáveis PL/SQL ocorrerem em
instruções SQL e tiverem o mesmo nome que uma coluna, o Oracle Server pressuporá que
é a coluna que está sendo referenciada. Embora o código de exemplo do slide funcione, um
código criado com o mesmo nome em uma tabela do banco de dados e em uma variável
não é de fácil leitura ou manutenção.
• Imponha a constraint NOT NULL se a variável precisar conter um valor. Você não pode
designar nulos a uma variável definida como NOT NULL. A constraint NOT NULL deve ser
seguida por uma cláusula de inicialização.
pincode VARCHAR2(15) NOT NULL := 'Oxford';

Oracle Database: Fundamentos de PL/SQL 2 - 14


Convenções de Nomeação das
Estruturas PL/SQL Usadas Neste Curso
Estrutura PL/SQL Convenção Exemplo

Variável v_variable_name v_rate

Constante c_constant_name c_rate

Parâmetro de p_parameter_name p_id


subprograma

Variável de bind (host) b_bind_name b_salary

Cursor cur_cursor_name cur_emp

Registro rec_record_name rec_emp

Tipo type_name_type ename_table_type

Exceção e_exception_name e_products_invalid

Handle de arquivo f_file_handle_name f_file

2 - 15 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Convenções de Nomeação das Estruturas PL/SQL Usadas Neste Curso


A tabela do slide exibe alguns exemplos das convenções de nomeação das estruturas PL/SQL
usadas neste curso.

Oracle Database: Fundamentos de PL/SQL 2 - 15


Tipos de Dados Escalares

• Armazenam um único valor


• Não possuem componentes internos

TRUE 15-JAN-09

O preguiçoso
deseja e coisa nenhuma
alcança; mas o desejo do
diligente será satisfeito.

256120.08 Atlanta

2 - 16 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Tipos de Dados Escalares


O código PL/SQL fornece vários tipos de dados predefinidos. Por exemplo, você pode escolher
entre os tipos inteiro, ponto flutuante, caractere, booleano, data, conjunto e LOB. Esta lição
aborda os tipos básicos que são usados com frequência em programas PL/SQL.
Um tipo de dados escalar armazena um único valor e não possui componentes internos. Os tipos
de dados escalares podem ser classificados em quatro categorias: número, caractere, data e
booleano. Os tipos de dados de caractere e número têm subtipos que associam um tipo básico a
uma constraint. Por exemplo, INTEGER e POSITIVE são subtipos do tipo básico NUMBER.
Para obter mais informações sobre os tipos de dados escalares (bem como uma lista completa),
consulte PL/SQL User’s Guide and Reference.

Oracle Database: Fundamentos de PL/SQL 2 - 16


Tipos Básicos de Dados Escalares

• CHAR [(maximum_length)]
• VARCHAR2 (maximum_length)
• NUMBER [(precision, scale)]
• BINARY_INTEGER
• PLS_INTEGER
• BOOLEAN
• BINARY_FLOAT
• BINARY_DOUBLE

2 - 17 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Tipos Básicos de Dados Escalares

Tipo de Dados Descrição


CHAR Tipo básico de dados de caracteres de tamanho fixo de até 32.767
[(maximum_length)] bytes. Se você não especificar um tamanho máximo, o tamanho
default será definido como 1.
VARCHAR2 Tipo básico de dados de caracteres de tamanho variável de até 32.767
(maximum_length) bytes. Não existe tamanho default para as variáveis e constantes
VARCHAR2.
NUMBER Número com a precisão p e a escala s. A precisão p pode variar de 1
[(precision, a 38, enquanto a escala s pode variar de –84 a 127.
scale)]
BINARY_INTEGER Tipo básico para inteiros entre -2.147.483.647 e 2.147.483.647

Oracle Database: Fundamentos de PL/SQL 2 - 17


Tipos Básicos de Dados Escalares (continuação)

Tipo de Dados Descrição


PLS_INTEGER Tipo básico para inteiros sinalizados entre -2.147.483.647 e
2.147.483.647. Valores PLS_INTEGER necessitam de menos
armazenamento e são mais rápidos do que os valores NUMBER.
No Oracle Database 11g, os tipos de dados PLS_INTEGER e
BINARY_INTEGER são idênticos. As operações aritméticas em
valores PLS_INTEGER e BINARY_INTEGER são mais rápidas do
que em valores NUMBER.
BOOLEAN Tipo básico que armazena um dos três valores possíveis usados em
cálculos lógicos: TRUE, FALSE e NULL.
BINARY_FLOAT Representa número de ponto flutuante no formato IEEE 754.
Necessita de 5 bytes para armazenar o valor.

BINARY_DOUBLE Representa número de ponto flutuante no formato IEEE 754.


Necessita de 9 bytes para armazenar o valor.

Oracle Database: Fundamentos de PL/SQL 2 - 18


Tipos Básicos de Dados Escalares

• DATE
• TIMESTAMP
• TIMESTAMP WITH TIME ZONE
• TIMESTAMP WITH LOCAL TIME ZONE
• INTERVAL YEAR TO MONTH
• INTERVAL DAY TO SECOND

2 - 19 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Tipos Básicos de Dados Escalares (continuação)

Tipo de Dados Descrição


DATE Tipo básico para datas e horários. Os valores DATE incluem o horário do dia em
segundos, desde a meia-noite. A faixa para datas está entre 4712 AC e 9999 DC.
TIMESTAMP O tipo de dados TIMESTAMP, que expande DATE, armazena ano, mês, dia, hora,
minuto, segundo e fração de segundo. A sintaxe é
TIMESTAMP[(precision)], onde o parâmetro opcional precision
especifica o número de dígitos na parte fracional do campo de segundos. Para
especificar a precisão, você deve usar um número inteiro na faixa 0–9. O default é
6.
TIMESTAMP WITH O tipo de dados TIMESTAMP WITH TIME ZONE, que expande TIMESTAMP,
TIME ZONE inclui um deslocamento de fuso horário. O deslocamento de fuso horário é a
diferença (em horas e minutos) entre o horário local e o UTC (Coordinated
Universal Time), conhecido antigamente como GMT (Greenwich Mean Time). A
sintaxe é TIMESTAMP[(precision)] WITH TIME ZONE, onde o parâmetro
opcional precision especifica o número de dígitos na parte fracional do campo
de segundos. Para especificar a precisão, você deve usar um número inteiro na
faixa 0–9. O default é 6.

Oracle Database: Fundamentos de PL/SQL 2 - 19


Tipos Básicos de Dados Escalares (continuação)
Tipo de Dados Descrição
TIMESTAMP WITH O tipo de dados TIMESTAMP WITH LOCAL TIME ZONE, que expande
LOCAL TIME ZONE TIMESTAMP, inclui um deslocamento de fuso horário. O deslocamento de
fuso horário é a diferença (em horas e minutos) entre o horário local e o UTC
(Coordinated Universal Time), conhecido antigamente como GMT
(Greenwich Mean Time). A sintaxe é TIMESTAMP[(precision)] WITH
LOCAL TIME ZONE, onde o parâmetro opcional precision especifica o
número de dígitos na parte fracional do campo de segundos. Não é possível
usar uma constante simbólica ou uma variável para especificar o parâmetro
precision; você deve usar um inteiro literal na faixa 0-9. O default é 6.
Este tipo de dados difere de TIMESTAMP WITH TIME ZONE porque se você
inserir um valor em uma coluna do banco de dados, o valor será normalizado
para o fuso horário do banco de dados, e o deslocamento de fuso horário não
será armazenado na coluna. Quando você recuperar o valor, o servidor Oracle
retornará esse valor no fuso horário da sua sessão local.
INTERVAL YEAR Use o tipo de dados INTERVAL YEAR TO MONTH para armazenar e
TO MONTH manipular intervalos de anos e meses. A sintaxe é INTERVAL
YEAR[(precision)] TO MONTH, onde precision especifica o número
de dígitos para o campo de ano. Não é possível usar uma constante simbólica
ou uma variável para especificar o parâmetro precision; você deve usar um
inteiro literal na faixa 0-4. O default é 2.
INTERVAL DAY TO Use o tipo de dados INTERVAL DAY TO SECOND para armazenar e
SECOND manipular intervalos de dias, horas, minutos e segundos. A sintaxe é
INTERVAL DAY[(precision1)] TO SECOND[(precision2)],
onde precision1 e precision2 especificam o número de dígitos no
campo de dias e no campo de segundos, respectivamente. Em ambos os casos,
não é possível usar uma constante simbólica ou uma variável para especificar
o parâmetro precision; você deve usar um inteiro literal na faixa 0-9. Os
defaults são 2 e 6, respectivamente.

Oracle Database: Fundamentos de PL/SQL 2 - 20


Declarando Variáveis Escalares

Exemplos:

DECLARE
v_emp_job VARCHAR2(9);
v_count_loop BINARY_INTEGER := 0;
v_dept_total_sal NUMBER(9,2) := 0;
v_orderdate DATE := SYSDATE + 7;
c_tax_rate CONSTANT NUMBER(3,2) := 8.25;
v_valid BOOLEAN NOT NULL := TRUE;
...

2 - 21 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Declarando Variáveis Escalares


Os exemplos de declaração de variável mostrados no slide são definidos assim:
• v_emp_job: Variável para armazenar o cargo de um funcionário
• v_count_loop: Variável para contar as iterações de um loop; inicializada em 0
• v_dept_total_sal: Variável para acumular o salário total de um departamento;
inicializada como 0
• v_orderdate: Variável para armazenar a data de entrega de um pedido; inicializada em
uma semana a partir de hoje
• c_tax_rate: Variável constante para a alíquota de imposto (que nunca muda no
decorrer do bloco PL/SQL); definida como 8.25
• v_valid: Flag para indicar se um componente dos dados é válido ou não; inicializada
como TRUE

Oracle Database: Fundamentos de PL/SQL 2 - 21


Atributo %TYPE

• É usado para declarar uma variável de acordo com:


– Uma definição de coluna do banco de dados
– Outra variável declarada
• Tem como prefixo:
– A tabela do banco de dados e o nome da coluna
– O nome da variável declarada

2 - 22 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Atributo %TYPE
Em geral, as variáveis PL/SQL são declaradas para conter e manipular dados armazenados no
banco de dados. Ao declarar variáveis PL/SQL para armazenar valores de colunas, assegure-se
de que a variável tenha o tipo de dados e a precisão corretos. Caso contrário, ocorrerá um erro
PL/SQL durante a execução. Se você precisar projetar subprogramas extensos, isso poderá tomar
muito tempo e gerar erros.
Em vez de codificar o tipo de dados e a precisão de uma variável, você pode usar o atributo
%TYPE
para declarar uma variável de acordo com outra variável ou
coluna do banco de dados declarada anteriormente. O atributo %TYPE é usado com mais
frequência quando o valor armazenado na variável tem origem em uma tabela do banco de
dados. Se usar o atributo %TYPE para declarar uma variável, você deverá prefixá-lo com a tabela
do banco de dados e o nome da coluna. Caso você faça referência a uma variável previamente
declarada, use como prefixo o nome da variável declarada anteriormente na variável que está
sendo declarada.

Oracle Database: Fundamentos de PL/SQL 2 - 22


Atributo %TYPE (continuação)
Vantagens do Atributo %TYPE
• Você pode evitar erros causados por incompatibilidade de tipo de dados ou precisão errada.
• Você pode evitar a codificação do tipo de dados de uma variável.
• Não será necessário trocar a declaração da variável se a definição da coluna for trocada. Se
você já tiver declarado algumas variáveis para determinada tabela sem usar o atributo
%TYPE, talvez o bloco PL/SQL acione erros caso a coluna para a qual a variável foi
declarada tenha sido alterada. Se você usar o atributo %TYPE, o código PL/SQL
determinará o tipo de dados e o tamanho da variável quando o bloco for compilado. Isso
assegura que essa variável seja sempre compatível com a coluna que é usada para
preenchê-la.

Oracle Database: Fundamentos de PL/SQL 2 - 23


Declarando Variáveis
com o Atributo %TYPE
Sintaxe

identifier table.column_name%TYPE;

Exemplos

...
v_emp_lname employees.last_name%TYPE;
...

...
v_balance NUMBER(7,2);
v_min_balance v_balance%TYPE := 1000;
...

2 - 24 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Declarando Variáveis com o Atributo %TYPE


Declare variáveis para armazenar o sobrenome de um funcionário. A variável v_emp_lname é
definida para ser do mesmo tipo de dados que a coluna v_last_name da tabela employees.
O atributo %TYPE fornece o tipo de dados de uma coluna do banco de dados.
Declare variáveis para armazenar o saldo de uma conta bancária, assim como o saldo mínimo,
que é 1.000. A variável v_min_balance é definida para ser do mesmo tipo de dados que a
variável v_balance. O atributo %TYPE fornece o tipo de dados de uma variável.
Uma constraint de coluna de banco de dados NOT NULL não se aplica a variáveis que são
declaradas com %TYPE. Portanto, se você declarar uma variável usando o atributo %TYPE que
usa uma coluna do banco de dados definida como NOT NULL, poderá designar o valor NULL à
variável.

Oracle Database: Fundamentos de PL/SQL 2 - 24


Declarando Variáveis Booleanas

• Somente os valores TRUE, FALSE e NULL podem ser


atribuídos a uma variável booleana.
• As expressões condicionais usam os operadores lógicos
AND e OR e o operador unário NOT para verificar os valores
da variável.
• As variáveis sempre retornam TRUE, FALSE ou NULL.
• As expressões aritméticas, de caractere ou de data podem
ser usadas para retornar um valor booleano.

2 - 25 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Declarando Variáveis Booleanas


Com o código PL/SQL, é possível comparar variáveis em instruções SQL e procedurais. Essas
comparações, chamadas de expressões booleanas, consistem em expressões simples ou
complexas separadas por operadores relacionais. Em uma instrução SQL, é possível usar
expressões booleanas para especificar as linhas de uma tabela que são afetadas pela instrução.
Em uma instrução procedural, as expressões booleanas são a base do controle condicional.
NULL significa um valor ausente, não aplicável ou desconhecido.
Exemplos
emp_sal1 := 50000;
emp_sal2 := 60000;
A seguinte expressão retorna TRUE:
emp_sal1 < emp_sal2
Declare e inicialize uma variável booleana:
DECLARE
flag BOOLEAN := FALSE;
BEGIN
flag := TRUE;
END;
/

Oracle Database: Fundamentos de PL/SQL 2 - 25


Variáveis do Tipo de Dados LOB

Livro
(CLOB)

Foto
(BLOB)

Filme
(BFILE)

NCLOB

2 - 26 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Variáveis do Tipo de Dados LOB


Os LOBs (large objects) destinam-se a armazenar uma grande quantidade de dados. Uma coluna
do banco de dados pode ser da categoria LOB. Com a categoria LOB de tipos de dados (BLOB,
CLOB, e assim por diante) , você pode armazenar blocos de dados não estruturados (como texto,
imagens gráficas, videoclipes e formas de ondas sonoras) de até 128 terabytes, dependendo do
tamanho do bloco do banco de dados. Os tipos de dados LOB permitem um acesso eficaz,
aleatório e em nível de componente aos dados e podem ser atributos de um tipo de objeto.
• O tipo de dados CLOB (character large object) é usado para armazenar blocos grandes de
dados de caracteres no banco de dados.
• O tipo de dados BLOB (binary large object) é usado para armazenar objetos grandes
estruturados ou não no banco de dados. Quando você insere tais dados no banco de dados
ou os recupera de lá, o banco de dados não interpreta os dados. As aplicações externas que
utilizam esses dados devem interpretá-los.
• O tipo de dados BFILE (binary file) é usado para armazenar arquivos binários grandes.
Diferentemente de outros LOBs, BFILES são armazenados fora do banco de dados e não
dentro deles. Eles podem ser arquivos do sistema operacional. No banco de dados, será
armazenado apenas um ponteiro para o BFILE.
• O tipo de dados NCLOB (national language character large object) é usado para armazenar
blocos grandes de dados unicode NCHAR single-byte ou multibyte no banco de dados.

Oracle Database: Fundamentos de PL/SQL 2 - 26


Tipos de Dados Compostos: Registros e Conjuntos
Registro PL/SQL:

TRUE 23-DEC-98 ATLANTA

Conjuntos PL/SQL:

1 SMITH 1 5000
2 JONES 2 2345
3 NANCY 3 12
4 TIM 4 3456

VARCHAR2 NUMBER
PLS_INTEGER PLS_INTEGER

2 - 27 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Tipos de Dados Compostos: Registros e Conjuntos


Como mencionado anteriormente, um tipo de dados escalar armazena um único valor e não
possui componentes internos. Tipos de dados compostos — chamados Registros PL/SQL e
Conjuntos PL/SQL — têm componentes internos que você pode tratar como variáveis
individuais.
• Em um registro PL/SQL, os componentes internos podem ser de tipos de dados diferentes e
são chamados campos. Você acessa cada campo com esta sintaxe:
record_name.field_name. Uma variável de registro pode armazenar uma linha de
tabela ou algumas colunas de uma linha de tabela. Cada campo de registro corresponde a
uma coluna da tabela.
• Em um conjunto PL/SQL, os componentes internos são sempre do mesmo tipo de dados e
são chamados elementos. Acesse cada elemento por seu subscript exclusivo. Listas e arrays
são exemplos clássicos de conjuntos. Há três tipos de conjuntos PL/SQL: Arrays
Associativos, Tabelas Aninhadas e VARRAY.
Observação
• Registros PL/SQL e Arrays Associativos são abordados nesta lição: “Trabalhando com
Tipos de Dados Compostos”.
• Os tipos de dados NESTED TABLE e VARRAY são abordados no curso intitulado Oracle
Database 10g: Advanced PL/SQL ou Oracle Database 11g: Advanced PL/SQL.

Oracle Database: Fundamentos de PL/SQL 2 - 27


Agenda

• Apresentando variáveis
• Examinando tipos de dados de variável e o atributo
%TYPE
• Examinando variáveis de bind

2 - 28 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 2 - 28


Variáveis de Bind

As variáveis de bind são:


• Criadas no ambiente
• Também chamadas de variáveis de host
• Criadas com a palavra-chave* VARIABLE
• Usadas em instruções SQL e blocos PL/SQL
• Acessadas mesmo após a execução do bloco PL/SQL
• Precedidas por dois-pontos quando referenciadas
Os valores podem ser exibidos com o comando PRINT.
* Necessárias na utilização do SQL*Plus e SQL Developer

2 - 29 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Variáveis de Bind
As variáveis de bind são as criadas em um ambiente de host. Por esse motivo, às vezes elas são
chamadas de variáveis de host.
Usos de Variáveis de Host
As variáveis de bind são criadas no ambiente e não na seção declarativa de um bloco
PL/SQL. Portanto, as variáveis de bind são acessíveis mesmo após a execução do bloco. Quando
criadas, as variáveis de bind podem ser usadas e manipuladas por vários subprogramas. Elas
podem ser usadas em instruções SQL e blocos PL/SQL como qualquer outra variável. Essas
variáveis podem ser especificadas como valores de runtime para subprogramas PL/SQL ou
podem ser retornadas por eles.
Observação: Uma variável de bind é de ambiente, mas não é uma variável global.
Criando Variáveis de Bind
Para criar uma variável de bind no SQL Developer, use o comando VARIABLE. Por exemplo,
declare uma variável do tipo NUMBER e VARCHAR2 assim:
VARIABLE return_code NUMBER
VARIABLE return_msg VARCHAR2(30)
Exibindo Valores em Variáveis de Bind
É possível fazer referência à variável de bind usando o SQL Developer e exibir seu valor usando
o comando PRINT.
Oracle Database: Fundamentos de PL/SQL 2 - 29
Variáveis de Bind (continuação)
Exemplo
É possível fazer referência a uma variável de bind em um programa PL/SQL colocando dois-
pontos antes da variável.
Por exemplo, o bloco PL/SQL a seguir cria e usa a variável de bind b_result. A saída
resultante do comando PRINT é mostrado abaixo do código.

VARIABLE b_result NUMBER


BEGIN
SELECT (SALARY*12) + NVL(COMMISSION_PCT,0) INTO :b_result
FROM employees WHERE employee_id = 144;
END;
/
PRINT b_result

Observação: Se você estiver criando uma variável de bind do tipo NUMBER, não será possível
especificar a precisão e a escala. No entanto, é possível especificar o tamanho de strings de
caracteres. Um NUMBER do Oracle é armazenado da mesma forma, qualquer que seja a sua
dimensão. O Oracle Server usa o mesmo número de bytes para armazenar 7, 70 e .0734. Não é
conveniente calcular o tamanho da representação numérica Oracle partindo do formato do
número, por isso o código sempre aloca os bytes necessários. Com strings de caracteres, o
usuário tem que especificar o tamanho para que o número de bytes necessário possa ser alocado.

Oracle Database: Fundamentos de PL/SQL 2 - 30


Fazendo Referência a Variáveis de Bind

Exemplo:
VARIABLE b_emp_salary NUMBER
BEGIN
SELECT salary INTO :b_emp_salary
FROM employees WHERE employee_id = 178;
END;
/
PRINT b_emp_salary
SELECT first_name, last_name
FROM employees
WHERE salary=:b_emp_salary;

Saída

2 - 31 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Fazendo Referência a Variáveis de Bind


Como mencionado anteriormente, depois de criar uma variável de bind, você pode fazer
referência a ela em qualquer instrução SQL ou programa PL/SQL.
No exemplo, a variável b_emp_salary é criada como uma variável de bind no bloco
PL/SQL. Em seguida, ela é usada na próxima instrução SELECT.
Se você executar o bloco PL/SQL mostrado no slide, obterá a seguinte saída:
• O comando PRINT executa:
b_emp_salary
------------------
7000
• Em seguida, a saída da instrução SQL é:
FIRST_NAME LAST_NAME
------------------ ----------------------
Oliver Tuvault
Sarath Sewall
Kimberely Grant
Observação: Para exibir todas as variáveis de bind, use o comando PRINT sem uma variável.

Oracle Database: Fundamentos de PL/SQL 2 - 31


Usando AUTOPRINT com Variáveis de Bind

2 - 32 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Usando AUTOPRINT com Variáveis de Bind


Use o comando SET AUTOPRINT ON para exibir automaticamente as variáveis de bind usadas
em um bloco PL/SQL bem-sucedido.
Exemplo
No código de exemplo:
• Uma variável de bind chamada b_emp_salary é criada e AUTOPRINT é ativado.
• Uma variável chamada v_empno é declarada e uma variável de substituição é usada para
receber a entrada do usuário.
• Por último, a variável de bind e as variáveis temporárias são usadas na seção executável do
bloco PL/SQL.
Quando um número de funcionário válido é informado — neste caso, 178 — a saída da variável
de bind é automaticamente impressa. A variável de bind contém o salário referente ao número
do funcionário que o usuário fornece.

Oracle Database: Fundamentos de PL/SQL 2 - 32


Questionário

O atributo %TYPE:
a. É usado para declarar uma variável de acordo com uma
definição de coluna do banco de dados
b. É usado para declarar uma variável de acordo com um
conjunto de colunas de uma tabela ou view do banco de
dados
c. É usado para declarar uma variável de acordo com a
definição de outra variável declarada
d. Tem como prefixo o nome da tabela do banco de dados e
o nome da coluna ou da variável declarada

2 - 33 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Resposta: a, c, d
O Atributo %TYPE
Em geral, as variáveis PL/SQL são declaradas para conter e manipular dados armazenados no
banco de dados. Ao declarar variáveis PL/SQL para armazenar valores de colunas, assegure-se
de que a variável tenha o tipo de dados e a precisão corretos. Caso contrário, ocorrerá um erro
PL/SQL durante a execução. Se você precisar projetar subprogramas extensos, isso poderá tomar
muito tempo e gerar erros.
Em vez de codificar o tipo de dados e a precisão de uma variável, você pode usar o atributo
%TYPE
para declarar uma variável de acordo com outra variável ou
coluna do banco de dados declarada anteriormente. O atributo %TYPE é usado com mais
frequência quando o valor armazenado na variável tem origem em uma tabela do banco de
dados. Se usar o atributo %TYPE para declarar uma variável, você deverá prefixá-lo com a tabela
do banco de dados e o nome da coluna. Caso você faça referência a uma variável previamente
declarada, use como prefixo o nome da variável declarada anteriormente na variável que está
sendo declarada. A vantagem de %TYPE é que não será necessário alterar a variável caso a
coluna seja alterada. Além disso, se a variável for usada em um cálculo, você não precisará se
preocupar com a sua precisão.
O Atributo %ROWTYPE
O atributo %ROWTYPE é usado para declarar um registro que possa armazenar uma linha inteira
de uma tabela ou view. Você aprenderá sobre esse atributo na lição “Trabalhando com Tipos de
Dados Compostos.”
Oracle Database: Fundamentos de PL/SQL 2 - 33
Sumário

Nesta lição, você aprendeu a:


• Reconhecer identificadores válidos e inválidos
• Declarar variáveis na seção declarativa de um bloco
PL/SQL
• Inicializar variáveis e utilizá-las na seção executável
• Diferenciar tipos de dados escalares e compostos
• Usar o atributo %TYPE
• Usar variáveis de bind

2 - 34 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Sumário
Um bloco PL/SQL anônimo é uma unidade básica não nomeada de um programa PL/SQL. Ele
consiste em um conjunto de instruções SQL ou PL/SQL para executar uma função lógica. A
parte declarativa é a primeira parte de um bloco PL/SQL e é usada para declarar objetos como
variáveis, constantes, cursores e definições de situações de erro chamadas de exceções.
Nesta lição, você aprendeu a declarar variáveis na seção declarativa. Você conheceu algumas
diretrizes para declaração de variáveis. E aprendeu a inicializar variáveis ao declará-las.
A parte executável de um bloco PL/SQL é a parte obrigatória e contém instruções SQL e
PL/SQL para consultar e manipular dados. Você aprendeu a inicializar variáveis na seção
executável, a como utilizá-las e a manipular seus valores.

Oracle Database: Fundamentos de PL/SQL 2 - 34


Exercício 2: Visão Geral

Este exercício aborda os seguintes tópicos:


• Definição de identificadores válidos
• Definição de declarações de variáveis válidas
• Declaração de variáveis dentro de um bloco anônimo
• Uso do atributo %TYPE para declarar variáveis
• Declaração e exibição de uma variável de bind
• Execução de um bloco PL/SQL

2 - 35 Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Exercício 2: Visão Geral


Os exercícios 1, 2 e 3 são impressos.

Oracle Database: Fundamentos de PL/SQL 2 - 35


Criando Instruções Executáveis

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.
Objetivos

Ao concluir esta lição, você será capaz de:


• Identificar as unidades lexicais de um bloco PL/SQL
• Usar funções SQL predefinidas no código PL/SQL
• Descrever quando ocorrem conversões implícitas e
quando conversões explícitas devem ser usadas
• Criar blocos aninhados e qualificar variáveis com labels
• Criar código legível com recuos adequados
• Usar sequências em expressões PL/SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Objetivos
Você aprendeu a declarar variáveis e criar instruções executáveis em um bloco PL/SQL. Nesta
lição, você aprenderá como as unidades lexicais formam um bloco PL/SQL. Você aprenderá a
criar blocos aninhados. Você também aprenderá sobre o escopo e a visibilidade das variáveis nos
blocos aninhados e a qualificar variáveis com labels.

Oracle Database: Fundamentos de PL/SQL 3 - 2


Agenda

• Criando instruções executáveis em um bloco PL/SQL


• Criando blocos aninhados
• Usando operadores e desenvolvendo código legível

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 3 - 3


Unidades Lexicais de um Bloco PL/SQL

Unidades lexicais:
• São blocos de construção para qualquer bloco PL/SQL
• São sequências de caracteres, incluindo letras, dígitos,
tabulações, espaços, quebras de linha e símbolos
• Podem ser classificadas como:
– Identificadores: v_fname, c_percent
– Delimitadores: ; , +, -
– Literais: John, 428, True
– Comentários: --, /* */

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Unidades Lexicais de um Bloco PL/SQL


As unidades lexicais incluem letras, números, caracteres especiais, tabulações, espaços, quebras
de linha e símbolos.
• Identificadores: Os identificadores são os nomes dados aos objetos PL/SQL. Você
aprendeu a reconhecer identificadores válidos e inválidos. Lembre-se de que as palavras-
chave não podem ser usadas como identificadores.
Identificadores entre aspas:
- Fazem os identificadores distinguirem entre maiúsculas e minúsculas.
- Incluem caracteres, como espaços.
- Usam palavras reservadas.
Exemplos:
"begin date" DATE;
"end date" DATE;
"exception thrown" BOOLEAN DEFAULT TRUE;
Todos os usos subsequentes dessas variáveis deverão ter aspas duplas. No entanto, o uso de
identificadores entre aspas não é recomendado.
• Delimitadores: Os delimitadores são símbolos que têm significado especial. Você já
aprendeu que o ponto e vírgula (;) é usado para encerrar uma instrução SQL ou PL/SQL.
Portanto, ; é um exemplo de delimitador.
Para obter mais informações, consulte PL/SQL User’s Guide and Reference.
Oracle Database: Fundamentos de PL/SQL 3 - 4
Unidades Lexicais de um Bloco PL/SQL (continuação)
• Delimitadores (continuação)
Os delimitadores são símbolos simples ou compostos que têm significado especial em
blocos PL/SQL.
Símbolos simples
Símbolo Significado
+ Operador de adição
- Operador de subtração/de negativo
* Operador de multiplicação
/ Operador de divisão
= Operador de igualdade
@ Indicador de acesso remoto
; Finalizador de instrução

Símbolos compostos
Símbolo Significado
<> Operador de desigualdade
!= Operador de desigualdade
|| Operador de concatenação
-- Indicador de comentário de uma única linha
/* Delimitador de início de comentário
*/ Delimitador de fim de comentário
:= Operador de designação

Observação: Esse é apenas um subconjunto, e não uma lista completa dos delimitadores.
• Literais: Qualquer valor designado a uma variável é um literal. Qualquer valor de
caractere, numérico, booleano ou de data que não seja um identificador é um literal. Os
literais são classificados como:
- Literais de caractere: Todos os literais de string têm o tipo de dados CHAR ou
VARCHAR2 e são, portanto, chamados de literais de caractere (por exemplo, John e
12C).
- Literais numéricos: Um literal numérico representa um valor inteiro ou real (por
exemplo, 428 e1.276).
- Literais booleanos: Os valores designados a variáveis booleanas são literais
booleanos. TRUE, FALSE e NULL são literais booleanos ou palavras-chave.
• Comentários: Em programação, convém explicar o que um trecho de código está tentando
obter. No entanto, quando você inclui a explicação em um bloco PL/SQL, o compilador
não pode interpretar essas instruções. Portanto, deve haver um modo de indicar que essas
instruções não precisam ser compiladas. Os comentários são usados principalmente com
essa finalidade. Qualquer instrução comentada não será interpretada pelo compilador.
- Dois hífens (--) são usados para uma única linha de comentário.
- Os delimitadores inicial e final do comentário (/* e*/) são usados para comentar
várias linhas.
Oracle Database: Fundamentos de PL/SQL 3 - 5
Diretrizes e Sintaxe de Blocos PL/SQL

• Usando Literais
– Os literais de caractere e de data devem ser delimitados por aspas simples.
– Os números podem estar em valores simples ou em notação científica.
v_name := 'Henderson';
• Formatando código: as instruções podem abranger várias linhas.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Diretrizes e Sintaxe de Blocos PL/SQL


Usando Literais
Um literal é um valor explícito numérico, de string de caracteres, de data ou booleano que não é
representado por um identificador.
• Os literais de caracteres incluem todos os caracteres imprimíveis no conjunto de caracteres
PL/SQL: letras, números, espaços e símbolos especiais.
• Os literais numéricos podem ser representados por um simples valor (por exemplo, –
32.5) ou em notação científica (por exemplo, 2E5 significa 2 * 105 = 200.000).
Formatando Código
Em um bloco PL/SQL, uma instrução SQL pode abranger várias linhas (como mostrado no
exemplo 3 do slide).
Você pode formatar uma instrução SQL não formatada (como mostrado no exemplo 1 do slide)
usando o menu de atalho SQL Worksheet. Clique com o botão direito do mouse na SQL
Worksheet ativa e, no menu de atalho que aparecer, selecione a opção Format (como mostrado
no exemplo 2).
Observação: Também é possível usar a combinação de teclas de atalho Ctrl + F7 para formatar
o código.

Oracle Database: Fundamentos de PL/SQL 3 - 6


Comentando o Código

• Inicie os comentários de uma única linha com dois hífens


(--).
• Coloque um comentário em bloco entre os símbolos /* e
*/.
Exemplo:
DECLARE
...
v_annual_sal NUMBER (9,2);
BEGIN
/* Compute the annual salary based on the
monthly salary input from the user */
v_annual_sal := monthly_sal * 12;
--The following line displays the annual salary
DBMS_OUTPUT.PUT_LINE(v_annual_sal);
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Comentando o Código
Comente o código para documentar cada fase e para ajudar a depuração. No código PL/SQL:
• Normalmente, o comentário de uma única linha é iniciado por dois hífens (--)
• Você também pode colocar um comentário entre os símbolos /* e */
Observação: No caso de comentários de várias linhas, você pode iniciar cada linha do
comentário com dois hífens ou usar o formato de comentário em bloco.
Os comentários são estritamente informativos e não impõem condições ou comportamento na
lógica ou nos dados. Comentários bem colocados são extremamente importantes para a
legibilidade do código e a sua manutenção futura.

Oracle Database: Fundamentos de PL/SQL 3 - 7


Funções SQL no Código PL/SQL

• Disponíveis em instruções procedurais:


– Funções de uma única linha
• Não disponíveis em instruções procedurais:
– DECODE
– Funções de grupo

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Funções SQL no Código PL/SQL


O código SQL oferece várias funções predefinidas que podem ser usadas em instruções SQL. A
maioria delas (como funções de uma única linha de número e caractere, de conversão de tipo de
dados e de data e timestamp) é válida em expressões PL/SQL.
Estas funções não estão disponíveis em instruções procedurais:
• DECODE
• Funções de grupo: AVG, MIN, MAX, COUNT, SUM, STDDEV e VARIANCE
As funções de grupo aplicam-se a grupos de linhas de uma tabela e, por isso, estão
disponíveis apenas em instruções SQL de um bloco PL/SQL. As funções aqui mencionadas
são apenas um subconjunto da lista completa.

Oracle Database: Fundamentos de PL/SQL 3 - 8


Funções SQL no Código PL/SQL: Exemplos

• Obter o tamanho de uma string:


v_desc_size INTEGER(5);
v_prod_description VARCHAR2(70):='You can use this
product with your radios for higher frequency';

-- get the length of the string in prod_description


v_desc_size:= LENGTH(v_prod_description);

• Obtenha o número de meses que um funcionário


trabalhou:
v_tenure:= MONTHS_BETWEEN (CURRENT_DATE, v_hiredate);

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Funções SQL no Código PL/SQL: Exemplos


É possível usar funções SQL para manipular dados. Essas funções estão agrupadas nas seguintes
categorias:
• Número
• Caractere
• Conversão
• Data
• Diversos

Oracle Database: Fundamentos de PL/SQL 3 - 9


Usando Sequências em Expressões PL/SQL

Iniciando no 11g:
DECLARE
v_new_id NUMBER;
BEGIN
v_new_id := my_seq.NEXTVAL;
END;
/

Antes do 11g:
DECLARE
v_new_id NUMBER;
BEGIN
SELECT my_seq.NEXTVAL INTO v_new_id FROM Dual;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Acessando Valores de Sequência


No Oracle Database 11g, você pode usar as pseudocolunas NEXTVAL e CURRVAL em qualquer
contexto PL/SQL, no qual uma expressão de tipo de dados NUMBER possa ser exibida
legalmente. Embora o estilo antigo de utilização de uma instrução SELECT para consultar uma
sequência ainda seja válido, é recomendável não utilizá-lo.
Antes do lançamento do Oracle Database 11g, era obrigatório que você criasse uma instrução
SQL para usar um valor de objeto de sequência em uma subrotina PL/SQL. Normalmente, você
cria uma instrução SELECT para fazer referência às pseudocolunas NEXTVAL e CURRVAL a
fim de obter um número de sequência. Esse método criava um problema de utilização.
No Oracle Database 11g, a limitação da obrigatoriedade da criação de uma instrução SQL para
recuperar um valor de sequência é eliminada. Com o recurso de aprimoramento da sequência:
• A utilização da sequência é aprimorada
• O desenvolvedor digita menos
• O código resultante é mais claro

Oracle Database: Fundamentos de PL/SQL 3 - 10


Conversão de Tipo de Dados

• Converte dados em tipos de dados comparáveis


• É de dois tipos:
– Conversão implícita
– Conversão explícita
• Funções:
– TO_CHAR
– TO_DATE
– TO_NUMBER
– TO_TIMESTAMP

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Conversão de Tipo de Dados


Em qualquer linguagem de programação, converter um tipo de dados em outro é um requisito
importante. O código PL/SQL pode tratar dessas conversões com tipos de dados escalares. As
conversões de tipo de dados podem ser de dois tipos:
Conversões implícitas: O código PL/SQL tentará converter os tipos de dados dinamicamente se
eles estiverem misturados em uma instrução. Considere o seguinte exemplo:
DECLARE
v_salary NUMBER(6):=6000;
v_sal_hike VARCHAR2(5):='1000';
v_total_salary v_salary%TYPE;
BEGIN
v_total_salary:=v_salary + v_sal_hike;
END;
/
Nesse exemplo, a variável sal_hike é do tipo VARCHAR2. Ao calcular o salário total, o
código PL/SQL primeiro converterá sal_hike em NUMBER e, em seguida, realizará a
operação. O resultado é do tipo NUMBER.
As conversões implícitas podem acontecer entre:
• Caracteres e números
• Caracteres e datas

Oracle Database: Fundamentos de PL/SQL 3 - 11


Conversão de Tipo de Dados (continuação)
Conversões explícitas Para converter valores de um tipo de dados para outro, use funções
predefinidas. Por exemplo, para converter um valor CHAR em um valor DATE ou NUMBER, use
TO_DATE ou TO_NUMBER, respectivamente.

Oracle Database: Fundamentos de PL/SQL 3 - 12


Conversão de Tipo de Dados

-- implicit data type conversion


1 v_date_of_joining DATE:= '02-Feb-2000';

-- error in data type conversion


2 v_date_of_joining DATE:= 'February 02,2000';

-- explicit data type conversion


3 v_date_of_joining DATE:= TO_DATE('February
02,2000','Month DD, YYYY');

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Conversão de Tipo de Dados (continuação)


Observe os três exemplos de conversões implícitas e explícitas do tipo de dados DATE do slide:
1. Como a literal de string designada à variável date_of_joining está no formato
default, este exemplo executa a conversão implícita e designa a data especificada à
date_of_joining.
2. O código PL/SQL retorna um erro porque a data que está sendo designada não está no
formato default.
3. A função TO_DATE é usada para converter explicitamente a data determinada em um
formato específico e designá-la ao tipo de dados DATE com a variável
date_of_joining.

Oracle Database: Fundamentos de PL/SQL 3 - 13


Agenda

• Criando instruções executáveis em um bloco PL/SQL


• Criando blocos aninhados
• Usando operadores e desenvolvendo código legível

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 3 - 14


Blocos Aninhados

Os blocos PL/SQL podem ser aninhados.


• Uma seção executável (BEGIN …
END) pode conter blocos aninhados.
• Uma seção de exceções pode conter
blocos aninhados.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Blocos Aninhados
Por ser procedural, a linguagem PL/SQL permite aninhar instruções. É possível aninhar blocos
onde quer que uma instrução executável seja permitida, transformando, então, o bloco aninhado
em uma instrução. Se a seção executável tiver código para muitas funcionalidades logicamente
relacionadas para suportar vários requisitos de negócios, você poderá dividir a seção executável
em blocos menores. A seção de exceções também pode conter blocos aninhados.

Oracle Database: Fundamentos de PL/SQL 3 - 15


Blocos Aninhados: Exemplo

DECLARE
v_outer_variable VARCHAR2(20):='GLOBAL VARIABLE';
BEGIN
DECLARE
v_inner_variable VARCHAR2(20):='LOCAL VARIABLE';
BEGIN
DBMS_OUTPUT.PUT_LINE(v_inner_variable);
DBMS_OUTPUT.PUT_LINE(v_outer_variable);
END;
DBMS_OUTPUT.PUT_LINE(v_outer_variable);
END;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Blocos Aninhados (continuação)


O exemplo mostrado no slide tem um bloco externo (pai) e um bloco aninhado (filho). A
variável v_outer_variable é declarada no bloco externo e a variável
v_inner_variable é declarada no bloco interno.
A variável v_outer_variable é local no bloco externo, mas é global no bloco interno. Se
você acessar essa variável no bloco interno, o código PL/SQL primeiro procurará uma variável
local no bloco interno com esse nome. Não há variável com o mesmo nome no bloco interno,
por isso o PL/SQL procura a variável no bloco externo. Portanto, v_outer_variable é
considerada a variável global para todos os blocos que contêm outros. Essa variável pode ser
acessada nos blocos internos como é mostrado no slide. As variáveis declaradas em um bloco
PL/SQL são consideradas locais para aquele bloco e globais para todos os seus sub-blocos.
A variável v_inner_variable é local para o bloco interno e não é global porque o bloco
interno não possui blocos aninhados. Essa variável só pode ser acessada dentro do bloco interno.
Se o bloco PL/SQL não encontrar a variável declarada localmente, ele procurará acima na seção
declarativa dos blocos pais. O bloco PL/SQL não procura de cima para baixo, na direção dos
blocos filhos.

Oracle Database: Fundamentos de PL/SQL 3 - 16


Escopo e Visibilidade da Variável

DECLARE
v_father_name VARCHAR2(20):='Patrick';
v_date_of_birth DATE:='20-Apr-1972';
BEGIN
DECLARE
v_child_name VARCHAR2(20):='Mike';
v_date_of_birth DATE:='12-Dec-2002';
BEGIN
DBMS_OUTPUT.PUT_LINE('Father''s Name: '||v_father_name);
DBMS_OUTPUT.PUT_LINE('Date of Birth: '||v_date_of_birth);
DBMS_OUTPUT.PUT_LINE('Child''s Name: '||v_child_name);
END;
DBMS_OUTPUT.PUT_LINE('Date of Birth: '||v_date_of_birth);
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Escopo e Visibilidade da Variável


A saída do bloco mostrado no slide é a seguinte:
anonymous block completed
Father's Name: Patrick
Date of Birth: 12.12.02
Child's Name: Mike
Date of Birth: 20.04.72
Examine a data de nascimento que é impressa para pai e filho. A saída não oferece as
informações corretas porque o escopo e a visibilidade das variáveis não estão aplicadas
corretamente.
• O escopo de uma variável é a parte do programa em que a variável é declarada e está
acessível.
• A visibilidadede uma variável é a parte do programa em que a variável pode ser acessada
sem usar um qualificador.
Escopo
• A variável v_father_name e a primeira ocorrência da variável v_date_of_birth
são declaradas no bloco externo. Essas variáveis têm o escopo do bloco em que foram
declaradas. Portanto, o escopo dessas variáveis está limitado ao bloco externo.

Oracle Database: Fundamentos de PL/SQL 3 - 17


Escopo e Visibilidade da Variável (continuação)
Escopo (continuação)
• As variáveis v_child_name e v_date_of_birth são declaradas no bloco interno ou
no bloco aninhado. Essas variáveis podem ser acessadas apenas dentro do bloco aninhado,
e não no bloco externo. Quando uma variável estiver fora do escopo, o código PL/SQL
liberará a memória usada para armazenar a variável; desse modo, não será possível fazer
referência a essas variáveis.
Visibilidade
• A variável v_date_of_birth declarada no bloco externo tem escopo mesmo no bloco
interno. No entanto, essa variável não é visível no bloco interno porque ele tem uma
variável local com o mesmo nome.
1. Examine o código na seção executável do bloco PL/SQL. Você pode imprimir o
nome do pai, o nome do filho e a data de nascimento. Apenas a data de nascimento
do filho pode ser exibida aqui porque a data de nascimento do pai não é visível.
2. A data de nascimento do pai é visível no bloco externo e, portanto, pode ser
impressa.
Observação:Não é possível ter variáveis com o mesmo nome em um bloco. No entanto, como
mostrado no exemplo, é possível declarar variáveis com nome igual em dois blocos diferentes
(blocos aninhados). Os dois itens representados pelos identificadores são diferentes, e alterações
em um não afetarão o outro.

Oracle Database: Fundamentos de PL/SQL 3 - 18


Usando um Qualificador com Blocos Aninhados

BEGIN <<outer>>
DECLARE
v_father_name VARCHAR2(20):='Patrick';
v_date_of_birth DATE:='20-Apr-1972';
BEGIN
DECLARE
v_child_name VARCHAR2(20):='Mike';
v_date_of_birth DATE:='12-Dec-2002';
BEGIN
DBMS_OUTPUT.PUT_LINE('Father''s Name: '||v_father_name);
DBMS_OUTPUT.PUT_LINE('Date of Birth: '
||outer.v_date_of_birth);
DBMS_OUTPUT.PUT_LINE('Child''s Name: '||v_child_name);
DBMS_OUTPUT.PUT_LINE('Date of Birth: '||v_date_of_birth);
END;
END;
END outer;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Usando um Qualificador com Blocos Aninhados


Um qualificador é um label dado a um bloco. Você pode usar um qualificador para acessar as
variáveis que têm escopo, mas não são visíveis.
Exemplo
No código de exemplo:
• O bloco externo recebeu o label outer
• Dentro do bloco interno, o qualificador outer é usado para acessar a variável
v_date_of_birth que está declarada no bloco externo. Portanto, a data de nascimento
do pai e a do filho podem ser impressas de dentro do bloco interno.
• A saída do código do slide mostra as informações corretas:

Observação: O uso de labels não se limita ao bloco externo. Você pode pôr label em qualquer
bloco.

Oracle Database: Fundamentos de PL/SQL 3 - 19


Desafio: Determinação do Escopo de Variáveis

BEGIN <<outer>>
DECLARE
v_sal NUMBER(7,2) := 60000;
v_comm NUMBER(7,2) := v_sal * 0.20;
v_message VARCHAR2(255) := ' eligible for commission';
BEGIN
DECLARE
v_sal NUMBER(7,2) := 50000;
v_comm NUMBER(7,2) := 0;
v_total_comp NUMBER(7,2) := v_sal + v_comm;
BEGIN
1 v_message := 'CLERK not'||v_message;
outer.v_comm := v_sal * 0.30;
END;
2 v_message := 'SALESMAN'||v_message;
END;
END outer;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Desafio: Determinação do Escopo de Variáveis


Avalie o bloco PL/SQL no slide. Determine cada um dos seguintes valores, de acordo com as
regras de escopo:
1. O valor de v_message na posição 1

2. O valor de v_total_comp na posição 2

3. O valor de v_comm na posição 1

4. O valor de outer.v_comm na posição 1

5. O valor de v_comm na posição 2

6. O valor de v_message na posição 2

Oracle Database: Fundamentos de PL/SQL 3 - 20


Respostas: Determinação do Escopo de Variáveis
Estas são as respostas para as perguntas sobre escopo:
1. O valor de v_message na posição 1: CLERK not eligible for commission

2. O valor de v_total_comp na posição 2: Error. v_total_comp is not visible here


because it is defined within the inner block.

3. O valor de v_comm na posição 1: 0

4. O valor de outer.v_comm na posição 1: 12000

5. O valor de v_comm na posição 2: 15000

6. O valor de v_message na posição 2: SALESMANCLERK not eligible for commission

Oracle Database: Fundamentos de PL/SQL 3 - 21


Agenda

• Criando instruções executáveis em um bloco PL/SQL


• Criando blocos aninhados
• Usando operadores e desenvolvendo código legível

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 3 - 22


Operadores no Código PL/SQL

• Lógicos
• Aritméticos
• Concatenação Iguais aos do SQL
• Parênteses para controlar
a ordem das operações

• Operador exponencial (**)

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Operadores no Código PL/SQL


As operações dentro de uma expressão são executadas em uma ordem específica, dependendo da
precedência (prioridade) delas. A tabela a seguir mostra a ordem default das operações, da
prioridade mais alta à prioridade mais baixa.

Operator Operation
** Exponenciação
+, - Identidade, negação
*, / Multiplicação, divisão
+, -, || Adição, subtração, concatenação
=, <, >, <=, >=, <>, !=, ~=, ^=, Comparação
IS NULL, LIKE, BETWEEN, IN
NOT Negação lógica
AND Conjunção
OR Inclusão

Oracle Database: Fundamentos de PL/SQL 3 - 23


Operadores no Código PL/SQL: Exemplos

• Incrementar o contador para um loop.


loop_count := loop_count + 1;

• Definir o valor de um flag booleano.


good_sal := sal BETWEEN 50000 AND 150000;

• Validar se o número de um funcionário contém um valor.


valid := (empno IS NOT NULL);

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Operadores no Código PL/SQL (continuação)


Ao trabalhar com nulos, é possível evitar alguns erros comuns seguindo estas regras:
• Comparações envolvendo nulos sempre retornam NULL.
• A aplicação do operador lógico NOT a um nulo retorna NULL.
• Em instruções de controle condicional, se a condição retornar NULL, a sequência
de instruções associadas não será executada.

Oracle Database: Fundamentos de PL/SQL 3 - 24


Diretrizes de Programação

Facilite a manutenção do código:


• Documentando o código com comentários
• Desenvolvendo uma convenção de letras maiúsculas
e minúsculas para o código
• Desenvolvendo convenções de nomes para
identificadores e outros objetos
• Melhorando a legibilidade com o uso de recuos

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Diretrizes de Programação
Siga as diretrizes de programação mostradas no slide para produzir um código claro e reduzir a
manutenção ao desenvolver um bloco PL/SQL.
Convenções de Código
A tabela a seguir fornece diretrizes para criar código em caracteres maiúsculos ou minúsculos
para ajudar a distinguir palavras-chave de objetos nomeados.

Categoria Convenção para Exemplos


Maiúsculas/Minúsculas
Instruções SQL Letras maiúsculas SELECT, INSERT

Palavras-chave PL/SQL Letras maiúsculas DECLARE, BEGIN, IF

Tipos de dados Letras maiúsculas VARCHAR2, BOOLEAN

Identificadores e parâmetros Letras minúsculas v_sal, emp_cursor,


g_sal, p_empno
Tabelas de bancos de dados Letras minúsculas, plural employees, departments

Colunas de bancos de dados Letras minúsculas, singular employee_id,


department_id
Oracle Database: Fundamentos de PL/SQL 3 - 25
Usando Recuos no Código

Para obter clareza, use recuos para cada nível de código.

BEGIN DECLARE
IF x=0 THEN deptno NUMBER(4);
y:=1; location_id NUMBER(4);
END IF; BEGIN
END; SELECT department_id,
/ location_id
INTO deptno,
location_id
FROM departments
WHERE department_name
= 'Sales';
...
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Usando Recuos no Código


Para obter clareza e aumentar a legibilidade, use um recuo para cada nível de código. Para
mostrar a estrutura, você pode dividir as linhas usando retorno de carro e criar recuos nas linhas
usando espaços e tabulações. Compare a legibilidade das seguintes instruções IF:
IF x>y THEN max:=x;ELSE max:=y;END IF;

IF x > y THEN
max := x;
ELSE
max := y;
END IF;

Oracle Database: Fundamentos de PL/SQL 3 - 26


Questionário

Você pode usar a maioria das funções SQL de uma única


linha, como as de número, caractere, conversão e data em
expressões PL/SQL.
a. Verdadeiro
b. Falso

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Resposta: a
Funções SQL no Código PL/SQL
O código SQL oferece várias funções predefinidas que podem ser usadas em instruções SQL. A
maioria delas (como funções de uma única linha de número e caractere, de conversão de tipo de
dados e de data e timestamp) é válida em expressões PL/SQL.
Estas funções não estão disponíveis em instruções procedurais:
• DECODE
• Funções de grupo: AVG, MIN, MAX, COUNT, SUM, STDDEV e VARIANCE
As funções de grupo aplicam-se a grupos de linhas de uma tabela e, por isso, estão
disponíveis apenas em instruções SQL de um bloco PL/SQL. As funções aqui mencionadas
são apenas um subconjunto da lista completa.

Oracle Database: Fundamentos de PL/SQL 3 - 27


Sumário

Nesta lição, você aprendeu a:


• Identificar as unidades lexicais de um bloco PL/SQL
• Usar funções SQL predefinidas no código PL/SQL
• Criar blocos aninhados para fragmentar funcionalidades
relacionadas logicamente
• Decidir quando executar conversões explícitas
• Qualificar variáveis em blocos aninhados
• Usar sequências em expressões PL/SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Sumário
Como PL/SQL é uma extensão do código SQL, as regras gerais de sintaxe que se aplicam ao
SQL também se aplicam à linguagem PL/SQL.
Um bloco pode ter inúmeros blocos aninhados definidos dentro de sua parte executável. Os
blocos definidos dentro de um bloco são chamados de sub-blocos. Só é possível aninhar blocos
na parte executável de um bloco. Como a seção de exceções também faz parte da seção
executável, ela também pode conter blocos aninhados. Assegure escopo e visibilidade corretos
para as variáveis quando usar blocos aninhados. Evite usar identificadores iguais nos blocos pais
e filhos.
A maioria das funções disponíveis no código SQL também é válida em expressões PL/SQL. As
funções de conversão convertem um valor de um tipo de dados para outro. Os operadores de
comparação comparam uma expressão com outra. O resultado é sempre TRUE, FALSE ou
NULL. Normalmente, os operadores de comparação são usados em instruções de controle
condicional e na cláusula WHERE de instruções de manipulação de dados SQL. Os operadores
relacionais permitem comparar arbitrariamente expressões complexas.

Oracle Database: Fundamentos de PL/SQL 3 - 28


Exercício 3: Visão Geral

Este exercício aborda os seguintes tópicos:


• Verificando regras de escopo e aninhamento
• Criando e testando blocos PL/SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Exercício 3: Visão Geral


Os exercícios 1 e 2 são impressos.

Oracle Database: Fundamentos de PL/SQL 3 - 29


Interagindo com o Oracle Database Server:
Instruções SQL em Programas PL/SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.
Objetivos

Ao concluir esta lição, você será capaz de:


• Determinar quais instruções SQL podem ser incluídas
diretamente em um bloco executável PL/SQL
• Manipular dados com instruções DML em blocos PL/SQL
• Usar instruções de controle de transação em blocos
PL/SQL
• Usar a cláusula INTO para armazenar os valores
retornados por uma instrução SQL
• Fazer a distinção entre cursores explícitos e implícitos
• Usar atributos de cursores SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Objetivos
Nesta lição, você aprenderá a incorporar instruções-padrão SELECT, INSERT, UPDATE,
DELETE e MERGE em blocos PL/SQL. Aprenderá a incluir códigos DLL (Data Definition
Language) e instruções de controle de transação em PL/SQL. Você compreenderá a necessidade
dos cursores e as diferenças entre os dois tipos de cursores. A lição também apresentará os
vários atributos de cursores SQL que podem ser usados com cursores implícitos.

Oracle Database: Fundamentos de PL/SQL 4 - 2


Agenda

• Recuperando dados com PL/SQL


• Manipulando dados com PL/SQL
• Apresentando cursores SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 4 - 3


Instruções SQL em Blocos PL/SQL

• Recupere uma linha do banco de dados usando


o comando SELECT.
• Faça alterações em linhas do banco de dados usando
comandos DML.
• Controle uma transação com o comando COMMIT,
ROLLBACK ou SAVEPOINT.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Instruções SQL em Blocos PL/SQL


Em um bloco PL/SQL, use instruções SQL para recuperar e modificar dados da tabela do banco
de dados. O bloco PL/SQL suporta comandos DML (Data Manipulation Language) e de controle
de transações. Você pode usar comandos DML para modificar os dados contidos em uma tabela
do banco de dados. No entanto, lembre-se do seguinte ao usar instruções DML e comandos de
controle de transação em blocos PL/SQL:
• A palavra-chave END sinaliza o fim de um bloco PL/SQL, e não o fim de uma transação.
Da mesma forma que um bloco pode abranger várias transações, uma transação pode
abranger vários blocos.
• O bloco PL/SQL não suporta diretamente instruções DDL (data definition language), como
CREATE TABLE, ALTER TABLE ou DROP TABLE. Há suporte para Early Binding na
linguagem PL/SQL, mas esse suporte não ocorrerá se as aplicações precisarem criar
objetos de banco de dados passando valores durante o runtime. As instruções DDL não
podem ser executadas diretamente. Elas são instruções SQL dinâmicas. As instruções SQL
dinâmicas são construídas como strings de caracteres durante o runtime e podem conter
placeholders para parâmetros. Em consequência, você pode usar instruções SQL dinâmicas
para executar suas instruções DDL no bloco PL/SQL. Os detalhes sobre como trabalhar
com SQL dinâmico são abordados no curso Oracle Database: Desenvolvimento de
Unidades de Programa PL/SQL.
• O bloco PL/SQL não suporta diretamente instruções DCL (data control language), como
GRANT ou REVOKE. Você pode usar SQL dinâmico para executá-las.
Oracle Database: Fundamentos de PL/SQL 4 - 4
Instruções SELECT em Blocos PL/SQL

Recupere dados do banco de dados com uma instrução SELECT.


Sintaxe:
SELECT select_list
INTO {variable_name[, variable_name]...
| record_name}
FROM table
[WHERE condition];

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Instruções SELECT em Blocos PL/SQL


Use a instrução SELECT para recuperar dados do banco de dados.
select_list Lista de pelo menos uma coluna; pode incluir expressões SQL,
funções de linha ou funções de grupo
variable_name Variável escalar que contém o valor recuperado
record_name Registro PL/SQL que contém os valores recuperados
table Especifica o nome da tabela do banco de dados
condition É composto de nomes de colunas, expressões, constantes e
operadores de comparação, incluindo constantes e variáveis
PL/SQL
Diretrizes para Recuperar Dados em Blocos PL/SQL
• Encerre cada instrução SQL com um ponto-e-vírgula (;).
• Todo valor recuperado deve ser armazenado em uma variável por meio da cláusula INTO.
• A cláusula WHERE é opcional e pode ser usada para especificar variáveis, constantes,
literais ou expressões PL/SQL de entrada. Entretanto, ao usar a cláusula INTO, você
deverá extrair com o comando fetch apenas uma linha, e o uso da cláusula WHERE é
necessário nesses casos.

Oracle Database: Fundamentos de PL/SQL 4 - 5


Instruções SELECT em Blocos PL/SQL (continuação)
• O número de variáveis especificadas na cláusula INTO deve ser igual ao de colunas do
banco de dados na cláusula SELECT. Assegure-se de que correspondam em posição e que
seus tipos de dados sejam compatíveis.
• Use funções de grupo, como SUM, em uma instrução SQL, pois as funções de grupo se
aplicam a grupos de linha de uma tabela.

Oracle Database: Fundamentos de PL/SQL 4 - 6


Instruções SELECT em Blocos PL/SQL

• A cláusula INTO é obrigatória.


• As consultas devem retornar apenas uma linha.
DECLARE
v_fname VARCHAR2(25);
BEGIN
SELECT first_name INTO v_fname
FROM employees WHERE employee_id=200;
DBMS_OUTPUT.PUT_LINE(' First Name is : '||v_fname);
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Instruções SELECT em Blocos PL/SQL (continuação)


Cláusula INTO
A cláusula INTO é obrigatória e ocorre entre as cláusulas SELECT e FROM. Ela é usada para
especificar os nomes das variáveis que armazenam os valores que o código SQL retorna da
cláusula SELECT. Especifique uma variável para cada item selecionado. A ordem das variáveis
deve corresponder aos itens selecionados.
Use a cláusula INTO para preencher as variáveis PL/SQL ou as variáveis de host.
As Consultas Devem Retornar Apenas uma Linha
As instruções SELECT contidas em um bloco PL/SQL recaem na classificação ANSI de SQL
incorporada, para a qual se aplica a seguinte regra: As consultas devem retornar apenas uma
linha. Uma consulta que retorne mais de uma linha ou nenhuma linha gera um erro.
O bloco PL/SQL gerencia esses erros gerando exceções-padrão, que podem ser tratadas na seção
de exceções do bloco com as exceções NO_DATA_FOUND e TOO_MANY_ROWS. Inclua uma
condição WHERE na instrução SQL para que a instrução retorne uma única linha. Você
aprenderá sobre o tratamento de exceções na lição “Tratando Exceções”.
Observação: Em todos os casos em que DBMS_OUTPUT.PUT_LINE é usada nos códigos de
exemplo, a instrução SET SERVEROUTPUT ON antecede o bloco.

Oracle Database: Fundamentos de PL/SQL 4 - 7


Instruções SELECT em Blocos PL/SQL (continuação)
Como Recuperar Várias Linhas de uma Tabela e Operar nos Dados
Uma instrução SELECT com a cláusula INTO pode recuperar apenas uma linha de cada vez. Se
for necessário recuperar várias linhas e operar nos dados, você poderá usar cursores explícitos.
Posteriormente nesta lição, você será apresentado a cursores e aprenderá sobre cursores
explícitos na lição “Usando Cursores Explícitos”.

Oracle Database: Fundamentos de PL/SQL 4 - 8


Recuperando Dados em Blocos PL/SQL: Exemplo

Recupere hire_date e salary para o funcionário especificado.


DECLARE
v_emp_hiredate employees.hire_date%TYPE;
v_emp_salary employees.salary%TYPE;
BEGIN
SELECT hire_date, salary
INTO v_emp_hiredate, v_emp_salary
FROM employees
WHERE employee_id = 100;
DBMS_OUTPUT.PUT_LINE ('Hire date is :'|| v_emp_hiredate);
DBMS_OUTPUT.PUT_LINE ('Salary is :'|| v_emp_ salary);
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Recuperando Dados em Blocos PL/SQL


No exemplo do slide, as variáveis v_emp_hiredate e v_emp_salary são declaradas na
seção declarativa do bloco PL/SQL. Na seção executável, os valores das colunas hire_date e
salary referentes ao funcionário cujo employee_id é 100 são recuperados da tabela
employees. Em seguida, eles são armazenados nas variáveis emp_hiredate e
emp_salary, respectivamente. Observe como a cláusula INTO, juntamente com a instrução
SELECT, recupera os valores das colunas do banco de dados e armazena-os nas variáveis
PL/SQL.
Observação: A instrução SELECT recupera hire_date e, em seguida, salary. As variáveis
da cláusula INTO devem, portanto, estar na mesma ordem. Por exemplo, se você trocar
v_emp_hiredate e v_emp_salary na instrução do slide, a instrução resultará em um erro.

Oracle Database: Fundamentos de PL/SQL 4 - 9


Recuperando Dados em Blocos PL/SQL

Retorne a soma dos salários de todos os funcionários do


departamento especificado.
Exemplo:

DECLARE
v_sum_sal NUMBER(10,2);
v_deptno NUMBER NOT NULL := 60;
BEGIN
SELECT SUM(salary) -- group function
INTO v_sum_sal FROM employees
WHERE department_id = v_deptno;
DBMS_OUTPUT.PUT_LINE ('The sum of salary is ' || v_sum_sal);
END;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Recuperando Dados em Blocos PL/SQL (continuação)


No exemplo do slide, as variáveis v_sum_sal e v_deptno são declaradas na seção
declarativa do bloco PL/SQL. Na seção executável, o salário total dos funcionários do
departamento com o department_id 60 é calculado com base na função agregada SQL SUM.
O salário total calculado é designado à variável v_sum_sal.
Observação: As funções de grupo não podem ser usadas na sintaxe PL/SQL. Elas devem ser
usadas em instruções SQL dentro de um bloco PL/SQL, como mostrado no exemplo do slide.
Por exemplo, você não pode usar as funções de grupo com a seguinte sintaxe:
V_sum_sal := SUM(employees.salary);

Oracle Database: Fundamentos de PL/SQL 4 - 10


Ambiguidades de Nomeação

DECLARE
hire_date employees.hire_date%TYPE;
sysdate hire_date%TYPE;
employee_id employees.employee_id%TYPE := 176;
BEGIN
SELECT hire_date, sysdate
INTO hire_date, sysdate
FROM employees
WHERE employee_id = employee_id;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Ambiguidades de Nomeação
Em instruções SQL potencialmente ambíguas, os nomes das colunas dos bancos de dados têm
precedência sobre os nomes das variáveis locais.
O exemplo mostrado no slide é definido assim: Recupere a data de admissão e a data de hoje da
tabela employees para o funcionário cujo employee_id é176. Esse exemplo gera uma
exceção durante o runtime não tratada porque, na cláusula WHERE, os nomes das variáveis
PL/SQL são iguais aos nomes das colunas do banco de dados na tabela employees.
A instrução DELETE a seguir remove todos os funcionários da tabela employees, cujo
sobrenome não seja nulo (não apenas “King”), porque o Oracle Server pressupõe que ambas as
ocorrências de last_name na cláusula WHERE se referem à coluna do banco de dados:
DECLARE
last_name VARCHAR2(25) := 'King';
BEGIN
DELETE FROM employees WHERE last_name = last_name;
. . .

Oracle Database: Fundamentos de PL/SQL 4 - 11


Convenções de Nomeação

• Use uma convenção de nomeação para evitar


ambiguidade na cláusula WHERE.
• Evite usar nomes de colunas do banco de dados como
identificadores.
• Podem ocorrer erros de sintaxe porque o código PL/SQL
verifica primeiro se há uma coluna na tabela do banco de
dados.
• Os nomes de variáveis locais e parâmetros formais têm
precedência sobre os nomes de tabelasdo banco de
dados.
• Os nomes de colunasde tabelas do banco de dados têm
precedência sobre os nomes de variáveis locais.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Convenções de Nomeação
Evite ambiguidade na cláusula WHERE seguindo uma convenção de nomeação que diferencie os
nomes de colunas do banco de dados dos nomes de variáveis PL/SQL.
• As colunas de banco de dados e os identificadores devem ter nomes distintos.
• Podem ocorrer erros de sintaxe porque o código PL/SQL verifica primeiro se há uma
coluna na tabela do banco de dados.
Observação: Não há possibilidade de ambiguidade na cláusula SELECT pois qualquer
identificador na cláusula SELECT deve ser um nome de coluna do banco de dados. Não há
possibilidade de ambiguidade na clásula INTO pois os identificadores na cláusula INTO devem
ser variáveis PL/SQL. Só há possibilidade de confusão na cláusula WHERE.

Oracle Database: Fundamentos de PL/SQL 4 - 12


Agenda

• Recuperando dados com PL/SQL


• Manipulando dados com PL/SQL
• Apresentando cursores SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 4 - 13


Usando o Código PL/SQL para Manipular Dados

Faça alterações em tabelas do banco de dados usando


comandos DML:
• INSERT
• UPDATE
DELETE
• DELETE
• MERGE

INSERT

MERGE
UPDATE

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Usando o Código PL/SQL para Manipular Dados


Manipule dados no banco de dados usando comandos DML. Você pode executar comandos
DML como INSERT, UPDATE, DELETE e MERGE sem restrição no código PL/SQL. Os
bloqueios de linha (e os bloqueios de tabelas) são liberados quando instruções COMMIT ou
ROLLBACK são incluídas no código PL/SQL.
• A instrução INSERT adiciona novas linhas à tabela.
• A instrução UPDATE modifica linhas existentes na tabela.
• A instrução DELETE remove linhas da tabela.
• A instrução MERGE seleciona linhas de uma tabela a serem atualizadas ou inseridas em
outra tabela. A decisão de efetuar uma atualização ou inserção na tabela de destino se
baseia em uma condição na cláusula ON.
Observação: MERGE é uma instrução determinante. Quer dizer, não é possível atualizar a
mesma linha da tabela de destino várias vezes na mesma instrução MERGE. Você deve ter os
privilégios de objeto INSERT e UPDATE na tabela de destino e o privilégio SELECT na tabela
de origem.

Oracle Database: Fundamentos de PL/SQL 4 - 14


Inserindo Dados: Exemplo

Adicione informações sobre um novo funcionário à tabela


EMPLOYEES.

BEGIN
INSERT INTO employees
(employee_id, first_name, last_name, email,
hire_date, job_id, salary)
VALUES(employees_seq.NEXTVAL, 'Ruth', 'Cores',
'RCORES',CURRENT_DATE, 'AD_ASST', 4000);
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Inserindo Dados
No exemplo do slide, uma instrução INSERT é usada dentro de um bloco PL/SQL para inserir
um registro na tabela employees. Ao usar o comando INSERT em um bloco PL/SQL, você
pode:
• Usar funções SQL como USER e CURRENT_DATE
• Gerar valores de chave primária usando sequências existentes de banco de dados
• Derivar valores no bloco PL/SQL
Observação: Os dados da tabela employees devem permanecer inalterados. Embora a tabela
employees não seja somente para leitura, não é permitido fazer inserções, atualizações e
deleções nesta tabela para garantir a consistência de saída, como mostrado no arquivo
code_04_15_s.sqldo código de exemplo.

Oracle Database: Fundamentos de PL/SQL 4 - 15


Atualizando Dados: Exemplo
Aumente o salário de todos os funcionários que trabalham no
estoque.
DECLARE
sal_increase employees.salary%TYPE := 800;
BEGIN
UPDATE employees
SET salary = salary + sal_increase
WHERE job_id = 'ST_CLERK';
END;
/

...

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Atualizando Dados
É possível haver ambiguidade na cláusula SET da instrução UPDATE porque, embora o
identificador à esquerda do operador de designação seja sempre uma coluna do banco de dados,
o identificador à direita pode ser uma coluna do banco de dados ou uma variável PL/SQL.
Lembre-se de que, se os nomes de colunas e de identificadores foram iguais na cláusula WHERE,
o Oracle Server primeiro procurará o nome no banco de dados.
Lembre-se de que a cláusula WHERE é usada para determinar as linhas que são afetadas. Se
nenhuma linha for modificada, não ocorrerá erro (ao contrário do que acontece com a instrução
SELECT no código PL/SQL).
Observação: As designações de variáveis PL/SQL sempre usam := e as designações de colunas
SQL sempre usam =.

Oracle Database: Fundamentos de PL/SQL 4 - 16


Deletando Dados: Exemplo

Delete linhas que pertencem ao departamento 10 da tabela


employees.
DECLARE
deptno employees.department_id%TYPE := 10;
BEGIN
DELETE FROM employees
WHERE department_id = deptno;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Deletando Dados
A instrução DELETE remove linhas indesejadas da tabela. Se a cláusula WHERE não for usada,
todas as linhas de uma tabela poderão ser removidas desde que não haja constraints de
integridade.

Oracle Database: Fundamentos de PL/SQL 4 - 17


Intercalando Linhas

Insira ou atualize as linhas na tabela COPY_EMP3 para que


corresponda à tabela employees.

BEGIN
MERGE INTO copy_emp c
USING employees e
ON (e.employee_id = c.empno)
WHEN MATCHED THEN
UPDATE SET
c.first_name = e.first_name,
c.last_name = e.last_name,
c.email = e.email,
. . .
WHEN NOT MATCHED THEN
INSERT VALUES(e.employee_id, e.first_name, e.last_name,
. . .,e.department_id);
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Intercalando Linhas
A instrução MERGE insere ou atualiza linhas de uma tabela usando dados de outra tabela. Cada
linha é inserida ou atualizada na tabela de destino, de acordo com uma condição equijoin.
O exemplo mostrado faz a correspondência da coluna empno da tabela copy_emp com a
coluna employee_id da tabela employees. Se for encontrada uma correspondência, a linha
será atualizada para corresponder à linha da tabela employees. Se a linha não for encontrada,
ela será inserida na tabela copy_emp.
O exemplo completo de uso da instrução MERGE em um bloco PL/SQL é mostrado na próxima
página.

Oracle Database: Fundamentos de PL/SQL 4 - 18


Intercalando Linhas (continuação)
BEGIN
MERGE INTO copy_emp c
USING employees e
ON (e.employee_id = c.empno)
WHEN MATCHED THEN
UPDATE SET
c.first_name = e.first_name,
c.last_name = e.last_name,
c.email = e.email,
c.phone_number = e.phone_number,
c.hire_date = e.hire_date,
c.job_id = e.job_id,
c.salary = e.salary,
c.commission_pct = e.commission_pct,
c.manager_id = e.manager_id,
c.department_id = e.department_id
WHEN NOT MATCHED THEN
INSERT VALUES(e.employee_id, e.first_name, e.last_name,
e.email, e.phone_number, e.hire_date, e.job_id,
e.salary, e.commission_pct, e.manager_id,
e.department_id);
END;
/

Oracle Database: Fundamentos de PL/SQL 4 - 19


Agenda

• Recuperando dados com PL/SQL


• Manipulando dados com PL/SQL
• Apresentando cursores SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 4 - 20


Cursor SQL

• Um cursor é um ponteiro para a área de memória


particular alocada pelo Oracle Server. Ele é usado para
tratar o conjunto de resultados de uma instrução SELECT.
• Há dois tipos de cursores: implícitos e explícitos.
– Implícitos: Criados e gerenciados internamente pelo Oracle
Server para processar instruções SQL
– Explícitos: Declarados explicitamente pelo programador

Cursor implícito Cursor explícito

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Cursor SQL
Você já aprendeu que é possível incluir instruções SQL em um bloco PL/SQL para retornar uma
única linha. Os dados recuperados pela instrução SQL devem ser armazenados em variáveis por
meio da cláusula INTO.
Onde o Oracle Server Processa as Instruções SQL?
O Oracle Server aloca uma área de memória particular chamada área de contexto para processar
instruções SQL. É efetuado parse na instrução SQL e ela é processada nessa área. Todas as
informações necessárias para o processamento e aquelas recuperadas após o processamento são
armazenadas nessa área. Você não tem controle sobre essa área porque ela é internamente
gerenciada pelo Oracle Server.
Um cursor é um ponteiro para a área de contexto. No entanto, esse cursor é implícito e
gerenciado automaticamente pelo Oracle Server. Quando o bloco executável executa uma
instrução SQL, o bloco PL/SQL cria um cursor implícito.
Tipos de Cursores
Há dois tipos de cursores:
• Implícitos: Um cursor implícito é criado e gerenciado pelo Oracle Server. Você não tem
acesso a ele. O Oracle Server cria esse cursor quando precisa executar uma instrução SQL.

Oracle Database: Fundamentos de PL/SQL 4 - 21


Cursor SQL (continuação)
Tipos de Cursores (continuação)
• Explícitos: Como programador, talvez você queira recuperar várias linhas de uma tabela
do banco de dados, ter um ponteiro para cada linha que for recuperada e trabalhar em cada
linha individualmente. Nesses casos, você poderá declarar cursores explicitamente, de
acordo com as necessidades dos seus negócios. Um cursor declarado por programadores é
chamado de cursor explícito. Declare esse cursor na seção declarativa de um bloco
PL/SQL.

Oracle Database: Fundamentos de PL/SQL 4 - 22


Atributos de Cursores SQL para Cursores Implícitos

Usando os atributos de cursores SQL, você pode testar


o resultado das instruções SQL.
SQL%FOUND Atributo booleano que será avaliado como TRUE
se a instrução SQL mais recente afetar pelo
menos uma linha
SQL%NOTFOUND Atributo booleano que será avaliado como TRUE
se a instrução SQL mais recente não afetar
nenhuma linha
SQL%ROWCOUNT Um valor inteiro que representa o número de
linhas afetadas pela instrução SQL mais recente

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Atributos de Cursores SQL para Cursores Implícitos


Os atributos de cursores SQL permitem avaliar o que aconteceu quando um cursor implícito foi
usado pela última vez. Utilize esses atributos em instruções PL/SQL, mas não em instruções
SQL.
Você pode testar os atributos SQL%ROWCOUNT, SQL%FOUND e SQL%NOTFOUND na seção
executável de um bloco para reunir informações após o comando DML apropriado ser
executado. O código PL/SQL não retornará erro se uma instrução DML não afetar as linhas na
tabela subjacente. Entretanto, se uma instrução SELECT não recuperar nenhuma linha, o código
PL/SQL retornará uma exceção.
Observe que os atributos têm o prefixo SQL. Esses atributos de cursores são usados nos cursores
implícitos que são criados automaticamente pelo código PL/SQL e cujos nomes você não
conhece. Por isso, é usado SQL em vez do nome do cursor.
O atributo SQL%NOTFOUND é o oposto de SQL%FOUND. Esse atributo pode ser usado como a
condição de saída de um loop. Isso é útil em instruções UPDATE e DELETE quando nenhuma
linha é alterada, pois não são retornadas exceções nesses casos.
Você aprenderá sobre os atributos de cursores explícitos na lição “Usando Cursores Explícitos”.

Oracle Database: Fundamentos de PL/SQL 4 - 23


Atributos de Cursores SQL para Cursores Implícitos

Delete linhas que possuem o ID de funcionário especificado da


tabela employees. Imprima o número de linhas deletadas.
Exemplo:

DECLARE
v_rows_deleted VARCHAR2(30)
v_empno employees.employee_id%TYPE := 176;
BEGIN
DELETE FROM employees
WHERE employee_id= v_empno;
v_rows_deleted := (SQL%ROWCOUNT ||
' row deleted.');
DBMS_OUTPUT.PUT_LINE (v_rows_deleted);

END;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Atributos de Cursores SQL para Cursores Implícitos (continuação)


O exemplo no slide deleta uma linha com employee_id 176 da tabela employees. Com o
atributo SQL%ROWCOUNT, você pode imprimir o número de linhas deletadas.

Oracle Database: Fundamentos de PL/SQL 4 - 24


Questionário

Quando você usa a instrução SELECT em blocos PL/SQL,


a cláusula INTO é necessária e as consultas podem retornar
uma ou mais linhas.
a. Verdadeiro
b. Falso

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Resposta: b
Cláusula INTO
A cláusula INTO é obrigatória e ocorre entre as cláusulas SELECT e FROM. Ela é usada para
especificar os nomes das variáveis que armazenam os valores que o código SQL retorna da
cláusula SELECT. Especifique uma variável para cada item selecionado. A ordem das variáveis
deve corresponder aos itens selecionados.
Use a cláusula INTO para preencher as variáveis PL/SQL ou as variáveis de host.
As Consultas Devem Retornar Apenas uma Linha
As instruções SELECT contidas em um bloco PL/SQL recaem na classificação ANSI de SQL
incorporada, para a qual se aplica a seguinte regra: As consultas devem retornar apenas uma
linha. Uma consulta que retorne mais de uma linha ou nenhuma linha gera um erro.
O bloco PL/SQL gerencia esses erros gerando exceções-padrão, que podem ser tratadas na seção
de exceções do bloco com as exceções NO_DATA_FOUND e TOO_MANY_ROWS. Inclua uma
condição WHERE na instrução SQL para que a instrução retorne uma única linha. Você
aprenderá sobre o tratamento de exceções mais adiante no curso.

Oracle Database: Fundamentos de PL/SQL 4 - 25


Sumário

Nesta lição, você aprendeu a:


• Incorporar instruções DML, instruções de controle de
transações e instruções DDL aos blocos PL/SQL
• Usar a cláusula INTO, obrigatória para todas as instruções
SELECT, em blocos PL/SQL
• Fazer a distinção entre cursores explícitos e implícitos
• Usar atributos de cursores SQL para determinar o
resultado de instruções SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Sumário
Comandos DML e instruções de controle de transação podem ser usados em programas PL/SQL
sem restrição. Entretanto, os comandos DDL não podem ser usados diretamente.
Uma instrução SELECT de um bloco PL/SQL pode retornar apenas uma linha. É obrigatório o
uso da cláusula INTO para armazenar os valores recuperados pela instrução SELECT.
Um cursor é um ponteiro para a área da memória. Há dois tipos de cursores. Os cursores
implícitos são criados e gerenciados internamente pelo Oracle Server para executar as instruções
SQL. É possível usar atributos de cursores SQL com esses cursores para determinar o resultado
da instrução SQL. Os cursores explícitos são declarados pelos programadores.

Oracle Database: Fundamentos de PL/SQL 4 - 26


Exercício 4: Visão Geral

Este exercício aborda os seguintes tópicos:


• Selecionando dados de uma tabela
• Inserindo linhas em uma tabela
• Atualizando linhas de uma tabela
• Deletando um registro de uma tabela

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 4 - 27


Criando Estruturas de Controle

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.
Objetivos

Ao concluir esta lição, você será capaz de:


• Identificar os usos e os tipos de estruturas de controle
• Construir uma instrução IF
• Usar instruções CASE e expressões CASE
• Construir e identificar instruções de loop
• Usar diretrizes ao utilizar estruturas de controle
condicional

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Objetivos
Você aprendeu a criar blocos PL/SQL contendo as seções declarativa e executável. Aprendeu
também a incluir expressões e instruções SQL no bloco executável.
Nesta lição, você aprenderá a usar estruturas de controle, como instruções IF, expressões CASE
e estruturas LOOP em um bloco PL/SQL.

Oracle Database: Fundamentos de PL/SQL 5 - 2


Controlando o Fluxo de Execução

loop
for

while

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Controlando o Fluxo de Execução


Você pode alterar o fluxo lógico de instruções dentro do bloco PL/SQL com algumas estruturas
de controle. Esta lição aborda quatro tipos de estruturas de controle PL/SQL: estruturas
condicionais com a instrução IF, expressões CASE, estruturas de controle LOOP e a instrução
CONTINUE.

Oracle Database: Fundamentos de PL/SQL 5 - 3


Agenda

• Usando instruções IF
• Usando instruções CASE e expressões CASE
• Construindo e identificando instruções de loop

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 5 - 4


Instrução IF

Sintaxe:

IF condition THEN
statements;
[ELSIF condition THEN
statements;]
[ELSE
statements;]
END IF;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Instrução IF
A estrutura da instrução IF do código PL/SQL é semelhante à das instruções IF de outras
linguagens procedurais. Ela permite que o código PL/SQL realize ações seletivamente com base
em condições.
Na sintaxe:

condition É uma variável booleana ou expressão que retorna TRUE,


FALSE ou NULL
THEN Apresenta uma cláusula que associa a expressão booleana à
sequência de instruções que vem depois dela
statements Pode ser uma ou mais instruções PL/SQL ou SQL. (Podem
incluir outras instruções IF que contêm várias instruções IF,
ELSE e ELSIF aninhadas.) As instruções da cláusula THEN
serão executadas somente se a condição da cláusula IF
associada for avaliada como TRUE.

Oracle Database: Fundamentos de PL/SQL 5 - 5


Instrução IF (continuação)
Na sintaxe:
ELSIF É uma palavra-chave que apresenta uma expressão booleana (se a
primeira condição resultar em FALSE ou NULL, a palavra-chave
ELSIF apresentará condições adicionais.)
ELSE Apresenta a cláusula default que será executada se e somente se
nenhum dos predicados anteriores (apresentados por IF e ELSIF) for
igual a TRUE. Os
testes são executados em sequência, de modo que um predicado
posterior, que poderia ser
verdadeiro, seja previamente esvaziado por um predicado anterior que
seja verdadeiro.
END IF Marca o fim de uma instrução IF

Observação: ELSIF e ELSE são opcionais em uma instrução IF. Pode haver qualquer número
de palavras-chave ELSIF, mas apenas uma palavra-chave ELSE na instrução IF. END IF
marca o fim de uma instrução IF e deve ser encerrada por um ponto-e-vírgula.

Oracle Database: Fundamentos de PL/SQL 5 - 6


Instrução IF Simples

DECLARE
v_myage number:=31;
BEGIN
IF v_myage < 11
THEN
DBMS_OUTPUT.PUT_LINE(' I am a child ');
END IF;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Instrução IF Simples
Exemplo de Instrução IF Simples
O slide mostra um exemplo de uma instrução IF simples com a cláusula THEN.
• A variável v_myage é inicializada com 31.
• A condição para a instrução IF retorna FALSE porque v_myage não é menor que 11.
• Com isso, o controle nunca atinge a cláusula THEN.
Adicionando Expressões Condicionais
Uma instrução IF pode ter várias expressões condicionais relacionadas com operadores lógicos,
como AND, OR e NOT.
Por exemplo:
IF (myfirstname='Christopher' AND v_myage <11)

A condição usa o operador AND e, portanto, será avalidada como TRUE somente se ambas as
condiçções forem avaliadas como TRUE. Não há limitação explícita em relação ao número de
expressões condicionais. Entretanto, essas instruções devem estar relacionadas a operadores
lógicos adequados.

Oracle Database: Fundamentos de PL/SQL 5 - 7


Instrução IF THEN ELSE

DECLARE
v_myage number:=31;
BEGIN
IF v_myage < 11
THEN
DBMS_OUTPUT.PUT_LINE(' I am a child ');
ELSE
DBMS_OUTPUT.PUT_LINE(' I am not a child ');
END IF;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Instrução IF THEN ELSE


A cláusula ELSE foi adicionada ao código no slide anterior. A condição não foi alterada e,
portanto, ela ainda é avaliada como FALSE. Lembre-se de que as instruções da cláusula THEN
serão executadas somente se a condição retornar TRUE. Nesse caso, a condição retorna FALSE e
o controle é movido para a instrução ELSE.
A saída do bloco é mostrada abaixo do código.

Oracle Database: Fundamentos de PL/SQL 5 - 8


Cláusula IF ELSIF ELSE

DECLARE
v_myage number:=31;
BEGIN
IF v_myage < 11 THEN
DBMS_OUTPUT.PUT_LINE(' I am a child ');
ELSIF v_myage < 20 THEN
DBMS_OUTPUT.PUT_LINE(' I am young ');
ELSIF v_myage < 30 THEN
DBMS_OUTPUT.PUT_LINE(' I am in my twenties');
ELSIF v_myage < 40 THEN
DBMS_OUTPUT.PUT_LINE(' I am in my thirties');
ELSE
DBMS_OUTPUT.PUT_LINE(' I am always young ');
END IF;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Cláusula IF ELSIF ELSE


A cláusula IF pode conter várias cláusulas ELSIF e uma ELSE. O exemplo ilustra as seguintes
características dessas cláusulas:
• As cláusulas ELSIF podem ter condições, ao contrário da cláusula ELSE.
• A condição para ELSIF deve ser seguida pela cláusula THEN, que é executada se a
condição para ELSIF retornar TRUE.
• Quando houver várias cláusulas ELSIF, se a primeira condição for FALSE ou NULL, o
controle passará para a próxima cláusula ELSIF.
• As condições são avaliadas, uma a uma, a partir de cima.
• Se todas as condições forem FALSE ou NULL, as instruções da cláusula ELSE serão
executadas.
• A cláusula ELSE final é opcional.
No exemplo, a saída do bloco é mostrada abaixo do código.

Oracle Database: Fundamentos de PL/SQL 5 - 9


Valor NULL na Instrução IF

DECLARE
v_myage number;
BEGIN
IF v_myage < 11 THEN
DBMS_OUTPUT.PUT_LINE(' I am a child ');
ELSE
DBMS_OUTPUT.PUT_LINE(' I am not a child ');
END IF;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Valor NULL na Instrução IF


No exemplo mostrado no slide, a variável v_myage é declarada, mas não é inicializada. A
condição na instrução IF retorna NULL e não TRUE ou FALSE. Em casos como esse, o controle
passa para a instrução ELSE.
Diretrizes
• Você pode realizar ações seletivamente com base nas condições que vão sendo atendidas.
• Quando estiver criando o código, lembre-se da ortografia das palavras-chave:
– ELSIF é uma palavra.
– END IF são duas palavras.
• Se a condição booleana de controle for TRUE, a sequência associada de instruções será
executada; se a condição booleana de controle for FALSE ou NULL, a sequência associada
de instruções será ultrapassada. São permitidas inúmeras cláusulas ELSIF.
• Utilize recuos nas instruções executadas condicionalmente para garantir clareza.

Oracle Database: Fundamentos de PL/SQL 5 - 10


Agenda

• Usando instruções IF
• Usando instruções CASE e expressões CASE
• Construindo e identificando instruções de loop

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 5 - 11


Expressões CASE

• A expressão CASE seleciona e retorna um resultado.


• Para selecionar o resultado, a expressão CASE usa
expressões. O valor retornado por essas expressões é
usado para selecionar uma das várias alternativas.

CASE selector
WHEN expression1 THEN result1
WHEN expression2 THEN result2
...
WHEN expressionN THEN resultN
[ELSE resultN+1]
END;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Expressões CASE
A expressão CASE retorna um resultado baseado em uma ou mais alternativas. Para retornar o
resultado, a expressão CASE usa um seletor, que é uma expressão cujo valor é usado para
retornar uma entre várias alternativas. O seletor é seguido de uma ou mais cláusulas WHEN, que
são verificadas sequencialmente. O valor do seletor determina qual resultado será retornado.
Caso o valor do seletor seja igual ao valor de uma expressão da cláusula WHEN, essa cláusula
WHEN será executada e esse resultado será retornado.
O código PL/SQL também fornece uma expressão CASE pesquisada, que tem esta forma:
CASE
WHEN search_condition1 THEN result1
WHEN search_condition2 THEN result2
...
WHEN search_conditionN THEN resultN
[ELSE resultN+1]
END;
Uma expressão CASE pesquisada não possui seletor. Além disso, as cláusulas WHEN em
expressões CASE contêm condições de pesquisa que retornam um valor booleano em vez de
expressões que possam retornar um valor de qualquer tipo.

Oracle Database: Fundamentos de PL/SQL 5 - 12


Expressões CASE: Exemplo

SET VERIFY OFF


DECLARE
v_grade CHAR(1) := UPPER('&grade');
v_appraisal VARCHAR2(20);
BEGIN
v_appraisal := CASE v_grade
WHEN 'A' THEN 'Excellent'
WHEN 'B' THEN 'Very Good'
WHEN 'C' THEN 'Good'
ELSE 'No such grade'
END;
DBMS_OUTPUT.PUT_LINE ('Grade: '|| v_grade || '
Appraisal ' || v_appraisal);
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Expressões CASE: Exemplo


No exemplo do slide, a expressão CASE usa o valor da variável v_grade como expressão.
O valor é fornecido pelo usuário por meio de uma variável de substituição. Baseado no valor
informado pelo usuário, a expressão CASE retorna o valor da variável v_appraisal com base
no valor v_grade .
Resultado
Quando você informar a ou A para v_grade, como mostrado na janela Substitution Variable,
a saída do exemplo será a seguinte:

Oracle Database: Fundamentos de PL/SQL 5 - 13


Expressões CASE Pesquisadas

DECLARE
v_grade CHAR(1) := UPPER('&grade');
v_appraisal VARCHAR2(20);
BEGIN
v_appraisal := CASE
WHEN v_grade = 'A' THEN 'Excellent'
WHEN v_grade IN ('B','C') THEN 'Good'
ELSE 'No such grade'
END;
DBMS_OUTPUT.PUT_LINE ('Grade: '|| v_grade || '
Appraisal ' || v_appraisal);
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Expressões CASE Pesquisadas


No exemplo anterior, você viu uma única expressão de teste, a variável v_grade.
A cláusula WHEN compara um valor com essa expressão de teste.
Nas instruções CASE pesquisadas, não há uma expressão de teste. Em vez disso, a cláusula
WHEN contém uma expressão que resulta em um valor booleano. O mesmo exemplo foi reescrito
no slide para mostrar instruções CASE pesquisadas.
Resultado
Quando você informar b ou B para v_grade, a saída do exemplo será a seguinte:

Oracle Database: Fundamentos de PL/SQL 5 - 14


Instrução CASE
DECLARE
v_deptid NUMBER;
v_deptname VARCHAR2(20);
v_emps NUMBER;
v_mngid NUMBER:= 108;
BEGIN
CASE v_mngid
WHEN 108 THEN
SELECT department_id, department_name
INTO v_deptid, v_deptname FROM departments
WHERE manager_id=108;
SELECT count(*) INTO v_emps FROM employees
WHERE department_id=v_deptid;
WHEN 200 THEN
...
END CASE;
DBMS_OUTPUT.PUT_LINE ('You are working in the '|| v_deptname||
' department. There are '||v_emps ||' employees in this
department');
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Instrução CASE
Lembre-se do uso da instrução IF. É possível incluir n instruções PL/SQL na cláusula THEN e
também na cláusula ELSE. Da mesma forma, é possível incluir instruções na instrução CASE,
que é mais legível do que várias instruções IF e ELSIF.
Como uma Expressão CASE Difere de uma Instrução CASE
Uma expressão CASE avalia a condição e retorna um valor, enquanto uma instrução CASE
avalia a condição e executa uma ação. A instrução CASE pode ser um bloco PL/SQL inteiro.
• Instruções CASE são finalizadas com END CASE;
• Expressões CASE são finalizadas com END;
A saída do código de exemplo do slide é a seguinte:

Observação: Enquanto uma instrução IF não é capaz de executar algo (todas as condições
devem ser falsas e a cláusula ELSE não é obrigatória), uma instrução CASE deve executar uma
instrução PL/SQL.

Oracle Database: Fundamentos de PL/SQL 5 - 15


Tratando Valores Nulos

Ao trabalhar com nulos, é possível evitar alguns erros comuns


seguindo estas regras:
• Comparações simples envolvendo nulos sempre retornam
NULL.
• A aplicação do operador lógico NOT a um nulo retorna
NULL.
• Se a condição retornar NULL em instruções de controle
condicional, a sequência associada de instruções não será
executada.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Tratando Valores Nulos


Considere o seguinte exemplo:
x := 5;
y := NULL;
...
IF x != y THEN -- yields NULL, not TRUE
-- sequence_of_statements that are not executed
END IF;
É possível esperar que a sequência de instruções seja executada porque x e y parecem
diferentes. Contudo, os valores nulos são indeterminados. Não se sabe se x é igual ou não a y.
Portanto, a condição IF retorna NULL e a sequência de instruções é ignorada.
a := NULL;
b := NULL;
...
IF a = b THEN -- yields NULL, not TRUE
-- sequence_of_statements that are not executed
END IF;
No segundo exemplo, você pode esperar que a sequência de instruções seja executada porque a
e b parecem iguais. No entanto, novamente, a igualdade é desconhecida, portanto a condição IF
gera NULL e a sequência de instruções é ignorada.

Oracle Database: Fundamentos de PL/SQL 5 - 16


Tabelas Lógicas

Construa uma condição booleana simples com um operador


de comparação.

AND TRUE FALSE NULL OR TRUE FALSE NULL NOT

TRUE TRUE FALSE NULL TRUE TRUE TRUE TRUE TRUE FALSE

FALSE FALSE FALSE FALSE FALSE TRUE FALSE NULL FALSE TRUE

NULL NULL FALSE NULL NULL TRUE NULL NULL NULL NULL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Tabelas Lógicas
É possível construir uma condição booleana simples combinando expressões de número,
caractere e data com operadores de comparação.
Você pode construir uma condição booleana complexa combinando condições booleanas
simples com os operadores lógicos AND, OR e NOT. Os operadores lógicos são usados para
verificar os valores da variável booleana e retornar TRUE, FALSE ou NULL. Nas tabelas lógicas
mostradas no slide:
• FALSE tem precedência em uma condição AND e TRUE tem precedência em uma
condição OR
• AND retornará TRUE somente se os dois operandos forem TRUE
• OR retornará FALSE somente se os dois operandos forem FALSE
• NULL AND TRUE sempre é avaliado como NULL, pois não se sabe se o segundo operador é
avaliado como TRUE
Observação: A negação de NULL (NOT NULL) resulta em um valor nulo porque os valores
nulos são indeterminados.

Oracle Database: Fundamentos de PL/SQL 5 - 17


Expressões Booleanas ou Expressão Lógica?

Qual é o valor do flag em cada caso?

flag := reorder_flag AND available_flag;

REORDER_FLAG AVAILABLE_FLAG FLAG

TRUE TRUE ? (1)

TRUE FALSE ? (2)

NULL TRUE ? (3)

NULL FALSE ? (4)

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Expressões Booleanas ou Expressão Lógica?


A tabela lógica AND pode ajudá-lo a avaliar as possibilidades para a condição booleana do slide.
Respostas
1. TRUE
2. FALSE
3. NULL
4. FALSE

Oracle Database: Fundamentos de PL/SQL 5 - 18


Agenda

• Usando instruções IF
• Usando instruções CASE e expressões CASE
• Construindo e identificando instruções de loop

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 5 - 19


Controle Iterativo: Instruções LOOP

• Os loops repetem uma instrução (ou uma sequência


de instruções) várias vezes.
• Há três tipos de loop:
– Loop básico
– Loop FOR
– Loop WHILE

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Controle Iterativo: Instruções LOOP


O código PL/SQL oferece vários recursos para estruturar loops a fim de repetir uma instrução ou
uma sequência de instruções várias vezes. Os loops são usados principalmente para executar
instruções repetidamente até que uma condição de saída seja alcançada. É obrigatório que haja
uma condição de saída em um loop; caso contrário, o loop será infinito.
Estruturas de loop são o terceiro tipo de estruturas de controle. O código PL/SQL contém os
seguintes tipos de loops:
• Loop básico que executa ações repetitivas sem condições gerais
• Loops FOR que executam ações iterativas com base em uma contagem
• Loops WHILE que executam ações iterativas com base em uma condição
Observação: A instrução EXIT pode ser usada para encerrar loops. Um loop básico deve ter
uma instrução EXIT. O loop de cursor FOR (que é um outro tipo de loop FOR) é abordado na
lição “Usando Cursores Explícitos”.

Oracle Database: Fundamentos de PL/SQL 5 - 20


Loops Básicos

Sintaxe:
LOOP
statement1;
. . .
EXIT [WHEN condition];
END LOOP;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Loops Básicos
A forma mais simples de uma instrução de LOOP é o loop básico, que contém uma sequência de
instruções entre as palavras-chave LOOP e END LOOP. Cada vez que o fluxo de execução atinge
a instrução END LOOP, o controle é retornado à instrução LOOP correspondente acima dela. Um
loop básico permite a execução de suas instruções pelo menos uma vez, mesmo que a condição
EXIT seja atendida na entrada do loop. Sem a instrução EXIT, o loop seria infinito.
Instrução EXIT
Você pode usar a instrução EXIT para encerrar um loop. O controle passará para a próxima
instrução depois da instrução END LOOP. É possível executar EXIT como uma ação dentro de
uma instrução IF ou como uma instrução stand-alone dentro do loop. A instrução EXIT precisa
estar dentro de um loop. No último caso, você pode anexar uma cláusula WHEN para permitir o
término condicional do loop. Quando a instrução EXIT for encontrada, a condição da cláusula
WHEN será avaliada. Se a condição retornar TRUE, o loop será finalizado e o controle passará
para a instrução seguinte ao loop.
Um loop básico pode conter várias instruções EXIT, mas recomenda-se que haja apenas um
ponto EXIT.

Oracle Database: Fundamentos de PL/SQL 5 - 21


Loop Básico: Exemplo

DECLARE
v_countryid locations.country_id%TYPE := 'CA';
v_loc_id locations.location_id%TYPE;
v_counter NUMBER(2) := 1;
v_new_city locations.city%TYPE := 'Montreal';
BEGIN
SELECT MAX(location_id) INTO v_loc_id FROM locations
WHERE country_id = v_countryid;
LOOP
INSERT INTO locations(location_id, city, country_id)
VALUES((v_loc_id + v_counter), v_new_city, v_countryid);
v_counter := v_counter + 1;
EXIT WHEN v_counter > 3;
END LOOP;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Loop Básico: Exemplo


O exemplo de loop básico mostrado no slide é definido da seguinte maneira: “Inserir três novos
IDs de locais para o código do país CA e para a cidade Montreal.”
Observação
• Um loop básico permite a execução de suas instruções até que a condição EXIT WHEN seja
atendida.
• Se a condição estiver no loop de uma forma em que ela só será verificada após as
instruções de loop serem executadas, o loop será executado pelo menos uma vez.
• No entanto, se a condição de saída for colocada no início do loop (antes de quaisquer
outras instruções executáveis) e essa condição for verdadeira, o loop será encerrado e as
instruções nunca serão executadas.
Resultados
Para exibir a saída, execute o código de exemplo: code_05_22_s.sql.

Oracle Database: Fundamentos de PL/SQL 5 - 22


Loops WHILE

Sintaxe:
WHILE condition LOOP
statement1;
statement2;
. . .
END LOOP;

Use o loop WHILE para repetir instruções enquanto uma


condição for TRUE.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Loops WHILE
Você pode usar o loop WHILE para repetir uma sequência de instruções até que a condição de
controle não seja mais TRUE. A condição é avaliada no início de cada iteração. O loop será
encerrado quando a condição for FALSE ou NULL. Se a condição for FALSE ou NULL no início
do loop, nenhuma outra iteração será executada. Portanto, é possível que nenhuma das
instruções contidas no loop sejam executadas.
Na sintaxe:
condition É uma variável booleana ou expressão (TRUE, FALSE ou NULL)
statement Pode ser uma ou mais instruções PL/SQL ou SQL
Caso as variáveis envolvidas nas condições não se alterem durante o corpo do loop, a condição
permanecerá TRUE e o loop não será encerrado.
Observação:Se a condição retornar NULL, o loop será ignorado e o controle passará para a
próxima instrução.

Oracle Database: Fundamentos de PL/SQL 5 - 23


Loops WHILE: Exemplo

DECLARE
v_countryid locations.country_id%TYPE := 'CA';
v_loc_id locations.location_id%TYPE;
v_new_city locations.city%TYPE := 'Montreal';
v_counter NUMBER := 1;
BEGIN
SELECT MAX(location_id) INTO v_loc_id FROM locations
WHERE country_id = v_countryid;
WHILE v_counter <= 3 LOOP
INSERT INTO locations(location_id, city, country_id)
VALUES((v_loc_id + v_counter), v_new_city, v_countryid);
v_counter := v_counter + 1;
END LOOP;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Loops WHILE: Exemplo


No exemplo do slide, três novos IDs de local para o código de país CA e a cidade de Montreal
foram adicionados.
• Em cada iteração pelo loop WHILE, um contador (v_counter) é incrementado.
• Se o número de iterações for menor que ou igual a 3, o código dentro do loop será
executado e uma linha será inserida na tabela locations.
• Depois que v_counter exceder o número de novos locais para esta cidade e este país, a
condição que controla o loop será avaliada como FALSE e o loop será encerrado.
Resultados
Para exibir a saída, execute o código de exemplo: code_05_24_s.sql.

Oracle Database: Fundamentos de PL/SQL 5 - 24


Loops FOR

• Use um loop FOR para abreviar o teste diminuindo


o número de iterações.
• Não declare o contador; ele é declarado implicitamente.

FOR counter IN [REVERSE]


lower_bound..upper_bound LOOP
statement1;
statement2;
. . .
END LOOP;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Loops FOR
Os loops FOR têm a mesma estrutura geral de um loop básico. Além disso, eles têm uma
instrução de controle antes da palavra-chave LOOP para definir o número de iterações que o
código PL/SQL executará.
Na sintaxe:
counter É um inteiro implicitamente declarado, cujo valor aumenta ou
diminui de forma automática (diminui se for usada a palavra-chave
REVERSE) uma unidade a cada iteração do loop até que seja
alcançado o limite superior ou inferior
REVERSE Faz com que o contador seja diminuído a cada iteração, do limite
superior para o limite inferior
Observação: O limite inferior ainda é referenciado primeiro.
lower_bound Especifica o limite inferior da faixa de valores do contador
upper_bound Especifica o limite superior da faixa de valores do contador

Não declare o contador. Ele é declarado implicitamente como um inteiro.

Oracle Database: Fundamentos de PL/SQL 5 - 25


Loops FOR (continuação)
Observação:A sequência de instruções será executada cada vez que o contador for
incrementado, conforme foi determinado pelos dois limites. O limite inferior e o superior da
faixa do loop podem ser literais, variáveis ou expressões, mas devem ser avaliados como
inteiros. Os limites são arredondados como inteiros, isto é, 11/3 e 8/5 são limites superior ou
inferior válidos. O limite inferior e o superior estão incluídos na faixa do loop. Se o limite
inferior da faixa do loop for avaliado como um inteiro maior do que o limite superior, a
sequência de instruções não será executada.
Por exemplo, a seguinte instrução é executada apenas uma vez:
FOR i IN 3..3
LOOP
statement1;
END LOOP;

Oracle Database: Fundamentos de PL/SQL 5 - 26


Loops FOR: Exemplo

DECLARE
v_countryid locations.country_id%TYPE := 'CA';
v_loc_id locations.location_id%TYPE;
v_new_city locations.city%TYPE := 'Montreal';
BEGIN
SELECT MAX(location_id) INTO v_loc_id
FROM locations
WHERE country_id = v_countryid;
FOR i IN 1.0,3 LOOP
INSERT INTO locations(location_id, city, country_id)
VALUES((v_loc_id + i), v_new_city, v_countryid );
END LOOP;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Loops FOR: Exemplo


Você já aprendeu como inserir três novos locais para o código de país CA e a cidade Montreal
usando o loop básico e o loop WHILE. O exemplo do slide mostra como alcançar o mesmo
usando o loop FOR.
Resultados
Para exibir a saída, execute o código de exemplo code_05_27_s.sql.

Oracle Database: Fundamentos de PL/SQL 5 - 27


Regras do Loop FOR

• Faça referência ao contador apenas dentro do loop; fora


do loop ele é indefinido.
• Não faça referência ao contador como o destino de uma
designação.
• Nenhum limite de loop pode ser NULL.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Regras de Loop FOR


O slide lista as diretrizes a serem seguidas na criação de um loop FOR.
Observação: Os limites inferior e superior de uma instrução LOOP não precisam ser literais
numéricos. Eles podem ser expressões convertidas em valores numéricos.
Exemplo:
DECLARE
v_lower NUMBER := 1;
v_upper NUMBER := 100;
BEGIN
FOR i IN v_lower..v_upper LOOP
...
END LOOP;
END;
/

Oracle Database: Fundamentos de PL/SQL 5 - 28


Sugestão de Utilização de Loops

• Use o loop básico quando as instruções dentro do loop


precisarem ser executadas pelo menos uma vez.
• Use o loop WHILE se a condição precisar ser avaliada no
início de cada iteração.
• Use um loop FOR se o número de iterações for conhecido.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Sugestão de Utilização de Loops


Um loop básico permite a execução de sua instrução pelo menos uma vez, mesmo que a
condição já seja atendida na entrada do loop. Sem a instrução EXIT, o loop seria infinito.
Você pode usar o loop WHILE para repetir uma sequência de instruções até que a condição de
controle não seja mais TRUE. A condição é avaliada no início de cada iteração. O loop encerrará
quando a condição for FALSE. Se a condição for FALSE no início do loop, nenhuma outra
iteração será executada.
Loops FOR possuem uma instrução de controle antes da palavra-chave LOOP para determinar o
número de iterações que o código PL/SQL executará. Use um loop FOR se o número de
iterações for predeterminado.

Oracle Database: Fundamentos de PL/SQL 5 - 29


Loops Aninhados e Labels

• É possível aninhar loops em vários níveis.


• Use labels para diferenciar blocos e loops.
• Saia do loop externo com a instrução EXIT que faz
referência ao label.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Loops Aninhados e Labels


Você pode aninhar loops FOR, WHILE e básicos um dentro do outro. O encerramento de um
loop aninhado não encerra o loop que o contém, a menos que uma exceção seja gerada.
Entretanto, você pode utilizar labels nos loops e sair do loop externo com uma instrução EXIT.
Os nomes de label seguem as mesmas regras de outros identificadores. Um label é colocado
antes de uma instrução, seja na mesma linha ou em uma linha separada. Os espaços em branco
são insignificantes em todos os parses do código PL/SQL, menos dentro de literais. Use label em
loops básicos colocando-o antes da palavra LOOP e dentro de delimitadores de label
(<<label>>). Nos loops FOR e WHILE, coloque o label antes de FOR ou WHILE.
Se o loop tiver um label, o nome do label poderá ser incluído (opcionalmente) após a instrução
END LOOP para garantir clareza.

Oracle Database: Fundamentos de PL/SQL 5 - 30


Loops Aninhados e Labels: Exemplo

...
BEGIN
<<Outer_loop>>
LOOP
v_counter := v_counter+1;
EXIT WHEN v_counter>10;
<<Inner_loop>>
LOOP
...
EXIT Outer_loop WHEN total_done = 'YES';
-- Leave both loops
EXIT WHEN inner_done = 'YES';
-- Leave inner loop only
...
END LOOP Inner_loop;
...
END LOOP Outer_loop;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Loops Aninhados e Labels: Exemplo


No exemplo do slide, existem dois loops. O loop externo é identificado pelo label
<<Outer_Loop>> e o loop interno é identificado pelo label <<Inner_Loop>>.
Os identificadores foram colocados antes da palavra LOOP dentro dos delimitadores de label
(<<label>>). O loop interno está aninhado no loop externo. Os nomes dos labels foram incluídos
após as instruções END LOOP para garantir clareza.
.

Oracle Database: Fundamentos de PL/SQL 5 - 31


Instrução CONTINUE do Código PL/SQL

• Definição
– Adiciona a funcionalidade para iniciar a próxima iteração
de loop
– Permite que programadores possam transferir o controle
para a próxima iteração de um loop
– Usa estrutura e semântica paralela na instrução EXIT
• Vantagens
– Facilita o processo de programação
– Pode oferecer um pequeno aperfeiçoamento do
desempenho em relação às soluções de programação
anteriores para simular a instrução CONTINUE

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Instrução CONTINUE do Código PL/SQL


A instrução CONTINUE permite que você transfira o controle de um loop de volta para uma
nova iteração ou que você saia do loop. Muitas outras linguagens de programção possuem essa
funcionalidade. Com a release do Oracle Database 11g, a linguagem PL/SQL também oferece
essa funcionalidade. Antes do Oracle Database 11g, era possível codificar variáveis booleanas e
instruções condicionais como soluções alternativas para simular a funcionalidade programática
CONTINUE. Em alguns casos, as soluções alternativas são menos eficientes.
A instrução CONTINUE oferece um meio simplificado de controlar iterações de loop. Essa
funcionalidade pode ser mais eficiente do que a codificação de soluções alternativas.
A instrução CONTINUE é comumente usada para filtrar os dados dentro do corpo de um loop
antes do processamento principal ser iniciado.

Oracle Database: Fundamentos de PL/SQL 5 - 32


Instrução CONTINUE do Código PL/SQL: Exemplo 1

DECLARE
v_total SIMPLE_INTEGER := 0;
BEGIN
FOR i IN 1..10 LOOP
1 v_total := v_total + i;
dbms_output.put_line
('Total is: ' || v_total);
CONTINUE WHEN i > 5;
v_total := v_total + i;
2 dbms_output.put_line
('Out of Loop Total is:
' || v_total);
END LOOP;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Instrução CONTINUE do Código PL/SQL: Exemplo 1


Este é um código exclusivamente 11g. A instrução continue foi introduzida somente no 11g.
No exemplo, há duas designações que usam a variável v_total:
1. A primeira designação é executada para cada uma das 10 iterações do loop.
2 A segunda designação é executada para as cinco primeiras iterações do loop. A instrução
CONTINUE transfere o controle de um loop de volta para uma nova iteração, portanto,
para as cinco últimas iterações do loop, a segunda designação TOTAL não é executada.
O resultado final da variável TOTAL é 70.

Oracle Database: Fundamentos de PL/SQL 5 - 33


Instrução CONTINUE do Código PL/SQL: Exemplo 2
DECLARE
v_total NUMBER := 0;
BEGIN
<<BeforeTopLoop>>
FOR i IN 1..10 LOOP
v_total := v_total + 1;
dbms_output.put_line
('Total is: ' || v_total);
FOR j IN 1..10 LOOP
CONTINUE BeforeTopLoop WHEN i + j > 5;
v_total := v_total + 1;
END LOOP;
END LOOP;
END two_loop;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Instrução CONTINUE do Código PL/SQL: Exemplo 2


Você pode usar a instrução CONTINUE para ir para a próxima iteração de um loop externo. Este
é um código exclusivamente 11g.
Para fazer isso, forneça um label ao loop externo para identificar o local para o qual a instrução
CONTINUE deve ir.
A instrução CONTINUE do loop mais interno encerrará esse loop sempre que a condição WHEN
for verdadeira (da mesma forma que a palavra-chave EXIT). Depois que o loop mais interno for
encerrado pela instrução CONTINUE, o controle será transferido para a próxima iteração do loop
mais externo com o label BeforeTopLoop neste exemplo.
Quando esse par de loops for concluído, o valor da variável TOTAL será 20.
Você também pode usar a instrução CONTINUE de um bloco de código interno, que não contém
um loop, desde que o bloco esteja aninhado dentro do loop externo apropriado.
Restrições
• A instrução CONTINUE não pode, de forma alguma, ser exibida fora de um loop — isso
gera um erro do compilador.
• Você não pode usar a instrução CONTINUE para ultrapassar o limite de um método,
função ou procedure — isso gera um erro do compilador.

Oracle Database: Fundamentos de PL/SQL 5 - 34


Questionário

Existem três tipos de loops: básicos, FOR e WHILE.


a. Verdadeiro
b. Falso

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Resposta: a
Tipos de Loop
O código PL/SQL oferece os seguintes tipos de loops:
• Loops básicos que executam ações repetitivas sem condições gerais
• Loops FOR que executam ações iterativas com base em uma contagem
• Loops WHILE que executam ações iterativas com base em uma condição

Oracle Database: Fundamentos de PL/SQL 5 - 35


Sumário

Nesta lição, você aprendeu a alterar o fluxo lógico das


instruções usando as seguintes estruturas de controle:
• Condicional (instrução IF)
• Expressões CASE e instruções CASE
• Loops:
– Loop básico
– Loop FOR
– Loop WHILE
• Instrução EXIT
• Instrução CONTINUE

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Sumário
Uma linguagem só pode ser chamada de linguagem de programação se ela fornecer estruturas de
controle para a implementação da lógica de negócios. Essas estruturas de controle também são
usadas para controlar o fluxo do programa. O código PL/SQL é uma linguagem de programação
que integra estruturas de programação ao código SQL.
Um bloco de controle condicional verifica a validade de uma condição e executa uma ação de
acordo com ela. Use o bloco IF para realizar uma execução condicional de instruções.
Um bloco de controle interativo executa uma sequência de instruções repetidamente, enquanto a
condição especificada se mostrar TRUE. Use os vários blocos de loop para executar as operações
iterativas.

Oracle Database: Fundamentos de PL/SQL 5 - 36


Exercício 5: Visão Geral

Este exercício aborda os seguintes tópicos:


• Executando ações condicionais usando instruções IF
• Executando etapas iterativas usando estruturas LOOP

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Exercício 5: Visão Geral


Neste exercício, você criará blocos PL/SQL que incorporam loops e estruturas de controle
condicionais. Os exercícios testam sua compreensão de criação das várias instruções IF e blocos
LOOP.

Oracle Database: Fundamentos de PL/SQL 5 - 37


Trabalhando com
Tipos de Dados Compostos

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.
Objetivos

Ao concluir esta lição, você será capaz de:


• Descrever conjuntos e registros PL/SQL
• Criar registros PL/SQL definidos pelo usuário
• Criar um registro PL/SQL com o atributo %ROWTYPE
• Criar arrays associativos
– Tabela INDEX BY
– Tabela de registros INDEX BY

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Objetivos
Você já foi apresentado aos tipos de dados compostos. Nesta lição, você aprenderá mais sobre
os tipos de dados compostos e seus usos.

Oracle Database: Fundamentos de PL/SQL 6 - 2


Agenda

• Apresentando tipos de dados compostos


• Usando registros PL/SQL
– Manipulando dados com registros PL/SQL
– Vantagens do atributo %ROWTYPE
• Usando conjuntos PL/SQL
– Examinando arrays associativos
– Apresentando tabelas aninhadas
– Apresentando VARRAY

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 6 - 3


Tipos de Dados Compostos

• Podem armazenar diversos valores (ao contrário dos tipos


escalares)
• São de dois tipos:
– Registros PL/SQL
– Conjuntos PL/SQL
— Array associativo (tabela INDEX BY)
— Tabela aninhada
— VARRAY

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Tipos de Dados Compostos


Você aprendeu que variáveis de tipo de dados escalar só podem armazenar um valor, ao passo
que uma variável de tipo de dados composto pode armazenar vários valores do tipo de dados
escalar ou composto. Existem dois tipos de dados compostos:
• Registros PL/SQL:Os registros são usados para tratar dados relacionados, mas
diferentes, como uma unidade lógica. Um registro PL/SQL pode ter variáveis de
diferentes tipos. Por exemplo, você pode definir um registro para armazenar detalhes
sobre o funcionário. Isso envolve armazenar o número do funcionário como NUMBER,
nome e sobrenome como VARCHAR2 e assim por diante. Ao criar um registro para
armazenar detalhes sobre o funcionário, você cria uma unidade de conjunto lógica. Isso
facilita o acesso a dados e a manipulação.
• Conjuntos PL/SQL: Os conjuntos são usados para tratar os dados como uma só unidade.
Existem três tipos de conjuntos:
- Array associativo
- Tabela aninhada
- VARRAY
Por Que Usar Tipos de Dados Compostos?
Você terá todos os dados relacionados como uma só unidade. É possível acessar e modificar os
dados facilmente. Será mais fácil gerenciar, relacionar e transportar dados se eles forem
compostos. Uma analogia é ter uma única bolsa para todos os componentes do seu laptop em
vez de uma bolsa separada para cada componente.
Oracle Database: Fundamentos de PL/SQL 6 - 4
Registros ou Conjuntos PL/SQL?

• Use os registros PL/SQL quando desejar armazenar


valores de diferentes tipos de dados, mas apenas uma
ocorrência de cada vez.
• Use os conjuntos PL/SQL quando desejar armazenar
valores do mesmo tipo de dados. Conjunto PL/SQL:
Registro PL/SQL: 1 SMITH
2 JONES
3 BENNETT
TRUE 23-DEC-98 ATLANTA 4 KRAMER

VARCHAR2
PLS_INTEGER

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Registros ou Conjuntos PL/SQL?


Se tanto os registros PL/SQL quanto os conjuntos PL/SQL forem tipos compostos, como
escolher qual deles será usado?
• Use os registros PL/SQL quando desejar armazenar valores de diferentes tipos de dados
que são relacionados logicamente. Por exemplo, você pode criar um registro PL/SQL
para armazenar detalhes sobre um funcionário e indicar que todos os valores
armazenados estejam relacionados, pois eles fornecem informações sobre um
determinado funcionário.
• Use os conjuntos PL/SQL quando desejar armazenar valores do mesmo tipo de dados.
Observe que esse tipo de dados também pode ser do tipo composto, como registros. Você
pode definir um conjunto para armazenar os nomes de todos os funcionários. Você pode
ter n nomes armazenados no conjunto, porém o nome 1 não tem relação com o nome 2.
A única relação entre esses nomes é que eles são nomes de funcionários. Esses conjuntos
são semelhantes a arrays em linguagens de programação como C, C++ e Java.

Oracle Database: Fundamentos de PL/SQL 6 - 5


Agenda

• Examinando tipos de dados compostos


• Usando registros PL/SQL
– Manipulando dados com registros PL/SQL
– Vantagens do atributo %ROWTYPE
• Usando conjuntos PL/SQL
– Examinando arrays associativos
– Apresentando tabelas aninhadas
– Apresentando VARRAY

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 6 - 6


Registros PL/SQL

• Devem conter um ou mais componentes (chamados


campos) de qualquer tipo de dados escalar, RECORD,
ou tabela INDEX BY
• São semelhantes às estruturas na maioria das linguagens
de terceira geração (incluindo C e C++)
• São definidos pelos usuários e podem ser um subconjunto
de uma linha de uma tabela
• Tratam um conjunto de campos como uma unidade lógica
• São convenientes para extrair, com o comando fetch, uma
linha de dados de uma tabela para processamento

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Registros PL/SQL
Um registro é um grupo de itens de dados relacionados armazenados em campos,, cada um
com seu próprio nome e tipo de dados.
• Cada registro definido pode ter quantos campos forem necessários.
• É possível designar aos registros valores iniciais, e os registros podem ser definidos como
NOT NULL.
• Os campos sem valores iniciais serão inicializados como NULL.
• A palavra-chave DEFAULT, bem como := pode ser usada nos campos de inicialização.
• Você pode definir tipos RECORD e declarar registros definidos pelo usuário na parte
declarativa de qualquer bloco, subprograma ou pacote.
• Você pode declarar e fazer referência a registros aninhados. Um registro pode ser o
componente de outro registro.

Oracle Database: Fundamentos de PL/SQL 6 - 7


Criando um Registro PL/SQL

Sintaxe:

1 TYPE type_name IS RECORD


(field_declaration[, field_declaration]…);

2 identifier type_name;

field_declaration:
field_name {field_type | variable%TYPE
| table.column%TYPE | table%ROWTYPE}
[[NOT NULL] {:= | DEFAULT} expr]

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Criando um Registro PL/SQL


Os registros PL/SQL são tipos compostos definidos pelo usuário. Para usá-los, execute estas
etapas:
1. Defina o registro na seção declarativa de um bloco PL/SQL. A sintaxe para definir o
registro é mostrada no slide.
2. Declare (e, opcionalmente, inicialize) os componentes internos desse tipo de registro.
Na sintaxe:
type_name É o nome do tipo RECORD (Esse identificador é usado para declarar
registros.)
field_name É o nome de um campo dentro do registro
field_type É o tipo de dados do campo (representa qualquer tipo de dados PL/SQL,
exceto REF CURSOR. É possível usar os atributos %TYPE e %ROWTYPE).
expr É o field_type ou um valor inicial
A constraint NOT NULL impede a atribuição de nulos aos campos especificados. Certifique-se
de inicializar os campos NOT NULL.

Oracle Database: Fundamentos de PL/SQL 6 - 8


Estrutura de Registros PL/SQL

Declarações de campo:

Campo1 Campo2 Campo3


(tipo de dados) (tipo de dados) (tipo de dados)

Exemplo:

Campo1 Campo2 Campo3


(tipo de dados) (tipo de dados) (tipo de dados)
employee_id number(6) last_name varchar2(25) job_id varchar2(10)

100 King AD_PRES

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Estrutura de Registros PL/SQL


Os campos de um registro são acessados pelo nome do registro. Para fazer referência ou
inicializar um campo individual, use a notação de ponto:
record_name.field_name
Por exemplo, faça referência ao campo job_id do registro emp_record desta forma:
emp_record.job_id
Em seguida, você poderá designar um valor ao campo do registro:
emp_record.job_id := 'ST_CLERK';
Em um bloco ou subprograma, os registros definidos pelo usuário são instanciados quando
você informa o bloco ou o subprograma. Eles deixam de existir quando você sai do bloco ou
do subprograma.

Oracle Database: Fundamentos de PL/SQL 6 - 9


Atributo %ROWTYPE

• Declare uma variável de acordo com um conjunto de


colunas de uma view ou tabela de banco de dados.
• Use como prefixo de %ROWTYPE a view ou a tabela de
banco de dados.
• Os campos do registro adotam os nomes e tipos de dados
das colunas da view ou da tabela.
Sintaxe:
DECLARE
identifier reference%ROWTYPE;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Atributo %ROWTYPE
Você aprendeu que %TYPE é usado para declarar uma variável do tipo de coluna. A variável
tem o mesmo tipo de dados e tamanho de uma coluna da tabela. A vantagem de %TYPE é que
não será necessário alterar a variável caso a coluna seja alterada. Além disso, se a variável for
um número e for usada em qualquer cálculo, você não precisará se preocupar com a sua
precisão.
O atributo %ROWTYPE é usado para declarar um registro que possa armazenar uma linha
inteira de uma view ou tabela. Os campos do registro adotam os nomes e tipos de dados das
colunas da view ou da tabela. O registro também pode armazenar uma linha inteira de dados
extraídos de um cursor ou uma variável de cursor.
O slide mostra a sintaxe para se declarar um registro. Na sintaxe:
identifier É o nome escolhido para o registro como um todo
reference É o nome da tabela, view, cursor ou variável de cursor na qual
o registro deve ser baseado (a tabela ou view deve existir para
que essa referência seja válida).
Neste exemplo, um registro é declarado usando %ROWTYPE como um especificador de tipo de
dados:
DECLARE
emp_record employees%ROWTYPE;
...
Oracle Database: Fundamentos de PL/SQL 6 - 10
Atributo %ROWTYPE (continuação)
O registro emp_record tem uma estrutura que consiste nos campos a seguir, cada um
representando uma coluna da tabela employees.
Observação: Isso não é um código, mas apenas a estrutura da variável composta.
(employee_id NUMBER(6),
first_name VARCHAR2(20),
last_name VARCHAR2(20),
email VARCHAR2(20),
phone_number VARCHAR2(20),
hire_date DATE,
salary NUMBER(8,2),
commission_pct NUMBER(2,2),
manager_id NUMBER(6),
department_id NUMBER(4))
Para fazer referência a um determinado campo, use a notação de ponto:
record_name.field_name
Por exemplo, faça referência ao campo commission_pct do registro emp_record desta
forma:
emp_record.commission_pct
Em seguida, você poderá designar um valor ao campo do registro:
emp_record.commission_pct:= .35;
Designando Valores a Registros
Com a instrução SELECT ou FETCH, é possível designar uma lista de valores comuns a um
registro. Certifique-se de que os nomes de colunas aparecem na mesma ordem que os campos
do seu registro. Você também pode designar um registro a outro se ambos tiverem tipos de
dados correspondentes. Um registro do tipo employees%ROWTYPE e um tipo de registro
definido pelo usuário com campos análogos da tabela employees terão o mesmo tipo de
dados. Portanto, se um registro definido pelo usuário contiver campos semelhantes aos de um
registro %ROWTYPE, você poderá designar esse registro definido pelo usuário ao registro
%ROWTYPE.

Oracle Database: Fundamentos de PL/SQL 6 - 11


Criando um Registro PL/SQL: Exemplo

DECLARE
TYPE t_rec IS RECORD
(v_sal number(8),
v_minsal number(8) default 1000,
v_hire_date employees.hire_date%type,
v_rec1 employees%rowtype);
v_myrec t_rec;
BEGIN
v_myrec.v_sal := v_myrec.v_minsal + 500;
v_myrec.v_hire_date := sysdate;
SELECT * INTO v_myrec.v_rec1
FROM employees WHERE employee_id = 100;
DBMS_OUTPUT.PUT_LINE(v_myrec.v_rec1.last_name ||' '||
to_char(v_myrec.v_hire_date) ||' '|| to_char(v_myrec.v_sal));
END;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Criando um Registro PL/SQL: Exemplo


As declarações de campo usadas para definir um registro são como declarações de variáveis.
Cada campo tem um nome exclusivo e um tipo de dados específico. Não existem tipos de
dados predefinidos para registros PL/SQL, como existem para as variáveis escalares. Portanto,
você deve criar primeiro o tipo de registro e, depois, declarar um identificador usando aquele
tipo.
No exemplo do slide, um registro PL/SQL é criado usando o processo de duas etapas
necessário:
1. Um tipo de registro (t_rec) é definido
2. Um registro (v_myrec) do tipo t_rec é declarado
Observação
• O registro contém quatro campos: v_sal, v_minsal, v_hire_date e v_rec1.
• v_rec1 é definido usando o atributo %ROWTYPE, que é semelhante ao atributo %TYPE.
Com %TYPE, um campo herda o tipo de dados de uma coluna especificada. Com
%ROWTYPE, um campo herda os nomes de colunas e os tipos de dados de todas as
colunas da tabela referenciada.
• Os campos do registro PL/SQL são referenciados por meio da notação
<record>.<field> ou da notação <record>.<field>.<column> no caso dos
campos que são definidos com o atributo %ROWTYPE.
• É possível adicionar a constraint NOT NULL a qualquer declaração de campo para
impedir a designação de nulos a esse campo. Lembre-se de que esses campos que são
declarados como NOT NULL devem ser inicializados.
Oracle Database: Fundamentos de PL/SQL 6 - 12
Vantagens do Uso do Atributo %ROWTYPE

• O número e os tipos de dados das colunas subjacentes do


banco de dados não precisam ser conhecidos e, de fato,
devem mudar durante o runtime.
• O atributo %ROWTYPE é útil quando você deseja recuperar
uma linha com:
– A instrução SELECT *
– Instruções INSERT e UPDATE em nível de linha

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Vantagens do Uso de %ROWTYPE


As vantagens de usar o atributo %ROWTYPE estão listadas no slide. Use o atributo %ROWTYPE
quando não tiver certeza da estrutura da tabela subjacente do banco de dados.
A principal vantagem de usar %ROWTYPE é que ele simplifica a manutenção. A utilização de
%ROWTYPE assegura que os tipos de dados das variáveis declaradas com esse atributo serão
dinamicamente alterados caso a tabela subjacente seja alterada. Se uma instrução DDL alterar
as colunas de uma tabela, a unidade do programa PL/SQL será invalidada. Quando o programa
for recompilado, ele refletirá automaticamente o novo formato de tabela.
Os atributos %ROWTYPE serão particularmente úteis se você quiser recuperar uma linha inteira
de uma tabela. Na ausência desse atributo, você teria que declarar uma variável para cada
coluna recuperada pela instrução SELECT.

Oracle Database: Fundamentos de PL/SQL 6 - 13


Outro Exemplo do Atributo %ROWTYPE
DECLARE
v_employee_number number:= 124;
v_emp_rec employees%ROWTYPE;
BEGIN
SELECT * INTO v_emp_rec FROM employees
WHERE employee_id = v_employee_number;
INSERT INTO retired_emps(empno, ename, job, mgr,
hiredate, leavedate, sal, comm, deptno)
VALUES (v_emp_rec.employee_id, v_emp_rec.last_name,
v_emp_rec.job_id, v_emp_rec.manager_id,
v_emp_rec.hire_date, SYSDATE,
v_emp_rec.salary, v_emp_rec.commission_pct,
v_emp_rec.department_id);
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Outro Exemplo do Atributo %ROWTYPE


Outro exemplo do atributo %ROWTYPE é mostrado no slide. Se um funcionário estiver se
aposentando, as informações sobre ele serão adicionadas à tabela que armazena informações
sobre funcionários aposentados. O usuário fornece o número do funcionário. O registro do
funcionário especificado pelo usuário é obtido da tabela employees e armazenado na
variável emp_rec, que foi declarada com o atributo %ROWTYPE.
A instrução CREATE, que cria a tabela retired_emps é:
CREATE TABLE retired_emps
(EMPNO NUMBER(4), ENAME VARCHAR2(10),
JOB VARCHAR2(9),MGR NUMBER(4),
HIREDATE DATE, LEAVEDATE DATE,
SAL NUMBER(7,2), COMM NUMBER(7,2),
DEPTNO NUMBER(2))
Observação
• O registro inserido na tabela retired_emps é mostrado no slide.
• Para ver a saída mostrada no slide, coloque o cursor na instrução SELECT, na parte
inferior do código de exemplo no SQL Developer e pressione F9.
• O código de exemplo completo está em code_6_14_n-s.sql.

Oracle Database: Fundamentos de PL/SQL 6 - 14


Inserindo um Registro Usando %ROWTYPE
...
DECLARE
v_employee_number number:= 124;
v_emp_rec retired_emps%ROWTYPE;
BEGIN
SELECT employee_id, last_name, job_id, manager_id,
hire_date, hire_date, salary, commission_pct,
department_id INTO v_emp_rec FROM employees
WHERE employee_id = v_employee_number;
INSERT INTO retired_emps VALUES v_emp_rec;
END;
/
SELECT * FROM retired_emps;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Inserindo um Registro Usando %ROWTYPE


Compare a instrução INSERT do slide anterior com a instrução INSERT deste slide. O
registro emp_rec é do tipo retired_emps. O número de campos no registro deve ser igual
ao número de nomes de campos contido na cláusula INTO. É possível usar esse registro para
inserir valores em uma tabela. Isso torna o código mais legível.
Observe a instrução SELECT no slide. Selecione hire_date duas vezes e insira o valor
referente a hire_date no campo leavedate de retired_emps. Nenhum funcionário
se aposenta na data de admissão. O registro inserido é mostrado no slide. (No próximo slide,
você verá como atualizar isso.)
Observação: Para ver a saída mostrada no slide, coloque o cursor na instrução SELECT, na
parte inferior do código de exemplo no SQL Developer, e pressione F9.

Oracle Database: Fundamentos de PL/SQL 6 - 15


Atualizando uma Linha da Tabela
Usando um Registro
SET VERIFY OFF
DECLARE
v_employee_number number:= 124;
v_emp_rec retired_emps%ROWTYPE;
BEGIN
SELECT * INTO v_emp_rec FROM retired_emps;
v_emp_rec.leavedate:=CURRENT_DATE;
UPDATE retired_emps SET ROW = v_emp_rec WHERE
empno=v_employee_number;
END;
/
SELECT * FROM retired_emps;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Atualizando a Linha de uma Tabela Usando um Registro


Você aprendeu a inserir uma linha usando um registro. O slide mostra como atualizar uma
linha usando um registro.
• A palavra-chave ROW é usada para representar a linha inteira.
• O código mostrado no slide atualiza o campo leavedate do funcionário.
• O registro é atualizado como mostrado no slide.
Observação: Para ver a saída mostrada no slide, coloque o cursor na instrução SELECT, na
parte inferior do código de exemplo no SQL Developer, e pressione F9.

Oracle Database: Fundamentos de PL/SQL 6 - 16


Agenda

• Examinando tipos de dados compostos


• Usando registros PL/SQL
– Manipulando dados com registros PL/SQL
– Vantagens do atributo %ROWTYPE
• Usando conjuntos PL/SQL
– Examinando arrays associativos
– Apresentando tabelas aninhadas
– Apresentando VARRAY

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Agenda
Como mencionado anteriormente, os conjuntos PL/SQL são usados quando você deseja
armazenar valores do mesmo tipo de dados. Esse tipo de dados também pode ser do tipo
composto (como registros).
Portanto, os conjuntos são usados para tratar os dados como uma unidade única. Existem três
tipos de conjuntos:
• Array associativo
• Tabela aninhada
• VARRAY
Observação: Desses três conjuntos, o array associativo é o foco desta lição. A tabela aninhada
e VARRARY são apresentados apenas com a finalidade de comparação. Esses dois conjuntos
são abordados em detalhes no curso Oracle Database 10g: Advanced PL/SQL ou Oracle
Database 11g: Advanced PL/SQL (conforme for adequado para a versão que você estiver
usando).

Oracle Database: Fundamentos de PL/SQL 6 - 17


Arrays Associativos (Tabelas INDEX BY)

Um array associativo é um conjunto PL/SQL com duas


colunas:
• Chave primária de tipo de dados inteiro ou string
• Coluna de tipo de dados escalar ou de registro

Chave Valores

1 JONES
2 HARDEY
3 MADURO
4 KRAMER

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Arrays Associativos (Tabelas INDEX BY)


Um array associativo é um tipo de conjunto PL/SQL. Ele é um tipo de dados composto e é
definido pelo usuário. Os arrays associativos são conjuntos de pares de valor/chave. Eles
podem armazenar dados usando um valor de chave primária como o índice, em que os valores
da chave não são necessariamente sequenciais. Os arrays associativos também são conhecidos
como tabelas INDEX BY .
Eles possuem apenas duas colunas, sendo que nenhuma delas pode ser nomeada:
• A primeira coluna, de tipo inteiro ou string, funciona como a chave primária.
• A segunda coluna, de tipo de dados escalar ou de registro, armazena valores.

Oracle Database: Fundamentos de PL/SQL 6 - 18


Estrutura de Array Associativo

1 2
Coluna de chave ---- Coluna de valores ----
exclusiva
... ... <ou> ...

1 Jones 110 ADMIN Jones


5 Smith 103 ADMIN Smith
3 Maduro 176 IT_PROG Maduro

... ... ...

PLS_INTEGER Escalar Registro

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Estrutura de Array Associativo


Como mencionado anteriormente, os arrays associativos possuem duas colunas. A segunda
coluna armazena um valor por linha ou vários valores.
Coluna de Chave Exclusiva: O tipo de dados da coluna de chave pode ser:
• Numérico, seja BINARY_INTEGER ou PLS_INTEGER. Esses dois tipos de dados
numéricos requerem menos armazenamento do que NUMBER, e as operações aritméticas
nesses tipos de dados são mais rápidas do que a aritmética NUMBER.
• VARCHAR2 ou um dos seus subtipos
Coluna “Value”: A coluna de valor pode ser de um tipo de dados escalar ou de registro. Uma
coluna com tipo de dados escalar só pode armazenar um valor por linha, ao passo que uma
coluna com tipo de dados de registro pode armazenar vários valores por linha.
Outras Características
• Um array associativo não é preenchido no momento da declaração. Ele não contém
chaves ou valores e não pode ser inicializado na sua declaração.
• Uma instrução executável explícita é necessária para preencher o array associativo.
• Assim como o tamanho de uma tabela do banco de dados, o tamanho de um array
associativo não tem restrição, ou seja, o número de linhas pode aumentar dinamicamente,
de forma que o array associativo cresce à medida que novas linhas são adicionadas.
Observe que as chaves não precisam ser sequenciais e podem ser positivas e negativas.

Oracle Database: Fundamentos de PL/SQL 6 - 19


Etapas para a Criação de um Array Associativo

Sintaxe:
1 TYPE type_name IS TABLE OF
{column_type | variable%TYPE
| table.column%TYPE} [NOT NULL]
| table%ROWTYPE
| INDEX BY PLS_INTEGER | BINARY_INTEGER
| VARCHAR2(<size>);
2 identifier type_name;

Exemplo:
...
TYPE ename_table_type IS TABLE OF
employees.last_name%TYPE
INDEX BY PLS_INTEGER;
...
ename_table ename_table_type;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Etapas para a Criação de um Array Associativo


Há duas etapas na criação de um array associativo:
1. Declare um tipo de dados TABLE usando a opção INDEX BY.
2. Declare uma variável com esse tipo de dados.
Sintaxe
type_name É o nome do tipo de dados TABLE (Este nome é usado na declaração
subsequente do identificador do array.)
column_type É qualquer qualquer tipo de dados escalar ou composto como
VARCHAR2, DATE, NUMBER, ou %TYPE (é possível usar o atributo
%TYPE para fornecer o tipo de dados da coluna.)

identifier É o nome do identificador que representa um array associativo inteiro

Observação: A constraint NOT NULL impede que nulos sejam designados ao array
associativo.
Exemplo
No exemplo, um array associativo com o nome de variável ename_table é declarado para
armazenar os sobrenomes dos funcionários.

Oracle Database: Fundamentos de PL/SQL 6 - 20


Criando e Acessando Arrays Associativos
...
DECLARE
TYPE ename_table_type IS TABLE OF
employees.last_name%TYPE
INDEX BY PLS_INTEGER;
TYPE hiredate_table_type IS TABLE OF DATE
INDEX BY PLS_INTEGER;
ename_table ename_table_type;
hiredate_table hiredate_table_type;
BEGIN
ename_table(1) := 'CAMERON';
hiredate_table(8) := SYSDATE + 7;
IF ename_table.EXISTS(1) THEN
INSERT INTO ...
...
END;
/
...

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Criando e Acessando Arrays Associativos


O exemplo do slide cria dois arrays associativos, com os identificadores ename_table e
hiredate_table.
A chave de cada array associativo é usada para acessar um elemento do array, usando a
seguinte sintaxe:
identifier(index)
Em ambos os arrays, o valor index pertence ao tipo PLS_INTEGER.
• Para fazer referência à primeira linha do array associativo ename_table, especifique:
ename_table(1)
• Para fazer referência à oitava linha do array associativo hiredate_table,
especifique: hiredate_table(8)
Observação
• A faixa de magnitude de um PLS_INTEGER é de –2.147.483.647 a 2.147.483.647,
portanto, o valor da chave primária pode ser negativo. A indexação não precisa iniciar em
1.
• O método exists(i) retorna TRUE se uma linha com o índice i for retornada. Use o
método exists para impedir a ocorrência de erro em relação a um elemento não
existente na tabela.
• O código de exemplo completo está em code_6_21_s.sql.

Oracle Database: Fundamentos de PL/SQL 6 - 21


Usando Métodos da Tabela INDEX BY

Os seguintes métodos facilitam o uso de arrays associativos:


• EXISTS • PRIOR
• COUNT • NEXT
• FIRST • DELETE
• LAST

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Usando Métodos da Tabela INDEX BY


Um método da tabela INDEX BY é um procedure ou uma função incorporados que executam
operações em um array associativo e são chamados por meio da notação de ponto.
Sintaxe: table_name.method_name[ (parameters) ]

Método Descrição
EXISTS(n) Retorna TRUE caso o elemento enésimo exista em um array associativo
COUNT Retorna o número de elementos que um array associativo contenha atualmente
FIRST • Retorna o primeiro (o menor) número de índice em um array associativo
• Retorna NULL se o array associativo estiver vazio
LAST • Retorna o último (o maior) número de índice em um array associativo
• Retorna NULL se o array associativo estiver vazio
PRIOR(n) Retorna o número de índice que precede o índice n em um array associativo
NEXT(n) Retorna o número de índice que sucede o índice n em um array associativo
DELETE • DELETE remove todos os elementos de um array associativo.
• DELETE(n) remove o enésimo elemento de um array associativo.
• DELETE(m, n) remove todos os elementos na faixa m ... n de um array
associativo.
Oracle Database: Fundamentos de PL/SQL 6 - 22
Opção da Tabela de Registros INDEX BY

Defina um array associativo para armazenar uma linha inteira


de uma tabela.
DECLARE
TYPE dept_table_type IS TABLE OF
departments%ROWTYPE INDEX PLS_INTEGER;
dept_table dept_table_type;
-- Each element of dept_table is a record
Begin
SELECT * INTO dept_table(1) FROM departments
WHERE department_id = 10;
DBMS_OUTPUT.PUT_LINE(dept_table(1).department_id || ||
dept_table(1).department_name || ||
dept_table(1).manager_id);
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Opção da Tabela de Registros INDEX BY


Como abordado anteriormente, um array associativo que é declarado como uma tabela de tipo
de dados escalar pode armazenar os detalhes apenas de uma coluna de uma tabela do banco de
dados. Entretanto, com frequência, é necessário armazenar todas as colunas recuperadas por
uma consulta. A opção da tabela de registros INDEX BY permite a definição de um array para
armazenar as informações sobre todos os campos de uma tabela do banco de dados.
Criando e Fazendo Referência a uma Tabela de Registros
Como mostrado no exemplo do array associativo no slide, você pode:
• Usar o atributo %ROWTYPE para declarar um registro que represente uma linha de uma
tabela do banco de dados.
• Fazer referência a campos contidos no array dept_table, porque cada elemento do
array é um registro
As diferenças entre o atributo %ROWTYPE e o registro PL/SQL de tipo de dados composto são
as seguintes:
• Os tipos de registro PL/SQL podem ser definidos pelo usuário, ao passo que %ROWTYPE
define implicitamente o registro.
• Os registros PL/SQL permitem que você especifique campos e seus tipos de dados ao
declará-los. Se usar %ROWTYPE, você não poderá especificar os campos. O atributo
%ROWTYPE representa a linha de uma tabela com todos os campos baseados na definição
dessa tabela.
• Os registros definidos pelo usuário são estáticos, mas os registros %ROWTYPE são
dinâmicos — eles são baseados em uma estrutura de tabela. Se a estrutura da tabela for
alterada, a estrutura do registro também assimilará a alteração.
Oracle Database: Fundamentos de PL/SQL 6 - 23
Opção da Tabela de Registros INDEX BY: Exemplo 2

DECLARE
TYPE emp_table_type IS TABLE OF
employees%ROWTYPE INDEX BY PLS_INTEGER;
my_emp_table emp_table_type;
max_count NUMBER(3):= 104;
BEGIN
FOR i IN 100..max_count
LOOP
SELECT * INTO my_emp_table(i) FROM employees
WHERE employee_id = i;
END LOOP;
FOR i IN my_emp_table.FIRST..my_emp_table.LAST
LOOP
DBMS_OUTPUT.PUT_LINE(my_emp_table(i).last_name);
END LOOP;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Tabela de Registros INDEX BY: Exemplo 2


O exemplo do slide declara um array associativo, usando a opção da tabela de registros INDEX
BY, para armazenar temporariamente os detalhes dos funcionários cujos IDs estão entre 100 e
104. O nome da variável para o array é emp_table_type.
Usando um loop, as informações sobre os funcionários da tabela EMPLOYEES são recuperadas
e armazenadas no array. Outro loop é usado para imprimir os sobrenomes do array. Observe o
uso dos métodos first e last no exemplo.
Observação: O slide demonstra um modo de trabalhar com um array associativo que usa o
método da tabela de registros INDEX BY. Entretanto, você pode fazer o mesmo de forma mais
eficiente usando cursores. Os cursores são explicados na lição “Usando Cursores Explícitos”.
Os resultados do código de exemplo são os seguintes:

Oracle Database: Fundamentos de PL/SQL 6 - 24


Tabelas Aninhadas

1 Bombay
2 Sydney
3 Oxford
4 London
.. ....
2 GB no
máximo

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Tabelas Aninhadas
A funcionalidade das tabelas aninhadas é semelhante à dos arrays associativos; no entanto, há
diferenças na implementação da tabela aninhada.
• Uma tabela aninhada é um tipo de dados válido em uma tabela em nível de esquema, mas
um array associativo não é. Portanto, ao contrário dos arrays associativos, as tabelas
aninhadas podem ser armazenadas no banco de dados.
• O tamanho de uma tabela aninhada pode aumentar dinamicamente, embora o tamanho
máximo seja de 2 GB.
• A “chave” não pode ter um valor negativo (ao contrário do array associativo). Embora
seja feita uma referência à primeira coluna como chave, não há chave em uma tabela
aninhada. Há uma coluna com números.
• Os elementos podem ser deletados de qualquer lugar de uma tabela aninhada deixando a
tabela desordenada com “chaves” não seqüenciais. As linhas de uma tabela aninhada não
estão em uma ordem específica.
• Se você recuperar valores de uma tabela aninhada, as linhas receberão subscripts
consecutivos, começando em 1.
Sintaxe
TYPE type_name IS TABLE OF
{column_type | variable%TYPE
| table.column%TYPE} [NOT NULL]
| table.%ROWTYPE
Oracle Database: Fundamentos de PL/SQL 6 - 25
Tabelas Aninhadas (continuação)
Exemplo:
TYPE location_type IS TABLE OF locations.city%TYPE;
offices location_type;
Se você não inicializar uma tabela aninhada, ela será inicializada automaticamente como
NULL. Você pode inicializar a tabela aninhada offices usando um construtor:
offices := location_type('Bombay', 'Tokyo','Singapore',
'Oxford');

O código de exemplo completo e a saída são os seguintes:

SET SERVEROUTPUT ON;

DECLARE
TYPE location_type IS TABLE OF locations.city%TYPE;
offices location_type;
table_count NUMBER;
BEGIN
offices := location_type('Bombay', 'Tokyo','Singapore',
'Oxford');
FOR i in 1.. offices.count() LOOP
DBMS_OUTPUT.PUT_LINE(offices(i));
END LOOP;
END;
/

Oracle Database: Fundamentos de PL/SQL 6 - 26


VARRAY

1 Bombay
2 Sydney
3 Oxford
4 London
.. ....
10 Tokyo

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

VARRAY
Um array de tamanho variável (VARRAY) é semelhante a um array associativo, a diferença é
que um VARRAY tem restrição de tamanho.
• Um VARRAY é válido em uma tabela em nível de esquema.
• Itens do tipo VARRAY são chamados de VARRAYs.
• Os VARRAYs têm um limite superior fixo. Você deverá especificar o limite superior ao
declará-los. Essa característica é semelhante à dos arrays na linguagem C. O tamanho
máximo de um VARRAY é de 2 GB, como nas tabelas aninhadas.
• A diferença entre a tabela aninhada e o VARRAY é o modo de armazenamento físico. Os
elementos de um VARRAY são armazenados em linha com os dados da tabela, exceto se o
tamanho do VARRAY for superior a 4 KB. Compare-os com as tabelas aninhadas, que são
sempre armazenadas fora da linha.
• Com o código SQL, é possível criar um tipo VARRAY no banco de dados.
Exemplo:
TYPE location_type IS VARRAY(3) OF locations.city%TYPE;
offices location_type;
O tamanho desse VARRAY é restrito a 3. Você pode inicializar um VARRAY usando
construtores. Se você tentar inicializar o VARRAY com mais de três elementos, será exibida a
mensagem de erro “Subscript outside of limit”.

Oracle Database: Fundamentos de PL/SQL 6 - 27


Resumo dos Tipos de Conjunto

Array associativo

Organizado Organizado
pelo índice pelo índice
PLS_INTEGER 1 2 3 4 5 6 a f i o t w VARCHAR2

Tabela aninhada Varray

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Resumo dos Tipos de Conjunto


Arrays Associativos
Os arrays associativos são conjuntos de pares de valor/chave, em que cada chave é exclusiva e
usada para localizar um valor correspondente no array. A chave pode basear-se em um número
inteiro ou em um caractere. O array pode ter um valor de tipo de dados escalar (único valor) ou
de tipo de dados de registro (vários valores).
Como o objetivo dos arrays associativos é armazenar dados temporários, você não poderá usá-
los com instruções SQL como INSERT e SELECT INTO.
Tabelas Aninhadas
Uma tabela aninhada armazena um conjunto de valores. Em outras palavras, é uma tabela
dentro de outra. Não há limite para as tabelas aninhadas, ou seja, o tamanho delas pode
aumentar dinamicamente. As tabelas aninhadas estão disponíveis no código PL/SQL e no
banco de dados. No código PL/SQL, as tabelas aninhadas são como arrays unidimensionais
cujo tamanho pode aumentar dinamicamente.
Varrays
Os arrays de tamanho variável, ou varrays, também são conjuntos de elementos homogêneos
que armazenam um número fixo de elementos (embora você possa alterar o número de
elementos no runtime). Eles usam números sequenciais como subscripts. Você pode definir
tipos SQL equivalentes, permitindo dessa forma o armazenamento de varrays em tabelas do
banco de dados.
Oracle Database: Fundamentos de PL/SQL 6 - 28
Questionário

Identifique situações em que você possa usar o atributo %ROWTYPE.


a. Quando você não tiver certeza da estrutura da tabela
subjacente do banco de dados
b. Quando você desejar recuperar uma linha inteira de uma
tabela
c. Quando você desejar declarar uma variável de acordo com
outra declarada anteriormente ou com uma coluna do banco
de dados

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Resposta: a, b
Vantagens do Uso do Atributo %ROWTYPE
Use o atributo %ROWTYPE quando você não tiver certeza da estrutura da tabela subjacente do
banco de dados.
A principal vantagem de usar %ROWTYPE é que ele simplifica a manutenção. A utilização de
%ROWTYPE assegura que os tipos de dados das variáveis declaradas com esse atributo serão
dinamicamente alterados caso a tabela subjacente seja alterada. Se uma instrução DDL alterar
as colunas de uma tabela, a unidade do programa PL/SQL será invalidada. Quando o programa
for recompilado, ele refletirá automaticamente o novo formato de tabela.
O atributo %ROWTYPE é particularmente útil se você quiser recuperar uma linha inteira de uma
tabela. Na ausência desse atributo, você teria que declarar uma variável para cada coluna
recuperada pela instrução SELECT.

Oracle Database: Fundamentos de PL/SQL 6 - 29


Sumário

Nesta lição, você aprendeu a:


• Definir e fazer referência a variáveis PL/SQL de tipos de
dados compostos
– Registro PL/SQL
– Array associativo
— Tabela INDEX BY

— Tabela de registros INDEX BY

• Definir um registro PL/SQL usando o atributo %ROWTYPE


• Comparar os três tipos de conjunto PL/SQL:
– Array associativo
– Tabela aninhada
– VARRAY

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Sumário
Um registro PL/SQL é um conjunto de campos individuais que representam uma linha de uma
tabela. Usando registros, você pode agrupar os dados em uma estrutura e, posteriormente,
manipular essa estrutura como uma entidade ou unidade lógica. Isso ajuda a diminuir a
codificação e facilita a compreensão e a manutenção do código.
Assim como os registros PL/SQL, um conjunto PL/SQL é outro tipo de dados composto. Os
conjuntos PL/SQL incluem:
• Arrays associativos (também conhecidos como tabelas INDEX BY). Eles são objetos do
tipo TABLE e são semelhantes às tabelas do banco de dados, mas com uma pequena
diferença. As chamadas tabelas INDEX BY usam uma chave primária para prover acesso
às linhas de modo semelhante a arrays. O tamanho de um array associativo não tem
restrição.
• Tabelas aninhadas. A chave de tabelas aninhadas não pode ter um valor negativo, ao
contrário das tabelas INDEX BY. A chave também deve estar em uma sequência.
• Arrays de tamanho variável (VARRAY). Um VARRAY é semelhante a um array
associativo, a diferença é que um VARRAY tem restrição de tamanho.

Oracle Database: Fundamentos de PL/SQL 6 - 30


Exercício 6: Visão Geral

Este exercício aborda os seguintes tópicos:


• Declarando arrays associativos
• Processando dados usando arrays associativos
• Declarando um registro PL/SQL
• Processando dados usando um registro PL/SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Exercício 6: Visão Geral


Neste exercício, você definirá, criará e usará arrays associativos e registros PL/SQL.

Oracle Database: Fundamentos de PL/SQL 6 - 31


Usando Cursores Explícitos

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.
Objetivos

Ao concluir esta lição, você será capaz de:


• Fazer distinção entre cursores implícitos e explícitos
• Discutir os motivos para usar cursores explícitos
• Declarar e controlar cursores explícitos
• Usar os loop simples e os loops FOR de cursores para
extrair dados com o comando fetch
• Declarar e usar cursores com parâmetros
• Bloquear as linhas com a cláusula FOR UPDATE
• Fazer referência à linha atual com a cláusula WHERE
CURRENT OF

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Objetivos
Você aprendeu sobre os cursores implícitos que são criados automaticamente pelo código
PL/SQL quando você executa uma instrução SQL SELECT ou DML. Nesta lição, você
conhecerá os cursores explícitos. Você aprenderá a diferenciar os cursores implícitos dos
explícitos. Também será ensinado a declarar e controlar cursores simples, bem como cursores
com parâmetros.

Oracle Database: Fundamentos de PL/SQL 7 - 2


Agenda

• O que são cursores explícitos?


• Usando cursores explícitos
• Usando cursores com parâmetros
• Bloqueando linhas e fazendo referência à linha atual

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 7 - 3


Cursores

Cada instrução SQL que é executada pelo Oracle Server tem um


cursor individual associado:
• Cursores implícitos: declarados e gerenciados pelo código
PL/SQL em todas as instruções SELECT de DML e PL/SQL
• Cursores explícitos: declarados e gerenciados pelo
programador

Cursor implícito Cursor explícito

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Cursores
O Oracle Server usa áreas de trabalho (chamadas de áreas SQL privadas) para executar
instruções SQL e armazenar informações sobre o processamento. Você pode usar cursores
explícitos para nomear uma área SQL privada e para acessar as informações armazenadas nela.

Tipo de Cursor Descrição

Implícito Os cursores implícitos são declarados por PL/SQL


implicitamente para todas as instruções DML e PL/SQL
SELECT.
Explícito Para consultas que retornam mais de uma linha, os cursores
explícitos são declarados e gerenciados pelo programador e
manipulados por meio de instruções específicas nas ações
executáveis do bloco.

O Oracle Server abre implicitamente um cursor para processar cada instrução SQL não
associada a um cursor declarado explicitamente. Com o código PL/SQL, é possível fazer
referência ao cursor implícito mais recente como o cursor SQL.

Oracle Database: Fundamentos de PL/SQL 7 - 4


Operações com Cursores Explícitos

Tabela
100 King AD_PRES
101 Kochhar AD_VP
102 De Haan AD_VP
. . .
. . .
. . .
139 Seo ST_CLERK
140 Patel ST_CLERK
Conjunto ativo
. . .

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Operações com Cursores Explícitos


Declare cursores explícitos no código PL/SQL quando você quiser que uma instrução SELECT
retorne várias linhas. Você pode processar cada linha retornada pela instrução SELECT.
O conjunto de linhas retornadas por uma consulta de várias linhas é denominado conjunto ativo..
Seu tamanho é o número de linhas que satisfaz seus critérios de pesquisa. O diagrama no slide
mostra como um cursor explícito “aponta” para a linha atual do conjunto ativo. Isso permite que
seu programa processe as linhas uma de cada vez.
Funções de cursores explícitos:
• Podem executar o processamento, linha por linha, além da primeira linha retornada por
uma consulta
• Controlam a linha que está sendo processada no momento
• Permitem que o programador controle manualmente os cursores explícitos no bloco
PL/SQL

Oracle Database: Fundamentos de PL/SQL 7 - 5


Controlando Cursores Explícitos

Não

Sim
DECLARE OPEN FETCH VAZIO? CLOSE

• Crie uma • Identifique • Carregue • Verifique a • Libere o


área SQL o conjunto a linha existência conjunto
nomeada. ativo. atual em de linhas. ativo.
variáveis.
• Retorne a
FETCH se
forem
encontradas
linhas.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Controlando Cursores Explícitos


Agora que você conhece o conceito de cursor, verifique as etapas para utilizá-los.
1. Declare o cursor na seção declarativa de um bloco PL/SQL, nomeando e definindo a
estrutura da consulta a ser associada a ele.
2. Abra o cursor.
A instrução OPEN executa a consulta e associa todas as variáveis referenciadas. As linhas
identificadas pela consulta são chamadas de conjunto ativo e estão disponíveis para
extração com a instrução FETCH.
3. Extraia dados do cursor.
No diagrama de fluxo mostrado no slide, após cada fetch, teste o cursor em qualquer linha
existente. Se não houver mais linhas para processar, você deverá fechar o cursor.
4. Feche o cursor.
A instrução CLOSE libera o conjunto de linhas ativo. Agora é possível reabrir o cursor para
estabelecer um novo conjunto ativo.

Oracle Database: Fundamentos de PL/SQL 7 - 6


Controlando Cursores Explícitos

1 Abra o cursor.
Ponteiro
do cursor

2 Extraia uma linha


com o comando Ponteiro
fetch. do cursor

Ponteiro
3 Feche o cursor. do cursor

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Controlando Cursores Explícitos (continuação)


Um programa PL/SQL abre um cursor, processa as linhas retornadas por uma consulta e fecha o
cursor. O cursor marca a posição atual no conjunto ativo.
1. A instrução OPEN executa a consulta associada ao cursor, identifica o conjunto ativo e
posiciona o cursor na primeira linha.
2. A instrução FETCH recupera a linha atual e avança o cursor para a próxima
linha até que não existam mais linhas ou que uma condição especificada seja atendida.
3. A instrução CLOSE libera o cursor.

Oracle Database: Fundamentos de PL/SQL 7 - 7


Agenda

• O que são cursores explícitos?


• Usando cursores explícitos
• Usando cursores com parâmetros
• Bloqueando linhas e fazendo referência à linha atual

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 7 - 8


Declarando o Cursor

Sintaxe:

CURSOR cursor_name IS
select_statement;

Exemplos:
DECLARE
CURSOR c_emp_cursor IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;

DECLARE
v_locid NUMBER:= 1700;
CURSOR c_dept_cursor IS
SELECT * FROM departments
WHERE location_id = v_locid;
...

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Declarando o Cursor
A sintaxe para declarar um cursor é mostrada no slide. Na sintaxe:
cursor_name É um identificador PL/SQL
select_statement É uma instrução SELECT sem uma cláusula INTO
O conjunto ativo de um cursor é determinado pela instrução SELECT na declaração do cursor. É
obrigatória a existência de uma cláusula INTO para uma instrução SELECT no código PL/SQL.
Entretanto, observe que a instrução SELECT na declaração do cursor não pode ter uma cláusula
INTO. Isso acontece porque você está apenas definindo um cursor na seção declarativa e não
recuperando linhas para dentro do cursor.
Observação
• Não inclua a cláusula INTO na declaração do cursor porque ela aparecerá mais tarde na
instrução FETCH.
• Se você deseja que as linhas sejam processadas em uma sequência específica, use a
cláusula ORDER BY na consulta.
• O cursor pode ser qualquer instrução SELECT válida, incluindo joins, subconsultas etc.

Oracle Database: Fundamentos de PL/SQL 7 - 9


Declarando o Cursor (continuação)
O cursor c_emp_cursor é declarado para recuperar as colunas employee_id e
last_name daqueles funcionários cujo department_id é 30.
O cursor c_dept_cursor é declarado para recuperar todos os detalhes do departamento com
o location_id 1700. Observe que uma variável é usada na declaração do cursor. Essas
variáveis são consideradas variáveis de bind, e devem estar visíveis durante a declaração do
cursor. Essas variáveis são examinadas apenas uma vez no momento em que o cursor é aberto.
Você aprendeu que os cursores explícitos são usados quando é preciso recuperar e operar várias
linhas no código PL/SQL. Todavia, esse exemplo mostra que será possível usar o cursor
explícito mesmo se a instrução SELECT retornar uma linha.

Oracle Database: Fundamentos de PL/SQL 7 - 10


Abrindo o Cursor

DECLARE
CURSOR c_emp_cursor IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;
...
BEGIN
OPEN c_emp_cursor;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Abrindo o Cursor
A instruçãoOPEN executa a consulta associada ao cursor, identifica o conjunto ativo e posiciona
o cursor na primeira linha. A instrução OPEN é incluída na seção executável do bloco PL/SQL.
OPEN é uma instrução executável que realiza as seguintes operações:
1. Aloca memória dinamicamente para uma área de contexto
2. Efetua parse da instrução SELECT
3. Associa as variáveis de entrada (define os valores para as variáveis de entrada obtendo seus
endereços de memória)
4. Identifica o conjunto ativo (o conjunto de linhas que satisfaz os critérios de pesquisa). As
linhas do conjunto ativo não são recuperadas em variáveis quando a instrução OPEN é
executada. Mais especificamente, é a instrução FETCH que recupera as linhas do cursor
nas variáveis.
5. Posiciona o ponteiro na primeira linha do conjunto ativo.
Observação: Se nenhuma linha for retornada pela consulta quando o cursor for aberto, o código
PL/SQL não gerará uma exceção. Você pode saber o número de linhas retornadas com um
cursor explícito, usando o atributo <cursor_name>%ROWCOUNT.

Oracle Database: Fundamentos de PL/SQL 7 - 11


Extraindo Dados do Cursor

DECLARE
CURSOR c_emp_cursor IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;
v_empno employees.employee_id%TYPE;
v_lname employees.last_name%TYPE;
BEGIN
OPEN c_emp_cursor;
FETCH c_emp_cursor INTO v_empno, v_lname;
DBMS_OUTPUT.PUT_LINE( v_empno ||' '||v_lname);
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Extraindo Dados do Cursor


A instrução FETCH recupera as linhas do cursor uma de cada vez. Após cada extração, o cursor
avança para a linha seguinte no conjunto ativo. É possível usar o atributo %NOTFOUND para
verificar se o conjunto ativo inteiro foi recuperado.
Examine o exemplo mostrado no slide. Duas variáveis, empno e lname, são declaradas para
armazenar os valores obtidos do cursor com o comando fetch. Examine a instrução FETCH.
Os valores foram extraídos com sucesso do cursor para as variáveis. Entretanto, existem seis
funcionários no departamento 30, mas apenas uma linha foi extraída. Para extrair todas as linhas,
é necessário usar loops. No próximo slide, você verá como um loop é usado para extrair todas as
linhas.
A instrução FETCH executa as seguintes operações:
1. Lê os dados da linha atual nas variáveis PL/SQL de saída.
2. Avança o ponteiro para a linha seguinte do conjunto ativo.

Oracle Database: Fundamentos de PL/SQL 7 - 12


Extraindo Dados do Cursor (continuação)
Você pode incluir o mesmo número de variáveis na cláusula INTO da instrução FETCH, como
há colunas na instrução SELECT; certifique-se de que os tipos de dados sejam compatíveis.
Corresponda cada variável às colunas de acordo com a posição. Como alternativa, defina um
registro para o cursor e faça referência ao registro na cláusula FETCH INTO. Por último, teste se
o cursor contém linhas. Se a operação com o comando fetch não adquirir valores, não haverá
linhas restantes para processar e nenhum erro será registrado.

Oracle Database: Fundamentos de PL/SQL 7 - 13


Extraindo Dados do Cursor

DECLARE
CURSOR c_emp_cursor IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;
v_empno employees.employee_id%TYPE;
v_lname employees.last_name%TYPE;
BEGIN
OPEN c_emp_cursor;
LOOP
FETCH c_emp_cursor INTO v_empno, v_lname;
EXIT WHEN c_emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( v_empno ||' '||v_lname);
END LOOP;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Extraindo Dados do Cursor (continuação)


Observe que um LOOP simples é usado para extrair todas as linhas. Além disso, o atributo
%NOTFOUND do cursor é usado para testar a condição de saída. A saída do bloco PL/SQL é
mostrada abaixo:

Oracle Database: Fundamentos de PL/SQL 7 - 14


Fechando o Cursor

...
LOOP
FETCH c_emp_cursor INTO empno, lname;
EXIT WHEN c_emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( v_empno ||' '||v_lname);
END LOOP;
CLOSE c_emp_cursor;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Fechando o Cursor
A instrução CLOSE desativa o cursor, libera a área de contexto e remove a definição do conjunto
ativo. Feche o cursor após concluir o processamento da instrução FETCH. Você poderá reabrir o
cursor se necessário. Um cursor só poderá ser reaberto se ele tiver sido fechado. Se você tentar
extrair dados de um cursor com o comando fetch após ele ter sido fechado, uma exceção
INVALID_CURSOR será gerada.
Observação: Embora seja possível encerrar o bloco PL/SQL sem fechar os cursores, convém
que seja um hábito fechar todos os cursores declarados explicitamente para liberar recursos.
Existe um limite máximo no número de cursores abertos por sessão, que é determinado pelo
parâmetro OPEN_CURSORS no arquivo de parâmetros do banco de dados. (OPEN_CURSORS =
50 por default.)

Oracle Database: Fundamentos de PL/SQL 7 - 15


Cursores e Registros

Processe as linhas do conjunto ativo extraindo valores para um


registro PL/SQL.
DECLARE
CURSOR c_emp_cursor IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;
v_emp_record c_emp_cursor%ROWTYPE;
BEGIN
OPEN c_emp_cursor;
LOOP
FETCH c_emp_cursor INTO v_emp_record;
EXIT WHEN c_emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( v_emp_record.employee_id
||' '||v_emp_record.last_name);
END LOOP;
CLOSE c_emp_cursor;
END;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Cursores e Registros
Você já viu que é possível definir registros que tenham a estrutura de colunas em uma tabela.
Também é possível definir um registro baseado na lista selecionada de colunas de um cursor
explícito. Isso é conveniente para o processamento das linhas do conjunto ativo porque é
possível simplesmente extrair (fetch) para dentro do registro. Portanto, os valores das linhas são
carregados diretamente nos campos correspondentes do registro.

Oracle Database: Fundamentos de PL/SQL 7 - 16


Loops de Cursor FOR

Sintaxe:
FOR record_name IN cursor_name LOOP
statement1;
statement2;
. . .
END LOOP;

• O loop de cursor FOR é um atalho para processar cursores


explícitos.
• Os comandos implícitos open, fetch, exit e close são
executados.
• O registro é declarado implicitamente.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Loops de Cursor FOR


Você aprendeu a extrair dados de cursores com o comando fetch usando loops simples. Agora
você vai aprender a usar um loop FOR de cursor, que processa linhas em um cursor explícito.
Trata-se de um atalho porque o cursor é aberto, uma linha é extraída uma vez para cada iteração
do loop, o loop termina quando a última linha é processada e o cursor é fechado
automaticamente. O loop propriamente dito é encerrado no fim da iteração que extrai a última
linha.
Na sintaxe:
record_name É o nome do registro declarado implicitamente
cursor_name É um identificador PL/SQL para o cursor declarado anteriormente
Diretrizes
• Não declare o registro que controla o loop; ele é declarado implicitamente.
• Se necessário, teste os atributos do cursor durante o loop.
• Se preciso, informe os parâmetros para um cursor entre parênteses após o nome do cursor
na instrução FOR.

Oracle Database: Fundamentos de PL/SQL 7 - 17


Loops de Cursor FOR

DECLARE
CURSOR c_emp_cursor IS
SELECT employee_id, last_name FROM employees
WHERE department_id =30;
BEGIN
FOR emp_record IN c_emp_cursor
LOOP
DBMS_OUTPUT.PUT_LINE( emp_record.employee_id
||' ' ||emp_record.last_name);
END LOOP;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Loops For de Cursor (continuação)


O exemplo para demonstrar o uso de um loop simples na extração de dados dos cursores foi
reescrito para usar o loop FOR de cursor.
emp_record é o registro declarado implicitamente. Você pode acessar os dados extraídos com
esse registro implícito, como mostra o slide. Observe que nenhuma variável é declarada para
armazenar os dados extraídos usando a cláusula INTO. O código não tem instruções OPEN e
CLOSE para abrir e fechar o cursor, respectivamente.

Oracle Database: Fundamentos de PL/SQL 7 - 18


Atributos de Cursores Explícitos

Use os atributos de cursores explícitos para obter as


informações de status sobre um cursor.

Atributo Tipo Descrição

%ISOPEN Booleano Será avaliado como TRUE se o cursor estiver


aberto
%NOTFOUND Booleano Será avaliado como TRUE se a extração mais
recente não retornar uma linha
%FOUND Booleano Será avaliado como TRUE se a extração mais
recente retornar uma linha; complemento de
%NOTFOUND

%ROWCOUNT Número Será avaliado como o número total de linhas


retornadas até agora

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Atributos de Cursores Explícitos


A exemplo dos cursores implícitos, existem quatro atributos para a obtenção de informações de
status sobre um cursor. Quando anexados ao nome da variável do cursor, esses atributos
retornam informações úteis sobre a execução de uma instrução de manipulação de cursor.
Observação:Não é possível fazer referência a atributos de cursores diretamente em uma
instrução SQL.

Oracle Database: Fundamentos de PL/SQL 7 - 19


Atributo %ISOPEN

• Só é possível extrair linhas quando o cursor está aberto.


• Use o atributo de cursor %ISOPEN antes de executar um
comando fetch para saber se o cursor está aberto.
Exemplo:
IF NOT c_emp_cursor%ISOPEN THEN
OPEN c_emp_cursor;
END IF;
LOOP
FETCH c_emp_cursor...

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Atributo %ISOPEN
• Só é possível extrair linhas quando o cursor está aberto. Use o atributo de cursor %ISOPEN
para determinar se o cursor está aberto.
• Extraia linhas em um loop. Use os atributos de cursores para determinar quando sair do
loop.
• Use o atributo de cursor %ROWCOUNT para fazer o seguinte:
- Processar um número exato de linhas.
- Extrair as linhas de um loop com o comando fetch e determinar quando sair do loop.
Observação: %ISOPEN retorna o status do cursor: TRUE se estiver aberto e FALSE se não
estiver aberto.

Oracle Database: Fundamentos de PL/SQL 7 - 20


%ROWCOUNT e %NOTFOUND: Exemplo
DECLARE
CURSOR c_emp_cursor IS SELECT employee_id,
last_name FROM employees;
v_emp_record c_emp_cursor%ROWTYPE;
BEGIN
OPEN c_emp_cursor;
LOOP
FETCH c_emp_cursor INTO v_emp_record;
EXIT WHEN c_emp_cursor%ROWCOUNT > 10 OR
c_emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE( v_emp_record.employee_id
||' '||v_emp_record.last_name);
END LOOP;
CLOSE c_emp_cursor;
END; /

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

%ROWCOUNT e %NOTFOUND: Exemplo


O exemplo no slide recupera os dez primeiros funcionários, um a um. Esse exemplo mostra
como os atributos %ROWCOUNT e %NOTFOUND podem ser usados para condições de saída de
um loop.

Oracle Database: Fundamentos de PL/SQL 7 - 21


Loops For de Cursor Usando Subconsultas

Não é necessário declarar o cursor.


BEGIN
FOR emp_record IN (SELECT employee_id, last_name
FROM employees WHERE department_id =30)
LOOP
DBMS_OUTPUT.PUT_LINE( emp_record.employee_id
||' '||emp_record.last_name);
END LOOP;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Loops For de Cursor Usando Subconsultas


Observe que não há seção declarativa nesse bloco PL/SQL. A diferença entre os loops FOR de
cursor usando subconsultas e o loop FOR de cursor está na declaração do cursor. Se estiver
criando loops FOR de cursor com subconsultas, você não precisará declarar o cursor na seção
declarativa. Você precisará informar a instrução SELECT que determina o conjunto ativo no
loop propriamente dito.
O exemplo usado para ilustrar um loop FOR de cursor foi reescrito para ilustrar um loop FOR de
cursor que utiliza subconsultas.
Observação: Não será possível fazer referência aos atributos de cursores explícitos se você usar
uma subconsulta em um loop FOR de cursor porque você não poderá dar um nome explícito ao
cursor.

Oracle Database: Fundamentos de PL/SQL 7 - 22


Agenda

• O que são cursores explícitos?


• Usando cursores explícitos
• Usando cursores com parâmetros
• Bloqueando linhas e fazendo referência à linha atual

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 7 - 23


Cursores com Parâmetros

Sintaxe:
CURSOR cursor_name
[(parameter_name datatype, ...)]
IS
select_statement;

• Especifique valores de parâmetros para um cursor quando


o cursor for aberto e a consulta for executada.
• Abra um cursor explícito várias vezes com um conjunto
ativo distinto a cada vez.

OPEN cursor_name(parameter_value,.....) ;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Cursores com Parâmetros


Você pode especificar parâmetros para um cursor. Isso significa que você pode abrir e fechar um
cursor explícito várias vezes em um bloco, retornando um conjunto ativo diferente em cada
ocasião. Para cada execução, o cursor anterior é fechado e reaberto com um novo conjunto de
parâmetros.
Cada parâmetro formal na declaração do cursor deve ter um parâmetro real correspondente
na instrução OPEN. Os tipos de dados dos parâmetros são iguais aos das variáveis escalares,
mas você não define seus tamanhos. Os nomes dos parâmetros são para referências na expressão
de consulta do cursor.
Na sintaxe:
cursor_name É um identificador PL/SQL para o cursor declarado
parameter_name É o nome de um parâmetro
datatype É o tipo de dados escalar do parâmetro
select_statement É uma instrução SELECT sem a cláusula INTO

A notação do parâmetro não oferece melhor funcionalidade; ela simplesmente permite que você
especifique valores de entrada com facilidade e clareza. Isso será especialmente útil quando o
mesmo cursor for referido de forma repetitiva.
Oracle Database: Fundamentos de PL/SQL 7 - 24
Cursores com Parâmetros

DECLARE
CURSOR c_emp_cursor (deptno NUMBER) IS
SELECT employee_id, last_name
FROM employees
WHERE department_id = deptno;
...
BEGIN
OPEN c_emp_cursor (10);
...
CLOSE c_emp_cursor;
OPEN c_emp_cursor (20);
...

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Cursores com Parâmetros (continuação)


Os tipos de dados dos parâmetros são iguais aos das variáveis escalares, mas você não define
seus tamanhos. Os nomes dos parâmetros servem para fazer referência na consulta do cursor.
Neste exemplo, um cursor é declarado e definido com um parâmetro:
DECLARE
CURSOR c_emp_cursor(deptno NUMBER) IS SELECT ...
As seguintes instruções abrem o cursor e retornam diferentes conjuntos ativos:
OPEN c_emp_cursor(10);
OPEN c_emp_cursor(20);
Você pode especificar parâmetros para o cursor usado em um loop FOR de cursor:
DECLARE
CURSOR c_emp_cursor(p_deptno NUMBER, p_job VARCHAR2)IS
SELECT ...
BEGIN
FOR emp_record IN c_emp_cursor(10, 'Sales') LOOP ...

Oracle Database: Fundamentos de PL/SQL 7 - 25


Agenda

• O que são cursores explícitos?


• Usando cursores explícitos
• Usando cursores com parâmetros
• Bloqueando linhas e fazendo referência à linha atual

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 7 - 26


Cláusula FOR UPDATE

Sintaxe:
SELECT ...
FROM ...
FOR UPDATE [OF column_reference][NOWAIT | WAIT n];

• Use o bloqueio explícito para negar acesso a outras


sessões no período da transação.
• Bloqueie as linhas antes do comando update ou delete.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Cláusula FOR UPDATE


Se houver várias sessões para um único banco de dados, existirá a possibilidade de que as linhas
de uma tabela sejam atualizadas depois de você ter aberto o cursor. Você verá os dados
atualizados apenas quando reabrir o cursor. Portanto, convém colocar bloqueios nas linhas antes
de atualizá-las ou deletá-las. Você pode bloquear as linhas com a cláusula FOR UPDATE na
consulta do cursor.
Na sintaxe:
column_reference É uma coluna em uma tabela com a qual a consulta
é executada (Também é possível usar uma lista de
colunas.)
NOWAIT Retornará um erro do Oracle Server se as linhas
forem bloqueadas por outra sessão.
A cláusula FOR UPDATE é a última cláusula em uma instrução SELECT, mesmo após ORDER
BY (se ela existir). Quando você quiser consultar várias tabelas, poderá usar a cláusula FOR
UPDATE para restringir o bloqueio de linha a determinadas tabelas. FOR UPDATE OF
col_name(s) bloqueia linhas apenas em tabelas que contêm col_name(s).

Oracle Database: Fundamentos de PL/SQL 7 - 27


Cláusula FOR UPDATE (continuação)
A instrução SELECT ... FOR UPDATE identifica as linhas que serão atualizadas ou deletadas,
e bloqueia cada linha no conjunto de resultados. Isso será útil se você quiser basear uma
atualização nos valores existentes em uma linha. Nesse caso, você deverá se certificar de que a
linha não seja alterada por outra sessão antes da atualização.
A palavra-chave NOWAIT informa ao Oracle Server para não esperar caso as linhas necessárias
tenham sido bloqueadas por outro usuário. O controle será retornado imediatamente ao seu
programa para que ele possa fazer outro trabalho antes de tentar novamente adquirir o bloqueio.
Se você omitir a palavra-chave NOWAIT, o Oracle Server esperará até que as linhas estejam
disponíveis.
Exemplo:
DECLARE
CURSOR c_emp_cursor IS
SELECT employee_id, last_name, FROM employees
WHERE department_id = 80 FOR UPDATE OF salary NOWAIT;
...
Se o Oracle Server não puder adquirir os bloqueios das linhas de que necessita em uma operação
SELECT FOR UPDATE, ele esperará indefinidamente. Use a palavra-chave NOWAIT para tratar
essas situações. Caso as linhas estejam bloqueadas por outra sessão e você tenha especificado
NOWAIT, abrir o cursor resultará em erro. Você poderá tentar abrir o cursor mais tarde. Você
pode usar WAIT no lugar de NOWAIT, especificar o número de segundos para esperar e, em
seguida, determinar se as linhas estão desbloqueadas. Se as linhas ainda estiverem bloqueadas
após n segundos, será retornado um erro.
Não é obrigatória a cláusula FOR UPDATE OF para fazer referência a uma coluna,
mas ela é recomendável para obter melhor legibilidade e manutenção.

Oracle Database: Fundamentos de PL/SQL 7 - 28


Cláusula WHERE CURRENT OF

Sintaxe:
WHERE CURRENT OF cursor ;
• Use cursores para atualizar ou deletar a linha atual.
• Inclua a cláusula FOR UPDATE na consulta do cursor para
bloquear as linhas primeiro.
• Use a cláusula WHERE CURRENT OF para fazer referência
à linha atual de um cursor explícito.
UPDATE employees
SET salary = ...
WHERE CURRENT OF c_emp_cursor;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Cláusula WHERE CURRENT OF


A cláusula WHERE CURRENT OF é usada junto com a cláusula FOR UPDATE para se referir à
linha atual em um cursor explícito. A cláusula WHERE CURRENT OF é usada na instrução
UPDATE ou DELETE, enquanto a cláusula FOR UPDATE é especificada na declaração do
cursor. Você pode usar a combinação para atualizar e deletar a linha atual da tabela
correspondente do banco de dados. Isso permite aplicar atualizações e deleções à linha tratada
no momento sem a necessidade de fazer referência explícita ao ID da linha. Inclua a cláusula
FOR UPDATE na consulta do cursor para que as linhas sejam bloqueadas em OPEN.
Na sintaxe:
cursor É o nome do cursor declarado (o cursor deverá ter sido declarado com a cláusula
FOR UPDATE).

Oracle Database: Fundamentos de PL/SQL 7 - 29


Questionário

Os cursores implícitos são declarados implicitamente por PL/SQL


em todas as instruções SELECT de DML e PL/SQL. O Oracle
Server abre implicitamente um cursor para processar cada
instrução SQL não associada a um cursor declarado
explicitamente.
a. Verdadeiro
b. Falso

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Resposta: a

Oracle Database: Fundamentos de PL/SQL 7 - 30


Sumário

Nesta lição, você aprendeu a:


• Distinguir os tipos de cursores:
– Os cursores implícitos são usados em todas as instruções
DML e consultas de uma linha.
– Os cursores explícitos são usados em consultas com
nenhuma, uma ou mais linhas
• Criar e gerenciar cursores explícitos
• Usar loops simples e loops FOR de cursores para
gerenciar várias linhas nos cursores
• Avaliar o status do cursor usando os atributos de cursor
• Usar as cláusulas FOR UPDATE e WHERE CURRENT OF
para atualizar ou deletar a linha atual extraída

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Sumário
O Oracle Server usa áreas de trabalho para executar instruções SQL e armazenar as informações
de processamento. Você pode usar uma estrutura PL/SQL chamada cursor para nomear uma
área de trabalho e acessar as informações armazenadas. Há dois tipos de cursores: implícitos e
explícitos. O bloco PL/SQL declara implicitamente um cursor para todas as instruções de
manipulação de dados SQL, incluindo consultas que retornam apenas uma linha. No caso das
consultas que retornam várias linhas, você deve declarar explicitamente um cursor para
processar as linhas individualmente.
Os cursores explícitos e as variáveis de cursor têm quatro atributos: %FOUND, %ISOPEN,
%NOTFOUND e %ROWCOUNT. Quando anexados ao nome da variável do cursor, esses atributos
retornam informações úteis sobre a execução de uma instrução SQL. É possível usar atributos de
cursor em instruções procedurais, mas não em instruções SQL.
Use loops simples ou loops FOR de cursor para operar várias linhas extraídas pelo cursor. Se
usar loops simples, você terá de usar os comandos open, fetch e close com o cursor; no entanto,
os loops FOR de cursor fazem isso implicitamente. Se estiver atualizando ou deletando linhas,
bloqueie as linhas com a cláusula FOR UPDATE. Isso assegura que os dados que você está
usando não sejam atualizados por outra sessão depois que você abriu o cursor. Use uma cláusula
WHERE CURRENT OF junto com a cláusula FOR UPDATE para fazer referência à linha atual
extraída pelo cursor.

Oracle Database: Fundamentos de PL/SQL 7 - 31


Exercício 7: Visão Geral

Este exercício aborda os seguintes tópicos:


• Declarando e usando cursores explícitos para consultar
linhas de uma tabela
• Usando um loop FOR de cursor
• Aplicando atributos de cursores para testar o status do
cursor
• Declarando e usando cursores com parâmetros
• Usando as cláusulas FOR UPDATE e WHERE CURRENT OF

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Exercício 7: Visão Geral


Neste exercício, você aplica seu conhecimento de cursores para processar uma série de linhas de
uma tabela e preencher outra tabela com os resultados usando um loop FOR de cursor. Você
também cria um cursor com parâmetros.

Oracle Database: Fundamentos de PL/SQL 7 - 32


Tratando Exceções

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.
Objetivos

Ao concluir esta lição, você será capaz de:


• Definir exceções PL/SQL
• Reconhecer exceções não resolvidas
• Listar e usar diferentes tipos de handlers de exceções
PL/SQL
• Interceptar erros inesperados
• Descrever o efeito da propagação da exceção em blocos
aninhados
• Personalizar mensagens de exceção PL/SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Objetivos
Você aprendeu a criar blocos PL/SQL contendo uma seção declarativa e uma seção executável.
Todos os códigos SQL e PL/SQL que precisam ser executados são gravados no bloco
executável.
Até agora, pressupomos que o código funcionará bem se tomarmos cuidado com os erros que
ocorrem no momento da compilação. No entanto, o código pode causar alguns erros inesperados
durante o runtime. Nesta lição, você aprenderá a tratar esses erros no bloco PL/SQL.

Oracle Database: Fundamentos de PL/SQL 8 - 2


Agenda

• Fundamentos das exceções PL/SQL


• Interceptando exceções

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 8 - 3


O Que É uma Exceção?
DECLARE
v_lname VARCHAR2(15);
BEGIN
SELECT last_name INTO v_lname
FROM employees
WHERE first_name='John';
DBMS_OUTPUT.PUT_LINE ('John''s last name is :' ||v_lname);
END;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

O Que É uma Exceção?


Examine o exemplo mostrado no slide. Não existem erros de sintaxe no código, o que significa
que você conseguirá executar o bloco anônimo com sucesso. A instrução SELECT do bloco
recupera o sobrenome John.
Entretanto, você verá o seguinte relatório de erro ao executar o código:

O código não funciona como esperado. Você esperava que a instrução SELECT recuperasse
apenas uma linha; entretanto, ela recupera várias linhas. Esses erros que ocorrem durante o
runtime são denominados exceções. Se ocorrer uma exceção, o bloco PL/SQL será encerrado. É
possível tratar essas exceções no bloco PL/SQL.

Oracle Database: Fundamentos de PL/SQL 8 - 4


Tratando a Exceção: Exemplo
DECLARE
v_lname VARCHAR2(15);
BEGIN
SELECT last_name INTO v_lname
FROM employees
WHERE first_name='John';
DBMS_OUTPUT.PUT_LINE ('John''s last name is :' ||v_lname);
EXCEPTION
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE (' Your select statement retrieved
multiple rows. Consider using a cursor.');
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Tratando a Exceção: Exemplo


Você aprendeu a criar blocos PL/SQL contendo uma seção declarativa (iniciando com a palavra-
chave DECLARE) e uma seção executável (iniciando e terminando com as palavras-chave
BEGIN e END, respectivamente).
Para o tratamento de exceções, inclua outra seção opcional chamada seção de exceções.
• Essa seção começa com a palavra-chave EXCEPTION.
• Quando presente, essa deverá ser a última seção de um bloco PL/SQL.
Exemplo
No exemplo do slide, o código do slide anterior foi reescrito para tratar a exceção gerada. A
saída do código também é mostrada no slide.
Quando você adiciona a seção EXCEPTION do código, o programa PL/SQL não é encerrado
abruptamente. Se a exceção for gerada, o controle passará para a seção de exceções e todas as
instruções dessa seção serão executadas. O bloco PL/SQL será encerrado normalmente, com
sucesso.

Oracle Database: Fundamentos de PL/SQL 8 - 5


Fundamentos das Exceções com PL/SQL

• Uma exceção é um erro PL/SQL gerado durante a


execução de um programa.
• Uma exceção pode ser gerada:
– Implicitamente pelo Oracle Server
– Explicitamente pelo programa
• Uma exceção pode ser tratada:
– Ao ser interceptada por um handler
– Ao ser propagada para o ambiente de chamada

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Fundamentos das Exceções com PL/SQL


Uma exceção é um erro no código PL/SQL gerado durante a execução de um bloco. Um bloco é
sempre encerrado quando o código PL/SQL gera uma exceção, mas você pode especificar um
handler de exceção para executar ações finais antes do encerramento do bloco.
Dois Métodos para Gerar uma Exceção
• Um erro Oracle ocorre, e a exceção associada é gerada automaticamente. Por exemplo, se
o erro ORA-01403 ocorrer quando nenhuma linha for recuperada do banco de dados em
uma instrução SELECT, o código PL/SQL gerará a exceção NO_DATA_FOUND. Esses
erros são convertidos em exceções predefinidas.
• Dependendo da funcionalidade de negócios que o seu programa estiver implementando,
será necessário gerar uma exceção explicitamente. Para gerar uma exceção explicitamente,
execute a instrução RAISE no bloco. A exceção gerada pode ser predefinida ou definida
pelo usuário. Existem alguns erros Oracle não predefinidos. Esses são os erros Oracle
padrão não predefinidos. Você pode declarar explicitamente as exceções e associá-las a
erros Oracle não predefinidos.

Oracle Database: Fundamentos de PL/SQL 8 - 6


Tratando Exceções

A
exceção
foi inter- Encerre
ceptada? Não abruptamente.

Sim

A exceção Execute instruções Propague a


foi gerada. na seção EXCEPTION exceção.
.

Encerre
normalmente.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Tratando Exceções
Interceptando uma Exceção
Inclua uma seção EXCEPTION no programa PL/SQL para interceptar exceções. Se a exceção
for gerada na seção executável do bloco, o processamento será ramificado para o handler de
exceção correspondente na seção de exceções do bloco. Se o código PL/SQL tratar a exceção
com sucesso, ela não será propagada para o bloco que a contém ou para o ambiente de chamada.
O bloco PL/SQL será encerrado com sucesso.
Propagando uma Exceção
Se a exceção for gerada na seção executável do bloco e não houver um handler de exceções
correspondente, o bloco PL/SQL será encerrado com falha e a exceção se propagará a um bloco
que o contém ou ao ambiente de chamada. O ambiente de chamada pode ser qualquer aplicação,
como o SQL*Plus, que chame o programa PL/SQL.

Oracle Database: Fundamentos de PL/SQL 8 - 7


Tipos de Exceções



Predefinidas no Oracle Server
Não Predefinidas no Oracle Server } Geradas
implicitamente

• Definidas pelo usuário Geradas explicitamente

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Tipos de Exceções
Há três tipos de exceções.
Exceção Descrição Instruções para Tratamento
Erro predefinido do Um dos, Você não precisa declarar essas
Oracle Server aproximadamente, 20 exceções. Elas são predefinidas pelo
erros que ocorrem com Oracle Server e são emitidas
mais freqüência na implicitamente.
linguagem PL/SQL
Erro não Qualquer outro erro Você precisa declará-los na seção
predefinido do padrão do Oracle Server declarativa; o servidor Oracle gera o
Oracle Server erro implicitamente, e você pode
detectar o erro no handler de
exceção.
Erro definido pelo Uma condição que o Você precisa declarar dentro da
usuário desenvolvedor definiu seção declarativa e emitir
como anormal explicitamente.
Observação: Algumas ferramentas de aplicações com PL/SQL no lado cliente (como o Oracle
Developer Forms) possuem suas próprias exceções.

Oracle Database: Fundamentos de PL/SQL 8 - 8


Agenda

• Fundamentos das exceções PL/SQL


• Interceptando exceções

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 8 - 9


Sintaxe para Interceptar Exceções

EXCEPTION
WHEN exception1 [OR exception2 . . .] THEN
statement1;
statement2;
. . .
[WHEN exception3 [OR exception4 . . .] THEN
statement1;
statement2;
. . .]
[WHEN OTHERS THEN
statement1;
statement2;
. . .]

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Sintaxe para Interceptar Exceções


É possível interceptar qualquer erro, incluindo um handler correspondente dentro da seção de
tratamento de exceções do bloco PL/SQL. Cada handler consiste em uma cláusula WHEN, que
especifica um nome de exceção, seguida de uma sequência de instruções a serem executadas
quando essa exceção for gerada.
É possível incluir inúmeros handlers dentro de uma seção EXCEPTION para tratar exceções
específicas. No entanto, não é possível ter vários handlers para uma única exceção.
A sintaxe de interceptação de exceções contém os seguintes elementos:

exception É o nome padrão de uma exceção predefinida ou o nome de uma


exceção definida pelo usuário declarada dentro da seção declarativa
statement É uma ou mais instruções PL/SQL ou SQL
OTHERS É uma cláusula de tratamento de exceções opcional que intercepta
qualquer exceção que não foi explicitamente tratada

Oracle Database: Fundamentos de PL/SQL 8 - 10


Sintaxe para Interceptar Exceções (continuação)
Handler de Exceção WHEN OTHERS
Como mencionado anteriormente, a seção de tratamento de exceções intercepta apenas as
exceções especificadas.
Para interceptar qualquer exceção não especificada, use o handler de exceção OTHERS. Essa
opção intercepta qualquer exceção ainda não tratada. Por isso, se o handler OTHERS for usado,
ele deverá ser o último handler de exceção definido.
Por exemplo:
WHEN NO_DATA_FOUND THEN
statement1;
...
WHEN TOO_MANY_ROWS THEN
statement1;
...
WHEN OTHERS THEN
statement1;
Exemplo
Considere o exemplo anterior. Se a exceção NO_DATA_FOUND for gerada pelo programa, as
instruções do handler correspondente serão executadas. Se a exceção TOO_MANY_ROWS for
gerada, as instruções do handler correspondente serão executadas. Entretanto, se alguma outra
exceção for gerada, as instruções no handler de exceções OTHERS serão executadas.
O handler OTHERS intercepta todas as exceções ainda não interceptadas. Algumas ferramentas
Oracle têm suas próprias exceções predefinidas que podem ser geradas para causar eventos na
aplicação. O handler OTHERS também intercepta essas exceções.

Oracle Database: Fundamentos de PL/SQL 8 - 11


Diretrizes para Interceptar Exceções

• A palavra-chave EXCEPTION inicia a seção de tratamento


de exceções.
• São permitidos vários handlers de exceções.
• Apenas um handler será processado antes de deixar o
bloco.
• WHEN OTHERS é a última cláusula.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Diretrizes para Interceptar Exceções


• Inicie a seção de tratamento de exceções do bloco com a palavra-chave EXCEPTION.
• Defina vários handlers de exceções, cada um com seu próprio conjunto de ações, para o
bloco.
• Se ocorrer uma exceção, o código PL/SQL processará apenas um handler antes de deixar o
bloco.
• Coloque a cláusula OTHERS depois de todas as outras cláusulas de tratamento de
exceções.
• Você só pode ter uma cláusula OTHERS.
• .As exceções não podem aparecer em instruções de atribuição ou instruções SQL.

Oracle Database: Fundamentos de PL/SQL 8 - 12


Interceptando Erros Predefinidos do Servidor Oracle

• Faça referência ao nome predefinido na rotina de


tratamento de exceções.
• Exemplos de exceções predefinidas:
– NO_DATA_FOUND
– TOO_MANY_ROWS
– INVALID_CURSOR
– ZERO_DIVIDE
– DUP_VAL_ON_INDEX

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Interceptando Erros Predefinidos do Servidor Oracle


Intercepte um erro predefinido do Oracle Server fazendo referência a seu nome predefinido na
rotina de tratamento de exceções correspondente.
Para obter uma lista completa das exceções predefinidas, consulte o manual PL/SQL User’s
Guide and Reference.
Observação: O código PL/SQL declara as exceções predefinidas no pacote STANDARD.

Oracle Database: Fundamentos de PL/SQL 8 - 13


Exceções Predefinidas
Nome da Exceção Número Descrição
do Erro
do
Servidor
Oracle
ACCESS_INTO_NULL ORA- Tentativa de designar valores aos
06530 atributos de um objeto não inicializado
CASE_NOT_FOUND ORA- Nenhuma das opções das cláusulas WHEN
06592 de uma instrução CASE foi selecionada, e
não existe nenhuma cláusula ELSE.
COLLECTION_IS_NULL ORA- Tentativa de aplicar métodos de coleta
06531 diferentes de EXISTS a uma tabela
aninhada inicializada ou um VARRAY
CURSOR_ALREADY_OPEN ORA- Tentativa de abrir um cursor que já estava
06511 aberto
DUP_VAL_ON_INDEX ORA- Tentativa de inserir um valor duplicado
00001
INVALID_CURSOR ORA- Operação com cursor inválido.
01001
INVALID_NUMBER ORA- Falha na conversão de string de caracteres
01722 em número.
LOGIN_DENIED ORA- Logon no servidor Oracle com nome de
01017 usuário ou senha inválidos
NO_DATA_FOUND ORA- SELECT de uma única linha não retornou
01403 dados.
NOT_LOGGED_ON ORA- O programa PL/SQL executa uma
01012 chamada de banco de dados sem estar
conectado ao servidor Oracle.
PROGRAM_ERROR ORA- O código PL/SQL tem um problema
06501 interno.
ROWTYPE_MISMATCH ORA- A variável de cursor host e variável de
06504 cursor PL/SQL envolvidas em uma
designação têm tipos de retorno
incompatíveis.

Oracle Database: Fundamentos de PL/SQL 8 - 14


Exceções Predefinidas (continuação)

Nome da Exceção Número do Descrição


Erro do
Servidor
Oracle

STORAGE_ERROR ORA- O código PL/SQL está sem memória ou a


06500 memória está danificada.
SUBSCRIPT_BEYOND_COUNT ORA- Referência a uma tabela aninhada ou um
06533 elemento VARRAY usando um número de
índice maior que o número de elementos do
conjunto
SUBSCRIPT_OUTSIDE_LIMIT ORA- Referência a uma tabela aninhada ou um
06532 elemento VARRAY usando um número de
índice que está fora da faixa válida (por
exemplo, –1)
SYS_INVALID_ROWID ORA- Falha na conversão de uma string de caracteres
01410 em um ROWID universal porque a string não
representa um ROWID válido.
TIMEOUT_ON_RESOURCE ORA- Timeout enquanto o servidor Oracle esperava
00051 por um recurso.
TOO_MANY_ROWS ORA- SELECT de uma única linha retornou várias
01422 linhas.
VALUE_ERROR ORA- Erro aritmético, de conversão, de truncamento
06502 ou de restrição de tamanho.
ZERO_DIVIDE ORA- Tentativa de divisão por zero.
01476

Oracle Database: Fundamentos de PL/SQL 8 - 15


Interceptando Erros Não
Predefinidos do Servidor Oracle

Fazer
Declarar Associar
Referência

Seção declarativa Seção EXCEPTION

Nomeie a Use PRAGMA Trate a exceção


exceção. EXCEPTION_INIT. gerada.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Interceptando Erros Não Predefinidos do Servidor Oracle


Exceções não predefinidas são semelhantes às predefinidas; contudo, elas não são definidas
como exceções PL/SQL no Oracle Server. Elas são os erros Oracle padrão. Você pode criar
exceções com os erros Oracle padrão usando a função PRAGMA EXCEPTION_INIT. Essas
exceções são denominadas exceções não predefinidas.
Declare um erro não predefinido do Oracle Server para interceptá-lo. A exceção declarada será
gerada implicitamente. No código PL/SQL, a função PRAGMA EXCEPTION_INIT instrui o
compilador a associar um nome de exceção a um número de erro Oracle. Isso permite que você
faça referência a qualquer exceção interna pelo nome e crie um handler específico para ela.
Observação: PRAGMA (também chamada pseudoinstruções) é a palavra-chave que identifica a
instrução como uma diretiva de compilador, que não será processada quando o bloco PL/SQL
for executado. Em vez disso, ela direciona o compilador PL/SQL a interpretar todas as
ocorrências do nome da exceção dentro do bloco como o número de erro associado ao Oracle
Server.

Oracle Database: Fundamentos de PL/SQL 8 - 16


Interceptação de Erro Não Predefinido: Exemplo
Para interceptar o erro do Oracle Server 01400 (“cannot insert
NULL”):
DECLARE
e_insert_excep EXCEPTION; 1
PRAGMA EXCEPTION_INIT(e_insert_excep, -01400); 2
BEGIN
INSERT INTO departments
(department_id, department_name) VALUES (280, NULL);
EXCEPTION 3
WHEN e_insert_excep THEN
DBMS_OUTPUT.PUT_LINE('INSERT OPERATION FAILED');
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Interceptação de Erro Não Predefinido: Exemplo


O exemplo ilustra as três etapas associadas à interceptação de um erro não predefinido:
1. Declare o nome da exceção na seção declarativa, usando a sintaxe:
exception EXCEPTION;
Na sintaxe, exception é o nome da exceção.
2. Associe a exceção declarada ao número de erro padrão do Oracle Server usando a função
PRAGMA EXCEPTION_INIT. Use a seguinte sintaxe:
PRAGMA EXCEPTION_INIT(exception, error_number);
Na sintaxe, exception é a exceção declarada anteriormente e error_number é um
número de erro padrão do Oracle Server.
3. Faça referência à exceção declarada na rotina correspondente de tratamento de exceções.
Exemplo
O exemplo do slide tenta inserir o valor NULL para a coluna department_name da tabela
departments. Entretanto, a operação não é bem-sucedida porque department_name é
uma coluna NOT NULL. Observe a seguinte linha do exemplo:
DBMS_OUTPUT.PUT_LINE(SQLERRM);
A função SQLERRM é usada para recuperar a mensagem de erro. Você aprenderá mais sobre
SQLERRM nos próximos slides.

Oracle Database: Fundamentos de PL/SQL 8 - 17


Funções para Interceptar Exceções

• SQLCODE: Retorna o valor numérico para o código de erro


• SQLERRM: Retorna a mensagem associada ao número de
erro

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Funções para Interceptar Exceções


Se ocorrer uma exceção, você poderá identificar o código de erro associado ou a mensagem de
erro associada usando duas funções. Com base nos valores do código ou na mensagem, você
poderá decidir quais as ações subsequentes a serem tomadas.
SQLCODE retorna o número de erro Oracle para exceções internas. SQLERRM retorna a
mensagem associada ao número de erro.
Função Descrição
SQLCODE Retorna o valor numérico do código de erro (Você pode designá-lo a
uma variável NUMBER.)
SQLERRM Retorna dados de caracteres contendo a mensagem associada ao número
do erro
Valores
SQLCODE: Exemplos
Valor SQLCODE Descrição
0 Nenhuma exceção encontrada
1 Exceção definida pelo usuário
+100 Exceção NO_DATA_FOUND
negative number Número de erro de outro servidor Oracle

Oracle Database: Fundamentos de PL/SQL 8 - 18


Funções para Interceptar Exceções

DECLARE
error_code NUMBER;
error_message VARCHAR2(255);
BEGIN
...
EXCEPTION
...
WHEN OTHERS THEN
ROLLBACK;
error_code := SQLCODE ;
error_message := SQLERRM ;
INSERT INTO errors (e_user, e_date, error_code,
error_message) VALUES(USER,SYSDATE,error_code,
error_message);
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Funções para Interceptar Exceções (continuação)


Quando uma exceção for interceptada no handler de exceções WHEN OTHERS, você poderá usar
um conjunto de funções genéricas para identificar esse erro. O exemplo do slide ilustra os
valores de SQLCODE e SQLERRM sendo associados a variáveis e, em seguida, essas variáveis
sendo usadas em uma instrução SQL.
Não é possível usar SQLCODE ou SQLERRM diretamente em uma instrução SQL. Em vez disso,
você deverá designar seus valores a variáveis locais e, em seguida, usar as variáveis em
instruções SQL, como é mostrado neste exemplo:
DECLARE
err_num NUMBER;
err_msg VARCHAR2(100);
BEGIN
...
EXCEPTION
...
WHEN OTHERS THEN
err_num := SQLCODE;
err_msg := SUBSTR(SQLERRM, 1, 100);
INSERT INTO errors VALUES (err_num, err_msg);
END;
/
Oracle Database: Fundamentos de PL/SQL 8 - 19
Interceptando Exceções Definidas pelo Usuário

Declarar Gerar Fazer Referência

Seção Seção Seção de


declarativa executável tratamento de exceções

Nomeie a Gere a exceção Trate a exceção


exceção. explicitamente gerada.
usando a
instrução RAISE.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Interceptando Exceções Definidas pelo Usuário


O código PL/SQL permite que você defina suas próprias exceções de acordo com os requisitos
da aplicação. Por exemplo, você pode solicitar que o usuário informe um número de
departamento.
Defina uma exceção para tratar condições de erro nos dados de entrada. Verifique se o número
de departamento existe. Se não existir, você deverá gerar uma exceção definida pelo usuário.
As exceções PL/SQL devem ser:
• Declaradas na seção declarativa de um bloco PL/SQL
• Geradas explicitamente com instruções RAISE
• Tratadas na seção EXCEPTION

Oracle Database: Fundamentos de PL/SQL 8 - 20


Interceptando Exceções Definidas pelo Usuário
DECLARE
v_deptno NUMBER := 500;
v_name VARCHAR2(20) := 'Testing';
e_invalid_department EXCEPTION; 1
BEGIN
UPDATE departments
SET department_name = v_name
WHERE department_id = v_deptno;
IF SQL%NOTFOUND THEN
RAISE e_invalid_department; 2
END IF;
COMMIT;
EXCEPTION
3
WHEN e_invalid_department THEN
DBMS_OUTPUT.PUT_LINE('No such department id.');
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Interceptando Exceções Definidas pelo Usuário (continuação)


Para interceptar uma exceção definida pelo usuário, declare e gere essa exceção explicitamente.
1. Declare o nome da exceção definida pelo usuário dentro da seção declarativa.
Sintaxe:
exception EXCEPTION;
Na sintaxe, exception é o nome da exceção.
2. Use a instrução RAISE para gerar a exceção explicitamente na seção executável.
Sintaxe:
RAISE exception;
Na sintaxe, exception é a exceção declarada anteriormente.
3. Faça referência à exceção declarada na rotina correspondente de tratamento de exceções.
Exemplo
O bloco mostrado no slide atualiza o valor de department_name de um departamento. O
usuário informa o número do departamento e o novo nome. Se o número do departamento
fornecido não existir, nenhuma linha será atualizada na tabela departments. . Uma exceção
é gerada e uma mensagem é impressa para o usuário notificando-o de que um número de
departamento inválido foi informado.

Observação:Use a instrução RAISE sozinha dentro de um handler de exceções para gerar


novamente a mesma exceção e propagá-la de volta para o ambiente de chamada.
Oracle Database: Fundamentos de PL/SQL 8 - 21
Propagando Exceções em um Sub-bloco

DECLARE
. . .
e_no_rows exception;
e_integrity exception;
PRAGMA EXCEPTION_INIT (e_integrity, -2292);
BEGIN
FOR c_record IN emp_cursor LOOP
BEGIN
Os sub-blocos podem SELECT ...
tratar uma exceção ou UPDATE ...
transmiti-la para o IF SQL%NOTFOUND THEN
bloco que os contém. RAISE e_no_rows;
END IF;
END;
END LOOP;
EXCEPTION
WHEN e_integrity THEN ...
WHEN e_no_rows THEN ...
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Propagando Exceções em um Sub-bloco


Quando um sub-bloco trata uma exceção, ele é encerrado normalmente. O controle é retomado
no bloco que o contém imediatamente após a instrução END do sub-bloco.
Entretanto, se um código PL/SQL gerar uma exceção e o bloco atual não tiver um handler para
essa exceção, ela será propagada para os blocos que o contêm até encontrar um handler. Se
nenhum desses blocos tratar a exceção, será gerada uma exceção não tratada no ambiente host.
Quando a exceção se propagar para um bloco que contém outros, as ações executáveis restantes
nesse bloco serão ignoradas.
Uma vantagem desse comportamento é que você pode incluir instruções que necessitam de um
tratamento exclusivo de erros em blocos próprios, e deixar o tratamento geral de exceções para o
bloco que os contém.
Observe no exemplo que as exceções (no_rows e integrity) são declaradas no bloco
externo. No bloco interno, quando é gerada a exceção no_rows, o código PL/SQL procura
fazer com que a exceção seja tratada no sub-bloco. Como a exceção não é resolvida no sub-
bloco, a exceção é propagada para o bloco externo, onde o código PL/SQL encontra o handler.

Oracle Database: Fundamentos de PL/SQL 8 - 22


Procedure RAISE_APPLICATION_ERROR

Sintaxe:
raise_application_error (error_number,
message[, {TRUE | FALSE}]);

• Você pode usar esse procedure para gerar mensagens de


erro definidas pelo usuário em subprogramas
armazenados.
• É possível reportar erros à aplicação e evitar o retorno de
exceções não resolvidas.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Procedure RAISE_APPLICATION_ERROR
Use o procedure RAISE_APPLICATION_ERROR para comunicar interativamente uma
exceção predefinida, retornando uma mensagem e um código de erro não padrão. Com
RAISE_APPLICATION_ERROR, é possível reportar erros à aplicação e evitar o retorno de
exceções não tratadas.
Na sintaxe:

error_number É um número especificado pelo usuário para a exceção entre –


20.000 e –20.999
message É a mensagem especificada pelo usuário para a exceção; consiste em
uma string de caracteres com até 2.048 bytes
TRUE | FALSE É um parâmetro booleano opcional (se TRUE, o erro será colocado
na pilha de erros anteriores. Se o valor for FALSE, que é o default, o
erro substituirá todos os erros anteriores.)

Oracle Database: Fundamentos de PL/SQL 8 - 23


Procedure RAISE_APPLICATION_ERROR

• É usado em dois locais diferentes:


– Seção executável
– Seção de exceções
• Retorna condições de erro ao usuário, de modo
consistente com outros erros do Oracle Server

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Procedure RAISE_APPLICATION_ERROR (continuação)


É possível usar o procedure RAISE_APPLICATION_ERROR na seção executável, na seção de
exceções ou nas duas seções de um programa PL/SQL. O erro retornado será consistente com o
modo como o Oracle Server produz um erro predefinido, não predefinido ou definido pelo
usuário. O número e a mensagem do erro são exibidos para o usuário.

Oracle Database: Fundamentos de PL/SQL 8 - 24


Procedure RAISE_APPLICATION_ERROR

Seção executável:
BEGIN
...
DELETE FROM employees
WHERE manager_id = v_mgr;
IF SQL%NOTFOUND THEN
RAISE_APPLICATION_ERROR (-20202,
'This is not a valid manager');
END IF;
...

Seção de exceções:
...
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR (-20201,
'Manager is not a valid employee.');
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Procedure RAISE_APPLICATION_ERROR (continuação)


O slide mostra que o procedure RAISE_APPLICATION_ERROR pode ser usado tanto na seção
executável quanto na de exceções de um programa PL/SQL.
Veja um outro exemplo de uso do procedure RAISE_APPLICATION_ERROR:
DECLARE
e_name EXCEPTION;
BEGIN
...
DELETE FROM employees
WHERE last_name = 'Higgins';
IF SQL%NOTFOUND THEN RAISE e_name;
END IF;
EXCEPTION
WHEN e_name THEN
RAISE_APPLICATION_ERROR (-20999, 'This is not a valid
last name'); ...
END;
/

Oracle Database: Fundamentos de PL/SQL 8 - 25


Questionário

É possível interceptar qualquer erro, incluindo um handler


correspondente dentro da seção de tratamento de exceções
do bloco PL/SQL.
a. Verdadeiro
b. Falso

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Resposta: a
É possível interceptar qualquer erro, incluindo um handler correspondente dentro da seção de
tratamento de exceções do bloco PL/SQL. Cada handler consiste em uma cláusula WHEN, que
especifica um nome de exceção, seguida de uma sequência de instruções a serem executadas
quando essa exceção for gerada. É possível incluir inúmeros handlers dentro de uma seção
EXCEPTION para tratar exceções específicas. No entanto, não é possível ter vários handlers
para uma única exceção.

Oracle Database: Fundamentos de PL/SQL 8 - 26


Sumário

Nesta lição, você aprendeu a:


• Definir exceções PL/SQL
• Adicionar uma seção EXCEPTION ao bloco PL/SQL para
lidar com exceções durante o runtime
• Tratar diferentes tipos de exceções:
– Exceções predefinidas
– Exceções não predefinidas
– Exceções definidas pelo usuário
• Propagar exceções em blocos aninhados e chamar
aplicações

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Sumário
Nesta lição, você aprendeu a lidar com diferentes tipos de exceções. No código PL/SQL, uma
condição de advertência ou erro durante o runtime é chamada de exceção. As exceções
predefinidas são condições de erro que foram definidas pelo Oracle Server. As exceções não
predefinidas podem ser quaisquer erros padrão do Oracle Server. As exceções definidas pelo
usuário são exceções específicas da sua aplicação. A função PRAGMA EXCEPTION_INIT pode
ser usada para associar um nome de exceção declarada a um erro do Oracle Server.
Você pode definir suas próprias exceções na parte declarativa de um bloco PL/SQL. Por
exemplo, você pode definir a exceção INSUFFICIENT_FUNDS para identificar contas
bancárias com saldo insuficiente.
Se ocorrer um erro, será gerada uma exceção. A execução normal é interrompida e o controle é
transferido para a seção de tratamento de exceções do bloco PL/SQL. As exceções internas são
geradas implicitamente (automaticamente) pelo sistema durante o runtime; contudo, as exceções
definidas pelo usuário devem ser geradas explicitamente. Para tratar as exceções geradas, crie
rotinas separadas chamadas handlers de exceções.

Oracle Database: Fundamentos de PL/SQL 8 - 27


Exercício 8: Visão Geral

Este exercício aborda os seguintes tópicos:


• Criar e chamar exceções definidas pelo usuário
• Tratando exceções nomeadas do Oracle Server

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Exercício 8: Visão Geral


Nestes exercícios, você criará handlers de exceção para uma exceção predefinida e uma exceção
padrão do Oracle Server.

Oracle Database: Fundamentos de PL/SQL 8 - 28


Apresentando Procedures
e Funções Armazenados

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.
Objetivos

Ao concluir esta lição, você será capaz de:


• Diferenciar blocos anônimos de subprogramas
• Criar um procedure simples e chamá-lo a partir de um
bloco anônimo
• Criar uma função simples
• Criar uma função simples que aceite um parâmetro
• Diferenciar procedures de funções

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Objetivos
Você já aprendeu sobre os blocos anônimos. Esta lição apresenta os blocos nomeados, também
chamados de subprogramas. Os procedures e as funções são denominados subprogramas
PL/SQL. Nesta lição, você aprenderá a fazer a distinção entre blocos anônimos e subprogramas.

Oracle Database: Fundamentos de PL/SQL 9 - 2


Agenda

• Apresentando procedures e funções


• Visualizando procedures
• Visualizando funções

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 9 - 3


Procedures e Funções

• São blocos PL/SQL nomeados


• São chamados de subprogramas PL/SQL
• Possuem estruturas de blocos semelhantes aos blocos
anônimos:
– Seção declarativa opcional (sem a palavra-chave DECLARE)
– Seção executável obrigatória
– Seção opcional para tratar exceções

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Procedures e Funções
Até este ponto, blocos anônimos foram os únicos exemplos do código PL/SQL abordado neste
curso. Como o nome indica, os blocos anônimos são blocos PL/SQL executáveis não nomeados.
Como não são nomeados, eles não podem ser reutilizados nem armazenados para uso posterior.
Procedures e funções são blocos PL/SQL nomeados, também conhecidos como subprogramas.
Esses subprogramas são compilados e armazenados no banco de dados. A estrutura de bloco dos
subprogramas é semelhante à estrutura dos blocos anônimos. Os subprogramas podem ser
declarados não apenas no nível do esquema, mas também dentro de qualquer outro bloco
PL/SQL. Um subprograma contém as seguintes seções:
• Seção declarativa:Os subprogramas podem ter uma seção declarativa opcional. No
entanto, ao contrário dos blocos anônimos, a seção declarativa de um subprograma não
começa com a palavra-chave DECLARE. A seção declarativa opcional usa a palavra-chave
IS ou AS na declaração do subprograma.
• Seção executável: Esta é a seção obrigatória do subprograma, que contém a
implementação da lógica de negócios. Observando o código desta seção, você pode
facilmente determinar a funcionalidade do subprograma. Esta seção começa e termina com
as palavras-chave BEGIN e END, respectivamente.
• Seção de exceções: Esta é uma seção opcional que é incluída para tratar exceções.

Oracle Database: Fundamentos de PL/SQL 9 - 4


Diferenças entre Blocos Anônimos
e Subprogramas

Blocos Anônimos Subprogramas


Blocos PL/SQL não nomeados Blocos PL/SQL nomeados
Compilados todas as vezes Compilados apenas uma vez
Não armazenados no banco de Armazenados no banco de dados
dados
Não podem ser chamados por São nomeados e, portanto, podem ser
outra aplicação chamados por outras aplicações
Não retornam valores Se forem funções, devem retornar valores

Não podem aceitar parâmetros Podem aceitar parâmetros

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Diferenças entre Blocos Anônimos e Subprogramas


A tabela do slide não mostra apenas as diferenças entre blocos anônimos e subprogramas, mas
também destaca as vantagens dos subprogramas.
Os blocos anônimos não são objetos de banco de dados persistentes. Eles são compilados sempre
que estiverem prestes a ser executados. Eles não são armazenados no banco de dados para
reutilização. Se quiser reutilizá-los, você deverá executar novamente o script que cria o bloco
anônimo, o que causará a recompilação e a execução.
Procedures e funções são compilados e armazenados no banco de dados em formato compilado.
Eles serão recompilados apenas se forem modificados. Como as funções e os procedures são
armazenados no banco de dados, qualquer aplicação pode usar esses subprogramas com base em
permissões apropriadas. A aplicação que está fazendo a chamada poderá especificar parâmetros
para os procedures se eles tiverem sido projetados para aceitar parâmetros. Da mesma forma,
uma aplicação que está fazendo uma chamada poderá recuperar um valor se chamar uma função
ou um procedure.

Oracle Database: Fundamentos de PL/SQL 9 - 5


Agenda

• Apresentando procedures e funções


• Visualizando procedures
• Visualizando funções

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 9 - 6


Procedure: Sintaxe

CREATE [OR REPLACE] PROCEDURE procedure_name


[(argument1 [mode1] datatype1,
argument2 [mode2] datatype2,
. . .)]
IS|AS
procedure_body;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Procedure: Sintaxe
O slide mostra a sintaxe para criar procedures. Na sintaxe:
procedure_name É o nome do procedure a ser criado
argument É o nome dado ao parâmetro do procedure. Cada argumento é
associado a um modo e a um tipo de dados. É possível haver
inúmeros argumentos separados por vírgula.
mode Modo do argumento:
IN (default)
OUT
IN OUT
datatype É o tipo de dados do parâmetro associado. O tipo de dados dos
parâmetros não pode ter um tamanho explícito; em vez disso, use
%TYPE.
Procedure_body É o bloco PL/SQL que compõe o código.

A lista de argumentos é opcional em uma declaração de procedure. Você aprenderá sobre os


procedures em detalhes no curso Oracle Database: Desenvolvimento de Unidades de Programa
PL/SQL.

Oracle Database: Fundamentos de PL/SQL 9 - 7


Criando um Procedure

...
CREATE TABLE dept AS SELECT * FROM departments;
CREATE PROCEDURE add_dept IS
v_dept_id dept.department_id%TYPE;
v_dept_name dept.department_name%TYPE;
BEGIN
v_dept_id:=280;
v_dept_name:='ST-Curriculum';
INSERT INTO dept(department_id,department_name)
VALUES(v_dept_id,v_dept_name);
DBMS_OUTPUT.PUT_LINE(' Inserted '|| SQL%ROWCOUNT
||' row ');
END;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Criando um Procedure
No código do exemplo, o procedure add_dept insere um novo departamento com o ID 280 e
o nome ST-Curriculum.
Além disso, o exemplo mostra o seguinte:
• A seção declarativa de um procedure começa imediatamente após a declaração do
procedure, e não com a palavra-chave DECLARE.
• O procedure declara duas variáveis: dept_id e dept_name.
• O procedure usa o atributo de cursor implícito ou o atributo SQL SQL%ROWCOUNT para
verificar se a linha foi inserida com sucesso. O valor 1 deverá ser retornado nesse caso.
Observação: Consulte a página a seguir para obter mais informações sobre o exemplo.

Oracle Database: Fundamentos de PL/SQL 9 - 8


Procedure: Exemplo
Observação
• Quando você criar qualquer objeto, as entradas serão feitas na tabela user_objects.
Quando o código do slide for executado com sucesso, você poderá verificar se há novos
objetos na tabela user_objects executando o seguinte comando:

SELECT object_name,object_type FROM user_objects;

• A origem do procedure está armazenada na tabela user_source. Você pode verificar o


procedure na origem executando o seguinte comando:

SELECT * FROM user_source WHERE name='ADD_DEPT';

Oracle Database: Fundamentos de PL/SQL 9 - 9


Chamando um Procedure

...
BEGIN
add_dept;
END;
/
SELECT department_id, department_name FROM dept
WHERE department_id=280;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Chamando o Procedure
O slide mostra como chamar um procedure de um bloco anônimo. Você deve incluir a chamada
ao procedure na seção executável do bloco anônimo. Da mesma forma, é possível chamar o
procedure a partir de qualquer aplicação, como uma aplicação do Forms ou uma aplicação Java.
A instrução SELECT no código verifica se a linha foi inserida com sucesso.
Também é possível chamar um procedure com a instrução SQL CALL <procedure_name>.

Oracle Database: Fundamentos de PL/SQL 9 - 10


Agenda

• Apresentando procedures e funções


• Visualizando procedures
• Visualizando funções

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 9 - 11


Função: Sintaxe

CREATE [OR REPLACE] FUNCTION function_name


[(argument1 [mode1] datatype1,
argument2 [mode2] datatype2,
. . .)]
RETURN datatype
IS|AS
function_body;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Função: Sintaxe
O slide mostra a sintaxe para criar uma função. Na sintaxe:
function_name É o nome da função a ser criada
argument É o nome dado ao parâmetro da função (cada argumento é associado
a um modo e a um tipo de dados. É possível haver inúmeros
argumentos separados por vírgula. Você especifica o argumento ao
chamar a função).
mode É o tipo de parâmetro (apenas os parâmetros IN devem ser
declarados.)
datatype É o tipo de dados do parâmetro associado
RETURN datatype É o tipo de dados do valor retornado pela função
function_body É o bloco PL/SQL que compõe o código da função

A lista de argumentos é opcional na declaração de função. A diferença entre um procedure e


uma função é que uma função deve retornar um valor ao programa que está chamando. Portanto,
a sintaxe contém return_type, que especifica o tipo de dados do valor que a função retornará.
Um procedure pode retornar um valor por meio de um parâmetro OUT ou IN OUT.

Oracle Database: Fundamentos de PL/SQL 9 - 12


Criando uma Função
CREATE FUNCTION check_sal RETURN Boolean IS
v_dept_id employees.department_id%TYPE;
v_empno employees.employee_id%TYPE;
v_sal employees.salary%TYPE;
v_avg_sal employees.salary%TYPE;
BEGIN
v_empno:=205;
SELECT salary,department_id INTO v_sal,v_dept_id FROM
employees
WHERE employee_id= v_empno;
SELECT avg(salary) INTO v_avg_sal FROM employees WHERE
department_id=v_dept_id;
IF v_sal > v_avg_sal THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NULL;
END;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Função: Exemplo
A função check_sal foi criada para determinar se o salário de um funcionário específico é
maior ou menor que a média de salário de todos os funcionários que trabalham no mesmo
departamento. A função retornará TRUE se o salário do funcionário for maior que o salário
médio dos funcionários do departamento; se não for, ela retornará FALSE. A função retornará
NULL se uma exceção NO_DATA_FOUND for gerada.
Observe que a função verifica o funcionário cujo ID é 205. A função foi codificada para
verificar apenas esse ID de funcionário. Se desejar verificar qualquer outro funcionário, você
precisará modificar a função propriamente dita. Para resolver esse problema, declare a função de
uma forma em que ela aceite um argumento. Em seguida, você poderá especificar o ID do
funcionário como um parâmetro.

Oracle Database: Fundamentos de PL/SQL 9 - 13


Chamando uma Função

BEGIN
IF (check_sal IS NULL) THEN
DBMS_OUTPUT.PUT_LINE('The function returned
NULL due to exception');
ELSIF (check_sal) THEN
DBMS_OUTPUT.PUT_LINE('Salary > average');
ELSE
DBMS_OUTPUT.PUT_LINE('Salary < average');
END IF;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Chamando a Função
Inclua a chamada na função na seção executável do bloco anônimo.
A função é chamada como parte de uma instrução. Lembre-se de que a função check_sal
retorna Boolean ou NULL. Dessa forma, a chamada à função é incluída como a expressão
condicional para o bloco IF.
Observação: Você pode usar o comando DESCRIBE para verificar os argumentos e retornar o
tipo da função, como no seguinte exemplo:
DESCRIBE check_sal;

Oracle Database: Fundamentos de PL/SQL 9 - 14


Transmitindo Parâmetros para a Função

DROP FUNCTION check_sal;


CREATE FUNCTION check_sal(p_empno employees.employee_id%TYPE)
RETURN Boolean IS
v_dept_id employees.department_id%TYPE;
v_sal employees.salary%TYPE;
v_avg_sal employees.salary%TYPE;
BEGIN
SELECT salary,department_id INTO v_sal,v_dept_id FROM employees
WHERE employee_id=p_empno;
SELECT avg(salary) INTO v_avg_sal FROM employees
WHERE department_id=v_dept_id;
IF v_sal > v_avg_sal THEN
RETURN TRUE;
ELSE
RETURN FALSE;
END IF;
EXCEPTION
...

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Transmitindo Parâmetros para a Função


Lembre-se de que a função havia sido codificada para a verificação do salário do funcionário
cujo ID era 205. O código mostrado no slide removeu essa constraint porque ele foi reescrito
para aceitar o número do funcionário como parâmetro. Agora é possível transmitir diferentes
números de funcionário e verificar o salário dele.
Você aprenderá mais sobre as funções no curso Oracle Database: Desenvolvimento de Unidades
de Programa PL/SQL.
A saída do código de exemplo do slide é a seguinte:

Oracle Database: Fundamentos de PL/SQL 9 - 15


Chamando a Função com um Parâmetro
BEGIN
DBMS_OUTPUT.PUT_LINE('Checking for employee with id 205');
IF (check_sal(205) IS NULL) THEN
DBMS_OUTPUT.PUT_LINE('The function returned
NULL due to exception');
ELSIF (check_sal(205)) THEN
DBMS_OUTPUT.PUT_LINE('Salary > average');
ELSE
DBMS_OUTPUT.PUT_LINE('Salary < average');
END IF;
DBMS_OUTPUT.PUT_LINE('Checking for employee with id 70');
IF (check_sal(70) IS NULL) THEN
DBMS_OUTPUT.PUT_LINE('The function returned
NULL due to exception');
ELSIF (check_sal(70)) THEN
...
END IF;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Chamando a Função com um Parâmetro


O código mostrado no slide chama a função duas vezes ao transmitir parâmetros. A saída dos
argumentos é apresentada a seguir.

Oracle Database: Fundamentos de PL/SQL 9 - 16


Questionário

Subprogramas:
a. São blocos PL/SQL nomeados e podem ser chamados por
outras aplicações
b. São compilados apenas uma vez
c. São armazenados no banco de dados
d. Não precisam retornar valores se forem funções
e. Podem aceitar parâmetros

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Resposta: a, b, c, e

Oracle Database: Fundamentos de PL/SQL 9 - 17


Sumário

Nesta lição, você aprendeu a:


• Criar um procedure simples
• Chamar o procedure a partir de um bloco anônimo
• Criar uma função simples
• Criar uma função simples que aceita parâmetros
• Chamar a função a partir de um bloco anônimo

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Sumário
É possível usar blocos anônimos para criar qualquer funcionalidade em blocos PL/SQL. No
entanto, a restrição principal em relação aos blocos anônimos é que eles não são armazenados e,
consequentemente, não podem ser reutilizados.
Em vez de criar blocos anônimos, você pode criar subprogramas PL/SQL. Funções e procedures
são considerados subprogramas, que são blocos PL/SQL nomeados. Os subprogramas expressam
lógica reutilizável por meio dos parâmetros. A estrutura de um procedure ou de uma função é
semelhante à estrutura de um bloco anônimo. Esses subprogramas são armazenados no banco de
dados e, portanto, são reutilizáveis.

Oracle Database: Fundamentos de PL/SQL 9 - 18


Exercício 9: Visão Geral

Este exercício aborda os seguintes tópicos:


• Convertendo um bloco anônimo existente em um
procedure
• Modificando o procedure para aceitar um parâmetro
• Criando um bloco anônimo para chamar o procedure

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL 9 - 19


Apêndice A
Exercícios e Soluções
Índice
Exercícios e Soluções da Lição I ........................................................................................ 3
Exercício I-1: Acessando Recursos do SQL Developer ................................................. 3
Exercício I-2: Conceitos Básicos .................................................................................... 3
Solução I-1: Acessando Recursos do SQL Developer.................................................... 6
Solução I-2: Conceitos Básicos ...................................................................................... 7
Exercícios e Soluções da Lição 1...................................................................................... 14
Exercício 1: Introdução à Linguagem PL/SQL ............................................................ 14
Solução 1: Introdução à Linguagem PL/SQL............................................................... 15
Exercícios e Soluções da Lição 2...................................................................................... 17
Exercício 2: Declarando Variáveis PL/SQL ................................................................. 17
Solução 2: Declarando Variáveis PL/SQL ................................................................... 19
Exercícios e Soluções da Lição 3...................................................................................... 22
Exercício 3: Criando Instruções Executáveis ............................................................... 22
Solução 3: Criando Instruções Executáveis.................................................................. 25
Exercícios e Soluções da Lição 4...................................................................................... 29
Exercício 4: Interagindo com o Oracle Server.............................................................. 29
Solução 4: Interagindo com o Oracle Server ................................................................ 31
Exercícios e Soluções da Lição 5...................................................................................... 34
Exercício 5: Criando Estruturas de Controle ................................................................ 34
Solução 5: Criando Estruturas de Controle................................................................... 36
Exercícios e Soluções da Lição 6...................................................................................... 39
Exercício 6: Trabalhando com Tipos de Dados Compostos......................................... 39
Solução 6: Trabalhando com Tipos de Dados Compostos ........................................... 41
Exercícios e Soluções da Lição 7...................................................................................... 46
Exercício 7-1: Usando Cursores Explícitos .................................................................. 46
Exercício 7-2: Usando Cursores Explícitos – Opcional ............................................... 49
Solução 7-1: Usando Cursores Explícitos..................................................................... 50
Solução 7-2: Usando Cursores Explícitos – Opcional.................................................. 55
Exercícios e Soluções da Lição 8...................................................................................... 57
Exercício 8-1: Tratando Exceções Predefinidas ........................................................... 57
Exercício 8-2: Tratando Exceções Padrão do Oracle Server ........................................ 58
Solução 8-1: Tratando Exceções Predefinidas.............................................................. 59
Solução 8-2: Tratando Exceções Padrão do Oracle Server .......................................... 61
Exercícios e Soluções da Lição 9...................................................................................... 62
Exercício 9: Criando e Usando Procedures Armazenados ........................................... 62
Solução 9: Criando e Usando Procedures Armazenados.............................................. 64

Oracle Database: Fundamentos de PL/SQL A - 2


Exercícios e Soluções da Lição I

Nestes exercícios, você identificará os recursos de informações do SQL Developer,


executará instruções SQL usando o SQL Developer e examinará os dados no esquema de
classe. Especificamente, você:
• Iniciará o SQL Developer
• Criará uma nova conexão com o banco de dados
• Navegará nas tabelas do esquema
• Definirá uma preferência do SQL Developer

Observação: Todos os exercícios criados usam o SQL Developer como ambiente de


desenvolvimento. Embora seja recomendado o uso do SQL Developer, você também
pode usar os ambientes do SQL*Plus ou do JDeveloper, que estão disponíveis neste
curso.

Exercício I-1: Acessando Recursos do SQL Developer


Neste exercício, você navegará na home page do SQL Developer e procurará
informações úteis sobre essa ferramenta.
1) Acesse a home page do SQL Developer.
a) Acesse a home page on-line do SQL Developer, disponível em:
http://www.oracle.com/technology/products/database/sql_developer/index.html
b) Adicione um marcador à página para facilitar o acesso no futuro.
2) Acesse o tutorial do SQL Developer, que está disponível on-line em http://st-
curriculum.oracle.com/tutorial/SQLDeveloper/index.htm. Em seguida, verifique as
seguintes seções e demonstrações associadas:
a) What to Do First
b) Working with Database Objects
c) Accessing Data

Exercício I-2: Conceitos Básicos

1) Inicie o SQL Developer.

2) Crie uma conexão com o banco de dados utilizando as seguintes informações (Dica:
Marque a caixa de seleção Save Password):
a) Nome da Conexão: MyConnection
b) Nome de usuário: ora41
c) Senha: ora41
d) Nome do host: localhost

Oracle Database: Fundamentos de PL/SQL A 3


Exercício I-2: Conceitos Básicos (continuação)
e) Porta: 1521
f) SID: orcl

3) Teste a nova conexão. Se o Status for Success, conecte-se ao banco de dados


utilizando a nova conexão.
a) Na janela Database Connection, clique no botão Test.
Observação: O status da conexão é exibido no canto inferior esquerdo da janela.
b) Se o status for Success, clique no botão Connect.

4) Navegue pela estrutura da tabela EMPLOYEES e exiba os dados.


a) Expanda a conexão MyConnection, clicando no sinal de mais ao lado dela.
b) Expanda o ícone Tables, clicando no sinal de mais ao lado dele.
c) Exiba a estrutura da tabela EMPLOYEES.

5) Use a tab EMPLOYEES para exibir os dados da tabela EMPLOYEES.

6) Use a Planilha SQL para selecionar os sobrenomes e os salários de todos os


funcionários cujo salário anual seja superior a US$ 10.000. Use os ícones Execute
Statement (F9) e Run Script (F5) para executar a instrução SELECT. Verifique os
resultados de ambos os métodos de execução das instruções SELECT nas tabs
apropriadas.
Observação: Reserve alguns minutos para se familiarizar com os dados ou consulte o
Apêndice B, que oferece a descrição e os dados de todas as tabelas do esquema HR
que você usará neste curso.

7) No menu SQL Developer, selecione Tools > Preferences. A janela Preferences é


exibida.

8) Selecione Database > Worksheet Parameters. Na caixa de texto “Select default path
to look for scripts”, use o botão Browse para selecionar a pasta
/home/oracle/labs/plsf. Essa pasta contém os scripts do código de exemplo,
os scripts de laboratório e os scripts de solução dos exercícios usados neste curso. Em
seguida, na janela Preferences, clique em OK para salvar a configuração Worksheet
Parameters.

9) Familiarize-se com a estrutura da pasta /home/oracle/labs/plsf.


a) Selecione File > Open. Na janela Open, a pasta …/plsf é selecionada
automaticamente como o local inicial. Essa pasta contém três subpastas:
• A pasta /code_ex contém códigos de exemplo localizados nos materiais
do curso. Cada script .sql é associado a uma página específica da lição.
• A pasta /labs contém o código usado em alguns exercícios das lições.
Você será orientado a executar o script solicitado no exercício apropriado.

Oracle Database: Fundamentos de PL/SQL A - 4


Exercício I-2: Conceitos Básicos (continuação)
• A pasta /soln contém as soluções de cada exercício. Cada script .sql é
numerado com a referência practice_exercise associada.
b) Você também pode usar a tab Files para navegar pelas pastas a fim de abrir os
arquivos de script.
c) Usando a janela Open e a tab Files, navegue pelas pastas e abra um arquivo de
script sem executar o código.
d) Feche a Planilha SQL.

Oracle Database: Fundamentos de PL/SQL A - 5


Solução I-1: Acessando Recursos do SQL Developer

1) Acesse a home page do SQL Developer.


a) Acesse a home page on-line do SQL Developer, disponível em:
http://www.oracle.com/technology/products/database/sql_developer/index.html

A home page do SQL Developer é exibida da seguinte maneira:

b) Adicione um marcador à página para facilitar o acesso no futuro.

2) Acesse o tutorial do SQL Developer, que está disponível on-line em http://st-


curriculum.oracle.com/tutorial/SQLDeveloper/index.htm. Em seguida, verifique as
seguintes seções e demonstrações associadas:
a) What to Do First
b) Working with Database Objects
c) Accessing Data

Oracle Database: Fundamentos de PL/SQL A - 6


Solução I-2: Conceitos Básicos

1) Inicie o SQL Developer.


Clique no ícone SQL Developer no seu desktop.

2) Crie uma conexão com o banco de dados utilizando as seguintes informações (Dica:
Marque a caixa de seleção Save Password):
a) Nome da Conexão: MyConnection
b) Nome de usuário: ora41
c) Senha: ora41
d) Nome do host: localhost
e) Porta: 1521
f) SID: orcl

Clique com o botão direito do mouse no nó Connections, na página com a tab


Connections, e selecione New Database Connection no menu de atalho.
Resultado: A janela New/Select Database Connection é exibida.
Use as informações anteriores para criar a nova conexão com o banco de
dados. Além disso, marque a caixa de seleção Save Password. Por exemplo:

Oracle Database: Fundamentos de PL/SQL A - 7


Solução I-2: Conceitos Básicos (continuação)
3) Teste a nova conexão. Se o Status for Success, conecte-se ao banco de dados
utilizando a nova conexão.
a) Na janela Database Connection, clique no botão Test.
Observação:O status da conexão é exibido no canto inferior esquerdo da janela.
b) Se o status for Success, clique no botão Connect.

Observação: Para exibir as propriedades de uma conexão existente, clique com o


botão direito do mouse no nome da conexão, na tab Connections, e selecione
Properties, no menu de atalho.

4) Navegue pela estrutura da tabela EMPLOYEES e exiba os dados.


a) Expanda a conexão MyConnection, clicando no sinal de mais ao lado dela.
b) Expanda o ícone Tables, clicando no sinal de mais ao lado dele.
c) Exiba a estrutura da tabela EMPLOYEES.

Faça drill-down na tabela EMPLOYEES, clicando no sinal de mais ao lado


dela.
Clique na tabela EMPLOYEES.
Resultado: A tab Columns exibe as colunas da tabela EMPLOYEES da
seguinte maneira:

Oracle Database: Fundamentos de PL/SQL A - 8


Solução I-2: Conceitos Básicos (continuação)

5) Use a tab EMPLOYEES para exibir os dados da tabela EMPLOYEES.

Para exibir os dados dos funcionários, clique na tab Data.


Resultado: Os dados da tabela EMPLOYEES são exibidos da seguinte maneira:

Oracle Database: Fundamentos de PL/SQL A - 9


Solução I-2: Conceitos Básicos (continuação)

6) Use a Planilha SQL para selecionar os sobrenomes e os salários de todos os


funcionários cujo salário anual seja superior a US$ 10.000. Use os ícones Execute
Statement (F9) e Run Script (F5) para executar a instrução SELECT. Verifique os
resultados de ambos os métodos de execução das instruções SELECT nas tabs
apropriadas.
Observação: Reserve alguns minutos para se familiarizar com os dados ou consulte o
Apêndice B, que oferece a descrição e os dados de todas as tabelas do esquema HR
que você usará neste curso.

Para exibir a Planilha SQL, clique na tab MyConnection.


Observação: Essa tab foi aberta anteriormente quando você fez drill-down na sua
conexão com o banco de dados.
Informe a instrução SELECT apropriada. Pressione F9 para executar a consulta e F5
para executar a consulta usando o método Run Script.

Por exemplo, quando você pressionar F9, os resultados exibidos serão semelhantes a
estes:

Oracle Database: Fundamentos de PL/SQL A - 10


Solução I-2: Conceitos Básicos (continuação)

7) No menu SQL Developer, selecione Tools > Preferences. A janela Preferences é


exibida.

8) Selecione Database > Worksheet Parameters. Na caixa de texto “Select default path
to look for scripts”, use o botão Browse para selecionar a pasta
/home/oracle/labs/plsf.

Essa pasta contém os scripts do código de exemplo, os scripts de laboratório e os


scripts de solução dos exercícios usados neste curso.
Clique em Open para selecionar a pasta.

Oracle Database: Fundamentos de PL/SQL A - 11


Solução I-2: Conceitos Básicos (continuação)

Em seguida, na janela Preferences, clique em OK para salvar a configuração


Worksheet Parameters.

9) Familiarize-se com a estrutura da pasta /home/oracle/labs/plsf.


a) Selecione File > Open. Na janela Open, a pasta …/plsf é selecionada
automaticamente como o local inicial. Essa pasta contém três subpastas:

• A pasta /code_ex contém códigos de exemplo localizados nos materiais


do curso. Cada script .sql é associado a uma página específica da lição.
• A pasta /labs contém o código usado em alguns exercícios das lições.
Você será orientado a executar o script solicitado no exercício apropriado.

Oracle Database: Fundamentos de PL/SQL A - 12


Solução I-2: Conceitos Básicos (continuação)
• A pasta /soln contém as soluções de cada exercício. Cada script .sql é
numerado com a referência practice_exercise associada.

b) Você também pode usar a tab Files para navegar pelas pastas a fim de abrir os
arquivos de script.

c) Usando a janela Open e a tab Files, navegue pelas pastas e abra um arquivo de
script sem executar o código.
d) Feche a Planilha SQL.
Para fechar qualquer tab da Planilha SQL, clique em X na tab, como
mostrado aqui:

Oracle Database: Fundamentos de PL/SQL A - 13


Exercícios e Soluções da Lição 1

A pasta /home/oracle/labs é o diretório de trabalho no qual você salva os scripts


que cria.
As soluções de todos os exercícios estão na pasta
/home/oracle/labs/plsf/soln.

Exercício 1: Introdução à Linguagem PL/SQL


1) Quais dos seguintes blocos PL/SQL são executados com sucesso?

a) BEGIN
END;

b) DECLARE
v_amount INTEGER(10);
END;

c) DECLARE
BEGIN
END;

d) DECLARE
v_amount INTEGER(10);
BEGIN
DBMS_OUTPUT.PUT_LINE(amount);
END;

2) Crie e execute um bloco anônimo simples que exiba a saída “Hello World”. Execute e
salve esse script como lab_01_02_soln.sql.

Oracle Database: Fundamentos de PL/SQL A - 14


Solução 1: Introdução à Linguagem PL/SQL
1) Quais dos seguintes blocos PL/SQL são executados com sucesso?

a) BEGIN
END;

b) DECLARE
v_amount INTEGER(10);
END;

c) DECLARE
BEGIN
END;

d) DECLARE
v_amount INTEGER(10);
BEGIN
DBMS_OUTPUT.PUT_LINE(amount);
END;

O bloco em a não é executado. Ele não possui instruções executáveis.


O bloco em b não tem a seção executável obrigatória que inicia com a palavra-
chave BEGIN.
O bloco em c possui todas as partes necessárias, mas não possui instruções
executáveis.
O bloco em d é executado com sucesso.

2) Crie e execute um bloco anônimo simples que exiba a saída “Hello World”. Execute e
salve esse script como lab_01_02_soln.sql.

Informe o código a seguir no espaço de trabalho e, em seguida, pressione F5.


SET SERVEROUTPUT ON
BEGIN
DBMS_OUTPUT.PUT_LINE(' Hello World ');
END;

Você deverá ver a saída a seguir na tab Script Output:

Oracle Database: Fundamentos de PL/SQL A - 15


Solução 1: Introdução à Linguagem PL/SQL (continuação)

Clique no botão Save. Selecione a pasta em que deseja salvar o arquivo. Insira
lab_01_02_soln.sql como o nome do arquivo e clique em Save.

Oracle Database: Fundamentos de PL/SQL A - 16


Exercícios e Soluções da Lição 2

Exercício 2: Declarando Variáveis PL/SQL


Neste exercício, você declarará variáveis PL/SQL.

1) Reconheça os identificadores válidos e os inválidos:


a) today
b) last_name
c) today’s_date
d) Number_of_days_in_February_this_year
e) Isleap$year
f) #number
g) NUMBER#
h) number1to7

2) Identifique a declaração e a inicialização de variáveis válidas e inválidas:


a) number_of_copies PLS_INTEGER;
b) PRINTER_NAME constante VARCHAR2(10);
c) deliver_to VARCHAR2(10):=Johnson;
d) by_when DATE:= CURRENT_DATE+1;

3) Examine o bloco anônimo a seguir e, em seguida, selecione uma das instruções a


seguir que seja verdadeira.
DECLARE
v_fname VARCHAR2(20);
v_lname VARCHAR2(15) DEFAULT 'fernandez';
BEGIN
DBMS_OUTPUT.PUT_LINE(v_fname ||' ' ||v_lname);
END;

a) O bloco é executado com sucesso e imprime “fernandez”.


b) O bloco gera um erro porque a variável fname é usada sem ter sido inicializada.
c) O bloco é executado com sucesso e imprime “null fernandez”.
d) O bloco retorna um erro porque não é possível usar a palavra-chave DEFAULT
para inicializar uma variável do tipo VARCHAR2.
e) O bloco gera um erro porque a variável v_fname não foi declarada.

Oracle Database: Fundamentos de PL/SQL A - 17


Exercício 2: Declarando Variáveis PL/SQL (continuação)

4) Modifique um bloco anônimo existente e salve-o como um novo script.


a) Abra o script lab_01_02_soln.sql , que você criou no Exercício 1.
b) Neste bloco PL/SQL, declare as seguintes variáveis:
1. v_today do tipo DATE. Inicialize today com SYSDATE.
2. v_tomorrow do tipo today. Use o atributo %TYPE para declarar essa
variável.
c) Na seção executável:
1. Inicialize a variável v_tomorrow com uma expressão que calcula a data de
amanhã (adicione um ao valor em today)
2. Imprima o valor de v_today e tomorrow após imprimir “Hello World”
d) Salve o seu script como lab_02_04_soln.sql e, em seguida, execute-o.
Este é o exemplo de saída (os valores de v_today e v_tomorrow serão
diferentes para refletir a data de hoje e de amanhã):

5) Edite o script lab_02_04_soln.sql.


a) Adicione código para criar duas variáveis de bind, chamadas
b_basic_percent e b_pf_percent. Ambas as variáveis de bind são do
tipo NUMBER.
b) Na seção executável do bloco PL/SQL, designe os valores 45 e 12 a
b_basic_percent e b_pf_percent, respectivamente.
c) Encerre o bloco PL/SQL com “/” e exiba o valor das variáveis de bind usando o
comando PRINT.
d) Execute e salve o script como lab_02_05_soln.sql. O exemplo de saída é o
seguinte:

Oracle Database: Fundamentos de PL/SQL A - 18


Solução 2: Declarando Variáveis PL/SQL
1) Reconheça os identificadores válidos e os inválidos:
a) today Válido
b) last_name Válido
c) today’s_date Inválido – caractere “’” não
permitido
d) Number_of_days_in_February_this_year Inválido – Longo demais
e) Isleap$year Válido
f) #number Inválido – Impossível iniciar com
“#”
g) NUMBER# Válido
h) number1to7 Válido

2) Identifique a declaração e a inicialização de variáveis válidas e inválidas:


a) number_of_copies PLS_INTEGER; Válido
b) PRINTER_NAME constante VARCHAR2(10); Inválido
c) deliver_to VARCHAR2(10):=Johnson; Inválido
d) by_when DATE:= CURRENT_DATE+1; Válido

A declaração em b é inválida porque as variáveis de constantes devem ser


inicializadas durante a declaração.
A declaração em c é inválida porque os literais de string devem ser delimitados por
aspas simples.

3) Examine o bloco anônimo a seguir e, em seguida, selecione uma das instruções a


seguir que seja verdadeira.
DECLARE
v_fname VARCHAR2(20);
v_lname VARCHAR2(15) DEFAULT 'fernandez';
BEGIN
DBMS_OUTPUT.PUT_LINE(v_fname ||' ' ||v_lname);
END;

a) O bloco é executado com sucesso e imprime “fernandez”.


b) O bloco gera um erro porque a variável fname é usada sem ter sido inicializada.
c) O bloco é executado com sucesso e imprime “null fernandez”.
d) O bloco retorna um erro porque não é possível usar a palavra-chave DEFAULT
para inicializar uma variável do tipo VARCHAR2.
e) O bloco gera um erro porque a variável v_fname não foi declarada.
a. O bloco será executado com sucesso e imprimirá “fernandez.”

Oracle Database: Fundamentos de PL/SQL A - 19


Solução 2: Declarando Variáveis PL/SQL (continuação)
4) Modifique um bloco anônimo existente e salve-o como um novo script.
a) Abra o script lab_01_02_soln.sql, que você criou no Exercício 1.
b) No bloco PL/SQL, declare as seguintes variáveis:
1. Variável v_today do tipo DATE. Inicialize today com SYSDATE.

DECLARE
v_today DATE:=SYSDATE;

2. Variável v_tomorrow do tipo today. Use o atributo %TYPE para declarar


essa variável.

v_tomorrow v_today%TYPE;

c) Na seção executável:
1. Inicialize a variável v_tomorrow com uma expressão que calcula a data de
amanhã (adicione um ao valor em v_today)
2. Imprima o valor de v_today e v_tomorrow após imprimir “Hello World”

BEGIN
v_tomorrow:=v_today +1;
DBMS_OUTPUT.PUT_LINE(' Hello World ');
DBMS_OUTPUT.PUT_LINE('TODAY IS : '|| v_today);
DBMS_OUTPUT.PUT_LINE('TOMORROW IS : ' || v_tomorrow);
END;

d) Salve o seu script como lab_02_04_soln.sql e, em seguida, execute-o.


Este é o exemplo de saída (os valores de v_today e v_tomorrow serão
diferentes para refletir a data de hoje e de amanhã):

Oracle Database: Fundamentos de PL/SQL A - 20


Solução 2: Declarando Variáveis PL/SQL (continuação)

5) Edite o script lab_02_04_soln.sql.

a) Adicione o código para criar duas variáveis de bind, chamadas


b_basic_percent e b_pf_percent. Ambas as variáveis de bind são do
tipo NUMBER.
VARIABLE b_basic_percent NUMBER
VARIABLE b_pf_percent NUMBER

b) Na seção executável do bloco PL/SQL, designe os valores 45 e 12 a


b_basic_percent e b_pf_percent, respectivamente.
:b_basic_percent:=45;
:b_pf_percent:=12;

c) Encerre o bloco PL/SQL com “/” e exiba o valor das variáveis de bind usando o
comando PRINT.
/
PRINT b_basic_percent
PRINT b_pf_percent

OU

PRINT

d) Execute e salve o script como lab_02_05_soln.sql. O exemplo de saída é o


seguinte:

Oracle Database: Fundamentos de PL/SQL A - 21


Exercícios e Soluções da Lição 3

Exercício 3: Criando Instruções Executáveis


Neste exercício, você examinará e criará instruções executáveis.

DECLARE
v_weight NUMBER(3) := 600;
v_message VARCHAR2(255) := 'Product 10012';
BEGIN
DECLARE
v_weight NUMBER(3) := 1;
v_message VARCHAR2(255) := 'Product 11001';
v_new_locn VARCHAR2(50) := 'Europe';
BEGIN
v_weight := v_weight + 1;
v_new_locn := 'Western ' || v_new_locn;
1
END;
v_weight := v_weight + 1;
v_message := v_message || ' is in stock';
v_new_locn := 'Western ' || v_new_locn;
2
END;
/

1) Avalie o bloco PL/SQL anterior e determine o tipo de dados e o valor de cada uma
das variáveis a seguir, de acordo com as regras de escopo.
a) O valor de v_weight na posição 1 é:

b) O valor de v_new_locn na posição 1 é:

c) O valor de v_weight na posição 2 é:

d) O valor de v_message na posição 2 é:

e) O valor de v_new_locn na posição 2 é:

Oracle Database: Fundamentos de PL/SQL A - 22


Exercício 3: Criando Instruções Executáveis (continuação)

DECLARE
v_customer VARCHAR2(50) := 'Womansport';
v_credit_rating VARCHAR2(50) := 'EXCELLENT';
BEGIN
DECLARE
v_customer NUMBER(7) := 201;
v_name VARCHAR2(25) := 'Unisports';
BEGIN
v_credit_rating :='GOOD';

END;

END;

2) No bloco PL/SQL anterior, determine os valores e tipos de dados para cada um dos
seguintes casos:
a) O valor de v_customer no bloco aninhado é:

b) O valor de v_name no bloco aninhado é:

c) O valor de v_credit_rating no bloco aninhado é:

d) O valor de v_customer no bloco principal é:

e) O valor de v_name no bloco principal é:

f) O valor de v_credit_rating no bloco principal é:

3) Use a mesma sessão usada para executar os exercícios da lição “Declarando Variáveis
PL/SQL”. Se você abriu uma nova sessão, execute lab_02_05_soln.sql Em
seguida, edite lab_02_05_soln.sql como se segue:
a) Use a sintaxe de comentário de uma única linha para incluir comentários nas
linhas que criam as variáveis de bind e ative SERVEROUTPUT.

b) Use comentários de várias linhas na seção executável para comentar as linhas que
designam valores às variáveis de bind.

c) Na seção declarativa:
1. Declare e inicialize duas variáveis temporárias para substituir as variáveis
de bind nas linhas comentadas.
2. Declare duas variáveis adicionais: v_fname do tipo VARCHAR2 e
tamanho 15, e v_emp_sal do tipo NUMBER e tamanho 10.

Oracle Database: Fundamentos de PL/SQL A - 23


Exercício 3: Criando Instruções Executáveis (continuação)
d) Inclua esta instrução SQL na seção executável:

SELECT first_name, salary INTO v_fname, v_emp_sal


FROM employees WHERE employee_id=110;

e) Mude a linha que exibe “Hello World” para exibir “Hello” e o nome. Em seguida,
comente as linhas que exibem as datas e imprima as variáveis de bind.

f) Calcule a contribuição do funcionário para o fundo de previdência (PF).


PF é 12% do salário básico e o salário básico é 45% do salário. Use as variáveis
locais para o cálculo. Tente usar apenas uma expressão para calcular PF. Imprima
o salário do funcionário e sua contribuição para o PF.

g) Execute e salve esse script como lab_03_03_soln.sql. O exemplo de saída


é o seguinte:

Oracle Database: Fundamentos de PL/SQL A - 24


Solução 3: Criando Instruções Executáveis
Neste exercício, você examinará e criará instruções executáveis.

DECLARE
v_weight NUMBER(3) := 600;
v_message VARCHAR2(255) := 'Product 10012';
BEGIN
DECLARE
v_weight NUMBER(3) := 1;
v_message VARCHAR2(255) := 'Product 11001';
v_new_locn VARCHAR2(50) := 'Europe';
BEGIN
v_weight := v_weight + 1;
v_new_locn := 'Western ' || v_new_locn;
1
END;
v_weight := v_weight + 1;
v_message := v_message || ' is in stock';
v_new_locn := 'Western ' || v_new_locn;
2
END;
/

1) Avalie o bloco PL/SQL anterior e determine o tipo de dados e o valor de cada uma
das variáveis a seguir, de acordo com as regras de escopo.
a) O valor dev_weight na posição 1 é:
2
O tipo de dados é NUMBER.
b) O valor de v_new_locn na posição 1 é:
Western Europe
O tipo de dado é VARCHAR2.
c) O valor dev_weight na posição 2 é:
601
O tipo de dados é NUMBER.
d) O valor de v_message na posição 2 é:
Product 10012 is in stock
O tipo de dado é VARCHAR2.
e) O valor de v_new_locn na posição 2 é:
Inválido pois v_new_locn não é visível fora do sub-bloco

Oracle Database: Fundamentos de PL/SQL A - 25


Solução 3: Criando Instruções Executáveis (continuação)
DECLARE
v_customer VARCHAR2(50) := 'Womansport';
v_credit_rating VARCHAR2(50) := 'EXCELLENT';
BEGIN
DECLARE
v_customer NUMBER(7) := 201;
v_name VARCHAR2(25) := 'Unisports';
BEGIN
v_credit_rating :='GOOD';

END;

END;

2) No bloco PL/SQL anterior, determine os valores e tipos de dados para cada um dos
seguintes casos:

a) O valor de v_customer no bloco aninhado é:


201
O tipo de dados é NUMBER.
b) O valor de v_name no bloco aninhado é:
Unisports
O tipo de dado é VARCHAR2.
c) O valor de v_credit_rating no bloco aninhado é:
GOOD
O tipo de dado é VARCHAR2.
d) O valor de v_customer no bloco principal é:
Womansport
O tipo de dado é VARCHAR2.
e) O valor dev_name no bloco principal é:
Null. name não está visível no bloco principal e você veria um erro.
f) O valor de v_credit_rating no bloco principal é:
EXCELLENT
O tipo de dado é VARCHAR2.

3) Use a mesma sessão usada para executar os exercícios da lição “Declarando Variáveis
PL/SQL”. Se você abriu uma nova sessão, execute lab_02_05_soln.sql Em
seguida, edite lab_02_05_soln.sql como se segue:
a) Use a sintaxe de comentário de uma única linha para incluir comentários nas
linhas que criam as variáveis de bind e ative SERVEROUTPUT.

-- VARIABLE b_basic_percent NUMBER


-- VARIABLE b_pf_percent NUMBER
SET SERVEROUTPUT ON

Oracle Database: Fundamentos de PL/SQL A - 26


Solução 3: Criando Instruções Executáveis (continuação)
b) Use comentários de várias linhas na seção executável para comentar as linhas que
designam valores às variáveis de bind.

/*:b_basic_percent:=45;
:b_pf_percent:=12;*/

c) Na seção declarativa:
1. Declare e inicialize duas variáveis temporárias para substituir as variáveis
de bind nas linhas comentadas.
2. Declare duas variáveis adicionais: v_fname do tipo VARCHAR2 e
tamanho 15, e v_emp_sal do tipo NUMBER e tamanho 10.

DECLARE
v_basic_percent NUMBER:=45;
v_pf_percent NUMBER:=12;
v_fname VARCHAR2(15);
v_emp_sal NUMBER(10);

d) Inclua esta instrução SQL na seção executável:

SELECT first_name, salary INTO v_fname, v_emp_sal


FROM employees WHERE employee_id=110;

e) Mude a linha que exibe “Hello World” para exibir “Hello” e o nome. Em seguida,
comente as linhas que exibem as datas e imprima as variáveis de bind.

DBMS_OUTPUT.PUT_LINE(' Hello '|| v_fname);


/* DBMS_OUTPUT.PUT_LINE('TODAY IS : '|| v_today);
DBMS_OUTPUT.PUT_LINE('TOMORROW IS : ' || v_tomorrow);*/
...
...

/
--PRINT b_basic_percent
--PRINT b_basic_percent

f) Calcule a contribuição do funcionário para o fundo de previdência (PF).


PF é 12% do salário básico e o salário básico é 45% do salário. Use as variáveis
locais para o cálculo. Tente usar apenas uma expressão para calcular PF. Imprima
o salário do funcionário e sua contribuição para o PF.

DBMS_OUTPUT.PUT_LINE('YOUR SALARY IS : '||v_emp_sal);


DBMS_OUTPUT.PUT_LINE('YOUR CONTRIBUTION TOWARDS PF:
'||v_emp_sal*v_basic_percent/100*v_pf_percent/100);
END;

Oracle Database: Fundamentos de PL/SQL A - 27


Solução 3: Criando Instruções Executáveis (continuação)
g) Execute e salve esse script como lab_03_03_soln.sql. O exemplo de saída
é o seguinte:

Oracle Database: Fundamentos de PL/SQL A - 28


Exercícios e Soluções da Lição 4

Exercício 4: Interagindo com o Oracle Server


Neste exercício, você usará o código PL/SQL para interagir com o Oracle Server.
1) Crie um bloco PL/SQL que selecione o maior ID de departamento na tabela
departments e armazene-o na variável v_max_deptno. Exiba o maior ID de
departamento.
a) Declare uma variável v_max_deptno do tipo NUMBERna seção declarativa.
b) Inicie a seção executável com a palavra-chave BEGIN e inclua uma instrução
SELECT para recuperar o maior department_id da tabela departments.
c) Exiba v_max_deptno e encerre o bloco executável.
d) Execute e salve esse script como lab_04_01_soln.sql. O exemplo de saída
é o seguinte:

2) Modifique o bloco PL/SQL criado na etapa 1 para inserir um novo departamento na


tabela departments.
a) Carregue o script lab_04_01_soln.sql. Declare duas variáveis:
v_dept_name do tipo departments.department_name e
v_dept_id do tipo NUMBER
Designe 'Education' a v_dept_name na seção declarativa.
b) Você já recuperou o maior número de departamento da tabela departments.
Adicione 10 a ele e designe o resultado à v_dept_id.
c) Inclua uma instrução INSERT para inserir dados nas colunas
department_name, department_ide location_id da tabela
departments.
Use valores em dept_name e dept_id para department_name e
department_id, respectivamente, e use NULL para location_id.
d) Use o atributo SQL SQL%ROWCOUNT para exibir o número de linhas que foram
afetadas.
e) Execute uma instrução SELECT para verificar se o novo departamento foi
inserido. Encerre o bloco PL/SQL com “/” e inclua a instrução SELECT no
script.
f) Execute e salve seu script como lab_04_02_soln.sql. O exemplo de saída é
o seguinte:

Oracle Database: Fundamentos de PL/SQL A - 29


Exercício 4: Interagindo com o Oracle Server (continuação)

3) Na etapa 2, você define location_id como NULL. Crie um bloco PL/SQL que
atualiza location_id como 3000 para o novo departamento.
Observação:Se você concluiu a etapa 2 com sucesso, siga para a etapa 3a. Caso não
tenha concluído com sucesso, execute primeiro o script de solução
/soln/sol_04_02.sql.
a) Inicie o bloco executável com a palavra-chave BEGIN. Inclua a instrução
UPDATE para definir location_id como 3000 para o novo departamento
(dept_id =280).
b) Finalize o bloco executável com a palavra-chaveEND. Encerre o bloco PL/SQL
com “/” e inclua uma instrução SELECT para exibir o departamento que foi
atualizado.
c) Inclua uma instrução DELETE para deletar o departamento adicionado.
d) Execute e salve esse script como lab_04_03_soln.sql. O exemplo de saída
é o seguinte:

Oracle Database: Fundamentos de PL/SQL A - 30


Solução 4: Interagindo com o Oracle Server
Neste exercício, você usará o código PL/SQL para interagir com o Oracle Server.
1) Crie um bloco PL/SQL que selecione o maior ID de departamento na tabela
departments e armazene-o na variável v_max_deptno. Exiba o maior ID de
departamento.
a) Declare uma variável v_max_deptno do tipo NUMBERna seção declarativa.

DECLARE
v_max_deptno NUMBER;

b) Inicie a seção executável com a palavra-chave BEGIN e inclua uma instrução


SELECT para recuperar o maior department_id da tabela departments.

BEGIN
SELECT MAX(department_id) INTO v_max_deptno FROM
departments;

c) Exiba v_max_deptno e encerre o bloco executável.

DBMS_OUTPUT.PUT_LINE('The maximum department_id is : ' ||


v_max_deptno);
END;

d) Execute e salve esse script como lab_04_01_soln.sql. O exemplo de saída


é o seguinte:

2) Modifique o bloco PL/SQL criado na etapa 1 para inserir um novo departamento na


tabela departments.
a) Carregue o script lab_04_01_soln.sql. Declare duas variáveis:
v_dept_name do tipo departments.department_name e
v_dept_id do tipo NUMBER
Designe 'Education' a v_dept_name na seção declarativa.

v_dept_name departments.department_name%TYPE:= 'Education';


v_dept_id NUMBER;

Oracle Database: Fundamentos de PL/SQL A - 31


Solução 4: Interagindo com o Oracle Server (continuação)

b) Você já recuperou o maior número de departamento da tabela departments.


Adicione 10 a ele e designe o resultado à v_dept_id.

v_dept_id := 10 + v_max_deptno;

c) Inclua uma instrução INSERT para inserir dados nas colunas


department_name, department_id, e location_id da tabela
departments.
Use valores em dept_name e dept_id para department_name e
department_id, respectivamente, e use NULL para location_id.


INSERT INTO departments (department_id, department_name,
location_id)
VALUES (v_dept_id, v_dept_name, NULL);

d) Use o atributo SQL SQL%ROWCOUNT para exibir o número de linhas que foram
afetadas.

DBMS_OUTPUT.PUT_LINE (' SQL%ROWCOUNT gives ' || SQL%ROWCOUNT);


e) Execute uma instrução SELECT para verificar se o novo departamento foi


inserido. Encerre o bloco PL/SQL com “/” e inclua a instrução SELECT no
script.


/
SELECT * FROM departments WHERE department_id= 280;

f) Execute e salve seu script como lab_04_02_soln.sql. O exemplo de saída é


o seguinte:

Oracle Database: Fundamentos de PL/SQL A - 32


Solução 4: Interagindo com o Oracle Server (continuação)

3) Na etapa 2, você define location_id como NULL. Crie um bloco PL/SQL que
atualiza location_id como 3000 para o novo departamento.
Observação: Se você concluiu a etapa 2 com sucesso, siga para a etapa 3a. Caso não
tenha concluído com sucesso, execute primeiro o script de solução
/soln/sol_04_02.sql.
a) Inicie o bloco executável com a palavra-chave BEGIN. Inclua a instrução
UPDATE para definir location_id como 3000 para o novo departamento
(dept_id =280).

BEGIN
UPDATE departments SET location_id=3000 WHERE
department_id=280;

b) Finalize o bloco executável com a palavra-chaveEND. Encerre o bloco PL/SQL


com “/” e inclua uma instrução SELECT para exibir o departamento que foi
atualizado.

END;
/
SELECT * FROM departments WHERE department_id=280;

c) Inclua uma instrução DELETE para deletar o departamento adicionado.

DELETE FROM departments WHERE department_id=280;

d) Execute e salve esse script como lab_04_03_soln.sql. O exemplo de saída


é o seguinte:

Oracle Database: Fundamentos de PL/SQL A - 33


Exercícios e Soluções da Lição 5

Exercício 5: Criando Estruturas de Controle


Neste exercício, você criará blocos PL/SQL que incorporam loops e estruturas de
controle condicionais. Este exercício testará a sua compreensão a respeito de diversas
instruções IF e estruturas LOOP.

1) Execute o comando do arquivo lab_05_01.sql para criar a tabela messages.


Crie um bloco PL/SQL para inserir números na tabela messages.
a) Insira os números de 1 a 10, excluindo 6 e 8.
b) Faça commit antes do fim do bloco.
c) Execute uma instrução SELECT para verificar se o seu bloco PL/SQL funcionou.

Resultado: Você verá a seguinte saída:

2) Execute o script lab_05_02.sql. Esse script cria uma tabela emp que é uma
réplica da tabela employees. Ele altera a tabela emp para adicionar uma nova
coluna, stars, do tipo de dados VARCHAR2 e tamanho 50. Crie um bloco PL/SQL
que insere um asterisco na coluna stars para cada $1000 do salário do
funcionário. Salve o script como lab_05_02_soln.sql.
a) Na seção declarativa do bloco, declare uma variável v_empno do tipo
emp.employee_id e inicialize-a com 176. Declare uma variável
v_asterisk do tipo emp.stars e inicialize-a com NULL. Crie uma variável
v_sal do tipo emp.salary..
b) Na seção executável, crie uma lógica para anexar um asterisco (*) à string para
cada US$ 1.000 do salário. Por exemplo, se o funcionário ganhar US$ 8.000, a

Oracle Database: Fundamentos de PL/SQL A - 34


Exercício 5: Criando Estruturas de Controle (continuação)
string de asteriscos deverá conter oito asteriscos. Se o funcionário ganhar US$
12.500, a string de asteriscos deverá conter 13 asteriscos.
c) Atualize a coluna stars do funcionário com a string de asteriscos. Faça commit
antes do fim do bloco.
d) Exiba a linha da tabela emp para verificar se o seu bloco PL/SQL foi executado
com sucesso.
e) Execute e salve esse script como lab_05_02_soln.sql. A saída é a seguinte:

Oracle Database: Fundamentos de PL/SQL A - 35


Solução 5: Criando Estruturas de Controle
1) Execute o comando do arquivo lab_05_01.sql para criar a tabela messages.
Crie um bloco PL/SQL para inserir números na tabela messages.
a) Insira os números de 1 a 10, excluindo 6 e 8.
b) Faça commit antes do fim do bloco.

BEGIN
FOR i in 1..10 LOOP
IF i = 6 or i = 8 THEN
null;
ELSE
INSERT INTO messages (results)
VALUES (i);
END IF;
END LOOP;
COMMIT;
END;
/

c) Execute uma instrução SELECT para verificar se o seu bloco PL/SQL funcionou.

SELECT * FROM messages;

Resultado: Você verá a seguinte saída:

Oracle Database: Fundamentos de PL/SQL A 36


Solução 5: Criando Estruturas de Controle (continuação)

2) Execute o script lab_05_02.sql. Esse script cria uma tabela emp que é uma
réplica da tabela employees. Ele altera a tabela emp para adicionar uma nova
coluna stars, do tipo de dados VARCHAR2 e tamanho 50. Crie um bloco PL/SQL
que insere um asterisco na coluna starspara cada $1000 do salário do funcionário.
Salve o script como lab_05_02_soln.sql.
a) Na seção declarativa do bloco, declare uma variável v_empno do tipo
emp.employee_id e inicialize-a com 176. Declare uma variável
v_asterisk do tipo emp.stars e inicialize-a com NULL. Crie uma variável
v_sal do tipo emp.salary.
.
DECLARE
v_empno emp.employee_id%TYPE := 176;
v_asterisk emp.stars%TYPE := NULL;
v_sal emp.salary%TYPE;

b) Na seção executável, crie uma lógica para anexar um asterisco (*) à string para
cada US$ 1.000 do salário. Por exemplo, se o funcionário ganhar US$ 8.000, a
string de asteriscos deverá conter oito asteriscos. Se o funcionário ganhar US$
12.500, a string de asteriscos deverá conter 13 asteriscos.

BEGIN
SELECT NVL(ROUND(salary/1000), 0) INTO v_sal
FROM emp WHERE employee_id = v_empno;

FOR i IN 1..v_sal
LOOP
v_asterisk := v_asterisk ||'*';
END LOOP;

c) Atualize a coluna stars do funcionário com a string de asteriscos. Faça commit


antes do fim do bloco.

UPDATE emp SET stars = v_asterisk


WHERE employee_id = v_empno;
COMMIT;
END;
/

d) Exiba a linha da tabela emp para verificar se o seu bloco PL/SQL foi executado
com sucesso.

SELECT employee_id,salary, stars


FROM emp WHERE employee_id =176;

e) Execute e salve esse script como lab_05_02_soln.sql. A saída é a seguinte:

Oracle Database: Fundamentos de PL/SQL A - 37


Solução 5: Criando Estruturas de Controle (continuação)

Oracle Database: Fundamentos de PL/SQL A - 38


Exercícios e Soluções da Lição 6

Exercício 6: Trabalhando com Tipos de Dados Compostos


1) Crie um bloco PL/SQL para imprimir informações sobre um dado país.
a) Declare um registro PL/SQL baseado na estrutura da tabela countries.
b) Declare uma variável v_countryid. Designe CA à v_countryid.
c) Na seção declarativa, use o atributo %ROWTYPE e declare a variável
v_country_record do tipo countries.
d) Na seção executável, obtenha todas as informações da tabela countries
usando v_countryid. Exiba as informações selecionadas sobre o país. O
exemplo de saída é o seguinte:

e) Você pode executar e testar o bloco PL/SQL para os países com os IDs DE, UK e
US.

2) Crie um bloco PL/SQL para recuperar os nomes de alguns departamentos da tabela


departments e exibir o nome de cada departamento na tela, incorporando um
array associativo. Salve o script como lab_06_02_soln.sql.
a) Declare uma tabela INDEX BY dept_table_type do tipo
departments.department_name. Declare uma variável
my_dept_table do tipo dept_table_type para armazenar
temporariamente os nomes dos departamentos.
b) Declare duas variáveis: f_loop_count e v_deptno do tipo NUMBER.
Designe 10 a f_loop_count e 0 a v_deptno.
c) Usando um loop, recupere os nomes de 10 departamentos e armazene-os no array
associativo. Comece com o department_id de 10. Adicione 10 à v_deptno
para cada iteração de loop. A tabela a seguir mostra o department_id para o
qual você deve recuperar o department_name.

DEPARTMENT_ID DEPARTMENT_NAME
10 Administration
20 Marketing
30 Purchasing
40 Human Resources
50 Shipping
60 IT
70 Public Relations
80 Sales
90 Executive
100 Finance

Oracle Database: Fundamentos de PL/SQL A - 39


Exercício 6: Trabalhando com Tipos de Dados Compostos
(continuação)

d) Usando outro loop, recupere os nomes dos departamentos do array associativo e


exiba-os.
e) Execute e salve esse script como lab_06_02_soln.sql. A saída é a seguinte:

3) Modifique o bloco que você criou no Exercício 2 para recuperar todas as informações
sobre cada departamento da tabela departments e exiba as informações. Use um
array associativo com a tabela INDEX BY do método de registros.
a) Carregue o script lab_06_02_soln.sql.
b) Você declarou que o array associativo é do tipo
departments.department_name. Modifique a declaração do array
associativo para armazenar temporariamente o número, o nome e o local de todos
os departamentos. Use o atributo %ROWTYPE.
c) Modifique a instrução SELECT para recuperar todas as informações sobre os
departamentos que estão atualmente na tabela departments e armazene-as no
array associativo.
d) Usando outro loop, recupere as informações sobre os departamentos do array
associativo e exiba-as.

O exemplo de saída é o seguinte:

Oracle Database: Fundamentos de PL/SQL A - 40


Solução 6: Trabalhando com Tipos de Dados Compostos
1) Crie um bloco PL/SQL para imprimir informações sobre um dado país.
a) Declare um registro PL/SQL baseado na estrutura da tabela countries.
b) Declare uma variável v_countryid. Designe CA à v_countryid.

SET SERVEROUTPUT ON

SET VERIFY OFF


DECLARE
v_countryid varchar2(20):= 'CA';

c) Na seção declarativa, use o atributo %ROWTYPE e declare a variável


v_country_record do tipo countries.

v_country_record countries%ROWTYPE;

d) Na seção executável, obtenha todas as informações da tabela countries


usando v_countryid. Exiba as informações selecionadas sobre o país. O
exemplo de saída é o seguinte:

BEGIN
SELECT *
INTO v_country_record
FROM countries
WHERE country_id = UPPER(v_countryid);

DBMS_OUTPUT.PUT_LINE ('Country Id: ' ||


v_country_record.country_id ||
' Country Name: ' || v_country_record.country_name
|| ' Region: ' || v_country_record.region_id);

END;

e) Você pode executar e testar o bloco PL/SQL para os países com os IDs DE, UK e
US.

Oracle Database: Fundamentos de PL/SQL A - 41


Solução 6: Trabalhando com Tipos de Dados Compostos
(continuação)
2) Crie um bloco PL/SQL para recuperar os nomes de alguns departamentos da tabela
departments e exibir o nome de cada departamento na tela, incorporando um
array associativo. Salve o script como lab_06_02_soln.sql.
a) Declare uma tabela INDEX BY dept_table_type do tipo
departments.department_name. Declare uma variável
my_dept_table do tipo dept_table_type para armazenar
temporariamente os nomes dos departamentos.

SET SERVEROUTPUT ON

DECLARE
TYPE dept_table_type is table of
departments.department_name%TYPE
INDEX BY PLS_INTEGER;
my_dept_table dept_table_type;

b) Declare duas variáveis: f_loop_count e v_deptno do tipo NUMBER.


Designe 10 a f_loop_count e 0 a v_deptno.

loop_count NUMBER(2) := 10;


deptno NUMBER(4) := 0;

c) Usando um loop, recupere os nomes de 10 departamentos e armazene-os no array


associativo. Comece com department_id 10. Aumente v_deptno em 10
para cada iteração do loop. A tabela a seguir mostra o department_id cujo
department_name você deve recuperar e armazenar no array associativo.

DEPARTMENT_ID DEPARTMENT_NAME
10 Administration
20 Marketing
30 Purchasing
40 Human Resources
50 Shipping
60 IT
70 Public Relations
80 Sales
90 Executive
100 Finance

Oracle Database: Fundamentos de PL/SQL A - 42


Solução 6: Trabalhando com Tipos de Dados Compostos
(continuação)

BEGIN
FOR i IN 1..f_loop_count
LOOP
v_deptno:=v_deptno+10;
SELECT department_name
INTO my_dept_table(i)
FROM departments
WHERE department_id = v_deptno;
END LOOP;

d) Usando outro loop, recupere os nomes dos departamentos do array associativo e


exiba-os.

FOR i IN 1..f_loop_count
LOOP
DBMS_OUTPUT.PUT_LINE (my_dept_table(i));
END LOOP;
END;

e) Execute e salve esse script como lab_06_02_soln.sql. A saída é a seguinte:

3) Modifique o bloco que você criou no Exercício 2 para recuperar todas as informações
sobre cada departamento da tabela departments e exiba as informações. Use um
array associativo com a tabela INDEX BY do método de registros.
a) Carregue o script lab_06_02_soln.sql.
b) Você declarou que o array associativo é do tipo
departments.department_name. Modifique a declaração do array

Oracle Database: Fundamentos de PL/SQL A - 43


Solução 6: Trabalhando com Tipos de Dados Compostos
(continuação)
associativo para armazenar temporariamente o número, o nome e o local de todos
os departamentos. Use o atributo %ROWTYPE.

SET SERVEROUTPUT ON

DECLARE
TYPE dept_table_type is table of departments%ROWTYPE
INDEX BY PLS_INTEGER;
my_dept_table dept_table_type;
f_loop_count NUMBER(2) := 10;
v_deptno NUMBER (4):=0;

c) Modifique a instrução SELECT para recuperar todas as informações sobre os


departamentos que estão atualmente na tabela departments e armazene-as no
array associativo.

BEGIN
FOR i IN 1..f_loop_count
LOOP
v_deptno := v_deptno + 10;
SELECT *
INTO my_dept_table(i)
FROM departments
WHERE department_id = v_deptno;
END LOOP;

d) Usando outro loop, recupere as informações sobre os departamentos do array


associativo e exiba-as.

FOR i IN 1..f_loop_count
LOOP
DBMS_OUTPUT.PUT_LINE ('Department Number : ' ||
my_dept_table(i).department_id
|| ' Department Name: ' ||
my_dept_table(i).department_name
|| ' Manager Id: '|| my_dept_table(i).manager_id
|| ' Location Id: ' || my_dept_table(i).location_id);
END LOOP;
END;

Oracle Database: Fundamentos de PL/SQL A - 44


Solução 6: Trabalhando com Tipos de Dados Compostos
(continuação)

O exemplo de saída é o seguinte:

Oracle Database: Fundamentos de PL/SQL A - 45


Exercícios e Soluções da Lição 7

Exercício 7-1: Usando Cursores Explícitos


Neste exercício, você executará duas atividades:
• Primeiro, você usará um cursor explícito para processar diversas linhas de uma tabela
e preencher outra tabela com os resultados usando um loop de cursor FOR.
• Em seguida, você criará um bloco PL/SQL que processa informações com dois
cursores, incluindo um que usa um parâmetro.

1) Crie um bloco PL/SQL para fazer o seguinte:


a) Na seção declarativa, declare e inicialize uma variável chamada v_deptno do
tipo NUMBER Designe um valor de ID de departamento válido (para obter valores,
consulte a tabela da etapa d).

b) Declare um cursor denominado c_emp_cursor, que recupera o last_name,


salary, e manager_id de funcionários que trabalham no departamento
especificado em v_deptno.

c) Na seção executável, use o loop de cursor FOR para operar os dados recuperados.
Se o salário do funcionário for menor que 5.000 e se o ID do gerente for 101 ou
124, exiba a mensagem “<<last_name>> Due for a raise.” Caso contrário, exiba a
mensagem “<<last_name>> Not Due for a raise.”

d) Teste o bloco PL/SQL para os seguintes casos:

Department ID Message
10 Whalen Due for a raise
20 Hartstein Not Due for a raise
Fay Not Due for a raise
50 Weiss Not Due for a raise
Fripp Not Due for a raise
Kaufling Not Due for a raise
Vollman Not Due for a raise. . .
. . .
OConnell Due for a raise
Grant Due for a raise
80 Russell Not Due for a raise
Partners Not Due for a raise
Errazuriz Not Due for a raise
Cambrault Not Due for a raise
. . .
Livingston Not Due for a raise
Johnson Not Due for a raise

Oracle Database: Fundamentos de PL/SQL A - 46


Exercício 7-1: Usando Cursores Explícitos (continuação)

2) Em seguida, crie um bloco PL/SQL que declara e usa dois cursores — um sem
parâmetro e outro com parâmetro. O primeiro cursor recupera o número e o nome do
departamento da tabela departments para todos os departamentos cujo número de
ID é menor que 100. O segundo cursor recebe o número do departamento como um
parâmetro e recupera os detalhes dos funcionários que trabalham nesse departamento
e cujo employee_id é menor que 120.

a) Declare um cursor c_dept_cursor para recuperar department_id e


department_name dos departamentos com department_id menor que
100. Ordene por department_id.

b) Declare outro cursor c_emp_cursor que assume o número do departamento


como parâmetro e recupera os seguintes dados da tabela employees:
last_name, job_id, hire_date e salary dos funcionários que trabalham
nesse departamento, com employee_id menor que 120.

c) Declare variáveis para reter os valores recuperados de cada cursor. Use o atributo
%TYPE enquanto estiver declarando variáveis.

d) Abra c_dept_cursor e use um loop simples para extrair com o comando fetch
valores para as variáveis declaradas. Exiba o número e o nome do departamento.
Use o atributo de cursor apropriado para sair do loop.

e) Abra c_emp_cursor, passando o número do departamento atual como um


parâmetro. Inicie outro loop e extraia valores de emp_cursor para variáveis e
imprima todos os detalhes recuperados da tabela employees.

Observação
• Verifique se c_emp_cursor já está aberto antes de abrir o cursor.
• Use os atributos de cursor apropriados para a condição de saída.
• Quando o loop for concluído, imprima uma linha após ter exibido os detalhes
de cada departamento e feche c_emp_cursor.

f) Finalize o primeiro loop e feche c_dept_cursor. Em seguida, finalize a seção


executável.

g) Execute o script. O exemplo de saída é o seguinte:

Oracle Database: Fundamentos de PL/SQL A - 47


Exercício 7-1: Usando Cursores Explícitos (continuação)

Oracle Database: Fundamentos de PL/SQL A - 48


Exercício 7-2: Usando Cursores Explícitos – Opcional
Se você tiver tempo, faça o seguinte exercício opcional: Crie um bloco PL/SQL que usa
um cursor explícito para determinar os n salários mais altos dos funcionários.

1) Execute o script lab_07-2.sql para criar a tabela top_salaries a fim de


armazenar os salários dos funcionários.

2) Na seção declarativa, declare a variável v_num do tipo NUMBER que contém um


número n, representando o número dos maiores n assalariados da tabela
employees. Por exemplo, para ver os cinco maiores salários, informe 5. Declare
outra variável sal do tipo employees.salary. Declare um cursor,
c_emp_cursor, que recupera os salários dos funcionários em ordem decrescente.
Lembre-se de que os salários não devem ser duplicados.

3) Na seção executável, abra o loop e extraia com o comando fetch os n salários mais
altos e, em seguida, insira-os na tabela top_salaries. Você pode usar um loop
simples para operar os dados. Além disso, tente e use os atributos %ROWCOUNT e
%FOUND para a condição de saída.
Observação: Certifique-se de adicionar uma condição de saída para evitar um loop
infinito.
4) Após fazer a inserção na tabela top_salaries, exiba as linhas com a instrução
SELECT. A saída mostrada representa os cinco maiores salários da tabela
employees.

5) Teste alguns casos especiais como v_num = 0 ou onde v_num seja maior que o
número de funcionários na tabela employees. Esvazie a tabela top_salaries
após cada teste.

Oracle Database: Fundamentos de PL/SQL A - 49


Solução 7-1: Usando Cursores Explícitos
Neste exercício, você executará duas atividades:
• Primeiro, você usará um cursor explícito para processar diversas linhas de uma tabela
e preencher outra tabela com os resultados usando um loop de cursor FOR.
• Em seguida, você criará um bloco PL/SQL que processa informações com dois
cursores, incluindo um que usa um parâmetro.

1) Crie um bloco PL/SQL para fazer o seguinte:


a) Na seção declarativa, declare e inicialize uma variável chamada v_deptno do
tipo NUMBER Designe um valor de ID de departamento válido (para obter valores,
consulte a tabela da etapa d).

DECLARE
v_deptno NUMBER := 10;

b) Declare um cursor denominado c_emp_cursor, que recupera o last_name,


salary, e manager_id de funcionários que trabalham no departamento
especificado em v_deptno.

CURSOR c_emp_cursor IS
SELECT last_name, salary,manager_id
FROM employees
WHERE department_id = v_deptno;

c) Na seção executável, use o loop de cursor FOR para operar os dados recuperados.
Se o salário do funcionário for menor que 5.000 e se o ID do gerente for 101 ou
124, exiba a mensagem “<<last_name>> Due for a raise.” Caso contrário, exiba a
mensagem “<<last_name>> Not Due for a raise.”

BEGIN
FOR emp_record IN c_emp_cursor
LOOP
IF emp_record.salary < 5000 AND (emp_record.manager_id=101
OR emp_record.manager_id=124) THEN
DBMS_OUTPUT.PUT_LINE (emp_record.last_name || ' Due for
a raise');
ELSE
DBMS_OUTPUT.PUT_LINE (emp_record.last_name || ' Not Due
for a raise');
END IF;
END LOOP;
END;

d) Teste o bloco PL/SQL para os seguintes casos:

Oracle Database: Fundamentos de PL/SQL A - 50


Solução 7-1: Usando Cursores Explícitos (continuação)

Department ID Message
10 Whalen Due for a raise
20 Hartstein Not Due for a raise
Fay Not Due for a raise
50 Weiss Not Due for a raise
Fripp Not Due for a raise
Kaufling Not Due for a raise
Vollman Not Due for a raise. . .
. . .
OConnell Due for a raise
Grant Due for a raise
80 Russell Not Due for a raise
Partners Not Due for a raise
Errazuriz Not Due for a raise
Cambrault Not Due for a raise
. . .
Livingston Not Due for a raise
Johnson Not Due for a raise

2) Em seguida, crie um bloco PL/SQL que declara e usa dois cursores — um sem
parâmetro e outro com parâmetro. O primeiro cursor recupera o número e o nome do
departamento da tabela departments para todos os departamentos cujo número de
ID é menor que 100. O segundo cursor recebe o número do departamento como um
parâmetro e recupera os detalhes dos funcionários que trabalham nesse departamento
e cujo employee_id é menor que 120.
a) Declare um cursor c_dept_cursor para recuperar department_id e
department_name dos departamentos com department_id menor que
100. Ordene por department_id.

DECLARE
CURSOR c_dept_cursor IS
SELECT department_id,department_name
FROM departments
WHERE department_id < 100
ORDER BY department_id;

Oracle Database: Fundamentos de PL/SQL A - 51


Solução 7-1: Usando Cursores Explícitos (continuação)

b) Declare outro cursor c_emp_cursor que assume o número do departamento


como parâmetro e recupera os seguintes dados da tabela employees:
last_name, job_id, hire_date e salary dos funcionários que trabalham
nesse departamento, com employee_id menor que 120.

CURSOR c_emp_cursor(v_deptno NUMBER) IS


SELECT last_name,job_id,hire_date,salary
FROM employees
WHERE department_id = v_deptno
AND employee_id < 120;

c) Declare variáveis para reter os valores recuperados de cada cursor. Use o atributo
%TYPE enquanto estiver declarando variáveis.

v_current_deptno departments.department_id%TYPE;
v_current_dname departments.department_name%TYPE;
v_ename employees.last_name%TYPE;
v_job employees.job_id%TYPE;
v_hiredate employees.hire_date%TYPE;
v_sal employees.salary%TYPE;

d) Abra c_dept_cursor e use um loop simples para extrair com o comando fetch
valores para as variáveis declaradas. Exiba o número e o nome do departamento.
Use o atributo de cursor apropriado para sair do loop.

BEGIN
OPEN c_dept_cursor;
LOOP
FETCH c_dept_cursor INTO v_current_deptno,
v_current_dname;
EXIT WHEN c_dept_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE ('Department Number : ' ||
v_current_deptno || ' Department Name : ' ||
v_current_dname);

Oracle Database: Fundamentos de PL/SQL A - 52


Solução 7-1: Usando Cursores Explícitos (continuação)

e) Abra c_emp_cursor, passando o número do departamento atual como um


parâmetro. Inicie outro loop e extraia valores de emp_cursor para variáveis e
imprima todos os detalhes recuperados da tabela employees.

Observação
• Verifique se c_emp_cursor já está aberto antes de abrir o cursor.
• Use os atributos de cursor apropriados para a condição de saída.
• Quando o loop for concluído, imprima uma linha após ter exibido os detalhes
de cada departamento e feche c_emp_cursor.

IF c_emp_cursor%ISOPEN THEN
CLOSE c_emp_cursor;
END IF;
OPEN c_emp_cursor (v_current_deptno);
LOOP
FETCH c_emp_cursor INTO v_ename,v_job,v_hiredate,v_sal;
EXIT WHEN c_emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE (v_ename || ' ' || v_job
|| ' ' || v_hiredate || ' ' ||
v_sal);
END LOOP;
DBMS_OUTPUT.PUT_LINE('--------------------------------------
--------------------------------------------------');
CLOSE c_emp_cursor;

f) Finalize o primeiro loop e feche c_dept_cursor. Em seguida, finalize a seção


executável.

END LOOP;
CLOSE c_dept_cursor;
END;

g) Execute o script. O exemplo de saída é o seguinte:

Oracle Database: Fundamentos de PL/SQL A - 53


Solução 7-1: Usando Cursores Explícitos (continuação)

Oracle Database: Fundamentos de PL/SQL A - 54


Solução 7-2: Usando Cursores Explícitos – Opcional
Se você tiver tempo, faça o exercício opcional a seguir. Crie um bloco PL/SQL que usa
um cursor explícito para determinar os n salários mais altos dos funcionários.

1) Execute o script lab_07-02.sql para criar a nova tabela top_salaries a fim


de armazenar os salários dos funcionários.

2) Na seção declarativa, declare a variável v_num do tipo NUMBER que contém um


número n, representando o número dos maiores n assalariados da tabela
employees. Por exemplo, para ver os cinco maiores salários, informe 5. Declare
outra variável sal do tipo employees.salary. Declare um cursor,
c_emp_cursor, que recupera os salários dos funcionários em ordem decrescente.
Lembre-se de que os salários não devem ser duplicados.

DECLARE
v_num NUMBER(3) := 5;
v_sal employees.salary%TYPE;
CURSOR c_emp_cursor IS
SELECT salary
FROM employees
ORDER BY salary DESC;

3) Na seção executável, abra o loop e extraia com o comando fetch os n salários mais
altos e, em seguida, insira-os na tabela top_salaries. Você pode usar um loop
simples para operar os dados. Além disso, tente e use os atributos %ROWCOUNT e
%FOUND para a condição de saída.
Observação: Certifique-se de adicionar uma condição de saída para evitar um loop
infinito.

BEGIN
OPEN c_emp_cursor;
FETCH c_emp_cursor INTO v_sal;
WHILE c_emp_cursor%ROWCOUNT <= v_num AND c_emp_cursor%FOUND
LOOP
INSERT INTO top_salaries (salary)
VALUES (v_sal);
FETCH c_emp_cursor INTO v_sal;
END LOOP;
CLOSE c_emp_cursor;
END;

Oracle Database: Fundamentos de PL/SQL A - 55


Solução 7-2: Usando Cursores Explícitos – Opcional
(continuação)
4) Após fazer a inserção na tabela top_salaries, exiba as linhas com a instrução
SELECT. A saída mostrada representa os cinco maiores salários da tabela
employees.

/
SELECT * FROM top_salaries;

O exemplo de saída é o seguinte:

5) Teste alguns casos especiais como v_num = 0 ou onde v_num seja maior que o
número de funcionários na tabela employees. Esvazie a tabela top_salaries
após cada teste.

Oracle Database: Fundamentos de PL/SQL A - 56


Exercícios e Soluções da Lição 8
Exercício 8-1: Tratando Exceções Predefinidas
Neste exercício, você criará um bloco PL/SQL que aplica uma exceção predefinida para
processar apenas um registro de cada vez. O bloco PL/SQL seleciona o nome do
funcionário com um dado valor de salário.
1) Execute o comando do arquivo lab_05_01.sql para recriar a tabela messages.

2) Na seção declarativa, declare duas variáveis: v_ename do tipo


employees.last_name e v_emp_sal do tipo employees.salary.
Inicialize a última como 6000.

3) Na seção executável, recupere os sobrenomes dos funcionários cujos salários sejam


iguais ao valor de v_emp_sal. Se o salário informado retornar apenas uma linha,
insira na tabela messages o nome do funcionário e o valor do salário.
Observação: Não use cursores explícitos.

4) Se o salário informado não retornar nenhuma linha, trate a exceção com um handler
de exceções adequado e insira na tabela messages a mensagem “No employee with
a salary of <salary>.”

5) Se o salário informado retornar várias linhas, trate a exceção com um handler de


exceções adequado e insira na tabela messages a mensagem “More than one
employee with a salary of <salary>.”

6) Trate qualquer outra exceção com um handler de exceções adequado e insira na


tabela messages a mensagem “Some other error occurred.”

7) Exiba as linhas da tabela messages para verificar se o bloco PL/SQL foi executado
com sucesso. A saída é a seguinte:

8) Altere o valor inicializado de v_emp_sal para 2000 e efetue uma nova execução. A
saída é a seguinte:

Oracle Database: Fundamentos de PL/SQL A - 57


Exercício 8-2: Tratando Exceções Padrão do Oracle Server
Neste exercício, você criará um bloco PL/SQL que declara uma exceção para o erro do
Oracle Server ORA-02292 (integrity constraint violated – child
record found). O bloco testa se há exceção e exibe a mensagem de erro.
1) Na seção declarativa, declare uma exceção e_childrecord_exists. Associe a
exceção declarada ao erro padrão do Oracle Server –02292..

2) Na seção executável, exiba “Deleting department 40....” Inclua a instrução DELETE


para deletar o departamento com department_id 40.

3) Inclua uma seção de exceções para tratar a exceção e_childrecord_exists e


exibir a mensagem adequada.

O exemplo de saída é o seguinte:

Oracle Database: Fundamentos de PL/SQL A - 58


Solução 8-1: Tratando Exceções Predefinidas
Neste exercício, você criará um bloco PL/SQL que aplica uma exceção predefinida para
processar apenas um registro de cada vez. O bloco PL/SQL seleciona o nome do
funcionário com um dado valor de salário.

1) Execute o comando do arquivo lab_05_01.sql para recriar a tabela messages.

2) Na seção declarativa, declare duas variáveis: v_ename do tipo


employees.last_name e v_emp_sal do tipo employees.salary.
Inicialize a última como 6000.

DECLARE
v_ename employees.last_name%TYPE;
v_emp_sal employees.salary%TYPE := 6000;

3) Na seção executável, recupere os sobrenomes dos funcionários cujos salários sejam


iguais ao valor de v_emp_sal. Se o salário informado retornar apenas uma linha,
insira na tabela messages o nome do funcionário e o valor do salário.
Observação: Não use cursores explícitos.

BEGIN
SELECT last_name
INTO v_ename
FROM employees
WHERE salary = v_emp_sal;
INSERT INTO messages (results)
VALUES (v_ename || ' - ' || v_emp_sal);

4) Se o salário informado não retornar nenhuma linha, trate a exceção com um handler
de exceções adequado e insira na tabela messages a mensagem “No employee with
a salary of <salary>.”

EXCEPTION
WHEN no_data_found THEN
INSERT INTO messages (results)
VALUES ('No employee with a salary of '||
TO_CHAR(v_emp_sal));

Oracle Database: Fundamentos de PL/SQL A - 59


Solução 8-1: Tratando Exceções Predefinidas (continuação)

5) Se o salário informado retornar várias linhas, trate a exceção com um handler de


exceções adequado e insira na tabela messages a mensagem “More than one
employee with a salary of <salary>.”

WHEN too_many_rows THEN


INSERT INTO messages (results)
VALUES ('More than one employee with a salary of '||
TO_CHAR(v_emp_sal));

6) Trate qualquer outra exceção com um handler de exceções adequado e insira na


tabela messages a mensagem “Some other error occurred.”

WHEN others THEN


INSERT INTO messages (results)
VALUES ('Some other error occurred.');
END;

7) Exiba as linhas da tabela messages para verificar se o bloco PL/SQL foi executado
com sucesso.
/
SELECT * FROM messages;

A saída é a seguinte:

8) Altere o valor inicializado de v_emp_sal para 2000 e efetue uma nova execução. A
saída é a seguinte:

Oracle Database: Fundamentos de PL/SQL A - 60


Solução 8-2: Tratando Exceções Padrão do Oracle Server
Neste exercício, você criará um bloco PL/SQL que declara uma exceção para o erro do
Oracle Server ORA-02292 (integrity constraint violated – child
record found). O bloco testa se há exceção e exibe a mensagem de erro.
1) Na seção declarativa, declare uma exceção e_childrecord_exists. Associe a
exceção declarada ao erro padrão do Oracle Server –02292..

SET SERVEROUTPUT ON
DECLARE
e_childrecord_exists EXCEPTION;
PRAGMA EXCEPTION_INIT(e_childrecord_exists, -02292);

2) Na seção executável, exiba “Deleting department 40....” Inclua a instrução DELETE


para deletar o departamento com department_id 40.

BEGIN
DBMS_OUTPUT.PUT_LINE(' Deleting department 40........');
delete from departments where department_id=40;

3) Inclua uma seção de exceções para tratar a exceção e_childrecord_exists e


exibir a mensagem adequada.

EXCEPTION
WHEN e_childrecord_exists THEN
DBMS_OUTPUT.PUT_LINE(' Cannot delete this department. There
are employees in this department (child records exist.) ');
END;

O exemplo de saída é o seguinte:

Oracle Database: Fundamentos de PL/SQL A - 61


Exercícios e Soluções da Lição 9

Exercício 9: Criando e Usando Procedures Armazenados


Neste exercício, você modificará scripts existentes para criar e usar procedures
armazenados.

1) Carregue o script sol_02_04.sql da pasta /home/oracle/plsf/soln/.


a) Modifique o script para converter o bloco anônimo em um procedure chamado
greet. (Dica: Além disso, remova o comando SET SERVEROUTPUT ON.)
b) Execute o script para criar o procedure. Os resultados de saída devem ser os
seguintes:

c) Salve esse script como lab_09_01_soln.sql.


d) Clique no botão Clear para limpar o espaço de trabalho.
e) Crie e execute um bloco anônimo para chamar o procedure greet. (Dica:
Certifique-se de ter habilitado SERVEROUTPUT no início do bloco.)

A saída deverá ser semelhante à seguinte:

2) Modifique o script lab_09_01_soln.sql da seguinte maneira:


a) Elimine o procedure greet executando o seguinte comando:

DROP PROCEDURE greet;

b) Modifique o procedure para aceitar um argumento do tipo VARCHAR2. Chame o


argumento p_name.
c) Imprima Hello <name> (ou seja, o conteúdo do argumento) em vez de
imprimir Hello World.
d) Salve esse script como lab_09_02_soln.sql.

Oracle Database: Fundamentos de PL/SQL A - 62


Exercício 9: Criando e Usando Procedures Armazenados
(continuação)
e) Execute o script para criar o procedure. Os resultados de saída devem ser os
seguintes:

f) Crie e execute um bloco anônimo para chamar o procedure greet com um valor
de parâmetro. O bloco também deve gerar a saída.

O exemplo de saída deverá ser semelhante ao seguinte:

Oracle Database: Fundamentos de PL/SQL A - 63


Solução 9: Criando e Usando Procedures Armazenados
Neste exercício, você modificará scripts existentes para criar e usar procedures
armazenados.

1) Carregue o script sol_02_04.sql da pasta /home/oracle/plsf/soln/.


a) Modifique o script para converter o bloco anônimo em um procedure chamado
greet. (Dica: Além disso, remova o comando SET SERVEROUTPUT ON.)

CREATE PROCEDURE greet IS


V_today DATE:=SYSDATE;
V_tomorrow today%TYPE;
...

b) Execute o script para criar o procedure. Os resultados de saída devem ser os


seguintes:

c) Salve esse script como lab_09_01_soln.sql.


d) Clique no botão Clear para limpar o espaço de trabalho.
e) Crie e execute um bloco anônimo para chamar o procedure greet.
(Dica:Certifique-se de ter habilitado SERVEROUTPUT no início do bloco.)

SET SERVEROUTPUT ON

BEGIN
greet;
END;

A saída deverá ser semelhante à seguinte:

Oracle Database: Fundamentos de PL/SQL A - 64


Solução 9: Criando e Usando Procedures Armazenados
(continuação)

2) Modifique o script lab_09_01_soln.sql da seguinte maneira:


a) Elimine o procedure greet executando o seguinte comando:

DROP PROCEDURE greet;

b) Modifique o procedure para aceitar um argumento do tipo VARCHAR2. Chame o


argumento p_name.

CREATE PROCEDURE greet(p_name VARCHAR2) IS


V_today DATE:=SYSDATE;
V_tomorrow today%TYPE;

c) Imprima Hello <name> em vez de imprimir Hello World.

BEGIN
V_tomorrow:=v_today +1;
DBMS_OUTPUT.PUT_LINE(' Hello '|| p_name);
...

d) Salve esse script como lab_09_02_soln.sql.

e) Execute o script para criar o procedure. Os resultados de saída devem ser os


seguintes:

f) Crie e execute um bloco anônimo para chamar o procedure greet com um valor
de parâmetro. O bloco também deve gerar a saída.

SET SERVEROUTPUT ON;


BEGIN
greet('Nancy');
END;

Oracle Database: Fundamentos de PL/SQL A - 65


Solução 9: Criando e Usando Procedures Armazenados
(continuação)

O exemplo de saída deverá ser semelhante ao seguinte:

Oracle Database: Fundamentos de PL/SQL A - 66


Apêndice B:
Descrição de Tabelas
e Dados
DIAGRAMA DE RELACIONAMENTO ENTRE ENTIDADES

Oracle Database: Fundamentos de PL/SQL B -2


Tabelas do Esquema
SELECT * FROM tab;

Oracle Database: Fundamentos de PL/SQL B -3


Tabela regions
DESCRIBE regions

SELECT * FROM regions;

Oracle Database: Fundamentos de PL/SQL B -4


Tabela countries
DESCRIBE countries

SELECT * FROM countries;

Oracle Database: Fundamentos de PL/SQL B -5


Tabela locations
DESCRIBE locations;

SELECT * FROM locations;

Oracle Database: Fundamentos de PL/SQL B -6


Tabela departments
DESCRIBE departments

SELECT * FROM departments;

Oracle Database: Fundamentos de PL/SQL B -7


Tabela jobs
DESCRIBE jobs

SELECT * FROM jobs;

Oracle Database: Fundamentos de PL/SQL B -8


Tabela employees
DESCRIBE employees

Oracle Database: Fundamentos de PL/SQL B -9


Tabela employees (continuação)
Os cabeçalhos das colunas commission_pct, manager_id e department_id são
definidos como comm, mgrid e deptid, respectivamente, na tela a seguir para ajustar os
valores das tabelas na página.
SELECT * FROM employees;

Oracle Database: Fundamentos de PL/SQL B -10


Tabela employees (continuação)

Oracle Database: Fundamentos de PL/SQL B -11


Tabela employees (continuação)

Oracle Database: Fundamentos de PL/SQL B -12


Tabela job_history
DESCRIBE job_history

SELECT * FROM job_history;

Oracle Database: Fundamentos de PL/SQL B -13


Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.
Objetivos

Ao concluir este apêndice, você será capaz de:


• Listar os principais recursos do Oracle SQL Developer
• Identificar os itens de menu do Oracle SQL Developer
• Criar uma conexão de banco de dados
• Gerenciar objetos de banco de dados
• Usar a Planilha SQL
• Salvar e executar scripts SQL
• Criar e salvar relatórios

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Objetivos
Neste apêndice, você será apresentado à ferramenta gráfica chamada SQL Developer. Você
aprenderá a usar o SQL Developer nas tarefas de desenvolvimento de seu banco de dados. Você
aprenderá a usar a Planilha SQL para executar instruções e scripts SQL.

Oracle Database: Fundamentos de PL/SQL C- 2


O que É o Oracle SQL Developer?

• O Oracle SQL Developer é uma ferramenta gráfica que


melhora a produtividade e simplifica as tarefas de
desenvolvimento de banco de dados.
• Você pode se conectar a qualquer esquema de banco de dados
Oracle de destino usando a autenticação de banco de dados
padrão Oracle.

SQL Developer

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

O que É o Oracle SQL Developer?


O Oracle SQL Developer é uma ferramenta gráfica gratuita projetada para melhorar sua
produtividade e simplificar o desenvolvimento das tarefas diárias de banco de dados. Com
apenas alguns cliques, você poderá criar e depurar com facilidade procedures armazenados,
testar instruções SQL e exibir planos do otimizador.
O SQL Developer, a ferramenta visual para o desenvolvimento de banco de dados, simplifica as
seguintes tarefas:
• Pesquisa e gerenciamento de objetos de banco de dados
• Execução de scripts e instruções SQL
• Edição e depuração de instruções PL/SQL
• Criação de relatórios
Você pode se conectar a qualquer esquema de banco de dados Oracle de destino usando a
autenticação padrão de banco de dados Oracle. Quando estiver conectado, você poderá executar
operações em objetos no banco de dados.
O SQL Developer release 1.2 está totalmente integrado ao Developer Migration Workbench, que
oferece aos usuários um único ponto para navegar pelos dados e objetos de bancos de dados em
bancos de dados de terceiros e para migrar desses bancos de dados para o Oracle. Você também
pode se conectar a esquemas de bancos de dados de terceiros (não Oracle) selecionados como,
por exemplo, MySQL, Microsoft SQL Server e Microsoft Access, e pode também exibir dados e
metadados desses bancos de dados.
Além disso, o SQL Developer inclui suporte para o Oracle Application Express 3.0.1 (Oracle
APEX).
Oracle Database: Fundamentos de PL/SQL C- 3
Especificações do SQL Developer

• É fornecido com o Oracle Database 11g Release 2


• É desenvolvido em Java
• Suporta as plataformas Windows, Linux e Mac OS X
• Oferece conectividade padrão usando o driver JDBC Thin
• Conecta-se ao Oracle Database versão 9.2.0.1 e posterior
• Está disponível para download gratuito a partir do seguinte
link:
– http://www.oracle.com/technology/products/database/sql_de
veloper/index.html

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Especificações do SQL Developer


O Oracle SQL Developer 1.5 é fornecido com o Oracle Database 11g Release 2. O SQL
Developer é desenvolvido em Java e utiliza o IDE (Integrated Development Environment) do
Oracle JDeveloper. Portanto, é uma ferramenta multiplataforma. Ela é executada nas
plataformas dos sistemas operacionais Windows, Linux e Mac (OS) X.
A conectividade default para o banco de dados se dá pelo driver Java Database Connectivity
(JDBC) Thin e, portanto, não há a necessidade de um Oracle Home. O SQL Developer não
requer um instalador. Basta que você descompacte o arquivo transferido por download. Com o
SQL Developer, os usuários podem se conectar ao Oracle Database release 9.2.0.1 e posteriores,
e a todas as edições do banco de dados Oracle, incluindo a Express Edition.
Observação
• Em versões do Oracle Database anteriores à Oracle Database 11g Release 2, você deverá
fazer o download e instalar o SQL Developer. O SQL Developer 1.5 está disponível para
download gratuito a partir do seguinte link:
- http://www.oracle.com/technology/products/database/sql_developer/index.html
• Para obter instruções sobre como instalar o SQL Developer, você pode visitar este link:
- http://download.oracle.com/docs/cd/E12151_01/index.htm

Oracle Database: Fundamentos de PL/SQL C- 4


Interface do SQL Developer 1.5

Você precisa definir


uma conexão para
começar a usar o SQL
Developer para a
execução de consultas
SQL em um esquema
de banco de dados.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Interface do SQL Developer 1.5


A interface do SQL Developer 1.5 contém três tabs principais de navegação, da esquerda para a
direita:
• Tab Connections: Com esta tab, você pode navegar pelos objetos e usuários de banco de
dados aos quais tem acesso.
• Tab Files: Identificada pelo ícone da pasta Files, essa tab permite o acesso aos arquivos na
máquina local sem que seja necessário usar o menu File > Open.
• Tab Reports: Identificada pelo ícone Reports, essa tab permite que você execute relatórios
predefinidos ou crie e adicione seus próprios relatórios.
Uso e Navegação Geral
O SQL Developer usa o lado esquerdo de navegação para localizar e selecionar objetos e o lado
direito para exibir informações sobre objetos selecionados. Você pode personalizar diversos
aspectos da aparência e do comportamento do SQL Developer configurando preferências.
Observação: Você precisa definir pelo menos uma conexão para poder conectar-se a um
esquema de banco de dados e executar consultas SQL ou procedures e funções.

Oracle Database: Fundamentos de PL/SQL C- 5


Interface do SQL Developer 1.5 (continuação)
Menus
Os menus a seguir contêm entradas padrão, bem como entradas referentes a recursos específicos
do SQL Developer:
• View: Contém opções que afetam o que é exibido na interface do SQL Developer
• Navigate: Contém opções para navegação pelos painéis e na execução de subprogramas
• Run: Contém as opções Run File e Execution Profile que são relevantes quando uma
função ou um procedure é selecionado, além de opções de depuração
• Source: Contém opções para serem usadas quando você editar funções e procedures
• Versioning: Oferece suporte integrado para os seguintes sistemas de controle de origem e
de versão: CVS (Concurrent Versions System) e Subversion
• Migration: Contém opções relacionadas à migração de bancos de dados de terceiros para
o Oracle
• Tools: Chama as ferramentas do SQL Developer como, por exemplo, SQL*Plus,
Preferences e Planilha SQL
Observação: O menu Run também contém opções que são relevantes quando uma função ou
um procedure é selecionado para depuração. Essas são as mesmas opções encontradas no menu
Debug na versão 1.2.

Oracle Database: Fundamentos de PL/SQL C- 6


Criando uma Conexão de Banco de Dados

• Você precisa ter pelo menos uma conexão de banco de


dados para usar o SQL Developer.
• Você pode criar e testar conexões com:
– Vários bancos de dados
– Vários esquemas
• O SQL Developer importa automaticamente as conexões
definidas no arquivo tnsnames.ora em seu sistema.
• Você pode exportar conexões para um arquivo XML
(Extensible Markup Language).
• Cada conexão adicional com o banco de dados que é
criada é listada na hierarquia do Connections Navigator.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Criando uma Conexão de Banco de Dados


Uma conexão é um objeto do SQL Developer que especifica as informações necessárias para
conexão com determinado banco de dados como um usuário específico desse banco de dados.
Para usar o SQL Developer, será necessário ter ao menos uma conexão de banco de dados, que
poderá ser existente, criada ou importada.
Você pode criar e testar conexões com vários bancos de dados e vários esquemas.
Por default, o arquivo tnsnames.ora está localizado no diretório
$ORACLE_HOME/network/admin, mas ele também pode estar no diretório especificado
pelo valor de Registro ou pela variável de ambiente TNS_ADMIN. Quando você iniciar o SQL
Developer e exibir a caixa de diálogo Database Connections, o SQL Developer importará
automaticamente as conexões definidas no arquivo tnsnames.ora do sistema.
Observação: No Windows, se existir o arquivo tnsnames.ora, mas suas conexões não
estiverem sendo usadas pelo SQL Developer, defina TNS_ADMIN como uma variável de
ambiente do sistema.
Você pode exportar conexões para um arquivo XML para que você possa reutilizá-las
posteriormente.
É possível criar conexões adicionais como usuários diferentes com o mesmo banco de dados ou
para conectar-se a diferentes bancos de dados.

Oracle Database: Fundamentos de PL/SQL C- 7


Criando uma Conexão de Banco de Dados

1 2

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Criando uma Conexão de Banco de Dados (continuação)


Para criar uma conexão de banco de dados, faça o seguinte:
1. Na página com a tab Connections, clique com o botão direito do mouse em Connections e
selecione New Connection.
2. Na janela New/Select Database Connection, informe o nome da conexão. Informe o nome
de usuário e a senha do esquema ao qual deseja se conectar.
a) Na caixa drop-down Role, você pode selecionar default ou SYSDBA (escolha
SYSDBA para o usuário sys ou para qualquer usuário com privilégios de
administrador de banco de dados).
b) Você pode selecionar o tipo de conexão como:
- Basic: Nesse tipo, informe o nome do host e o SID referentes ao banco de dados
ao qual deseja se conectar. A porta já foi configurada como 1521. Você também
tem a opção de informar diretamente o nome do serviço, se usar uma conexão
remota com o banco de dados.
- TNS: Você pode selecionar qualquer apelido de banco de dados importado do
arquivo tnsnames.ora.
- LDAP: Você pode pesquisar serviços de bancos de dados no Oracle Internet
Directory, que é um componente do Oracle Identity Management.
- Advanced: Você pode definir um URL JDBC (Java Database Connectivity)
personalizado para se conectar ao banco de dados.
c) Clique em Test para garantir que a conexão foi definida corretamente.
d) Clique em Connect.
Oracle Database: Fundamentos de PL/SQL C- 8
Criando uma Conexão de Banco de Dados (continuação)
Se você marcar a caixa de seleção Save Password, a senha será salva em um arquivo XML.
Assim, depois que você fechar a conexão com o SQL Developer e abri-la novamente, a
senha não será solicitada.
3. A conexão será adicionada ao Connections Navigator. Você pode expandir a conexão para
exibir os objetos de banco de dados e as definições de objeto, por exemplo, dependências,
detalhes, estatísticas e assim por diante.
Observação: Na mesma janela New/Select Database Connection, você poderá definir conexões
com origens de dados não Oracle usando as tabs Access, MySQL e SQL Server. No entanto,
essas conexões são somente para leitura, as quais permitem que você navegue por objetos e
dados nessa origem de dados.

Oracle Database: Fundamentos de PL/SQL C- 9


Navegando por Objetos de Banco de Dados
Use o Connections Navigator para:
• Navegar por vários objetos em um esquema de banco de
dados
• Analisar rapidamente as definições de objetos

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Navegando por Objetos de Banco de Dados


Após criar uma conexão com o banco de dados, você poderá usar o Connections Navigator para
navegar por vários objetos em um esquema de banco de dados, incluindo Tabelas, Views,
Índices, Pacotes, Procedures, Triggers e Tipos.
O SQL Developer usa o lado esquerdo de navegação para localizar e selecionar objetos e o lado
direito para exibir informações sobre objetos selecionados. Você pode personalizar diversos
aspectos da aparência do SQL Developer configurando preferências.
Você pode visualizar a definição dos objetos dividida em tabs de informações que são obtidas do
dicionário de dados. Por exemplo, se você tiver selecionado uma tabela no Navigator, os
detalhes sobre colunas, constraints, grants, estatísticas, triggers e assim por diante serão exibidos
em uma página com tabs fácil de ler.
Se desejar visualizar a definição da tabela EMPLOYEES conforme mostrada no slide, execute as
seguintes etapas:
1. Expanda o nó Connections no Connections Navigator.
2. Expanda Tables.
3. Clique em EMPLOYEES. Por default, a tab Columns é selecionada. Ela mostra a descrição
da coluna da tabela. Usando a tab Data, você poderá exibir os dados da tabela, assim como
incluir novas linhas, atualizar dados e fazer commit dessas alterações no banco de dados.

Oracle Database: Fundamentos de PL/SQL C- 10


Exibindo a Estrutura da Tabela

Use o comando DESCRIBE para exibir a estrutura de uma


tabela:

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Exibindo a Estrutura da Tabela


No SQL Developer, também é possível exibir a estrutura de uma tabela usando o comando
DESCRIBE. O resultado do comando é uma exibição de nomes de colunas e tipos de dados,
assim como uma indicação informando se a coluna deve conter dados.

Oracle Database: Fundamentos de PL/SQL C- 11


Procurando Arquivos

Use o Files Navigator para explorar o sistema de arquivos


e abrir os arquivos do sistema.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Navegando por Objetos de Banco de Dados


Você pode usar o Files Navigator para procurar e abrir os arquivos do sistema.
• Para exibir o Files Navigator, clique na tab Files ou selecione View > Files.
• Para exibir o conteúdo de um arquivo, clique duas vezes no nome dele para exibir seu
conteúdo na área da Planilha SQL.

Oracle Database: Fundamentos de PL/SQL C- 12


Criando um Objeto de Esquema

• O SQL Developer oferece suporte para a criação de


qualquer objeto de esquema:
– Executando uma instrução SQL em uma Planilha SQL
– Usando o menu de contexto
• Edite os objetos usando uma caixa de diálogo de edição
ou um dos muitos menus contextuais.
• Exiba a DDL (data definition language) referente aos
ajustes como, por exemplo, a criação de um novo objeto
ou a edição de um objeto de esquema existente.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Criando um Objeto de Esquema


O SQL Developer oferece suporte para a criação de qualquer objeto de esquema com a execução
de uma instrução SQL em uma planilha SQL. Você também tem a opção de criar objetos usando
o menu de contexto. Depois que os objetos estiverem criados, você poderá editá-los usando uma
caixa de diálogo de edição ou um dos muitos menus contextuais.
À medida que os novos objetos são criados ou que os objetos existentes são editados, a DDL
referente a esses ajustes se torna disponível para análise. A opção Export DDL estará disponível
se você quiser criar a DDL completa para um ou mais objetos no esquema.
O slide mostra como criar uma tabela usando o menu de contexto. Para abrir uma caixa de
diálogo a fim de criar uma nova tabela, clique com o botão direito do mouse em Tables e
selecione New Table. As caixas de diálogo para criar e editar objetos de banco de dados
possuem diversas tabs, cada uma delas refletindo um agrupamento lógico de propriedades para
esse tipo de objeto.

Oracle Database: Fundamentos de PL/SQL C- 13


Criando uma Nova Tabela: Exemplo

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Criando uma Nova Tabela: Exemplo


Na caixa de diálogo Create Table, se você não marcar a caixa de seleção Advanced , poderá
criar uma tabela rapidamente especificando colunas e alguns recursos usados com frequência.
Se você marcar a caixa de seleção Advanced, a caixa de diálogo Create Table será alterada para
outra com diversas opções, na qual será possível especificar um amplo conjunto de recursos
durante a criação da tabela.
O exemplo do slide mostra como criar a tabela DEPENDENTS, marcando a caixa de seleção
Advanced.
Para criar uma nova tabela, execute as seguintes etapas:
1. No Connections Navigator, clique com o botão direito do mouse em Tables.
2. Selecione New Table.
3. Na caixa de diálogo Create Table, selecione Advanced.
4. Especifique as informações da coluna.
5. Clique em OK.
Ainda que não seja obrigatório, você deve especificar também uma chave primária usando a tab
Primary Key na caixa de diálogo. Às vezes, convém editar a tabela criada. Para isso, clique com
o botão direito do mouse na tabela no Connections Navigator e selecione Edit.

Oracle Database: Fundamentos de PL/SQL C- 14


Usando a Planilha SQL

• Use a Planilha SQL para informar e executar instruções


SQL, PL/SQL e SQL*Plus.
• Especifique as ações que podem ser processadas pela
conexão de banco de dados associada à planilha.

Clique no ícone Open


Selecione SQL SQL Worksheet.
Worksheet no menu
Tools ou

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Usando a Planilha SQL


Quando você estabelecer uma conexão com um banco de dados, uma janela da Planilha SQL
será aberta automaticamente para essa conexão. Você pode usar a Planilha SQL para informar e
executar instruções SQL, PL/SQL e SQL*Plus. A Planilha SQL oferece suporte a instruções
SQL*Plus até determinado ponto. Entretanto, as instruções SQL*Plus que não são suportadas
pela Planilha SQL serão ignoradas e não serão passadas para o banco de dados.
Você pode especificar as ações que podem ser processadas pela conexão com o banco de dados
associada à planilha, como:
• Criar uma tabela
• Inserir dados
• Criar e editar um trigger
• Selecionar dados de uma tabela
• Salvar os dados selecionados em um arquivo
Você pode exibir uma Planilha SQL usando uma das seguintes opções:
• Selecione Tools > SQL Worksheet.
• Clique no ícone Open SQL Worksheet.

Oracle Database: Fundamentos de PL/SQL C- 15


Usando a Planilha SQL

2 4 6 8

1 3 5 7 9

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Usando a Planilha SQL (continuação)


Você poderá usar as teclas de atalho ou os ícones para executar determinadas tarefas como a
execução de uma instrução SQL ou de um script e a exibição do histórico das instruções SQL
que executa. Você poderá usar a barra de ferramentas da Planilha SQL que contém ícones para a
execução das seguintes tarefas:
1. Execute Statement: Executa a instrução no local onde o cursor está na janela Enter SQL
Statement. Você poderá usar variáveis de bind nas instruções SQL, mas não poderá usar
variáveis de substituição.
2. Run Script: Executa todas as instruções na janela Enter SQL Statement usando o Script
Runner. Você poderá usar variáveis de substituição nas instruções SQL, mas não poderá
usar variáveis de bind.
3. Commit: Grava as alterações no banco de dados e finaliza a transação
4. Rollback: Descarta as alterações no banco de dados sem gravá-las e finaliza a transação.
5. Cancel: Interrompe as instruções em execução no momento.
6. SQL History: Exibe uma caixa de diálogo com informações sobre as instruções SQL
executadas por você.
7. Execute Explain Plan: Gera o plano de execução, que você pode visualizar clicando na
tab Explain.
8. Autotrace: Gera informações de rastreamento da instrução.
9. Clear: Apaga as instruções na janela Enter SQL Statement.
Oracle Database: Fundamentos de PL/SQL C- 16
Usando a Planilha SQL

• Use a Planilha SQL para informar e executar instruções


SQL, PL/SQL e SQL*Plus.
• Especifique as ações que podem ser processadas pela
conexão de banco de dados associada à planilha.

Informe
instruções SQL.

Os resultados são
mostrados aqui.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Usando a Planilha SQL (continuação)


Quando você estabelecer uma conexão com um banco de dados, uma janela da Planilha SQL
será aberta automaticamente para essa conexão. Você pode usar a Planilha SQL para informar e
executar instruções SQL, PL/SQL e SQL*Plus. Todos os comandos SQL e PL/SQL são
suportados, já que passam diretamente da Planilha SQL para o banco de dados Oracle. Mas os
comandos do SQL*Plus usados no SQL Developer precisam ser interpretados pela Planilha SQL
antes de serem passados para o banco de dados.
Atualmente, a Planilha SQL oferece suporte a diversos comandos do SQL*Plus. No entanto, os
comandos não suportados pela Planilha SQL serão ignorados e não serão enviados ao banco de
dados Oracle. Com a Planilha SQL, você pode executar instruções SQL e alguns dos comandos
do SQL*Plus.
Você pode exibir uma Planilha SQL usando uma destas duas opções:
• Selecione Tools > SQL Worksheet.
• Clique no ícone Open SQL Worksheet.

Oracle Database: Fundamentos de PL/SQL C- 17


Executando Instruções SQL

Use a janela Enter SQL Statement para informar uma ou várias


instruções SQL.

F9 F5

F5
F9

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Executando Instruções SQL


O exemplo do slide mostra a diferença na saída da mesma consulta quando você usa a tecla F9
ou Execute Statement em vez de F5 ou Run Script.

Oracle Database: Fundamentos de PL/SQL C- 18


Salvando Scripts SQL
Clique no ícone Save
1 para salvar sua instrução
SQL em um arquivo.

Identifique um local,
O conteúdo do arquivo
2 informe um nome de
3 salvo estará visível e arquivo e clique em Save.
poderá ser editado na
janela da Planilha SQL.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Salvando Scripts SQL


Você pode salvar as instruções SQL da Planilha SQL em um arquivo de texto. Para salvar o
conteúdo da janela Enter SQL Statement, execute as seguintes etapas:
1. Clique no ícone Save ou use a opção de menu File > Save.
2. Na caixa de diálogo Salvar do Windows, informe um nome de arquivo e o local no qual
deseja salvar o arquivo.
3. Clique em Save.
Depois de salvar o conteúdo em um arquivo, a janela Enter SQL Statement exibirá uma página
com uma tab do conteúdo do arquivo. Você pode abrir vários arquivos ao mesmo tempo. Cada
arquivo será exibido como uma página com tab.
Script Pathing
Você pode selecionar um caminho default no qual poderá procurar e salvar scripts. Em Tools >
Preferences > Database > Worksheet Parameters, informe um valor no campo “Select default
path to look for scripts” .

Oracle Database: Fundamentos de PL/SQL C- 19


Executando Arquivos de Script Salvos: Método 1
1. Use a tab Files para localizar o
arquivo de script que deseja abrir.
2. Clique duas vezes no script para
exibir o código na Planilha SQL.

1
Para executar o código, clique
em uma destas opções: 2
• Execute Script (F9) Selecione uma conexão
3
• Run Script (F5) na lista drop-down.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Executando Arquivos de Script Salvos: Método 1


Para abrir um arquivo de script e exibir o código na área da Planilha SQL, faça o seguinte:
1. No Files Navigator, selecione (ou navegue até) o arquivo de script que deseja abrir.
2. Clique duas vezes no arquivo para abri-lo. O código do arquivo de script será exibido na
área da Planilha SQL.
3. Selecione uma conexão na lista drop-down.
4. Para executar o código, clique no ícone Run Script (F5) na barra de ferramentas da
Planilha SQL. Se você não tiver selecionado uma conexão na lista drop-down, uma caixa
de diálogo de conexão será exibida. Selecione a conexão que deseja usar para a execução
do script.
Como alternativa, você também pode fazer o seguinte:
1. Selecionar File > Open. A caixa de diálogo Open é exibida.
2. Na caixa de diálogo Open, selecione (ou navegue até) o arquivo de script que deseja abrir.
3. Clique em Open. O código do arquivo de script será exibido na área da Planilha SQL.
4. Selecione uma conexão na lista drop-down da conexão.
5. Para executar o código, clique no ícone Run Script (F5) na barra de ferramentas da
Planilha SQL. Se você não tiver selecionado uma conexão na lista drop-down, uma caixa
de diálogo de conexão será exibida. Selecione a conexão que deseja usar na execução do
script.

Oracle Database: Fundamentos de PL/SQL C- 20


Executando Arquivos de Script Salvos: Método 2

Use o comando @ seguido


pelo local e pelo nome do
arquivo que deseja executar
e clique no ícone Run Script.

A saída do script é
exibida na página com
a tab Script Output.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Executando Arquivos de Script Salvos: Método 2


Para executar um script SQL salvo, faça o seguinte:
1. Use o comando @ seguido pelo local e pelo nome do arquivo que deseja executar na janela
Enter SQL Statement.
2. Clique no ícone Run Script.
Os resultados da execução do arquivo são exibidos na página com a tab Script Output. Você
também poderá salvar a saída do script clicando no ícone Save na página com a tab Script
Output. A caixa de diálogo Salvar Arquivo, do Windows, será exibida e você poderá identificar
um nome e um local para o arquivo.

Oracle Database: Fundamentos de PL/SQL C- 21


Formatando o Código SQL

Antes
da formatação

Depois
da formatação

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Formatando o Código SQL


Você poderá aprimorar a endentação, o espaçamento, a capitalização e a separação de linha do
código SQL. O SQL Developer possui um recurso para a formatação do código SQL.
Para formatar o código SQL, clique com o botão direito do mouse na área da instrução e
selecione Format SQL.
No exemplo do slide, antes da formatação, as palavras-chave do código SQL não estão
capitalizadas e a endentação adequada não foi aplicada à instrução. Após a formatação, o código
SQL é aprimorado com a capitalização das palavras-chave e a endentação adequada.

Oracle Database: Fundamentos de PL/SQL C- 22


Usando Snippets

Snippets são fragmentos de códigos, tais como sintaxe ou


exemplos.
Quando você posiciona o cursor
aqui, ele mostra a janela
Snippets. Na lista drop-down, é
possível selecionar a categoria
de funções desejada.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Usando Snippets
Você poderá usar determinados fragmentos de código quando usar a Planilha SQL ou criar ou
editar um procedure ou uma função PL/SQL. O SQL Developer possui um recurso chamado
Snippets, que são fragmentos de código como funções SQL, dicas do Optimizer e diversas
técnicas de programação de PL/SQL. Você pode arrastar Snippets para a janela Editor.
Para exibir os Snippets, selecione View > Snippets.
A janela Snippets é exibida à direita. Você poderá usar a lista drop-down para selecionar um
grupo. O botão Snippets é exibido na margem da janela à direita para que você possa exibir a
janela Snippets se ela ficar oculta.

Oracle Database: Fundamentos de PL/SQL C- 23


Usando Snippets: Exemplo

Inserindo
um Snippet

Editando o
Snippet

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Usando Snippets: Exemplo


Para inserir um Snippet em seu código em uma Planilha SQL ou em uma função ou um
procedure PL/SQL, arraste o Snippet da janela Snippets para o local desejado no código. Em
seguida, você poderá editar a sintaxe para que a função SQL seja válida no contexto atual. Para
exibir uma breve descrição de uma função SQL em uma dica de ferramenta, posicione o cursor
sobre o nome da função.
O exemplo do slide mostra que CONCAT(char1, char2) é arrastado do grupo Character
Functions na janela Snippets. Em seguida, a sintaxe da função CONCAT é editada e o restante da
instrução é adicionado conforme a seguir:
SELECT CONCAT(first_name, last_name)
FROM employees;

Oracle Database: Fundamentos de PL/SQL C- 24


Depurando Procedures e Funções

• Use o SQL Developer para


depurar procedures e funções
PL/SQL.
• Use a opção Compile for Debug
para executar uma compilação
PL/SQL de modo que o
procedure possa ser depurado.
• Use as opções do menu Debug
para definir pontos de
interrupção e para executar
tarefas Step Into e Step Over.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Depurando Procedures e Funções


No SQL Developer, você pode depurar procedures e funções PL/SQL. Usando as opções do
menu Debug, você pode executar as seguintes tarefas de depuração:
• Find Execution Point vai para o próximo ponto de execução.
• Resume continua a execução.
• Step Over ignora o próximo método e vai para a instrução seguinte após o método.
• Step Into vai para a primeira instrução no próximo método.
• Step Out deixa o método atual e vai para a próxima instrução.
• Step to End of Method vai para a última instrução do método atual.
• Pause interrompe a execução, mas não sai, permitindo que a execução seja retomada.
• Terminate interrompe e sai da execução. Não é possível retomar a execução a partir deste
ponto. Em vez disso, para iniciar a execução ou a depuração no início da função ou do
procedure, clique no ícone Run ou Debug, na barra de ferramentas da tab Source.
• Garbage Collection remove objetos inválidos do cache para armazenar objetos acessados
com mais frequência e mais válidos.
Essas opções também estão disponíveis como ícones na barra de ferramentas de depuração.

Oracle Database: Fundamentos de PL/SQL C- 25


Geração de Relatórios de Banco de Dados

O SQL Developer oferece diversos relatórios predefinidos


sobre o banco de dados e seus objetos.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Geração de Relatórios de Banco de Dados


O SQL Developer oferece diversos relatórios sobre o banco de dados e seus objetos. Esses
relatórios podem ser agrupados nas seguintes categorias:
• About Your Database
• Database Administration
• Table
• PL/SQL
• Security
• XML
• Jobs
• Streams
• All Objects
• Data Dictionary
• User-Defined Reports
Para exibir os relatórios, clique na tab Reports à esquerda da janela. Relatórios individuais são
exibidos em painéis com tab, à direita da janela. Para cada relatório, você pode selecionar
(usando uma lista drop-down) a conexão com o banco de dados para a qual deseja exibir o
relatório. Nos relatórios sobre objetos, aqueles mostrados são apenas os objetos visíveis para o
usuário do banco de dados associado à conexão com o banco de dados selecionada, e as linhas
são normalmente ordenadas por Owner. Você também pode criar seus próprios relatórios
definidos pelo usuário.
Oracle Database: Fundamentos de PL/SQL C- 26
Criando um Relatório Definido pelo Usuário

Crie e salve relatórios definidos pelo usuário para reutilização.

Organize os relatórios em pastas.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Criando um Relatório Definido pelo Usuário


Os relatórios definidos pelo usuário são aqueles criados pelos usuários do SQL Developer. Para
criar um relatório definido pelo usuário, faça o seguinte:
1. Clique com o botão direito do mouse no nó User Defined Reports, em Reports, e selecione
Add Report.
2. Na caixa de diálogo Create Report, especifique o nome do relatório e a consulta SQL para
recuperar as informações do relatório. Em seguida, clique em Apply.
No exemplo do slide, o nome do relatório foi especificado como emp_sal. Uma descrição
opcional é oferecida, indicando que o relatório contém detalhes de funcionários com salary
>= 10000. A instrução SQL completa para a recuperação das informações a serem exibidas no
relatório definido pelo usuário está especificada na caixa SQL. Você também poderá incluir uma
dica de ferramenta opcional, a ser exibida quando o cursor for posicionado sobre o nome do
relatório na opção Reports do navegador.
Você pode organizar os relatórios definidos pelo usuário em pastas e pode criar uma hierarquia
de pastas e subpastas. Para criar uma pasta para os relatórios definidos pelo usuário, clique com
o botão direito do mouse no nó User Defined Reports ou em qualquer nome de pasta nesse nó e
selecione Add Folder. As informações sobre os relatórios definidos pelo usuário, incluindo as
pastas desses relatórios, são armazenadas em um arquivo chamado UserReports.xml no
diretório de informações específicas do usuário.

Oracle Database: Fundamentos de PL/SQL C- 27


Mecanismos de Pesquisa e Ferramentas Externas

Atalhos para
ferramentas usadas
com frequência
1

Links para
mecanismos de
pesquisa e fóruns de
discussão populares

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Mecanismos de Pesquisa e Ferramentas Externas


Para melhorar a produtividade dos desenvolvedores de SQL, o SQL Developer adicionou links
rápidos para mecanismos de pesquisa e fóruns de discussão populares como AskTom, Google e
assim por diante. Além disso, você tem disponíveis ícones de atalho para algumas das
ferramentas usadas com mais frequência, como Bloco de Notas, Microsoft Word e
Dreamweaver.
Você pode adicionar ferramentas externas à lista existente ou até mesmo deletar atalhos para
ferramentas que não usa com frequência. Para isso, faça o seguinte:
1. No menu Tools, selecione External Tools.
2. Na caixa de diálogo External Tools, selecione New para adicionar novas ferramentas.
Selecione Delete para remover qualquer ferramenta da lista.

Oracle Database: Fundamentos de PL/SQL C- 28


Definindo Preferências

• Personalize a interface e o ambiente do SQL Developer.


• No menu Tools, selecione Preferences.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Definindo Preferências
Você pode personalizar muitos aspectos da interface e do ambiente do SQL Developer,
modificando as preferências do SQL Developer de acordo com seus requisitos. Para modificar as
preferências do SQL Developer, selecione Tools e Preferences.
As preferências estão agrupadas nas seguintes categorias:
• Environment
• Accelerators (atalhos do teclado)
• Code Editors
• Database
• Debugger
• Documentation
• Extensions
• File Types
• Migration
• PL/SQL Compilers
• PL/SQL Debugger e assim por diante

Oracle Database: Fundamentos de PL/SQL C- 29


Redefinindo o Layout do SQL Developer

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Redefinindo o Layout do SQL Developer


Ao trabalhar com o SQL Developer, se o Connections Navigator desaparecer, ou se você não
puder encaixar a janela Log em seu local original, execute as seguintes etapas para corrigir o
problema:
1. Saia do SQL Developer.
2. Abra uma janela de terminal e use o comando locate para encontrar o local de
windowinglayout.xml.
3. Vá para o diretório em que windowinglayout.xml está e delete esse arquivo.
4. Reinicie o SQL Developer.

Oracle Database: Fundamentos de PL/SQL C- 30


Sumário

Neste apêndice, você aprendeu a usar o SQL Developer para:


• Criar, editar e navegar por objetos de banco de dados
• Executar scripts e instruções SQL na Planilha SQL
• Criar e salvar relatórios personalizados

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Sumário
O SQL Developer é uma ferramenta gráfica gratuita que simplifica as tarefas de
desenvolvimento de banco de dados. Com o SQL Developer, você pode criar, editar e navegar
por objetos de banco de dados. Você pode usar a Planilha SQL para executar scripts e instruções
SQL. O SQL Developer permite que você crie e salve seu próprio conjunto especial de relatórios
para reutilização.

Oracle Database: Fundamentos de PL/SQL C- 31


Usando o SQL*Plus

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.
Objetivos

Ao concluir este apêndice, você será capaz de:


• Efetuar login no SQL*Plus
• Editar comandos SQL
• Formatar a saída usando comandos do SQL*Plus
• Interagir com arquivos de script

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Objetivos
É possível criar instruções SELECT que possam ser usadas indefinidamente. Este apêndice também
aborda o uso de comandos do SQL*Plus para executar instruções SQL. Você aprenderá a formatar a
saída usando comandos do SQL*Plus, a editar comandos SQL e a salvar scripts no SQL*Plus.

Oracle Database: Fundamentos de PL/SQL D - 2


Interação entre SQL e SQL*Plus

Instruções SQL
Servidor
SQL*Plus

Resultados da consulta

Buffer

Scripts
SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

SQL e SQL*Plus
SQL é uma linguagem de comando que é usada para a comunicação com o Oracle Server por meio
de qualquer ferramenta ou aplicação. O Oracle SQL contém diversas extensões. Quando você
informa uma instrução SQL, ela é armazenada em uma parte da memória chamada de buffer SQL e
permanece lá até que você especifique uma nova instrução SQL. O SQL*Plus é uma ferramenta da
Oracle que reconhece e envia instruções SQL para o Oracle9i Server para serem executadas. Ele
contém sua própria linguagem de comandos.
Recursos da linguagem SQL
• Pode ser usada por vários usuários, incluindo aqueles com pouca ou nenhuma experiência em
programação
• É uma linguagem não procedural
• Reduz a quantidade de tempo necessária para a criação e a manutenção de sistemas
• É uma linguagem semelhante ao idioma inglês
Recursos do SQL*Plus
• Aceita a entrada ad hoc de instruções
• Aceita a entrada SQL de arquivos
• Oferece um editor de linha para a modificação de instruções SQL
• Controla as configurações do ambiente
• Formata os resultados da consulta em relatórios básicos
• Acessa bancos de dados locais e remotos
Oracle Database: Fundamentos de PL/SQL D - 3
Instruções SQL Versus
Comandos do SQL*Plus
SQL SQL*Plus
• Uma linguagem • Um ambiente
• Padrão ANSI • Proprietário da Oracle
• Palavras-chave não • Palavras-chave podem
podem ser abreviadas. ser abreviadas.
• As instruções manipulam • Os comandos não
dados e definições de permitem a manipulação
tabelas no banco de de valores no banco de
dados. dados.

Instruções Buffer Comandos Buffer


SQL SQL do SQL*Plus SQL*Plus

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

SQL e SQL*Plus (continuação)


A tabela a seguir compara o SQL e o SQL*Plus:

SQL SQL*Plus
É uma linguagem para a comunicação com o Reconhece instruções SQL e as envia ao
servidor Oracle a fim de acessar os dados servidor
É baseada no padrão ANSI (American É a interface proprietária da Oracle para a
National Standards Institute) SQL execução de instruções SQL
Manipula dados e definições de tabelas no Não permite a manipulação de valores no
banco de dados banco de dados
É incluída no buffer SQL em uma ou mais É incluído em uma linha de cada vez; não é
linhas armazenado no buffer SQL
Não tem um caractere de continuação Utiliza um traço (–) como caractere de
continuação se o comando ultrapassa uma
linha
Não pode ser abreviada Pode ser abreviado
Utiliza um caractere de finalização para Não requer caracteres de finalização; executa
executar os comandos imediatamente os comandos imediatamente
Utiliza funções para aplicar formatação Utiliza comandos para formatar dados

Oracle Database: Fundamentos de PL/SQL D - 4


SQL*Plus: Visão Geral

• Efetue login no SQL*Plus.


• Descreva a estrutura da tabela.
• Edite sua instrução SQL.
• Execute o SQL pelo SQL*Plus.
• Salve as instruções SQL em arquivos e anexe instruções
SQL a arquivos.
• Execute os arquivos salvos.
• Carregue os comandos do arquivo para o buffer, para
edição.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

SQL*Plus
O SQL*Plus é um ambiente no qual você pode:
• Executar instruções SQL para recuperar, modificar, adicionar e remover dados do banco de
dados
• Formatar, executar cálculos, armazenar e imprimir resultados de consultas no formato de
relatórios
• Criar arquivos de script para armazenar instruções SQL para uso repetido no futuro
Os comandos do SQL*Plus podem ser divididos nas seguintes categorias principais:
Categoria Objetivo
Environment Afeta o comportamento geral das instruções SQL na sessão
Format Formata os resultados da consulta
File manipulation Salva, carrega e executa arquivos de script
Execution Envia instruções SQL do buffer SQL para o servidor Oracle
Edit Modifica as instruções SQL no buffer
Interaction Cria e especifica variáveis para instruções SQL, imprime valores de
variáveis e imprime mensagens na tela
Miscellaneous Conecta-se ao banco de dados, manipula o ambiente SQL*Plus e exibe
definições de colunas

Oracle Database: Fundamentos de PL/SQL D - 5


Efetuando Login no SQL*Plus

sqlplus [username[/password[@database]]]

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Efetuando Login no SQL*Plus


O modo como você chama o SQL*Plus depende do tipo de sistema operacional no qual você está
executando o Oracle Database.
Para efetuar login em um ambiente Linux, execute as seguintes etapas:
1. Clique com o botão direito do mouse na área de trabalho Linux e selecione o terminal.
2. Digite o comando sqlplus mostrado no slide.
3. Digite o nome do usuário, a senha e o nome do banco de dados.
Na sintaxe:
username É o seu nome de usuário do banco de dados
password É a sua senha do banco de dados (sua senha será visível se você informá-la
aqui).
@database É a string de conexão com o banco de dados
Observação: Para assegurar a integridade de sua senha, não digite-a no prompt do sistema
operacional. Em vez disso, digite apenas seu nome de usuário. Digite a senha no prompt de senha.

Oracle Database: Fundamentos de PL/SQL D - 6


Exibindo a Estrutura da Tabela

Use o comando DESCRIBE do SQL*Plus para exibir a estrutura


de uma tabela:

DESC[RIBE] tablename

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Exibindo a Estrutura da Tabela


No SQL*Plus, você pode exibir a estrutura de uma tabela usando o comando DESCRIBE. O
resultado do comando é uma exibição de nomes de colunas e tipos de dados, assim como uma
indicação informando se a coluna deve conter dados.
Na sintaxe:
tablename É o nome de qualquer tabela, view ou sinônimo acessível para
o usuário
Para descrever a tabela DEPARTMENTS, use este comando:
SQL> DESCRIBE DEPARTMENTS
Name Null? Type
----------------------- -------- ---------------

DEPARTMENT_ID NOT NULL NUMBER(4)


DEPARTMENT_NAME NOT NULL VARCHAR2(30)
MANAGER_ID NUMBER(6)
LOCATION_ID NUMBER(4)

Oracle Database: Fundamentos de PL/SQL D - 7


Exibindo a Estrutura da Tabela

DESCRIBE departments

Name Null? Type


----------------------- -------- ------------
DEPARTMENT_ID NOT NULL NUMBER(4)
DEPARTMENT_NAME NOT NULL VARCHAR2(30)
MANAGER_ID NUMBER(6)
LOCATION_ID NUMBER(4)

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Exibindo a Estrutura da Tabela (continuação)


O exemplo no slide exibe informações sobre a estrutura da tabela DEPARTMENTS. No resultado:
Null?: Especifica se uma coluna deve conter dados (NOT NULL indica que a coluna deve conter
dados).
Type: Exibe o tipo de dados de uma coluna

Oracle Database: Fundamentos de PL/SQL D - 8


Comandos de Edição do SQL*Plus

• A[PPEND] text
• C[HANGE] / old / new
• C[HANGE] / text /
• CL[EAR] BUFF[ER]
• DEL
• DEL n
• DEL m n

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Comandos de Edição do SQL*Plus


Os comandos do SQL*Plus são incluídos em uma linha de cada vez e não são armazenados no buffer
SQL.

Comando Descrição
A[PPEND] text Adiciona texto ao final da linha atual
C[HANGE] / old / new Altera o texto old para o new na linha atual

C[HANGE] / text / Deleta text da linha atual


CL[EAR] BUFF[ER] Deleta todas as linhas do buffer SQL
DEL Deleta a linha atual
DEL n Deleta a linha n
DEL m n Deleta as linhas m a n inclusive

Diretrizes
• Se você pressionar Enter antes da conclusão de um comando, o SQL*Plus solicitará um número
de linha.
• Você pode finalizar o buffer SQL digitando um dos caracteres finalizadores (ponto e vírgula ou
barra) ou pressionando Enter duas vezes. O prompt SQL será exibido.

Oracle Database: Fundamentos de PL/SQL D - 9


Comandos de Edição do SQL*Plus

• I[NPUT]
• I[NPUT] text
• L[IST]
• L[IST] n
• L[IST] m n
• R[UN]
• n
• n text
• 0 text

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Comandos de Edição do SQL*Plus (continuação)


Comando Descrição
I[NPUT] Insere um número indefinido de linhas
I[NPUT] text Insere uma linha que consiste em text
L[IST] Lista todas as linhas no buffer SQL
L[IST] n Lista uma linha (especificada por n)
L[IST] m n Lista uma faixa de linhas (m a n) inclusive
R[UN] Exibe e executa a instrução SQL atual no buffer
n Especifica a linha que se tornará a atual
n text Substitui a linha n por text
0 text Insere uma linha antes da linha 1

Observação: Você pode informar apenas um comando do SQL*Plus para cada prompt SQL. Os
comandos do SQL*Plus não são armazenados no buffer. Para continuar um comando do SQL*Plus
na linha seguinte, finalize a primeira linha com um hífen (-).

Oracle Database: Fundamentos de PL/SQL D - 10


Usando LIST, n e APPEND

LIST
1 SELECT last_name
2* FROM employees

1
1* SELECT last_name

A , job_id
1* SELECT last_name, job_id

LIST
1 SELECT last_name, job_id
2* FROM employees

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Usando LIST, n e APPEND


• Use o comando L[IST] para exibir o conteúdo do buffer SQL. O asterisco (*) ao lado da linha
2 no buffer indica que a linha 2 é a linha atual. Quaisquer edições feitas se aplicam à linha atual.
• Altere o número da linha atual digitando o número (n) da linha que você deseja editar. A nova
linha atual será exibida.
• Use o comando A[PPEND] para adicionar texto à linha atual. A linha recém-editada será
exibida. Verifique o novo conteúdo do buffer usando o comando LIST.
Observação: Muitos comandos do SQL*Plus, incluindo LIST e APPEND, podem ser abreviados
para apenas sua primeira letra. LIST pode ser abreviado para L; APPEND pode ser abreviado para A.

Oracle Database: Fundamentos de PL/SQL D - 11


Usando o Comando CHANGE

LIST
1* SELECT * from employees

c/employees/departments
1* SELECT * from departments

LIST
1* SELECT * from departments

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Usando o Comando CHANGE


• Use o comando L[IST] para exibir o conteúdo do buffer.
• Use o comando C[HANGE] para alterar o conteúdo da linha atual no buffer SQL. Neste caso,
substitua a tabela employees pela tabela departments. A nova linha atual será exibida.
• Use o comando L[IST] para verificar o novo conteúdo do buffer.

Oracle Database: Fundamentos de PL/SQL D - 12


Comandos de Arquivo do SQL*Plus

• SAVE nome de arquivo


• GET nome de arquivo
• START nome de arquivo
• @ nome de arquivo
• EDIT nome de arquivo
• SPOOL nome de arquivo
• EXIT

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Comandos de Arquivo do SQL*Plus


As instruções SQL se comunicam com o Oracle Server. Os comandos do SQL*Plus controlam o
ambiente, formatam os resultados das consultas e gerenciam arquivos. Você pode usar os comandos
descritos na seguinte tabela:
Comando Descrição
SAV[E] filename [.ext] Salva o conteúdo atual do buffer SQL em um arquivo. Use
[REP[LACE]APP[END]] APPEND para adicionar o conteúdo a um arquivo existente
e REPLACE para sobregravar um arquivo existente. A
extensão default é .sql.
GET filename [.ext] Grava o conteúdo de um arquivo salvo anteriormente no
buffer SQL. A extensão default do nome do arquivo é .sql.
STA[RT] filename [.ext] Executa um arquivo de comandos salvo anteriormente
@ filename Executa um arquivo de comandos salvo anteriormente (igual
a START)
ED[IT] Acessa o editor e salva o conteúdo do buffer no arquivo
afiedt.buf
ED[IT] [filename[.ext]] Acessa o editor para editar o conteúdo de um arquivo salvo
SPO[OL] [filename[.ext]| Armazena os resultados da consulta em um arquivo. OFF
OFF|OUT] fecha o arquivo de spool. OUT fecha o arquivo de spool e
envia os resultados do arquivo para a impressora.
EXIT Encerra o SQL*Plus
Oracle Database: Fundamentos de PL/SQL D - 13
Usando os Comandos SAVE e START

LIST
1 SELECT last_name, manager_id, department_id
2* FROM employees

SAVE my_query
Created file my_query

START my_query

LAST_NAME MANAGER_ID DEPARTMENT_ID


------------------------- ---------- -------------
King 90
Kochhar 100 90
...
107 rows selected.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Usando os Comandos SAVE e START


SAVE
Use o comando SAVE para armazenar o conteúdo atual do buffer em um arquivo. Dessa maneira,
você pode armazenar scripts usados com frequência para serem usados no futuro.
START
Use o comando START para executar um script no SQL*Plus. Você também pode, como alternativa,
usar o símbolo @ para executar um script.
@my_query

Oracle Database: Fundamentos de PL/SQL D - 14


Comando SERVEROUTPUT

• Use o comando SET SERVEROUT[PUT] para controlar se a


saída dos procedures armazenados ou dos blocos PL/SQL
deverá ser exibida no SQL*Plus.
• O limite de comprimento da linha DBMS_OUTPUT é aumentado
de 255 bytes para 32.767 bytes.
• O tamanho default agora é ilimitado.
• Os recursos não são pré-alocados quando SERVEROUTPUT
está definido.
• Como não há penalidades de desempenho, use UNLIMITED,
a não ser que você deseje preservar a memória física.

SET SERVEROUT[PUT] {ON | OFF} [SIZE {n | UNL[IMITED]}]


[FOR[MAT] {WRA[PPED] | WOR[D_WRAPPED] | TRU[NCATED]}]

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Comando SERVEROUTPUT
A maioria dos programas PL/SQL executa entrada e saída por meio de instruções SQL, para
armazenar dados em tabelas de banco de dados ou consultar essas tabelas. Todas as outras
entradas/saídas PL/SQL são feitas por meio de APIs que interagem com outros programas. Por
exemplo, o pacote DBMS_OUTPUT possui procedures como PUT_LINE. Para ver o resultado fora
do código PL/SQL, é necessário outro programa, como o SQL*Plus, para ler e exibir os dados
passados para DBMS_OUTPUT.
O SQL*Plus não exibirá os dados de DBMS_OUTPUT, a não ser que você primeiro execute o
comando SET SERVEROUTPUT ON do SQL*Plus, conforme a seguir:
SET SERVEROUTPUT ON
Observação
• SIZE define o número de bytes da saída, que pode ser armazenado em buffer no servidor do
Oracle Database. O default é UNLIMITED. n não pode ser menor que 2.000 ou mais que
1.000.000.
• Para obter informações adicionais sobre SERVEROUTPUT, consulte o Oracle Database PL/SQL
User’s Guide and Reference 11g.

Oracle Database: Fundamentos de PL/SQL D - 15


Usando o Comando SPOOL do SQL*Plus

SPO[OL] [file_name[.ext] [CRE[ATE] | REP[LACE] |


APP[END]] | OFF | OUT]

Opção Descrição
file_name[.ext] Envia a saída para o nome de arquivo especificado

CRE[ATE] Cria um novo arquivo com o nome especificado

REP[LACE] Substitui o conteúdo de um arquivo existente. Se o


arquivo não existir, REPLACE criará o arquivo.

APP[END] Adiciona o conteúdo do buffer ao final do arquivo


especificado

OFF Interrompe o spooling

OUT Para o spooling e envia o arquivo para a impressora


padrão (default) do computador

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Usando o Comando SPOOL do SQL*Plus


O comando SPOOL armazena os resultados da consulta em um arquivo ou, como opção, envia o
arquivo para uma impressora. O comando SPOOL foi aprimorado. Você agora pode anexar ou
substituir um arquivo existente; anteriormente, só era possível usar o comando SPOOL para criar (e
substituir) um arquivo. REPLACE é o default.
Para enviar a saída gerada pelos comandos em um script sem exibir a saída na tela, use SET
TERMOUT OFF. SET TERMOUT OFF não afeta a saída dos comandos executados de forma
interativa.
Você deve usar aspas simples nos nomes de arquivos que contêm espaço em branco. Para criar um
arquivo HTML válido usando os comandos SPOOL APPEND, você deve usar PROMPT ou um
comando similar para criar o cabeçalho e o rodapé da página HTML. O comando SPOOL APPEND
não efetua parse de tags HTML. Defina o comando SET SQLPLUSCOMPAT[IBILITY] para 9.2
ou anterior para desativar os parâmetros CREATE, APPEND e SAVE.

Oracle Database: Fundamentos de PL/SQL D - 16


Usando o Comando AUTOTRACE

• Ele exibe um relatório depois da execução bem-sucedida


das instruções SQL DML, como SELECT, INSERT,
UPDATE ou DELETE.
• Agora, o relatório pode incluir estatísticas de execução e o
caminho de execução da consulta.

SET AUTOT[RACE] {ON | OFF | TRACE[ONLY]} [EXP[LAIN]]


[STAT[ISTICS]]

SET AUTOTRACE ON
-- The AUTOTRACE report includes both the optimizer
-- execution path and the SQL statement execution
-- statistics

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Usando o Comando AUTOTRACE


EXPLAIN mostra o caminho de execução da consulta executando EXPLAIN PLAN. STATISTICS
exibe as estatísticas da instrução SQL. A formatação do relatório AUTOTRACE poderá variar
dependendo da versão do servidor ao qual você está conectado e da configuração desse servidor. O
pacote DBMS_XPLAN oferece uma maneira fácil de exibir a saída do comando EXPLAIN PLAN em
vários formatos predefinidos.
Observação
• Para obter informações adicionais sobre pacotes e subprogramas, consulte o Oracle Database
PL/SQL Packages and Types Reference 11g Guide.
• Para obter informações adicionais sobre EXPLAIN PLAN, consulte o Oracle Database SQL
Reference 11g.
• Para obter informações adicionais sobre Planos de Execução e estatísticas, consulte o Oracle
Database Performance Tuning Guide 11g.

Oracle Database: Fundamentos de PL/SQL D - 17


Sumário

Neste apêndice, você aprendeu a usar o SQL*Plus como um


ambiente para:
• Executar instruções SQL
• Editar instruções SQL
• Formatar a saída
• Interagir com arquivos de script

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Sumário
O SQL*Plus é um ambiente de execução que pode ser usado para enviar comandos SQL ao servidor
de banco de dados, bem como para editar e salvar esses comandos. Você pode executar comandos no
prompt do SQL ou em um arquivo de script.

Oracle Database: Fundamentos de PL/SQL D - 18


Usando o JDeveloper

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.
Oracle JDeveloper

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle JDeveloper
O Oracle JDeveloper é um IDE (Integrated Development Environment) para o desenvolvimento
e a disponibilização de aplicações Java e serviços Web. Ele suporta todos os estágios do SDLC
(Software Development Life Cycle), desde a modelagem até a disponibilização. Também dispõe
dos recursos que permitem usar os padrões mais recentes do setor para Java, XML e SQL no
desenvolvimento de aplicações.
O Oracle JDeveloper 11g introduz uma nova abordagem para o desenvolvimento em J2EE ao
oferecer recursos que permitem desenvolvimento visual e declarativo. Essa abordagem
inovadora torna o desenvolvimento em J2EE simples e eficiente.

Oracle Database: Fundamentos de PL/SQL E - 2


Database Navigator

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Database Navigator
Usando o Oracle JDeveloper, você pode armazenar em um objeto denominado “connection” as
informações necessárias para se conectar a um banco de dados. Uma conexão é armazenada
como parte das definições do IDE e pode ser exportada e importada, a fim de facilitar o
compartilhamento entre grupos de usuários. As conexões são usadas para várias finalidades,
desde a navegação no banco de dados e a criação de aplicações até a implantação.

Oracle Database: Fundamentos de PL/SQL E - 3


Criando uma Conexão

Clique no ícone New Connection


1 no Database Navigator.

2 Na janela Create Database


Connection, preencha os campos
Username, Password e SID.

3 Clique em Test Connection.

4 Clique em OK.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Criando uma Conexão


Uma conexão é um objeto que especifica as informações necessárias para se conectar com um
determinado banco de dados como um usuário específico desse banco de dados. Você pode criar
e testar conexões com vários bancos de dados e vários esquemas.
Para criar uma conexão de banco de dados, execute as seguintes etapas:
1. Clique no ícone New Connection no Database Navigator.
2. Na janela Create Database Connection, informe o nome da conexão. Informe o nome de
usuário e a senha do esquema ao qual deseja se conectar. Informe o SID do banco de dados
com o qual deseja se conectar.
3. Clique em Test para garantir que a conexão foi definida corretamente.
4. Clique em OK.

Oracle Database: Fundamentos de PL/SQL E - 4


Navegando por Objetos de Banco de Dados
Use o Database Navigator para:
• Navegar por vários objetos em um esquema de banco de
dados
• Analisar rapidamente as definições de objetos

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Navegando por Objetos de Banco de Dados


Após criar uma conexão com o banco de dados, você poderá usar o Database Navigator para
navegar por vários objetos em um esquema de banco de dados, incluindo tabelas, views, índices,
pacotes, procedures, triggers e tipos.
Você pode visualizar a definição dos objetos dividida em tabs de informações que são obtidas do
dicionário de dados. Por exemplo, se você tiver selecionado uma tabela no Navigator, os
detalhes sobre colunas, constraints, grants, estatísticas, triggers e assim por diante serão exibidos
em uma página com tabs fácil de ler.

Oracle Database: Fundamentos de PL/SQL E - 5


Executando Instruções SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Executando Instruções SQL


Para executar uma instrução SQL, siga estas etapas:
1. Clique no ícone Open SQL Worksheet.
2. Selecione a conexão.
3. Execute o comando SQL, efetuando um destes procedimentos:
• Clicando no botão Execute statement ou pressionando F9. A saída é a seguinte:

• Clicando no botão Run Script ou pressionando F5. A saída é a seguinte:

Oracle Database: Fundamentos de PL/SQL E - 6


Criando Unidades de Programa

Esqueleto da função

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Criando Unidades de Programa


Para criar uma unidade de programa PL/SQL, faça o seguinte:
1. Selecione View > Database Navigator. Selecione e expanda uma conexão com o banco de
dados. Clique com o botão direito do mouse na pasta correspondente ao tipo de objeto
(procedures, pacotes ou funções). Selecione “New [Procedures|Packages|Functions]”.
2. Informe um nome válido para a função, o pacote ou o procedure e clique em OK.
3. Uma definição de esqueleto é criada e aberta no Code Editor. Em seguida, você poderá
editar o subprograma para adequá-lo às suas necessidades.

Oracle Database: Fundamentos de PL/SQL E - 7


Compilando

Compilação com erros

Compilação sem erros

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Compilando
Após editar a definição de esqueleto, você precisa compilar a unidade de programa. Clique com
o botão direito do mouse no objeto PL/SQL a ser compilado no Connection Navigator e
selecione Compile. Como alternativa, também é possível pressionar CTRL + SHIFT + F9 para
fazer a compilação.

Oracle Database: Fundamentos de PL/SQL E - 8


Executando uma Unidade de Programa

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Executando uma Unidade de Programa


Para executar uma unidade de programa, clique com o botão direito do mouse no objeto e,
depois, clique em Run. A caixa de diálogo Run PL/SQL será exibida. Talvez seja preciso alterar
os valores NULL para valores aceitáveis que serão especificados na unidade de programa. Após
alterar os valores, clique em OK. A saída será exibida na janela Message-Log.

Oracle Database: Fundamentos de PL/SQL E - 9


Eliminando uma Unidade de Programa

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Eliminando uma Unidade de Programa


Para eliminar uma unidade de programa, clique com o botão direito do mouse no objeto e
selecione Drop. A caixa de diálogo Drop Confirmation será exibida. Clique em Apply. O objeto
é eliminado do banco de dados.

Oracle Database: Fundamentos de PL/SQL E - 10


Janela Structure

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Janela Structure
A janela Structure permite uma visão estrutural dos dados do documento selecionado na janela
ativa, que pode ser um dos elementos que formam a estrutura: navegadores, editores, modos de
exibição e o Property Inspector.
Selecione View > Structure window para exibir a janela Structure.
Na janela Structure, é possível exibir os dados do documento de várias maneiras. As estruturas
que estão disponíveis para exibição se baseiam no tipo do documento. No caso de um arquivo
Java, é possível exibir a estrutura de código, a estrutura da interface do usuário ou os dados de
modelo da interface do usuário. No caso de um arquivo XML, é possível exibir a estrutura XML,
a estrutura do projeto ou os dados de modelo da interface do usuário.
A janela Structure é dinâmica, controlando sempre a seleção atual da janela ativa (a menos que
você congele o conteúdo da janela em uma view específica), como acontece com o editor ativo
no momento. Quando a seleção atual é um nó no navegador, o editor default é utilizado. Se
quiser alterar a view da estrutura para a seleção atual, clique em outra tab de estrutura.

Oracle Database: Fundamentos de PL/SQL E - 11


Janela Editor

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Janela Editor
Quando você clica duas vezes no nome de uma unidade de programa, ela é aberta na janela
Editor. É possível exibir todos os arquivos do seu projeto em apenas uma janela do editor, abrir
várias views do mesmo arquivo ou abrir várias views de arquivos diferentes.
Na parte superior da janela do editor, encontram-se as tabs de documentos. Clicar em uma tab de
documento coloca esse arquivo em destaque, trazendo-o para o primeiro plano da janela do
editor atual.
Na parte inferior da janela do editor referente a um determinado arquivo, estão as tabs de editor.
Clicar em uma dessas tabs abre o arquivo no editor correspondente.

Oracle Database: Fundamentos de PL/SQL E - 12


Application Navigator

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Application Navigator
O Application Navigator permite uma visão lógica da aplicação e dos dados contidos nela. Esse
navegador fornece uma infraestrutura à qual as diversas extensões podem se conectar. Essas
extensões também podem usar a infraestrutura para organizar seus dados e menus de forma
consistente e abstrata. Embora o Application Navigator possa conter arquivos individuais (como
arquivos-fonte Java), ele foi projetado para consolidar dados complexos. Nesse navegador, os
tipos de dados complexos, como objetos de entidades, diagramas UML (Unified Modeling
Language), EJBs (Enterprise JavaBeans) ou serviços Web aparecem como nós únicos. Os
arquivos brutos que compõem esses nós abstratos são exibidos na janela Structure.

Oracle Database: Fundamentos de PL/SQL E - 13


Implantando Procedures Java Armazenados

Antes de implantar procedures Java armazenados, execute as


seguintes etapas:
1. Crie uma conexão de banco de dados.
2. Crie um perfil de implantação.
3. Implante os objetos.

1 2 3

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Implantando Procedures Java Armazenados


Crie um perfil de implantação para os procedures Java armazenados e implante as classes. Se
quiser, você também poderá implantar métodos estáticos públicos no JDeveloper usando as
definições do perfil.
Quando o banco de dados é disponibilizado, são usadas as informações fornecidas no
Deployment Profile Wizard e também dois utilitários do Oracle Database:
• loadjava carrega em um banco de dados Oracle a classe Java que contém os procedures
armazenados.
• publish gera os encapsuladores específicos de chamada PL/SQL para os métodos
estáticos públicos carregados. A publicação permite que os métodos Java sejam chamados
como funções ou procedures PL/SQL.

Oracle Database: Fundamentos de PL/SQL E - 14


Publicando Java em PL/SQL

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Publicando Java em PL/SQL


O slide mostra o código Java e ilustra como publicá-lo em um procedure PL/SQL.
1. Crie e compile uma rotina Java.
2. Execute o comando mostrado no slide para carregar a rotina TrimLob Java para o banco de
dados.
3. Publique o método de classe Java criando a especificação de chamada PL/SQL
TrimLobProc, que faz referência aos métodos de classe Java. Na especificação PL/SQL
TrimLobProc, você identifica o nome do método de classe Java e seus parâmetros. Esse
procedimento é chamado de “Publicação” do método de classe Java.
Para obter mais detalhes sobre como executar rotinas Java no banco de dados, consulte o
seguinte OBE: http://www.oracle.com/technology/obe/hol08/11gR1_JDBC_Java/java_otn.htm

Oracle Database: Fundamentos de PL/SQL E - 15


Como Posso Obter Mais Informações
sobre o JDeveloper 11g?

Tópico Web site


Página de Produto do http://www.oracle.com/technology/products/jdev/index.ht
Oracle JDeveloper ml
Tutoriais do Oracle http://www.oracle.com/technology/obe/obe11jdev/11/ind
JDeveloper 11g ex.html
Documentação do http://www.oracle.com/technology/documentation/jdev.ht
Produto doOracle
JDeveloper 11g ml
Fórum de Discussão do http://forums.oracle.com/forums/forum.jspa?forumID=83
Oracle JDeveloper 11g

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Oracle Database: Fundamentos de PL/SQL E - 16


Cursores REF

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.
Variáveis de Cursor

• As variáveis de cursor são como ponteiros C ou Pascal,


que armazenam a localização (endereço) de um item na
memória em vez do item propriamente dito.
• Na linguagem PL/SQL, um ponteiro é declarado como REF
X, onde REF é a abreviatura de REFERENCE e X significa
uma classe de objetos.
• Uma variável de cursor tem o tipo de dados REF CURSOR.
• Um cursor é estático, mas uma variável de cursor
é dinâmica.
• As variáveis de cursor oferecem maior flexibilidade.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Variáveis de Cursor
As variáveis de cursor são como ponteiros C ou Pascal, que armazenam a localização (endereço)
de um item na memória em vez do item propriamente dito. Portanto, declarar uma variável de
cursor cria um ponteiro, e não um item. Na linguagem PL/SQL, um ponteiro tem o tipo de dados
REF X, onde REF é a abreviatura de REFERENCE e X significa uma classe de objetos. Uma
variável de cursor tem o tipo de dados REF CURSOR.
Assim como um cursor, uma variável de cursor aponta para a linha atual do conjunto de
resultados de uma consulta de várias linhas. No entanto, os cursores diferem das variáveis de
cursor da mesma forma que as constantes diferem das variáveis. Um cursor é estático, mas uma
variável de cursor é dinâmica porque ela não está vinculada a uma consulta específica. É
possível abrir uma variável de cursor para qualquer consulta de tipo compatível. Isso
proporciona maior flexibilidade.
As variáveis de cursor estão disponíveis para todos os clientes PL/SQL. Por exemplo, você pode
declarar uma variável de cursor em um ambiente de host PL/SQL, como um programa OCI ou
Pro*C e, em seguida, transmiti-la como uma variável de host de entrada (variável de bind) para
o código PL/SQL. Além disso, as ferramentas de desenvolvimento de aplicações, como Oracle
Forms e Oracle Reports, que têm um mecanismo PL/SQL, podem usar variáveis de cursor no
lado cliente. O Oracle Server também tem um mecanismo PL/SQL. Você pode transmitir
variáveis de cursor entre uma aplicação e o servidor por meio de RPCs (remote procedure calls).

Oracle Database: Fundamentos de PL/SQL F - 2


Usando Variáveis de Cursor

• Você pode usar variáveis de cursor para transmitir


conjuntos de resultados de consultas entre subprogramas
armazenados PL/SQL e diversos clientes.
• O código PL/SQL pode compartilhar um ponteiro para a
área de trabalho da consulta em que o conjunto de
resultados é armazenado.
• Você pode transmitir o valor de uma variável de cursor
livremente de um escopo para outro.
• Além disso, é possível reduzir o tráfego na rede fazendo
com que um bloco PL/SQL abra (ou feche) diversas
variáveis de cursor host em um único percurso de ida e
volta.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Usando Variáveis de Cursor


As variáveis de cursor são usadas para transmitir conjuntos de resultados de consultas entre
subprogramas armazenados PL/SQL e diversos clientes. Nem os programas PL/SQL nem os
seus clientes possuem um conjunto de resultados; eles simplesmente compartilham um ponteiro
para a área de trabalho da consulta onde o conjunto de resultados é armazenado. Por exemplo,
um cliente OCI, uma aplicação do Oracle Forms e o Oracle Server podem fazer referência à
mesma área de trabalho.
A área de trabalho de uma consulta permanece acessível enquanto uma variável de cursor
apontar para ela. Portanto, é possível transmitir o valor de uma variável de cursor livremente de
um escopo para outro. Por exemplo, se você especificar uma variável de cursor host para um
bloco PL/SQL que esteja incorporado em um programa Pro*C, a área de trabalho para a qual a
variável de cursor aponta permanecerá acessível após a conclusão do bloco.
Caso exista um mecanismo PL/SQL no lado cliente, as chamadas do cliente para o servidor não
terão restrições. Por exemplo, você pode declarar uma variável de cursor no lado do cliente,
abri-la e usá-la com o comando fetch no lado do servidor e, depois, continuar a utilizá-la com
comando fetch no lado do cliente. Além disso, é possível reduzir o tráfego na rede fazendo com
que um bloco PL/SQL abra (ou feche) diversas variáveis de cursor host em um único percurso
de ida e volta.
Uma variável de cursor armazena uma referência à área de trabalho do cursor na PGA (Program
Global Area), em vez de se referir a ela com um nome estático. Como você utiliza uma
referência para essa área, ganha a flexibilidade de uma variável.
Oracle Database: Fundamentos de PL/SQL F - 3
Definindo Tipos REF CURSOR

Defina um tipo REF CURSOR:


Define a REF CURSOR type
TYPE ref_type_name IS REF CURSOR [RETURN return_type];

Declare uma variável de cursor desse tipo:

ref_cv ref_type_name;

Exemplo:
DECLARE
TYPE DeptCurTyp IS REF CURSOR RETURN
departments%ROWTYPE;
dept_cv DeptCurTyp;

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Definindo Tipos REF CURSOR


Para definir um REF CURSOR, são necessárias duas etapas. Primeiro, defina um tipo REF CURSOR
e, depois, declare as variáveis de cursor desse tipo. Você pode definir tipos REF CURSOR em
qualquer bloco, subprograma ou pacote PL/SQL usando a seguinte sintaxe:
TYPE ref_type_name IS REF CURSOR [RETURN return_type];
em que:
ref_type_name É um especificador de tipo usado nas declarações de variáveis de
cursor subsequentes variables
return_type Representa um registro ou uma linha em uma tabela do banco de
dados
Neste exemplo, é especificado um tipo de retorno que representa uma linha da tabela
DEPARTMENT do banco de dados .
Os tipos REF CURSOR podem ser fortes (restritivos) ou fracos (não restritivos). Como mostrado
no próximo exemplo, uma definição de tipo forte REF CURSOR especifica um tipo de retorno,
mas uma definição fraca não especifica:
DECLARE
TYPE EmpCurTyp IS REF CURSOR RETURN employees%ROWTYPE; --
strong
TYPE GenericCurTyp IS REF CURSOR; -- weak

Oracle Database: Fundamentos de PL/SQL F - 4


Definindo Tipos REF CURSOR (continuação)
Os tipos REF CURSOR fortes são menos sujeitos a erro porque o compilador PL/SQL somente
permite que você associe uma variável de cursor de tipo forte a consultas de tipo compatível. No
entanto, os tipos REF CURSOR fracos são mais flexíveis porque o compilador permite que você
associe um cursor de tipo fraco a qualquer consulta.
Declarando Variáveis de Cursor
Após definir um tipo REF CURSOR, você poderá declarar variáveis de cursor desse tipo em
qualquer bloco ou subprograma PL/SQL. Neste exemplo, é declarada a variável de cursor
DEPT_CV:
DECLARE
TYPE DeptCurTyp IS REF CURSOR RETURN departments%ROWTYPE;
dept_cv DeptCurTyp; -- declare cursor variable
Observação: Não é possível declarar variáveis de cursor em um pacote. Ao contrário de
variáveis em pacotes, as variáveis de cursor não têm estados persistentes. Lembre-se de que a
declaração de uma variável de cursor cria um ponteiro, e não um item. As variáveis de cursor
não podem ser salvas no banco de dados; elas seguem as regras usuais de escopo e instanciação.
Na cláusula RETURN de uma definição de tipo REF CURSOR, você pode usar %ROWTYPE para
especificar um tipo de registro que represente uma linha retornada por uma variável de cursor de
tipo forte (e não fraco), assim:
DECLARE
TYPE TmpCurTyp IS REF CURSOR RETURN employees%ROWTYPE;
tmp_cv TmpCurTyp; -- declare cursor variable
TYPE EmpCurTyp IS REF CURSOR RETURN tmp_cv%ROWTYPE;
emp_cv EmpCurTyp; -- declare cursor variable
Da mesma forma, você pode usar %TYPE para fornecer o tipo de dados de uma variável de
registro, como é mostrado neste exemplo:
DECLARE
dept_rec departments%ROWTYPE; -- declare record variable
TYPE DeptCurTyp IS REF CURSOR RETURN dept_rec%TYPE;
dept_cv DeptCurTyp; -- declare cursor variable
No exemplo final, você especifica um tipo RECORD definido pelo usuário na cláusula RETURN:
DECLARE
TYPE EmpRecTyp IS RECORD (
empno NUMBER(4),
ename VARCHAR2(1O),
sal NUMBER(7,2));
TYPE EmpCurTyp IS REF CURSOR RETURN EmpRecTyp;
emp_cv EmpCurTyp; -- declare cursor variable

Oracle Database: Fundamentos de PL/SQL F - 5


Variáveis de Cursor como Parâmetros
Você pode declarar variáveis de cursor como os parâmetros formais de funções e procedures.
Neste exemplo, é definido o tipo REF CURSOR como EmpCurTyp, e é declarada uma variável
de cursor desse tipo como o parâmetro formal de um procedure:
DECLARE
TYPE EmpCurTyp IS REF CURSOR RETURN emp%ROWTYPE;
PROCEDURE open_emp_cv (emp_cv IN OUT EmpCurTyp) IS ...

Oracle Database: Fundamentos de PL/SQL F - 6


Usando as Instruções OPEN-FOR, FETCH e CLOSE

• A instrução OPEN-FOR associa uma variável de cursor


a uma consulta de várias linhas, executa a consulta,
identifica o conjunto de resultados e posiciona o cursor
para apontar para a primeira linha do conjunto de
resultados.
• A instrução FETCH retorna uma linha do conjunto de
resultados de uma consulta de várias linhas, atribui os
valores de itens da lista selecionada às variáveis ou aos
campos correspondentes na cláusula INTO, incrementa a
contagem feita por %ROWCOUNT e avança o cursor para a
próxima linha.
• A instrução CLOSE desativa uma variável de cursor.

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Usando as Instruções OPEN-FOR, FETCHe CLOSE


Existem três instruções para processar uma consulta dinâmica de várias linhas: OPEN-FOR,
FETCH e CLOSE. Primeiro, você “abre” (OPEN) uma variável de cursor “para” (FOR) uma
consulta de várias linhas. Em seguida, você extrai (FETCH) linhas do conjunto de resultados, uma
de cada vez. Quando todas as linhas forem processadas, você fecha (CLOSE) a variável de cursor.
Abrindo a Variável de Cursor
A instrução OPEN-FOR associa uma variável de cursor a uma consulta de várias linhas, executa a
consulta, identifica o conjunto de resultados, posiciona o cursor para apontar para a primeira linha
do conjunto de resultados e define como zero a contagem das linhas processadas obtida por
%ROWCOUNT. Ao contrário da forma estática de OPEN-FOR, a forma dinâmica tem uma cláusula
USING opcional. Durante o runtime, os argumentos de bind da cláusula USING substituem os
marcadores de espaço correspondentes na instrução SELECT dinâmica. A sintaxe é:
OPEN {cursor_variable | :host_cursor_variable} FOR
dynamic_string
[USING bind_argument[, bind_argument]...];
em que CURSOR_VARIABLE é uma variável de cursor de tipo fraco (sem um tipo de retorno),
HOST_CURSOR_VARIABLE é uma variável de cursor declarada em um ambiente host PL/SQL,
como um programa OCI, e dynamic_string é uma expressão de string que representa uma
consulta de várias linhas.
Oracle Database: Fundamentos de PL/SQL F - 7
Usando as Instruções OPEN-FOR, FETCH e CLOSE (continuação)
Neste exemplo, a sintaxe declara uma variável de cursor e, em seguida, associa essa variável à
instrução dinâmica SELECT, que retorna linhas da tabela employees:
DECLARE
TYPE EmpCurTyp IS REF CURSOR; -- define weak REF CURSOR
type
emp_cv EmpCurTyp; -- declare cursor variable
my_ename VARCHAR2(15);
my_sal NUMBER := 1000;
BEGIN
OPEN emp_cv FOR -- open cursor variable
'SELECT last_name, salary FROM employees WHERE salary >
:s'
USING my_sal;
...
END;
Os argumentos de bind na consulta só serão avaliados quando a variável de cursor estiver aberta.
Portanto, para extrair linhas do cursor com o comando fetch usando diferentes valores de bind,
você deverá reabrir sempre a variável de cursor com os argumentos de bind definidos com seus
novos valores.
Utilizando o Comando Fetch com a Variável de Cursor
A instrução FETCH retorna uma linha do conjunto de resultados de uma consulta de várias
linhas, atribui os valores de itens da lista selecionada às variáveis ou aos campos
correspondentes na cláusula INTO, incrementa a contagem feita por %ROWCOUNT e avança o
cursor para a próxima linha. Use a seguinte sintaxe:
FETCH {cursor_variable | :host_cursor_variable}
INTO {define_variable[, define_variable]... | record};
Continuando o exemplo, extraia, com o comando fetch, linhas da variável de cursor emp_cv
para as variáveis de definição MY_ENAME e MY_SAL:
LOOP
FETCH emp_cv INTO my_ename, my_sal; -- fetch next row
EXIT WHEN emp_cv%NOTFOUND; -- exit loop when last row is
fetched
-- process row
END LOOP;
Para cada valor de coluna retornado pela consulta associada à variável de cursor, deve haver na
cláusula INTO um campo ou uma variável correspondente e de tipo compatível. Você pode usar
uma outra cláusula INTO em diferentes extrações com o comando fetch, usando a mesma
variável de cursor. Cada extração recupera outra linha do mesmo conjunto de resultados. Se
você utilizar fetch com uma variável de cursor fechada ou que nunca foi aberta, o código
PL/SQL emitirá a exceção predefinida INVALID_CURSOR.

Oracle Database: Fundamentos de PL/SQL F - 8


Usando as Instruções OPEN-FOR, FETCH e CLOSE (continuação)
Fechando a Variável de Cursor
A instrução CLOSE desativa uma variável de cursor. Depois disso, o conjunto de resultados
associado permanecerá indefinido. Use a seguinte sintaxe:
CLOSE {cursor_variable | :host_cursor_variable};
Neste exemplo, quando a última linha for processada, feche a variável de cursor emp_cv:
LOOP
FETCH emp_cv INTO my_ename, my_sal;
EXIT WHEN emp_cv%NOTFOUND;
-- process row
END LOOP;
CLOSE emp_cv; -- close cursor variable
Se você tentar fechar uma variável de cursor fechada ou que nunca foi aberta, o código PL/SQL
emitirá INVALID_CURSOR.

Oracle Database: Fundamentos de PL/SQL F - 9


Exemplo de Extração com o Comando Fetch

DECLARE
TYPE EmpCurTyp IS REF CURSOR;
emp_cv EmpCurTyp;
emp_rec employees%ROWTYPE;
sql_stmt VARCHAR2(200);
my_job VARCHAR2(10) := 'ST_CLERK';
BEGIN
sql_stmt := 'SELECT * FROM employees
WHERE job_id = :j';
OPEN emp_cv FOR sql_stmt USING my_job;
LOOP
FETCH emp_cv INTO emp_rec;
EXIT WHEN emp_cv%NOTFOUND;
-- process record
END LOOP;
CLOSE emp_cv;
END;
/

Copyright © 2011, Oracle e/ou suas empresas afiliadas. Todos os direitos reservados.

Exemplo de Extração com o Comando Fetch


O exemplo do slide mostra que você pode extrair, com o comando fetch, linhas do conjunto de
resultados de uma consulta dinâmica de várias linhas para um registro. Primeiro, defina um tipo
REF CURSOR, EmpCurTyp. Em seguida, defina uma variável de cursor emp_cv, do tipo
EmpcurTyp. Na seção executável do bloco PL/SQL, a instrução OPEN-FOR associa a variável
de cursor emp_cv à consulta de várias linhas, sql_stmt. A instrução FETCH retorna uma
linha do conjunto de resultados de uma consulta de várias linhas e designa os valores dos itens
da lista selecionada a EMP_REC na cláusula INTO. Quando a última linha for processada, feche
a variável de cursor emp_cv.

Oracle Database: Fundamentos de PL/SQL F - 10


Apêndice AP
Exercícios e Soluções
Índice
Visão Geral ................................................................................................................... 3
Exercícios Adicionais e Soluções: Lições 1 e 2............................................................ 4
Exercício 1: Avaliando Declarações............................................................................... 4
Exercício 2: Avaliando Expressões ................................................................................ 4
Solução 1: Avaliando Declarações ................................................................................. 5
Solução 2: Avaliando Expressões................................................................................... 5
Exercício Adicional e Solução: Lição 3........................................................................ 6
Exercício 3: Avaliando Instruções Executáveis.............................................................. 6
Solução 3: Avaliando Instruções Executáveis ................................................................ 7
Exercícios Adicionais e Soluções da Lição 4 ............................................................... 8
Exercício 4-1: Interagindo com o Oracle Server ............................................................ 8
Exercício 4-2: Interagindo com o Oracle Server ............................................................ 8
Solução 4-1: Interagindo com o Oracle Server............................................................... 9
Solução 4-2: Interagindo com o Oracle Server............................................................. 10
Exercícios Adicionais e Soluções da Lição 5 ............................................................. 12
Exercício 5-1: Criando Estruturas de Controle............................................................. 12
Exercício 5-2: Criando Estruturas de Controle............................................................. 12
Solução 5-1: Criando Estruturas de Controle ............................................................... 13
Solução 5-2: Criando Estruturas de Controle ............................................................... 14
Exercícios Adicionais e Soluções das Lições 6 e 7 .................................................... 15
Exercício 6/7-1: Extraindo Dados Usando o Comando Fetch com um Cursor
Explícito..................................................................................................................... 15
Exercício 6/7-2: Usando Arrays Associativos e Cursores Explícitos........................... 15
Solução 6/7-1: Extraindo Dados Usando o Comando Fetch com um Cursor Explícito16
Solução 6/7-2: Usando Arrays Associativos e Cursores Explícitos ............................. 17
Exercício Adicional e Solução da Lição 8.................................................................. 19
Exercício 8-1: Tratando Exceções ................................................................................ 19
Solução 8-1: Tratando Exceções................................................................................... 20

Oracle Database: Fundamentos de PL/SQL AP - 2


Visão Geral

Estes exercícios adicionais são fornecidos como um complemento do curso Oracle


Database: Fundamentos de PL/SQL. Nesses exercícios, você aplicará os conceitos
aprendidos no curso.

Os exercícios adicionais oferecem uma atividade complementar para você declarar


variáveis, criar instruções executáveis, interagir com o Oracle Server, criar estruturas de
controle e trabalhar com tipos de dados compostos e cursores, além de tratar exceções. As
tabelas usadas nesta parte dos exercícios adicionais incluem employees, jobs,
job_history e departments.

Oracle Database: Fundamentos de PL/SQL AP - 3


Exercícios Adicionais e Soluções: Lições 1 e 2

Estes exercícios impressos são usados como atividade extra para você declarar variáveis e
criar instruções executáveis.

Exercício 1: Avaliando Declarações


Avalie cada uma das declarações a seguir. Determine quais delas não são válidas e
explique o motivo.

1. DECLARE
name,dept VARCHAR2(14);

2. DECLARE
test NUMBER(5);

3. DECLARE
MAXSALARY NUMBER(7,2) = 5000;

4. DECLARE
JOINDATE BOOLEAN := SYSDATE;

Exercício 2: Avaliando Expressões


Em cada designação a seguir, determine o tipo de dados da expressão resultante.

1. email := firstname || to_char(empno);

2. confirm := to_date('20-JAN-1999', 'DD-MON-YYYY');

3. sal := (1000*12) + 500

4. test := FALSE;

5. temp := temp1 < (temp2/ 3);

6. var := sysdate;

Oracle Database: Fundamentos de PL/SQL AP - 4


Solução 1: Avaliando Declarações
Avalie cada uma das declarações a seguir. Determine quais delas não são válidas e
explique o motivo.

1. DECLARE
name,dept VARCHAR2(14);

É inválida porque só é permitido um identificador por declaração.

2. DECLARE
test NUMBER(5);

É válida.

3. DECLARE
MAXSALARY NUMBER(7,2) = 5000;

É inválida porque o operador de designação está errado. Deveria ser :=.

4. DECLARE
JOINDATE BOOLEAN := SYSDATE;
É inválida porque os tipos de dados não correspondem. O tipo de dados
booleano não pode receber valores de data. O tipo de dados deve ser date.

Solução 2: Avaliando Expressões


Em cada designação a seguir, determine o tipo de dados da expressão resultante.

1. email := firstname || to_char(empno);


String de caracteres

2. confirm := to_date('20-JAN-1999', 'DD-MON-YYYY');


Data
3. sal := (1000*12) + 500
Número

4. test := FALSE;
Booleano

5. temp := temp1 < (temp2/ 3);


Booleano
6. var := sysdate;
Data

Oracle Database: Fundamentos de PL/SQL AP - 5


Exercício Adicional e Solução: Lição 3
Exercício 3: Avaliando Instruções Executáveis

Neste exercício impresso, você avaliará o bloco PL/SQL e, em seguida, responderá às


perguntas subsequentes, determinando o tipo de dados e o valor de cada variável, de
acordo com as regras de escopo.

DECLARE
v_custid NUMBER(4) := 1600;
v_custname VARCHAR2(300) := 'Women Sports Club';
v_ new_custid NUMBER(3) := 500;
BEGIN
DECLARE
v_custid NUMBER(4) := 0;
v_custname VARCHAR2(300) := 'Shape up Sports Club';
v_new_custid NUMBER(3) := 300;
v_new_custname VARCHAR2(300) := 'Jansports Club';
BEGIN
v_custid := v_new_custid;
v_custname := v_custname || ' ' || v_new_custname;
1
END;
v_custid := (v_custid *12) / 10;
2
END;

Avalie o bloco PL/SQL anterior e determine o valor e o tipo de dados de cada uma das
variáveis a seguir, de acordo com as regras de escopo:

1. v_custid na posição 1:

2. v_custname na posição 1:

3. v_new_custid na posição 1:

4. v_new_custname na posição 1:

5. v_custid na posição 2:

6. v_custname na posição 2:

Oracle Database: Fundamentos de PL/SQL AP - 6


Solução 3: Avaliando Instruções Executáveis
Avalie o bloco PL/SQL a seguir. Em seguida, responda às perguntas subsequentes,
determinando o tipo de dados e o valor de cada uma das variáveis a seguir, de acordo
com as regras de escopo.

DECLARE
v_custid NUMBER(4) := 1600;
v_custname VARCHAR2(300) := 'Women Sports Club';
v_ new_custid NUMBER(3) := 500;
BEGIN
DECLARE
v_custid NUMBER(4) := 0;
v_custname VARCHAR2(300) := 'Shape up Sports Club';
v_new_custid NUMBER(3) := 300;
v_new_custname VARCHAR2(300) := 'Jansports Club';
BEGIN
v_custid := v_new_custid;
v_custname := v_custname || ' ' || v_new_custname;
1
END;
v_custid := (v_custid *12) / 10;
2
END;

Avalie o bloco PL/SQL anterior e determine o valor e o tipo de dados de cada uma das
variáveis a seguir, de acordo com as regras de escopo:

1. v_custid na posição 1:
300, e o tipo de dados é NUMBER.
2. v_custname na posição 1:
Shape up Sports Club Jansports Club, e o tipo de dados é VARCHAR2.
3. v_new_custid na posição 1:
500, e o tipo de dados é NUMBER (ou INTEGER).
4. v_new_custname na posição 1:
Jansports Club, e o tipo de dados é VARCHAR2.
5. v_custid na posição 2:
1920, e o tipo de dados é NUMBER.
6. v_custname na posição 2:
Women Sports Club, e o tipo de dados é VARCHAR2.

Oracle Database: Fundamentos de PL/SQL AP - 7


Exercícios Adicionais e Soluções da Lição 4
Exercício 4-1: Interagindo com o Oracle Server
Neste exercício, uma tabela temporária será necessária para o armazenamento dos
resultados.
Column Name NUM_STORE CHAR_STORE DATE_STORE
Key Type
Nulls/Unique
FK Table
FK Column
Data Type Number VARCHAR2 Date
Length 7,2 35

1. Execute o script lab_ap_04.sql que cria a tabela descrita aqui:


2. Crie um bloco PL/SQL que executa estes procedimentos:
a) Declara duas variáveis e designa os seguintes valores a essas variáveis:
Variável Tipo de dados Conteúdo
V_MESSAGE VARCHAR2(35) This is my first PL/SQL program
V_ DATE_WRITTEN DATA Current date
b) Armazena os valores dessas variáveis nas colunas da tabela TEMP adequadas
3. Verifique os resultados consultando a tabela TEMP. Os resultados de saída devem ser
exibidos da seguinte forma:

Exercício 4-2: Interagindo com o Oracle Server


Neste exercício, você usará dados da tabela employees.
1. Crie um bloco PL/SQL para determinar quantos funcionários trabalham para um
departamento especificado. O bloco PL/SQL deve:
• Usar uma variável de substituição para armazenar um número de
departamento
• Imprimir o número de pessoas que trabalham no departamento especificado

Oracle Database: Fundamentos de PL/SQL AP - 8


2. Quando o bloco for executado, uma variável de substituição será exibida. Informe um
número de departamento válido e clique em OK. Os resultados de saída deverão ser
semelhantes aos seguintes:

Solução 4-1: Interagindo com o Oracle Server


Neste exercício, uma tabela temporária será necessária para o armazenamento dos
resultados.
Column Name NUM_STORE CHAR_STORE DATE_STORE
Key Type
Nulls/Unique
FK Table
FK Column
Data Type Number VARCHAR2 Date
Length 7,2 35

1. Execute o script lab_ap_04.sql que cria a tabela descrita aqui:


2. Crie um bloco PL/SQL que executa estes procedimentos:
a) Declara duas variáveis e designa os seguintes valores a essas variáveis:
Variável Tipo de dados Conteúdo
V_MESSAGE VARCHAR2(35) This is my first PL/SQL program
V_ DATE_WRITTEN DATE Current date
b) Armazena os valores dessas variáveis nas colunas da tabela TEMP adequadas
DECLARE
V_MESSAGE VARCHAR2(35);
V_DATE_WRITTEN DATE;
BEGIN
V_MESSAGE := 'This is my first PLSQL Program';
V_DATE_WRITTEN := SYSDATE;
INSERT INTO temp(CHAR_STORE,DATE_STORE)
VALUES (V_MESSAGE,V_DATE_WRITTEN);
END;
/
3. Verifique os resultados consultando a tabela TEMP. Os resultados de saída deverão
ser semelhantes aos seguintes:
SELECT * FROM TEMP;

Oracle Database: Fundamentos de PL/SQL AP - 9


Solução 4-2: Interagindo com o Oracle Server
Neste exercício, você usará dados da tabela employees.
1. Crie um bloco PL/SQL para determinar quantos funcionários trabalham para um
departamento especificado. O bloco PL/SQL deve:
• Usar uma variável de substituição para armazenar um número de
departamento
• Imprimir o número de pessoas que trabalham no departamento especificado

SET SERVEROUTPUT ON;


DECLARE
V_HOWMANY NUMBER(3);
V_DEPTNO DEPARTMENTS.department_id%TYPE := &P_DEPTNO;
BEGIN
SELECT COUNT(*) INTO V_HOWMANY FROM employees
WHERE department_id = V_DEPTNO;
DBMS_OUTPUT.PUT_LINE (V_HOWMANY || ' employee(s)
work for department number ' ||V_DEPTNO);
END;
/

2. Quando o bloco for executado, uma variável de substituição será exibida. Informe um
número de departamento válido e clique em OK.

Oracle Database: Fundamentos de PL/SQL AP - 10


Os resultados de saída deverão ser semelhantes aos seguintes:

Oracle Database: Fundamentos de PL/SQL AP - 11


Exercícios Adicionais e Soluções da Lição 5
Nestes exercícios, você usará estruturas de controle para direcionar a lógica do fluxo do
programa.

Exercício 5-1: Criando Estruturas de Controle


1. Crie um bloco PL/SQL para aceitar a entrada de um ano e verificar se ele é bissexto.
Dica: O ano deverá ter divisão exata por 4, mas não por 100, ou deverá ser divisível
por 400.
2. Teste sua solução usando a tabela a seguir. Por exemplo, se o ano informado for
1990, a saída deverá ser “1990 is not a leap year”.
1990 Não é ano bissexto
2000 Ano bissexto
1996 Ano bissexto
1886 Não é ano bissexto
1992 Ano bissexto
1824 Ano bissexto

Exercício 5-2: Criando Estruturas de Controle


1. Crie um bloco PL/SQL para armazenar o salário mensal de um funcionário em uma
variável de substituição. O bloco PL/SQL deve:
• Calcular o salário anual como salário * 12
• Calcular o bônus como indicado na seguinte tabela:
Salário Anual Bônus
>= 20,000 2,000
19,999–10,000 1,000
<= 9,999 500
• Exibir o valor do bônus na janela Script Output no seguinte formato:

2. Teste o bloco PL/SQL para os seguintes casos:


Salário Mensal Bônus
3000 2000
1200 1000
800 500

Oracle Database: Fundamentos de PL/SQL AP - 12


Solução 5-1: Criando Estruturas de Controle
1. Crie um bloco PL/SQL para aceitar a entrada de um ano e verificar se ele é bissexto.
Dica: O ano deverá ter divisão exata por 4, mas não por 100, ou deverá ser divisível
por 400.
SET SERVEROUTPUT ON;
DECLARE
v_YEAR NUMBER(4) := &P_YEAR;
v_REMAINDER1 NUMBER(5,2);
v_REMAINDER2 NUMBER(5,2);
v_REMAINDER3 NUMBER(5,2);
BEGIN
v_REMAINDER1 := MOD(v_YEAR,4);
v_REMAINDER2 := MOD(v_YEAR,100);
v_REMAINDER3 := MOD(v_YEAR,400);
IF ((v_REMAINDER1 = 0 AND v_REMAINDER2 <> 0 ) OR
v_REMAINDER3 = 0) THEN
DBMS_OUTPUT.PUT_LINE(v_YEAR || ' is a leap year');
ELSE
DBMS_OUTPUT.PUT_LINE(v_YEAR || ' is not a leap
year');
END IF;
END;
/
2. Teste sua solução usando a tabela a seguir. Por exemplo, se o ano informado for
1990, a saída deverá ser “1990 is not a leap year”.
1990 Não é ano bissexto
2000 Ano bissexto
1996 Ano bissexto
1886 Não é ano bissexto
1992 Ano bissexto
1824 Ano bissexto

Oracle Database: Fundamentos de PL/SQL AP - 13


Solução 5-2: Criando Estruturas de Controle
1. Crie um bloco PL/SQL para armazenar o salário mensal de um funcionário em uma
variável de substituição. O bloco PL/SQL deve:
• Calcular o salário anual como salário * 12
• Calcular o bônus como indicado na seguinte tabela:
Salário Anual Bônus
>= 20,000 2,000
19,999–10,000 1,000
<= 9,999 500
• Exibir o valor do bônus na janela Script Output no seguinte formato:

SET SERVEROUTPUT ON;


DECLARE
V_SAL NUMBER(7,2) := &M_SALARY;
V_BONUS NUMBER(7,2);
V_ANN_SALARY NUMBER(15,2);
BEGIN
V_ANN_SALARY := V_SAL * 12;
IF V_ANN_SALARY >= 20000 THEN
V_BONUS := 2000;
ELSIF V_ANN_SALARY <= 19999 AND V_ANN_SALARY >=10000 THEN
V_BONUS := 1000;
ELSE
V_BONUS := 500;
END IF;
DBMS_OUTPUT.PUT_LINE ('The Bonus is $ ' ||
TO_CHAR(V_BONUS));
END;
/

2. Teste o bloco PL/SQL para os seguintes casos:


Salário Mensal Bônus
3000 2000
1200 1000
800 500

Oracle Database: Fundamentos de PL/SQL AP - 14


Exercícios Adicionais e Soluções das Lições 6 e 7
Nos exercícios a seguir, você usará arrays associativos (tópico abordado na lição 6) e
cursores explícitos (tópico abordado na lição 7). No primeiro exercício, você definirá e
usará um cursor explícito para extrair os dados com o comando fetch. No segundo
exercício, você combinará o uso dos arrays associativos com um cursor explícito para
gerar a saída de dados que atendem a determinados critérios.

Exercício 6/7-1: Extraindo Dados Usando o Comando Fetch com


um Cursor Explícito
Neste exercício, você criará um bloco PL/SQL para:
1. Declarar um cursor chamado EMP_CUR para selecionar o sobrenome, o salário e a
data de admissão na tabela EMPLOYEES
2. Processar cada linha do cursor e, se o salário for maior que 15.000 e a data de
admissão for posterior a 01-FEV-1988, exibir o nome, o salário e a data de admissão
do funcionário no formato do seguinte exemplo de saída:

Exercício 6/7-2: Usando Arrays Associativos e Cursores


Explícitos
Neste exercício, você criará um bloco PL/SQL para recuperar e gerar a saída do
sobrenome e do ID de departamento de cada funcionário da tabela EMPLOYEES cujo
valor de EMPLOYEE_ID for menor que 115.
No bloco PL/SQL, use uma estratégia de loop de cursor FOR em vez dos métodos de
cursor OPEN / FETCH / CLOSE usados no exercício anterior.
1. Na seção declarativa:
• Crie dois arrays associativos. A coluna da chave exclusiva para ambos os
arrays deve ser do tipo de dados BINARY INTEGER. Um array armazena o
sobrenome do funcionário e o outro armazena o ID do departamento.
• Declare um cursor que seleciona o sobrenome e o ID do departamento dos
funcionários cujo ID é menor que 115
• Declare a variável do contador adequada a ser usada na seção executável
2. Na seção executável, use um loop de cursor FOR (abordado na lição 7) para acessar
os valores de cursor, designe-os aos arrays associativos apropriados e gere a saída
desses valores dos arrays. A saída correta deve retornar 15 linhas, no seguinte
formato:

Oracle Database: Fundamentos de PL/SQL AP - 15


Solução 6/7-1: Extraindo Dados Usando o Comando Fetch com
um Cursor Explícito
Neste exercício, você criará um bloco PL/SQL para:
1. Declarar um cursor chamado EMP_CUR para selecionar o sobrenome, o salário e a
data de admissão na tabela EMPLOYEES
SET SERVEROUTPUT ON;
DECLARE
CURSOR C_EMP_CUR IS
SELECT last_name,salary,hire_date FROM EMPLOYEES;
V_ENAME VARCHAR2(25);
v_SAL NUMBER(7,2);
V_HIREDATE DATE;
2. Processar cada linha do cursor e, se o salário for maior que 15.000 e a data de
admissão for posterior a 01-FEV-1988, exibir o nome, o salário e a data de admissão
do funcionário no formato do seguinte exemplo de saída:
BEGIN
OPEN C_EMP_CUR;
FETCH C_EMP_CUR INTO V_ENAME,V_SAL,V_HIREDATE;
WHILE C_EMP_CUR%FOUND
LOOP
IF V_SAL > 15000 AND V_HIREDATE >=
TO_DATE('01-FEB-1988','DD-MON-YYYY') THEN
DBMS_OUTPUT.PUT_LINE (V_ENAME || ' earns '
|| TO_CHAR(V_SAL)|| ' and joined the organization on '
|| TO_DATE(V_HIREDATE,'DD-Mon-YYYY'));
END IF;
FETCH C_EMP_CUR INTO V_ENAME,V_SAL,V_HIREDATE;
END LOOP;
CLOSE C_EMP_CUR;
END;
/

Oracle Database: Fundamentos de PL/SQL AP - 16


Solução 6/7-2: Usando Arrays Associativos e Cursores
Explícitos
Neste exercício, você criará um bloco PL/SQL para recuperar e gerar a saída do
sobrenome e do ID de departamento de cada funcionário da tabela EMPLOYEES cujo
valor de EMPLOYEE_ID for menor que 115.
No bloco PL/SQL, use uma estratégia de loop de cursor FOR em vez dos métodos de
cursor OPEN / FETCH / CLOSE usados no exercício anterior.
1. Na seção declarativa:
• Crie dois arrays associativos. A coluna da chave exclusiva para ambos os
arrays deve ser do tipo de dados BINARY INTEGER. Um array armazena o
sobrenome do funcionário e o outro armazena o ID do departamento.
• Declare uma variável de contador adequada a ser usada na seção executável
• Declare um cursor que seleciona o sobrenome e o ID do departamento dos
funcionários cujo ID é menor que 115
SET SERVEROUTPUT ON;
DECLARE
TYPE Table_Ename IS table of employees.last_name%TYPE
INDEX BY BINARY_INTEGER;
TYPE Table_dept IS table of employees.department_id%TYPE
INDEX BY BINARY_INTEGER;
Tename Table_Ename;
Tdept Table_dept;
i BINARY_INTEGER :=0;
CURSOR Namedept IS SELECT last_name,department_id
FROM employees WHERE employee_id < 115;
2. Na seção executável, use um loop de cursor FOR (abordado na lição 7) para acessar
os valores de cursor, designe-os aos arrays associativos apropriados e gere a saída
desses valores dos arrays.
BEGIN
FOR emprec in Namedept
LOOP
i := i +1;
Tename(i) := emprec.last_name;
Tdept(i) := emprec.department_id;
DBMS_OUTPUT.PUT_LINE ('Employee: ' || Tename(i) ||
' is in department number: ' || Tdept(i));
END LOOP;
END;
/

Oracle Database: Fundamentos de PL/SQL AP - 17


A saída correta deve retornar 15 linhas, semelhante à seguinte:

Oracle Database: Fundamentos de PL/SQL AP - 18


Exercício Adicional e Solução da Lição 8

Exercício 8-1: Tratando Exceções


Neste exercício, primeiro você deve criar uma tabela para armazenar alguns resultados.
Execute o script lab_ap_08.sql que cria a tabela para você. O script será semelhante
a este:

CREATE TABLE analysis


(ename Varchar2(20), years Number(2), sal Number(8,2)
);

Neste exercício, você criará um bloco PL/SQL que trata uma exceção, como a seguir:
1. Declare variáveis para o sobrenome, o salário e a data de admissão do funcionário.
Use uma variável de substituição para o sobrenome do funcionário. Em seguida,
consulte a tabela employees para last_name, salary e hire_date do
funcionário especificado.
2. Se o funcionário estiver na organização há mais de cinco anos e o salário dele for
menor que 3.500, gere uma exceção. No handler de exceção, faça o seguinte:
• Gere a saída das seguintes informações: sobrenome do funcionário e a
mensagem “due for a raise”, semelhante à seguinte saída:

• Insira o sobrenome, os anos de serviço e o salário na tabela analysis..


3. Se não houver exceção, gere a saída do sobrenome do funcionário e a mensagem “not
due for a raise”, semelhante à seguinte:

4. Verifique os resultados consultando a tabela analysis. Use os seguintes casos de


teste para testar o bloco PL/SQL.
LAST_NAME MENSAGEM
Austin Not due for a raise
Nayer Due for a raise
Fripp Not due for a raise
Khoo Due for a raise

Oracle Database: Fundamentos de PL/SQL AP - 19


Solução 8-1: Tratando Exceções
Neste exercício, primeiro você deve criar uma tabela para armazenar alguns resultados.
Execute o script lab_ap_08.sql que cria a tabela para você. O script será semelhante
a este:

CREATE TABLE analysis


(ename Varchar2(20), years Number(2), sal Number(8,2)
);

Neste exercício, você criará um bloco PL/SQL que trata uma exceção, como a seguir:
1. Declare variáveis para o sobrenome, o salário e a data de admissão do funcionário.
Use uma variável de substituição para o sobrenome do funcionário. Em seguida,
consulte a tabela employees para last_name, salary e hire_date do
funcionário especificado.
2. Se o funcionário estiver na organização há mais de cinco anos e o salário dele for
menor que 3.500, gere uma exceção. No handler de exceção, faça o seguinte:
• Gere a saída das seguintes informações: sobrenome do funcionário e a
mensagem “due for a raise”.
• Insira o nome, os anos de serviço e o salário do funcionário na tabela
analysis..
3. Se não houver exceção, gere a saída do sobrenome do funcionário e a mensagem “not
due for a raise”.
SET SERVEROUTPUT ON;
DECLARE
E_DUE_FOR_RAISE EXCEPTION;
V_HIREDATE EMPLOYEES.HIRE_DATE%TYPE;
V_ENAME EMPLOYEES.LAST_NAME%TYPE := INITCAP( '& B_ENAME');
V_SAL EMPLOYEES.SALARY%TYPE;
V_YEARS NUMBER(2);
BEGIN
SELECT LAST_NAME,SALARY,HIRE_DATE
INTO V_ENAME,V_SAL,V_HIREDATE
FROM employees WHERE last_name = V_ENAME;
V_YEARS := MONTHS_BETWEEN(SYSDATE,V_HIREDATE)/12;
IF V_SAL < 3500 AND V_YEARS > 5 THEN
RAISE E_DUE_FOR_RAISE;
ELSE
DBMS_OUTPUT.PUT_LINE (' not due for a raise');
END IF;
EXCEPTION
WHEN E_DUE_FOR_RAISE THEN
BEGIN
DBMS_OUTPUT.PUT_LINE (V_NAME || ' due for a raise');
INSERT INTO ANALYSIS(ENAME,YEARS,SAL)
VALUES (V_ENAME,V_YEARS,V_SAL);
END;
END;
/

Oracle Database: Fundamentos de PL/SQL AP - 20


4. Verifique os resultados consultando a tabela analysis. Use os seguintes casos de
teste para testar o bloco PL/SQL.
LAST_NAME MENSAGEM
Austin Not due for a raise
Nayer Due for a raise
Fripp Not due for a raise
Khoo Due for a raise

SELECT * FROM analysis;

Oracle Database: Fundamentos de PL/SQL AP - 21

You might also like