Introdução ao Oracle 8i

595
Introdução ao Oracle: SQL e PL/SQL

Transcript of Introdução ao Oracle 8i

Page 1: Introdução ao Oracle 8i

Introdução ao Oracle:SQL e PL/SQL

Volume I

OR8iAbril/2000

Page 2: Introdução ao Oracle 8i
Page 3: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

Sumário

1. Introdução...........................................................................................................1-1Objetivos....................................................................................................................................1-2Ciclo de Vida do Desenvolvimento de Sistemas.......................................................................1-3Armazenamento de Dados em Diferentes Mídias.....................................................................1-4Conceito de Banco de Dados Relacional...................................................................................1-5Definição de Banco de Dados Relacional.................................................................................1-6Modelos de Dados.....................................................................................................................1-7Modelo Entidade-Relacionamento............................................................................................1-8Convenções do Modelo Entidade-Relacionamento...................................................................1-9Terminologia Utilizada em Bancos de Dados Relacionais.....................................................1-11Relacionando Múltiplas Tabelas.............................................................................................1-12Propriedades de um Banco de Dados Relacional....................................................................1-13Comunicando com um RDBMS utilizando SQL....................................................................1-14Sistema de Gerenciamento de Banco de Dados Relacional....................................................1-15Oracle8i: Sistema de Gerenciamento de Banco de Dados Objeto Relacional........................1-16Definição de Objeto.................................................................................................................1-17Utilizando um Modelo de Objeto............................................................................................1-18Características de Sistemas de Objeto.....................................................................................1-19Solução Completa Oracle........................................................................................................1-20Comandos SQL.......................................................................................................................1-21PL/SQL....................................................................................................................................1-22Ambiente PL/SQL...................................................................................................................1-23Benefícios do PL/SQL.............................................................................................................1-24Tabelas Utilizadas no Curso....................................................................................................1-28

2. Executando Comandos SQL Básicos................................................................2-1Objetivos....................................................................................................................................2-2Características do Comando SQL SELECT..............................................................................2-3Comando SELECT Básico........................................................................................................2-4Escrevendo Comandos SQL......................................................................................................2-5Selecionando todas as Colunas..................................................................................................2-6Selecionando Colunas Específicas............................................................................................2-7Padrões de Cabeçalho de Colunas.............................................................................................2-8Expressões Aritméticas.............................................................................................................2-9Utilizando Operadores Aritméticos.........................................................................................2-10Precedência dos Operadores....................................................................................................2-11Utilizando Parênteses..............................................................................................................2-12Definindo um Valor Nulo........................................................................................................2-13Valores Nulos em Expressões Aritméticas..............................................................................2-14Definindo um Alias de Coluna................................................................................................2-15Utilizando Alias de Colunas....................................................................................................2-16Operador de Concatenação......................................................................................................2-17Strings de Caracteres Literais..................................................................................................2-18Linhas Duplicadas...................................................................................................................2-19Eliminando Linhas Duplicadas................................................................................................2-20Interação entre SQL e SQL*Plus............................................................................................2-21Visão Geral do SQL*Plus.......................................................................................................2-23

DBC Database Company I

Page 4: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

Conectando com o SQL*Plus..................................................................................................2-24Exibindo a Estrutura de Tabelas..............................................................................................2-25Comandos de Edição do SQL*Plus.........................................................................................2-26Comandos de Arquivo do SQL*Plus......................................................................................2-27Exercícios - 2...........................................................................................................................2-28

3. Restringindo e Ordenando Dados....................................................................3-1Objetivos....................................................................................................................................3-2Limitando Linhas Utilizando uma Seleção...............................................................................3-3Limitando as Linhas Selecionadas............................................................................................3-4Utilizando a Cláusula WHERE.................................................................................................3-5Strings de Caractere e Datas......................................................................................................3-6Operadores de Comparação.......................................................................................................3-7Utilizando os Operadores de Comparação................................................................................3-8Outros Operadores de Comparação...........................................................................................3-9Operador BETWEEN..............................................................................................................3-10Operador IN.............................................................................................................................3-11Operador LIKE.......................................................................................................................3-12Operador IS NULL..................................................................................................................3-14Operadores Lógicos.................................................................................................................3-15Operador AND........................................................................................................................3-16Operador OR...........................................................................................................................3-17Operador NOT.........................................................................................................................3-18Regras de Precedência.............................................................................................................3-19Cláusula ORDER BY..............................................................................................................3-21Classificando em Ordem Descendente....................................................................................3-22Ordenando pelo Alias de Coluna.............................................................................................3-23Ordenando por Múltiplas Colunas...........................................................................................3-24Exercícios – 3..........................................................................................................................3-25

4. Funções Básicas..................................................................................................4-1Objetivos....................................................................................................................................4-2Funções SQL.............................................................................................................................4-3Tipos de Funções SQL..............................................................................................................4-4Funções do Tipo Single-Row.....................................................................................................4-5Funções de Caracteres...............................................................................................................4-7Funções de Conversão entre Maiúsculas/Minúsculas...............................................................4-8Utilizando Funções de Conversão entre Maiúsculas/Minúsculas.............................................4-9Funções de Manipulação de Caracteres..................................................................................4-10Utilizando as Funções de Manipulação de Caracteres............................................................4-11Funções Numéricas.................................................................................................................4-12Utilizando a Função ROUND.................................................................................................4-13Utilizando a Função TRUNC..................................................................................................4-14Utilizando a Função MOD......................................................................................................4-15Trabalhando com Datas...........................................................................................................4-16Cálculos com Datas.................................................................................................................4-17Utilizando Operadores Aritméticos com Datas.......................................................................4-18Funções de Data......................................................................................................................4-19Utilizando Funções de Data.....................................................................................................4-20Funções de Conversão.............................................................................................................4-22

DBC Database Company II

Page 5: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

Conversão Explícita de Tipos de Dados..................................................................................4-23Função TO_CHAR com Datas................................................................................................4-24Elementos de Formatação de Datas.........................................................................................4-25Utilizando a Função TO_CHAR com Datas...........................................................................4-27Função TO_CHAR com Números..........................................................................................4-28Utilizando a Função TO_CHAR com Números......................................................................4-29Funções TO_NUMBER e TO_DATE.....................................................................................4-30Formato de Data RR................................................................................................................4-31Função NVL............................................................................................................................4-32Utilizando a Função NVL.......................................................................................................4-33Função DECODE....................................................................................................................4-34Utilizando a Função DECODE...............................................................................................4-35Aninhando Funções.................................................................................................................4-36Exercícios – 4..........................................................................................................................4-37

5. Exibindo Dados a Partir de Múltiplas Tabelas...............................................5-1Objetivos....................................................................................................................................5-2Obtendo Dados a Partir de Múltiplas Tabelas...........................................................................5-3O que é um Join?.......................................................................................................................5-4Produto Cartesiano....................................................................................................................5-5Gerando um Produto Cartesiano...............................................................................................5-6Tipos de Joins............................................................................................................................5-7O que é um Equijoin?................................................................................................................5-8Recuperando Registros com Equijoins......................................................................................5-9Qualificando Nomes de Colunas Ambíguos...........................................................................5-10Condições Adicionais de Pesquisa com o Operador AND.....................................................5-11Utilizando Alias de Tabela......................................................................................................5-12Relacionando mais de Duas Tabelas.......................................................................................5-13Non-Equijoins..........................................................................................................................5-14Recuperando Registros com Non-Equijoins...........................................................................5-15Outer Joins...............................................................................................................................5-16Utilizando Outer Joins.............................................................................................................5-18Self Joins.................................................................................................................................5-19Relacionando uma Tabela com Ela Mesma............................................................................5-20Exercícios – 5..........................................................................................................................5-21

6. Agregando Dados Utilizando Funções de Grupo............................................6-1Objetivos....................................................................................................................................6-2O que são Funções de Grupo?...................................................................................................6-3Tipos de Funções de Grupo.......................................................................................................6-4Utilizando Funções de Grupo....................................................................................................6-5Utilizando as Funções AVG e SUM.........................................................................................6-6Utilizando as Funções MIN e MAX..........................................................................................6-7Utilizando a Função COUNT....................................................................................................6-8Funções de Grupo e Valores Nulos.........................................................................................6-10Utilizando a Função NVL com Funções de Grupo.................................................................6-11Criando Grupos de Dados.......................................................................................................6-12Criando Grupos de Dados: Cláusula GROUP BY..................................................................6-13Utilizando a Cláusula GROUP BY.........................................................................................6-14Agrupando por Mais de Uma Coluna......................................................................................6-16

DBC Database Company III

Page 6: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

Utilizando a Cláusula GROUP BY em Múltiplas Colunas.....................................................6-17Consultas Ilegais Utilizando Funções de Grupo.....................................................................6-18Excluindo Resultados de Grupos.............................................................................................6-20Excluindo Resultados de Grupos: Cláusula HAVING............................................................6-21Utilizando a Cláusula HAVING..............................................................................................6-22Aninhando Funções de Grupo.................................................................................................6-24Exercícios – 6..........................................................................................................................6-25

7. Subconsultas.......................................................................................................7-1Objetivos....................................................................................................................................7-2Utilizando uma Subconsulta para Resolver um Problema........................................................7-3Subconsultas..............................................................................................................................7-4Utilizando uma Subconsulta......................................................................................................7-5Diretrizes para Utilização de Subconsultas...............................................................................7-6Tipos de Subconsultas...............................................................................................................7-7Subconsultas Single-Row..........................................................................................................7-8Executando Subconsultas Single-Row......................................................................................7-9Utilizando Funções de Grupo em uma Subconsulta................................................................7-10Cláusula HAVING com Subconsultas....................................................................................7-11Qual o Erro deste Comando?...................................................................................................7-12Este Comando Funcionará?.....................................................................................................7-13Subconsultas do Tipo Multiple-Row.......................................................................................7-14Utilizando o Operador ANY em Subconsultas Multiple-Row................................................7-15Utilizando o Operador ALL em Subconsultas Multiple-Row.................................................7-16Exercícios – 7..........................................................................................................................7-17

8. Subconsultas Multiple-Column........................................................................8-1Objetivos....................................................................................................................................8-2Subconsultas Multiple-Column.................................................................................................8-3Utilizando Subconsultas Multiple-Column...............................................................................8-4Comparações de Colunas..........................................................................................................8-5Subconsulta com Comparação Tipo Nonpairwise....................................................................8-6Modificando a Tabela EMP.......................................................................................................8-7Subconsulta Tipo Pairwise........................................................................................................8-8Subconsulta Tipo Nonpairwise..................................................................................................8-9Valores Nulos em uma Subconsulta........................................................................................8-10Utilizando uma Subconsulta na Cláusula FROM....................................................................8-11Exercícios – 8..........................................................................................................................8-12

9. Produzindo Resultados mais Legíveis com SQL*Plus....................................9-1Objetivos....................................................................................................................................9-2Relatórios Interativos.................................................................................................................9-3Utilizando Variáveis de Substituição com (&)..........................................................................9-4Utilizando o Comando SET VERIFY.......................................................................................9-5Valores Caractere e Data com Variáveis de Substituição.........................................................9-6Especificando Nomes de Colunas, Expressões e Textos em Tempo de Execução...................9-7Utilizando Variáveis de Substituição com (&&).......................................................................9-9Definindo Variáveis de Usuário..............................................................................................9-10O Comando ACCEPT.............................................................................................................9-11Utilizando o Comando ACCEPT............................................................................................9-12

DBC Database Company IV

Page 7: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

Comandos DEFINE e UNDEFINE.........................................................................................9-13Utilizando o Comando DEFINE.............................................................................................9-14Customizando o Ambiente do SQL*Plus................................................................................9-15Variáveis do Comando SET....................................................................................................9-16Salvando as Customizações no Arquivo login.sql..................................................................9-17Comandos de Formatação do SQL*Plus.................................................................................9-18Comando COLUMN...............................................................................................................9-19Utilizando o Comando COLUMN..........................................................................................9-20Máscaras do Comando COLUMN..........................................................................................9-21Utilizando o Comando BREAK..............................................................................................9-22Utilizando os Comandos TTITLE e BTITLE.........................................................................9-23Criando um Arquivo de Script para Executar um Relatório...................................................9-24Relatório de Exemplo..............................................................................................................9-25Exercícios – 9..........................................................................................................................9-26

10. Manipulando Dados.........................................................................................10-1Objetivos..................................................................................................................................10-2Linguagem de Manipulação de Dados....................................................................................10-3Inserindo uma Nova Linha em uma Tabela............................................................................10-4Comando INSERT...................................................................................................................10-5Inserindo Novas Linhas...........................................................................................................10-6Inserindo Linhas com Valores Nulos......................................................................................10-7Inserindo Valores Especiais....................................................................................................10-8Inserindo Valores de Data Específicos....................................................................................10-9Inserindo Valores Utilizando Variáveis de Substituição.......................................................10-10Criando um Script com Prompts Customizados....................................................................10-11Copiando Linhas a Partir de Outra Tabela............................................................................10-12Alterando Dados em uma Tabela..........................................................................................10-13Comando UPDATE...............................................................................................................10-14Alterando Linhas em uma Tabela..........................................................................................10-15Atualizando com Subconsultas Multiple-Column.................................................................10-16Atualizando Linhas com Valores de Outra Tabela................................................................10-17Atualizando Linhas: Erro de Constraint de Integridade........................................................10-18Removendo uma Linha de uma Tabela.................................................................................10-19Comando DELETE...............................................................................................................10-20Removendo Linhas de uma Tabela.......................................................................................10-21Removendo Linhas com Base nos Valores de Outra Tabela................................................10-22Removendo Linhas: Erro de Constraint de Integridade........................................................10-23Transações de Banco de Dados.............................................................................................10-24Vantagens do COMMIT e ROLLBACK..............................................................................10-25Controlando Transações........................................................................................................10-26Processamento Implícito de Transações................................................................................10-27Situação dos Dados Antes do COMMIT ou ROLLBACK...................................................10-28Situação dos Dados Após o COMMIT..................................................................................10-29Efetivando os Dados..............................................................................................................10-30Situação dos Dados Após o ROLLBACK.............................................................................10-31Desfazendo as Alterações Até uma Marca............................................................................10-32Rollback a Nível de Comando...............................................................................................10-33Leitura Consistente................................................................................................................10-34Implementação de Leitura Consistente.................................................................................10-35Lock.......................................................................................................................................10-36

DBC Database Company V

Page 8: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

Exercícios – 10......................................................................................................................10-37

11. Criando e Gerenciando Tabelas.....................................................................11-1Objetivos..................................................................................................................................11-2Objetos do Banco de Dados....................................................................................................11-3Convenções de Nomes............................................................................................................11-4Comando CREATE TABLE...................................................................................................11-5Referenciando Tabelas de Outro Usuário................................................................................11-6Opção DEFAULT...................................................................................................................11-7Criando Tabelas.......................................................................................................................11-8Consultando o Dicionário de Dados........................................................................................11-9Tipos de Dados......................................................................................................................11-10Criando uma Tabela Utilizando uma Subconsulta................................................................11-11Comando ALTER TABLE....................................................................................................11-13Adicionando uma Coluna......................................................................................................11-14Modificando uma Coluna......................................................................................................11-15Removendo uma Tabela........................................................................................................11-16Modificando o Nome de um Objeto......................................................................................11-17Truncando uma Tabela..........................................................................................................11-18Adicionando Comentários para Tabelas................................................................................11-19Exercícios – 11......................................................................................................................11-20

12. Implementando Constraints............................................................................12-1Objetivos..................................................................................................................................12-2O Que são Constraints?...........................................................................................................12-3Diretrizes para Constraints......................................................................................................12-4Definindo Constraints..............................................................................................................12-5Constraint NOT NULL............................................................................................................12-7Constraint UNIQUE Key........................................................................................................12-8Constraint PRIMARY KEY....................................................................................................12-9Constraint FOREIGN KEY...................................................................................................12-10Palavras Chave de Constraints FOREIGN KEY...................................................................12-11Constraint CHECK................................................................................................................12-12Adicionando uma Constraint.................................................................................................12-13Removendo uma Constraint..................................................................................................12-14Desabilitando Constraints......................................................................................................12-15Habilitando Constraints.........................................................................................................12-16Visualizando Constraints.......................................................................................................12-17Visualizando as Colunas Associadas com Constraints.........................................................12-18Exercícios – 12......................................................................................................................12-19

13. Criando Visões..................................................................................................13-1Objetivos..................................................................................................................................13-2Objetos do Banco de Dados....................................................................................................13-3O que é uma Visão?.................................................................................................................13-4Porquê Utilizar Visões?...........................................................................................................13-5Visões Simples e Visões Complexas.......................................................................................13-6Criando uma Visão..................................................................................................................13-7Recuperando Dados de uma Visão..........................................................................................13-9Consultando uma Visão.........................................................................................................13-10

DBC Database Company VI

Page 9: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

Modificando uma Visão........................................................................................................13-11Criando uma Visão Complexa...............................................................................................13-12Regras para Executar Operações DML em uma Visão.........................................................13-13Utilizando a Cláusula WITH CHECK OPTION...................................................................13-14Impedindo Operações DML..................................................................................................13-15Removendo uma Visão..........................................................................................................13-16Exercícios – 13......................................................................................................................13-17

14. Outros Objetos do Banco de Dados................................................................14-1Objetivos..................................................................................................................................14-2Objetos do Banco de Dados....................................................................................................14-3O que é uma Sequence?...........................................................................................................14-4Comando CREATE SEQUENCE...........................................................................................14-5Criando uma Sequence............................................................................................................14-6Confirmando Sequences..........................................................................................................14-7Pseudocolunas NEXTVAL e CURRVAL...............................................................................14-8Utilizando uma Sequence........................................................................................................14-9Modificando uma Sequence..................................................................................................14-11Diretrizes para Modificar uma Sequence..............................................................................14-12Removendo uma Sequence....................................................................................................14-13O que é um Índice?................................................................................................................14-14Como os Índices são Criados?...............................................................................................14-15Criando um Índice.................................................................................................................14-16Diretrizes para a Criação de Índices......................................................................................14-17Confirmando Índices.............................................................................................................14-18Removendo um Índice...........................................................................................................14-19Sinônimos..............................................................................................................................14-20Criando e Removendo Sinônimos.........................................................................................14-21Exercícios – 14......................................................................................................................14-22

15. Controlando o Acesso dos Usuários...............................................................15-1Objetivos..................................................................................................................................15-2Controlando o Acesso dos Usuários........................................................................................15-3Privilégios................................................................................................................................15-4Privilégios de Sistema.............................................................................................................15-5Criando Usuários.....................................................................................................................15-6Privilégios de Sistema do Usuário...........................................................................................15-7Concedendo Privilégios de Sistema........................................................................................15-8O que é uma Role?..................................................................................................................15-9Criando e Concedendo Privilégios para uma Role................................................................15-10Modificando Senhas..............................................................................................................15-11Privilégios de Objeto.............................................................................................................15-12Concedendo Privilégios de Objeto........................................................................................15-13Utilizando as Opções WITH GRANT OPTION e PUBLIC.................................................15-14Confirmando Privilégios Concedidos....................................................................................15-15Como Revogar Privilégios de Objeto....................................................................................15-16Revogando Privilégios de Objeto..........................................................................................15-17Exercícios – 15......................................................................................................................15-18

DBC Database Company VII

Page 10: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

16. Declarando Variáveis.......................................................................................16-1Objetivos..................................................................................................................................16-2Estrutura de um Bloco PL/SQL...............................................................................................16-3Tipos de Blocos.......................................................................................................................16-5Construções de Programas......................................................................................................16-6Utilização de Variáveis............................................................................................................16-7Tratando Variáveis em PL/SQL..............................................................................................16-8Tipos de Variáveis...................................................................................................................16-9Declarando Variáveis PL/SQL..............................................................................................16-10Regras de Nomenclatura........................................................................................................16-11Atribuindo Valores para Variáveis........................................................................................16-12Utilizando Variáveis e Palavras Chaves................................................................................16-13Tipos de Dados Escalares......................................................................................................16-14Declaração de Variáveis Escalares........................................................................................16-15Atributo %TYPE...................................................................................................................16-16Declarando Variáveis com o Atributo %TYPE.....................................................................16-17Declarando Variáveis BOOLEAN........................................................................................16-18Tipos de Dados Compostos...................................................................................................16-19Variáveis com Tipos de Dados LOB.....................................................................................16-20Variáveis Tipo Bind..............................................................................................................16-21Referenciando Variáveis Não PL/SQL.................................................................................16-22Exercícios – 16......................................................................................................................16-23

17. Escrevendo Comandos Executáveis...............................................................17-1Objetivos..................................................................................................................................17-2Sintaxe e Diretrizes de um Bloco PL/SQL..............................................................................17-3Comentando o Código.............................................................................................................17-5Funções SQL em PL/SQL.......................................................................................................17-6Funções PL/SQL.....................................................................................................................17-7Conversão de Tipos de Dados.................................................................................................17-8Blocos Aninhados e Escopo de Variáveis...............................................................................17-9Operadores em PL/SQL........................................................................................................17-10Utilizando Variáveis Bind.....................................................................................................17-11Diretrizes de Programação....................................................................................................17-12Convenções de Nomenclatura...............................................................................................17-13Identando o Código...............................................................................................................17-14Determine o Escopo das Variáveis........................................................................................17-15Exercícios – 17......................................................................................................................17-16

18. Interagindo com o Servidor Oracle................................................................18-1Objetivos..................................................................................................................................18-2Comandos SQL em PL/SQL...................................................................................................18-3Comandos SELECT em PL/SQL............................................................................................18-4Recuperando Dados em PL/SQL.............................................................................................18-6Manipulando Dados Utilizando PL/SQL................................................................................18-7Inserindo Dados.......................................................................................................................18-8Atualizando Dados..................................................................................................................18-9Removendo Dados.................................................................................................................18-10Convenções de Nomenclatura...............................................................................................18-11Comandos COMMIT e ROLLBACK...................................................................................18-12

DBC Database Company VIII

Page 11: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

Cursor SQL............................................................................................................................18-13Atributos do Cursor SQL.......................................................................................................18-14Exercícios – 18......................................................................................................................18-15

19. Escrevendo Estruturas de Controle...............................................................19-1Objetivos..................................................................................................................................19-2Controlando o Fluxo de Execução PL/SQL............................................................................19-3Comandos IF...........................................................................................................................19-4Comandos IF Simples..............................................................................................................19-5Fluxo de Execução do Comando IF-THEN-ELSE.................................................................19-6Comandos IF-THEN-ELSE.....................................................................................................19-7Fluxo de Execução do Comando IF-THEN-ELSIF................................................................19-8Comandos IF-THEN-ELSIF...................................................................................................19-9Construindo Condições Lógicas............................................................................................19-10Tabelas de Lógica..................................................................................................................19-11Condições Boleanas..............................................................................................................19-12Controle de Repetições: Comandos de LOOP......................................................................19-13Loop Básico...........................................................................................................................19-14FOR Loop..............................................................................................................................19-15WHILE Loop.........................................................................................................................19-17Loops Aninhados e Labels....................................................................................................19-18Exercícios – 19......................................................................................................................19-19

20. Trabalhando com Tipos de Dados Compostos..............................................20-1Objetivos..................................................................................................................................20-2Tipos de Dados Compostos.....................................................................................................20-3PL/SQL Records......................................................................................................................20-4Criando um PL/SQL Record...................................................................................................20-5Estrutura de um PL/SQL Record.............................................................................................20-7Atributo %ROWTYPE............................................................................................................20-8PL/SQL Tables......................................................................................................................20-10Criando uma PL/SQL Table..................................................................................................20-11Estrutura de uma PL/SQL Table...........................................................................................20-12Criando uma PL/SQL Table..................................................................................................20-13PL/SQL Table com Registros................................................................................................20-14Utilizando Métodos de PL/SQL Tables................................................................................20-15Exercícios – 20......................................................................................................................20-16

21. Escrevendo Cursores Explícitos.....................................................................21-1Objetivos..................................................................................................................................21-2Cursores...................................................................................................................................21-3Cursores Explícitos..................................................................................................................21-4Controlando Cursores Explícitos.............................................................................................21-5Declarando o Cursor................................................................................................................21-7Abrindo um Cursor..................................................................................................................21-8Recuperando Dados do Cursor................................................................................................21-9Fechando um Cursor..............................................................................................................21-11Atributos de Cursores Explícitos...........................................................................................21-12Controlando Múltiplos Fetch.................................................................................................21-13Atributo %ISOPEN...............................................................................................................21-14

DBC Database Company IX

Page 12: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

Atributos %NOTFOUND e %ROWCOUNT.......................................................................21-15Cursores e Registros..............................................................................................................21-16Cursor FOR Loop..................................................................................................................21-17Cursor FOR Loop Utilizando Subconsultas..........................................................................21-18Exercícios – 21......................................................................................................................21-19

22. Conceitos Avançados de Cursores Explícitos................................................22-1Objetivos..................................................................................................................................22-2Cursores com Parâmetros........................................................................................................22-3Cláusula FOR UPDATE..........................................................................................................22-5Cláusula WHERE CURRENT OF..........................................................................................22-6Cursores com Subconsultas.....................................................................................................22-7Exercícios – 22........................................................................................................................22-8

Apêndice A – Soluções dos Exercícios...................................................................A-1Soluções Exercícios – 2............................................................................................................A-2Soluções Exercícios – 3............................................................................................................A-4Soluções Exercícios – 4............................................................................................................A-7Soluções Exercícios – 5..........................................................................................................A-10Soluções Exercícios – 6..........................................................................................................A-13Soluções Exercícios – 7..........................................................................................................A-16Soluções Exercícios – 8..........................................................................................................A-18Soluções Exercícios – 9..........................................................................................................A-19Soluções Exercícios – 10........................................................................................................A-22Soluções Exercícios – 11........................................................................................................A-25Soluções Exercícios – 12........................................................................................................A-27Soluções Exercícios – 13........................................................................................................A-28Soluções Exercícios – 14........................................................................................................A-30Soluções Exercícios – 15........................................................................................................A-32Soluções Exercícios – 16........................................................................................................A-35Soluções Exercícios – 17........................................................................................................A-38Soluções Exercícios – 18........................................................................................................A-42Soluções Exercícios – 19........................................................................................................A-45Soluções Exercícios – 20........................................................................................................A-49Soluções Exercícios – 21........................................................................................................A-51Soluções Exercícios – 22........................................................................................................A-53

DBC Database Company X

Page 13: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

1.1. IntroduçãoIntrodução

On Targget Treinamento e Consultoria

Page 14: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Discutir os aspectos teóricos e físicos de um Banco de Dados Relacional Descrever a implementação Oracle do RDBMS e ORDBMS Descrever como SQL e PL/SQL são utilizados nos produtos Oracle Descrever o uso e os benefícios do PL/SQL

Neste capítulo, você obterá uma visão dos sistemas de gerenciamento de banco de dados relacionais (RDBMS) e dos sistemas de gerenciamento de banco de dados objeto relacionais (ORDBMS). Também será apresentado:

Comandos SQL que são específicos ao Oracle SQL*Plus, utilizado para executar códigos SQL e PL/SQL PL/SQL, que é a linguagem procedural do Oracle

On Targget Treinamento e Consultoria 2

Page 15: Introdução ao Oracle 8i

Funções Básicas

Ciclo de Vida do Desenvolvimento de Sistemas

Do conceito à produção, você pode desenvolver um banco de dados utilizando as técnicas do ciclo de vida do desenvolvimento de sistemas que contém várias fases de desenvolvimento:

Análise e Estratégia

Estudo e análise das necessidades de negócio. Entrevistas com usuários e gerentes para identificar as necessidades de informações.

Construção dos modelos do sistema. Conversão das narrativas em uma representação gráfica de informações e regras de negócio necessárias. Confirmação e refinamento do modelo com os analistas e peritos.

Design

Projete o banco de dados baseado no modelo desenvolvido na fase de análise e estratégia.

Construção e Documentação

Construa o protótipo do sistema. Escreva e execute os comandos para criar as tabelas e os objetos de suporte para o banco de dados.

Desenvolva a documentação de usuário, texto de ajuda, e os manuais de operação para auxiliar na utilização do sistema.

Transição

Refine o protótipo. Coloque a aplicação em produção após os testes dos usuários, convertendo os dados existentes. Efetue quaisquer modificações necessárias.

Produção

Coloque o sistema em produção, monitorando sua operação e desempenho, efetuando melhorias e refinamentos necessários.

On Targget Treinamento e Consultoria 3

Page 16: Introdução ao Oracle 8i

Funções Básicas

Armazenamento de Dados em Diferentes Mídias

Armazenando Informações

Toda organização possui necessidades de informação. Uma biblioteca mantém uma lista de sócios, livros, datas de entrega e multas. Uma empresa precisa armazenar informações sobre empregados, departamentos e salários. Estes pedaços de informação são chamados de dados.

Organizações podem armazenar dados em várias mídias e em formatos diferentes. Por exemplo, uma cópia física de um documento pode estar armazenada em um arquivo, ou em dados armazenados em planilhas eletrônicas ou em bancos de dados.

Um banco de dados é um conjunto organizado de informações.

Para administrar um bancos de dados, você precisa de sistemas de gerenciamento de banco de dados (DBMS). Um DBMS é um programa que armazena, recupera, e modifica os dados sempre que solicitado. Existem quatro tipos principais de bancos de dados: hierárquico, de rede, relacionao, e mais recentemente relacional de objeto.

Nota: Oracle7 é um banco de dados relacional enquanto que Oracle8i é um banco de dados objeto relacional.

On Targget Treinamento e Consultoria 4

Page 17: Introdução ao Oracle 8i

Funções Básicas

Conceito de Banco de Dados Relacional

Modelo Relacional

Os princípios do modelo relacional foram esboçados pela primeira vez pelo Dr. E. F. Codd por volta de junho de 1970 em um paper intitulado “Um Modelo Relacional de Dados para Grandes Bancos de Dados Compartilhados”. Neste paper, o Dr. Codd propôs o modelo relacional para sistemas de banco de dados.

Os modelos mais populares usados naquele momento eram hierárquicos e de rede, ou até mesmo arquivo de dados com estruturas simples. Sistemas de gerenciamento de banco de dados relacionais (RDBMS) logo tornaram-se muito populares, especialmente devido a sua facilidade de uso e flexibilidade na estrutura. Além disso, haviam vários vendedores inovadores, como a Oracle que completou o RDBMS com um conjunto poderoso de ferramentas para o desenvolvimento de aplicações e produtos para o usuário, provendo uma solução total.

Componentes do Modelo de Relacional

Conjunto de objetos ou relações que armazenam os dados Conjunto de operadores que podem agir nas relações para produzir outras relações Integridade de dados para precisão e consistência

On Targget Treinamento e Consultoria 5

Page 18: Introdução ao Oracle 8i

Funções Básicas

Definição de Banco de Dados Relacional

Banco de Dados Relacional

Um banco de dados relacional utiliza relações ou tabelas bi-dimensionais para armazenar informações.

Por exemplo, você poderia querer armazenar informações sobre todos os empregados de sua companhia. Em um banco de dados relacional, você cria várias tabelas para armazenar pedaços diferentes de informação sobre seus empregados, como uma tabela de empregado, uma tabela de departamento, e uma tabela de salário.

On Targget Treinamento e Consultoria 6

Page 19: Introdução ao Oracle 8i

Funções Básicas

Modelos de Dados

Modelos são uma base de design. Engenheiros constroem um modelo de um carro para trabalhar qualquer detalhe antes de colocá-lo em produção. Da mesma maneira, projetistas de sistemas desenvolvem modelos para explorar idéias e melhorar a compreensão do design de um banco de dados.

Propósito dos Modelos

Modelos ajudam a disseminar os conceitos nas mentes das pessoas. Eles podem ser utilizados para os seguintes propósitos:

Comunicar Categorizar Descrever Especificar Investigar Evoluir Analisar ImitarO objetivo é produzir um modelo que reúna vários destes propósitos e que possa ao mesmo

tempo ser entendido por um usuário final e conter detalhes suficientes para um desenvolvedor construir um sistema de banco de dados.

On Targget Treinamento e Consultoria 7

Page 20: Introdução ao Oracle 8i

Funções Básicas

Modelo Entidade-Relacionamento

Modelo ER

Em um sistema efetivo, os dados são divididos em categorias ou entidades distintas. Um modelo entidade-relacionamento (ER) é uma ilustração de várias entidades em um negócio e as relações entre elas. Um modelo ER é derivado de especificações empresariais ou narrativas e construído durante a fase de análise do ciclo de vida do desenvolvimento de sistemas. Modelos ER separam as informações necessárias por um negócio a partir das atividades executadas dentro deste. Embora as empresas possam mudar suas atividades, o tipo de informação tende a permanecer constante. Portanto, as estruturas de dados também tendem a ser constantes.

Benefícios do Modelo ER

Informação de documentos para a organização em um formato claro, preciso Provê um quadro claro do escopo de exigência de informação Provê um mapa facilitador para o design do banco de dados

Componentes Chaves

Entidade: algo que possui significado sobre o qual informações precisam ser conhecidas. Exemplos: departamentos, empregados e pedidos.

Atributo: descreve ou qualifica uma entidade. Por exemplo, para a entidade de empregado, os atributos seriam o número de empregado, nome, cargo, data de admissão, número do departamento e assim por diante. Cada um dos atributos pode ser requerido ou opcional. Este estado é chamado obrigatoriedade.

Relacionamento: associação nomeada entre entidades mostrando a obrigatoriedade e grau. Exemplos: empregados e departamentos; pedidos e itens.

On Targget Treinamento e Consultoria 8

Page 21: Introdução ao Oracle 8i

Funções Básicas

Convenções do Modelo Entidade-Relacionamento

Entidades

Para representar uma entidade em um modelo, utilize as seguintes convenções:

Caixa com qualquer dimensão. Nome da entidade no singular, único e em maiúsculo. Sinônimo opcional em maiúsculo dentro de parênteses: ().

Atributos

Símbolo DescriçãoLinha pontilhada Elemento opcional indicando “pode ser”Linha sólida Elemento obrigatório indicando “deve ser”Pé de “galinha” Elemento de grau indicando “um ou mais”Linha simples Elemento de grau indicando “um e somente um”

Para representar um atributo em um modelo, siga as seguintes convenções:

Utilize nomes no singular em minúsculo. Marque atributos obrigatórios, ou valores que devem ser conhecidos, com um asterisco: * Marque atributos opcionais, ou valores que podem ser conhecidos, com a letra o

Relacionamentos

Cada lado da relação contém:

Um nome. Por exemplo: ensinado por ou designado para Uma obrigatoriedade: deve ser ou pode ser Um grau: ambos um e somente um ou um dos lados um ou mais

Nota: O termo cardinalidade é um sinônimo para o termo grau.

Cada entidade de origem {pode ser | deve ser} nome da relação {um e somente um | um ou mais} entidade de destino.

On Targget Treinamento e Consultoria 9

Page 22: Introdução ao Oracle 8i

Funções Básicas

Identificadores Únicos

Um identificador único (UID) é qualquer combinação de atributos ou relações, ou ambos, que servem para distinguir ocorrências distintas de uma mesma entidade. Cada ocorrência da entidade deve ser exclusivamente identificada.

Marque cada atributo que é parte do UID com o símbolo: # Marque UIDs secundários com o símbolo entre parênteses: (#)

On Targget Treinamento e Consultoria 10

Page 23: Introdução ao Oracle 8i

Funções Básicas

Terminologia Utilizada em Bancos de Dados Relacionais

Um banco de dados relacional pode conter uma ou muitas tabelas. Uma tabela é uma estrutura básica de armazenamento em um RDBMS. Uma tabela armazena todos os dados necessários sobre algo no mundo real, por exemplo: empregados, faturas ou clientes.

A figura acima mostra o conteúdo da tabela ou relação EMP. Os números indicam o seguinte:

1. linha ou tupla representando todos os dados necessários para um único empregado. Cada linha de uma tabela deve ser identificada por uma chave primária que não permite linhas duplicadas. A ordem das linhas é insignificante; especifica-se a ordem das linhas quando os dados são recuperados.

2. coluna ou atributo que contém o número de empregado, sendo também a chave primária. Esta coluna identifica cada empregado da tabela EMP. Uma chave primária deve sempre conter um valor.

3. coluna que não é um valor chave. Uma coluna representa um tipo de dado em uma tabela; no exemplo, o cargo de todos os empregados. A ordem das colunas é insignificante quando armazenando dados; especifica-se a ordem das colunas quando os dados são recuperados.

4. coluna que contém o número do departamento, sendo também uma chave estrangeira. Uma chave estrangeira é uma coluna que define como uma tabela se relaciona com outra. Uma chave estrangeira se referencia a uma chave primária ou uma chave única em outra tabela. No exemplo, DEPTNO identifica um único departamento da tabela DEPT.

5. um campo pode ser encontrado na interseção de uma linha com uma coluna. Somente um valor poderá existir nesta interseção.

6. um campo pode não ter nenhum valor. Isto é chamado de valor nulo. Na tabela EMP, somente os empregados com o cargo de vendedor possuem valor no campo COMM (comissão).

Nota: Valores nulos serão discutidos mais adiante em capítulos subseqüentes.

On Targget Treinamento e Consultoria 11

Page 24: Introdução ao Oracle 8i

Funções Básicas

Relacionando Múltiplas Tabelas

Cada tabela contém dados que descrevem exatamente uma entidade. Por exemplo, a tabela EMP contém informações sobre empregados.

Devido aos dados de diferentes entidades serem armazenados em diferentes tabelas, pode ser necessário combinar duas ou mais tabelas para responder uma questão específica. Por exemplo, pode-se querer saber a localização do departamento onde um empregado trabalha. Neste caso, você precisa de informações da tabela EMP (que contém os dados sobre os empregados) e da tabela DEPT (que contém informações sobre os departamentos). Um RDBMS permite relacionar os dados em uma tabela com os dados contidos em outra utilizando-se as chaves estrangeiras. Uma chave estrangeira é uma coluna ou um conjunto de colunas que se referem a uma chave primária da mesma tabela ou de outra.

A facilidade para relacionar dados em uma tabela com dados em outra tabela permite a organização das informações em unidades separadas. Os dados de empregados podem ser mantidos logicamente distintos de dados de departamentos armazenando-os em tabelas separadas.

Diretrizes para Chaves Primárias e Chaves Estrangeiras

Nenhum valor duplicado é permitido em uma chave primária. Geralmente, chaves primárias não podem ser alteradas. Chaves estrangeiras estão baseadas em valores de dados e são puramente lógicas, não

sendo físicas ou ponteiros. Um valor de chave estrangeira tem que existir como um valor de chave primária ou chave

única, ou então ser NULO.

On Targget Treinamento e Consultoria 12

Page 25: Introdução ao Oracle 8i

Funções Básicas

Propriedades de um Banco de Dados Relacional

Em um banco de dados relacional, você não especifica o caminho de acesso para as tabelas, e também não necessita saber como os dados estão organizados fisicamente.

Para acessar o banco de dados, você executa comandos SQL (structured query language), que é a linguagem padrão para operação sobre bancos de dados relacionais, definida pelo American National Standards Institute (ANSI). Esta linguagem possui um grande conjunto de operadores para dividir e combinar as relações. O banco de dados pode ser modificado utilizando-se comandos SQL.

On Targget Treinamento e Consultoria 13

Page 26: Introdução ao Oracle 8i

Funções Básicas

Comunicando com um RDBMS utilizando SQL

Structured Query Language

A linguagem SQL lhe permite comunicar com o servidor e possui as seguintes vantagens:

Eficiência. Fácil de aprender e utilizar. Completa funcionalidade. A linguagem SQL permite definir, recuperar, e manipular dados

em tabelas.

On Targget Treinamento e Consultoria 14

Page 27: Introdução ao Oracle 8i

Funções Básicas

Sistema de Gerenciamento de Banco de Dados Relacional

A Oracle fornece um RDBMS flexível chamado Oracle8i. Suas características o permitem armazenar e administrar dados com todas as vantagens da estrutura relacional mais as vantagens do PL/SQL, uma ferramenta que lhe proporciona a capacidade para armazenar e executar unidades de programas. O Servidor oferece para os usuários opções para recuperar os dados baseado em técnicas de otimização. Inclui características de segurança que controlam como o banco de dados é acessado e utilizado. Outra característica é a consistência e a proteção dos dados através de mecanismos de bloqueio (lock).

As aplicações Oracle podem rodar no mesmo computador onde encontra-se o Servidor Oracle. Entretanto, você pode rodar as aplicações em um sistema local para o usuário e pode rodar o Servidor Oracle em um outro sistema (arquitetura cliente-servidor). Neste ambiente cliente-servidor, pode ser utilizado um grande número de recursos de computação. Por exemplo, uma aplicação de reserva de linhas aéreas pode rodar em um computador pessoal cliente ao mesmo tempo em que obtém acesso aos dados de vôos que são administrados convenientemente por um Servidor Oracle em um computador central.

On Targget Treinamento e Consultoria 15

Page 28: Introdução ao Oracle 8i

Funções Básicas

Oracle8i: Sistema de Gerenciamento de Banco de Dados Objeto Relacional

Oracle8i

Primeiro banco de dados de objeto desenvolvido pela Oracle. Estende as capacidades do modelo de dados do Oracle7 para suportar o novo modelo objeto relacional. O Oracle8i provêem uma nova força que traz a programação orientada a objeto, tipos de dados complexos, objetos de negócio complexos, e total compatibilidade com o mundo relacional.

Oracle8i implementa as características do Oracle7 de várias formas. Inclui novas técnicas para melhorar o desempenho e a funcionalidade do processo transacional online (OLTP) em aplicações, como um melhor compartilhamento das estruturas de dados em tempo de execução, buffer caches maiores, e constraints do tipo deferrable. Aplicações de data warehouse podem beneficiar-se de melhoramentos na execução paralela de operações de inserção, atualização, e deleção; particionamento; e otimização de consultas em paralelo. Operando dentro do conceito NCA (Network Computing Architecture), o Oracle8i suporta aplicações cliente-servidor e baseadas na web.

Oracle8i suporta milhares de usuários simultâneos, até 512 petabytes, e pode administrar qualquer tipo de dado, incluindo textos, espaciais, imagens, som, vídeo, além de dados estruturados tradicionais.

On Targget Treinamento e Consultoria 16

Page 29: Introdução ao Oracle 8i

Funções Básicas

Definição de Objeto

Objetos

Um objeto é freqüentemente considerado uma representação de alguma coisa do mundo real. Um objeto de empregado pode calcular suas deduções de folha de pagamento e um objeto de pedido pode efetuar seu transporte.

A seguir apresentam-se algumas definições de objetos:

“Um objeto é um "pacote" de software que contém um conjunto de procedimentos relacionados (métodos) e dados (variáveis).” David Taylor

“Um objeto é um conceito, abstração, ou coisa com limites definidos e significado à mão para o problema.” James Rumbaugh

On Targget Treinamento e Consultoria 17

Page 30: Introdução ao Oracle 8i

Funções Básicas

Utilizando um Modelo de Objeto

Modelos de Objeto

A tecnologia de objeto foi projetada para modelar problemas empresariais. O modelo é declarado no nível das interações entre os objetos.

Trabalhando com objetos, os desenvolvedores pensam mais em termos de necessidades da aplicação e menos na arquitetura dos sistemas operacionais e nas exigências do ambiente de desenvolvimento.

On Targget Treinamento e Consultoria 18

Page 31: Introdução ao Oracle 8i

Funções Básicas

Características de Sistemas de Objeto

Sistemas de objeto diferem de sistemas convencionais uma vez que possuem as seguintes características:

Representam a informação como coisas auto-suficientes (objetos). Classificam objetos em tipos de objeto e os organizam em hierarquias tipo treelike onde

um tipo de objeto pode ser um tipo especial de outro tipo de objeto (identificando metadado de tipo de objeto).

Objetos podem herdar as características dos seus tipos de objeto (herança). Escondem dados e processos relacionados a cada objeto dentro do próprio objeto

(encapsulamento). Isto permite mudanças em componentes específicos sem afetar outros componentes.

Conexão com outros objetos. Reconhecem diferentes tipos de coisas e o comportamento esperado delas sem ter que

analizá-las. Utiliza a mesma requisição para invocar implementações diferentes da mesma ação para

dois objetos diferentes (polimorfismo).

On Targget Treinamento e Consultoria 19

Page 32: Introdução ao Oracle 8i

Funções Básicas

Solução Completa Oracle

O principal produto da Oracle é o seu sistema de gerenciamento de banco de dados relacional, incluindo o Servidor Oracle e várias ferramentas com o objetivo de auxiliar os usuários na manutenção, monitoramento, e uso dos dados. O dicionário de dados Oracle é um dos componentes mais importantes do Servidor. Consiste em um conjunto de tabelas e visões que provêem uma referência somente de leitura para o banco de dados.

O RDBMS administra tarefas como as seguintes:

Administração do armazenamento e definição dos dados Controla e restringe o acesso aos dados e a concorrência Provê procedimentos de cópia e restauração dos dados Interpreta comandos SQL e PL/SQLNota: PL/SQL é uma linguagem procedural desenvolvida pela Oracle que estende as

definições do SQL adicionando-lhe lógica de aplicação.

Comandos SQL e PL/SQL são utilizados por todos os programas e usuários para acessar e manipular dados armazenados no banco de dados Oracle. Utilizando programas aplicativos você freqüentemente pode ter acesso ao banco de dados sem utilizar SQL ou PL/SQL diretamente, porque você pode apertar um botão ou selecionar um check box, por exemplo, mas os aplicativos implicitamente utilizam SQL ou PL/SQL para executar sua solicitação.

SQL*Plus é uma ferramenta Oracle que reconhece e envia comandos SQL e PL/SQL para serem executados no servidor e possui sua própria linguagem de comandos.

A Oracle oferece uma enorme variedade de interfaces gráficas de usuário (GUI) em ferramentas voltadas para a construção de aplicações empresariais como também um grande conjunto de softwares aplicativos para muitas áreas de negócio e indústrias.

Nota: Maiores informações sobre o dicionário de dados da Oracle serão vistas em capítulos posteriores.

On Targget Treinamento e Consultoria 20

Page 33: Introdução ao Oracle 8i

Funções Básicas

Comandos SQL

O SQL Oracle segue os padrões aceitos pela indústria. A Oracle assegura compatibilidade futura com a evolução destes padrões adicionando chaves próprias ao SQL definido pelos comitês. Comitês aceitos pela indústria são o Instituto de Padrões Americano (ANSI) e a Organização de Padrões Internacional (ISO). ANSI e ISO adotaram o SQL como a linguagem padrão para bancos de dados relacionais.

Comando DescriçãoSELECT Recupera dados a partir do banco de dadosINSERTUPDATEDELETE

Respectivamente insere novas linhas, modifica registros existentes e remove linhas não desejadas a partir de tabelas do banco de dados. Coletivamente conhecidos como linguagem de manipulação de dados – DML (data manipulation language)

CREATEALTERDROPRENAMETRUNCATE

Cria, modifica e remove estruturas de dados a partir de tabelas. Coletivamente conhecidos como linguagem de definição de dados – DDL (data definition language)

COMMITROLLBACKSAVEPOINT

Administra as mudanças efetuadas por comandos DML. As alterações nos dados podem ser agrupadas em transações lógicas.

GRANTREVOKE

Fornece ou remove direitos de acesso ao banco de dados e as estruturas nele definidas. Coletivamente conhecidos como linguagem de controle de dados – DCL (data control language)

On Targget Treinamento e Consultoria 21

Page 34: Introdução ao Oracle 8i

Funções Básicas

PL/SQL

PL/SQL é uma linguagem procedural desenvolvida pela Oracle que estende as funcionalidades do SQL, linguagem padrão para acesso aos banco de dados objeto-relacionais. PL/SQL oferece uma engenharia de software moderna que cria características como encapsulamento de dados, tratamento de exceções, ocultamento de informação e orientação à objetos.

PL/SQL incorpora muitas das características avançadas desenvolvidas nas linguagens de programação projetadas durante o período de 1970 à 1980. Permite a inclusão de comandos SQL de manipulação de dados e pesquisa em blocos estruturados e unidades procedurais de código, tornando o PL/SQL uma poderosa linguagem de processamento transacional. Com PL/SQL, você pode usar comandos SQL para recuperar dados do Oracle e comandos de controle PL/SQL para processar os dados.

On Targget Treinamento e Consultoria 22

Page 35: Introdução ao Oracle 8i

Funções Básicas

Ambiente PL/SQL

PL/SQL Engine e o Servidor Oracle

PL/SQL não é um produto isolado da Oracle. É uma tecnologia empregada pelo Servidor Oracle e por certas ferramentas da Oracle. Blocos de PL/SQL são passados para o PL/SQL Engine onde são processados, que pode residir dentro da ferramenta ou dentro do Servidor Oracle. O executor (engine) utilizado depende de onde o bloco PL/SQL foi invocado.

Quando você submete blocos PL/SQL a partir de um Pro* program, user-exit, SQL*Plus ou Server Manager, o PL/SQL Engine do Servidor Oracle é quem executa o processamento. Ele divide as declarações SQL dentro do bloco em comandos separados e os envia ao SQL Statement Executor. Isto significa que uma única transferência é necessária para enviar o bloco a partir da aplicação para o Servidor Oracle, melhorando a desempenho, especialmente em uma rede cliente-servidor. Programas armazenados dentro do banco de dados (stored procedures) podem ser referenciados por qualquer aplicação conectada ao Servidor Oracle.

On Targget Treinamento e Consultoria 23

Page 36: Introdução ao Oracle 8i

Funções Básicas

Benefícios do PL/SQL

Integração

PL/SQL representa um papel central tanto para o Servidor Oracle (através de stored procedures, stored functions, database triggers e packages) como para as ferramentas de desenvolvimento Oracle (através dos componentes de triggers do Developer/2000).

Aplicações desenvolvidas com Developer/2000 podem fazer uso de bibliotecas compartilhadas que armazenam código (procedures e funções) e podem ser acessadas localmente ou remotamente. As ferramentas que compoem o Developer/2000 são o Oracle Forms, Oracle Reports e Oracle Graphics.

Tipo de dados SQL também podem ser utilizados em PL/SQL. Combinado com o acesso direto que o SQL provê, estes tipos de dados compartilhados integram o PL/SQL com o dicionário de dados do Servidor Oracle. O PL/SQL preenche a lacuna entre o acesso conveniente para tecnologia de banco de dados e a necessidade de características de programação procedural.

PL/SQL em Ferramentas Oracle

Muitas ferramentas Oracle, incluindo o Developer/2000, possuem seu próprio PL/SQL Engine, que é independente do PL/SQL Engine presente no Servidor Oracle.

O engine filtra os comandos SQL e os envia individualmente para o SQL Statement Executor do Servidor Oracle, processando os comandos procedurais restantes no Procedural Statement Executor, que está dentro do PL/SQL Engine.

O Procedural Statement Executor processa os dados que são locais à aplicação (o que já está dentro do ambiente do cliente, em lugar do banco de dados). Isto reduz o trabalho enviado ao Servidor Oracle e o número de cursores de memória necessários.

On Targget Treinamento e Consultoria 24

Page 37: Introdução ao Oracle 8i

Funções Básicas

Melhor Desempenho

PL/SQL pode melhorar o desempenho de uma aplicação. Os benefícios diferem dependendo do ambiente de execução.

PL/SQL pode ser usado para agrupar comandos SQL dentro de um único bloco enviando-o ao servidor em uma única chamada, reduzindo-se de forma considerável o tráfico de rede. Sem PL/SQL, os comandos SQL seriam processadas um de cada vez. Cada comando SQL resultaria em outra chamada ao Servidor Oracle e aumento do tráfego da rede. Em um ambiente de rede, o tráfego pode tornar-se significativo. Como a figura ilustra, se sua aplicação utiliza SQL de forma intensiva, você pode utilizar blocos PL/SQL e sub-programas para agrupar comandos SQL antes de enviá-los ao Servidor Oracle para execução.

PL/SQL também pode cooperar com Servidor Oracle em ferramentas para o desenvolvimento de aplicações como o Developer/2000 Forms e Reports. Somando poder de processamento procedural para estas ferramentas, o PL/SQL impulsiona o melhoramento do desempenho.

Nota: Procedures e funções declaradas como parte de uma aplicação Developer/2000 são distintas das armazenadas no banco de dados, embora a estrutura geral delas seja a mesma. Stored procedures e funções são objetos do banco de dados é são armazenados no Dicionário de Dados. Eles podem ser acessados por qualquer aplicação, incluindo aplicações desenvolvidas com o Developer/2000.

Estrutura dos Blocos PL/SQL

Toda unidade de PL/SQL inclui um ou mais blocos. Estes blocos podem ser completamente separados ou aninhados um dentro do outro. As unidades básicas (procedures, funções e blocos anônimos) compõe um programa PL/SQL e formam bloco lógicos, que podem conter vários sub-blocos aninhados. Portanto, um bloco pode representar uma pequena parte de outro bloco, que por sua vez pode ser parte de uma unidade inteira de código.

On Targget Treinamento e Consultoria 25

Page 38: Introdução ao Oracle 8i

Funções Básicas

Construção de Programas PL/SQL

A figura acima mostra uma variedade de diferentes tipos de construções PL/SQL que utilizam blocos PL/SQL básicos. Eles estão disponíveis dependendo do ambiente onde forem executados.

Modularização do Desenvolvimento de Programas

Agrupe logicamente comandos relacionados dentro de blocos. Aninhe sub-blocos dentro de blocos maiores para construir programas poderosos. Resolva um problema complexo com um conjunto de módulos lógicos bem definido e

implemente os módulos com blocos. Coloque códigos PL/SQL reutilizáveis em bibliotecas compartilhadas entre as aplicações

desenvolvidas com as ferramentas do Developer/2000 ou então armazene-os em um Servidor Oracle para torná-los acessíveis para qualquer aplicação que possa interagir com um banco de dados Oracle.

Portabilidade

Devido ao fato de o PL/SQL ser nativo ao Servidor Oracle, você pode mover programas para qualquer ambiente servidor (sistema operacional ou plataforma) que suporte o Servidor Oracle e PL/SQL. Em outras palavras, programas PL/SQL podem ser executados em qualquer lugar onde o Servidor Oracle estiver rodando; você não precisa efetuar modificações para cada ambiente novo.

Você também pode mover código entre o Servidor Oracle e sua aplicação. Você pode escrever pacotes de programas portáveis e pode criar bibliotecas que podem ser reutilizadas em ambientes diferentes.

Declaração de Identificadores

Declare variáveis, cursores, constantes e exceções e os utilize em comandos SQL e procedurais.

Declare variáveis com tipos de dados escalares, de referência, compostos, e de objetos grandes (LOB).

Declare variáveis dinamicamente baseadas nas estruturas de dados de tabelas e colunas do banco de dados.

On Targget Treinamento e Consultoria 26

Page 39: Introdução ao Oracle 8i

Funções Básicas

Programe com Estruturas de Controle de Linguagem Procedural

Execute uma seqüência de comandos condicionalmente. Execute uma seqüência de comandos interativamente em um loop. Processe as linhas de uma consulta individualmente através do uso de cursores explícitos.

Tratamento de Erros

Processe erros do Servidor Oracle com rotinas de tratamento de exceções. Declare condições de erro definidas pelo usuário e processe-as também com rotinas de

tratamento de exceções.

On Targget Treinamento e Consultoria 27

Page 40: Introdução ao Oracle 8i

Funções Básicas

Tabelas Utilizadas no Curso

Serão usadas três tabelas principais neste curso. Estas são:

Tabela EMP, com informações sobre empregados Tabela DEPT, com informações sobre departamentos Tabela SALGRADE, com informações de salários para vários graus A estrutura e dados para todas as tabelas estão apresentadas no Apêndice B.

On Targget Treinamento e Consultoria 28

Page 41: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

2.2. Executando Comandos SQLExecutando Comandos SQL BásicosBásicos

On Targget Treinamento e Consultoria

Page 42: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Listar as características do comando SQL SELECT Executar um comando SELECT básico Diferenciar comandos SQL de comandos SQL*Plus

Para extrair dados a partir de um banco de dados você precisa utilizar o comando SQL (structured query language) SELECT. Você pode precisar restringir as colunas que serão exibidas. Este capítulo descreve todos os comandos SQL que você precisa para executar estas ações. Este capítulo também cobre o uso de comandos SQL*Plus para executar comandos SQL.

On Targget Treinamento e Consultoria 2

Page 43: Introdução ao Oracle 8i

Funções Básicas

Características do Comando SQL SELECT

Um comando SELECT recupera informações a partir do banco de dados. Usando um comando SELECT você pode fazer o seguinte:

Seleção: Você pode usar a capacidade de seleção em SQL para escolher as linhas de uma tabela que você deseja recuperar através de uma consulta. Você pode usar vários critérios para seletivamente restrinjir as linhas que serão visualizadas.

Projeção: Você pode usar a capacidade de projeção em SQL para escolher as colunas de uma tabela que você deseja recuperar através de uma consulta. Você pode escolher algumas ou todas as colunas de uma tabela, de acordo com sua necessidade.

Join: Você pode usar a capacidade de join em SQL para reunir dados que estão armazenados em tabelas diferentes, criando um vínculo através de colunas que ambas as tabelas compartilhem. Você aprenderá mais sobre joins em um capítulo posterior.

On Targget Treinamento e Consultoria 3

Page 44: Introdução ao Oracle 8i

Funções Básicas

Comando SELECT Básico

Em sua forma mais simples, um comando SELECT deve incluir o seguinte:

Uma cláusula SELECT que especifica as colunas a serem exibidas. Um cláusula FROM que especifica as tabelas que possuem as colunas listadas na cláusula

SELECT.

Na sintaxe:

SELECT é uma lista de uma ou mais colunas.

DISTINCT suprime duplicidades.

* seleciona todas as colunas.

column seleciona a coluna nomeada.

alias fornece para as colunas selecionadas títulos diferentes.

FROM table especifica a tabela que contém as colunas.

On Targget Treinamento e Consultoria 4

SELECT [DISTINCT] {*, column [alias],...}FROM table;

Page 45: Introdução ao Oracle 8i

Funções Básicas

Escrevendo Comandos SQL

Seguindo regras simples e as diretrizes apresentadas abaixo, você pode construir comandos válidos que são tanto fáceis de ler quanto de editar:

Comandos SQL não fazem distinção entre maiúsculas e minúsculas, a menos que especificado.

Podem ser escritos em uma ou mais linhas. Palavras chaves (keywords) não podem ser divididas em mais de uma linha ou abreviadas. As diferentes cláusulas são normalmente separadas em linhas distintas para facilitar a

visualização e edição do comando. Tabulações e identações podem ser utilizadas para tornar o código mais legível. Palavras chaves normalmente são escritas em maiúsculo, enquanto que as outras palavras,

como nomes de tabelas e colunas, são escritas em minúsculo. Dentro do SQL*Plus, um comando SQL é escrito no prompt de SQL, e as linhas

subseqüentes são numeradas. Isto é chamado de SQL buffer. Somente um comando pode estar no buffer de cada vez.

Executando Comandos SQL

Coloque um ponto-e-vírgula (;) ao término da última cláusula. Coloque uma barra (/) na última linha do buffer. Coloque uma barra (/) no prompt de SQL. Execute o comando RUN do SQL*Plus no prompt de SQL.

On Targget Treinamento e Consultoria 5

Page 46: Introdução ao Oracle 8i

Funções Básicas

Selecionando todas as Colunas

Selecionando todas as Colunas e todas as Linhas

Você pode exibir todas as colunas de dados de uma tabela colocando um asterisco (*) logo após a palavra chave SELECT. No exemplo acima, a tabela de departamentos possui três colunas: DEPTNO, DNAME e LOC. A tabela possui quatro linhas, uma para cada departamento.

Você também pode exibir todas as colunas da tabela listando-as depois da palavra chave SELECT. Por exemplo, o seguinte comando SQL, como no exemplo acima, também exibe todas as colunas e todas as linhas da tabela DEPT:

On Targget Treinamento e Consultoria 6

SQL> SELECT * 2 FROM dept; DEPTNO DNAME LOC--------- -------------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON

SQL> SELECT deptno, dname, loc 2 FROM dept;

Page 47: Introdução ao Oracle 8i

Funções Básicas

Selecionando Colunas Específicas

Selecionando Colunas Específicas e todas as Linhas

Você pode usar o comando SELECT para exibir colunas específicas da tabela especificando os nomes das colunas, separados por vírgulas. O exemplo acima exibe todos os números e localizações de departamentos a partir da tabela DEPT.

Na cláusula SELECT, especifique as colunas que você quer ver, na ordem na qual você quer que elas sejam mostradas. Por exemplo, para exibir a localização antes do número do departamento, você utiliza o seguinte comando:

On Targget Treinamento e Consultoria 7

SQL> SELECT deptno, loc 2 FROM dept; DEPTNO LOC--------- ------------- 10 NEW YORK 20 DALLAS 30 CHICAGO 40 BOSTON

SQL> SELECT loc, deptno 2 FROM dept;LOC DEPTNO ------------- ---------NEW YORK 10DALLAS 20CHICAGO 30BOSTON 40

Page 48: Introdução ao Oracle 8i

Funções Básicas

Padrões de Cabeçalho de Colunas

Cabeçalhos e dados de colunas tipo caractere bem como cabeçalhos e dados de colunas tipo data são alinhados à esquerda dentro do tamanho da coluna. Cabeçalhos e dados de colunas numéricas são alinhados à direita.

Cabeçalhos de colunas tipo caracter e data podem ser truncados, enquanto cabeçalhos de colunas numéricas não podem ser truncados. Normalmente os cabeçalhos de coluna aparecem em maiúsculas. Você pode substituir os cabeçalhos de colunas por um alias. Alias de colunas serão vistos posteriormente neste capítulo.

On Targget Treinamento e Consultoria 8

SQL> SELECT ename, hiredate, sal 2 FROM emp;ENAME HIREDATE SAL---------- --------- ---------KING 17-NOV-81 5000BLAKE 01-MAY-81 2850CLARK 09-JUN-81 2450JONES 02-APR-81 2975MARTIN 28-SEP-81 1250ALLEN 20-FEB-81 1600...14 rows selected.

Page 49: Introdução ao Oracle 8i

Funções Básicas

Expressões Aritméticas

Você pode precisar modificar a forma como os dados são exibidos, por exemplo, executando cálculos. Isto é possível através do uso de expressões aritméticas. Uma expressão aritmética pode conter nomes de colunas, valores numéricos constantes, e os operadores aritméticos.

Operadores Aritméticos

A figura acima mostra os operadores aritméticos disponíveis em SQL. Você pode usar os operadores aritméticos em qualquer cláusula de um comando SQL, exceto a cláusula FROM.

On Targget Treinamento e Consultoria 9

Page 50: Introdução ao Oracle 8i

Funções Básicas

Utilizando Operadores Aritméticos

O exemplo acima utiliza o operador de adição para calcular um aumento de salário de $300 para todos os empregados e mostrar uma nova coluna SAL+300 na tela.

Note que a coluna resultante SAL+300 não é uma nova coluna da tabela EMP; sendo utilizada somente na exibição. Por default, o nome da coluna nova é obtido a partir da expressão de cálculo que a gerou, neste caso, SAL + 300.

Nota: O SQL*Plus ignora espaços em branco antes e depois do operador aritmético.

On Targget Treinamento e Consultoria 10

SQL> SELECT ename, sal, sal+300 2 FROM emp;ENAME SAL SAL+300---------- --------- ---------KING 5000 5300BLAKE 2850 3150CLARK 2450 2750JONES 2975 3275MARTIN 1250 1550ALLEN 1600 1900...14 rows selected.

Page 51: Introdução ao Oracle 8i

Funções Básicas

Precedência dos Operadores

Se uma expressão aritmética possui mais de um operador, os de multiplicação e divisão são avaliados primeiro. Se os operadores dentro de uma expressão são da mesma prioridade, então a avaliação é feita da esquerda para direita.

Você pode usar parênteses para forçar a expressão colocada dentro deles a ser avaliada primeiro.

O exemplo acima exibe o nome, salário e a compensação anual dos empregados. Ele calcula a compensação anual multiplicando o salário mensal por 12, mais uma gratificação única de $100. Observe que a multiplicação é executada antes da adição.

Nota: Use parênteses para reforçar a ordem padrão de precedência e melhorar a clareza do comando. Por exemplo, a expressão acima poderia ser escrita desta forma, sem mudança no resultado: (12*sal)+100.

On Targget Treinamento e Consultoria 11

SQL> SELECT ename, sal, 12*sal+100 2 FROM emp;ENAME SAL 12*SAL+100---------- --------- ----------KING 5000 60100BLAKE 2850 34300CLARK 2450 29500JONES 2975 35800MARTIN 1250 15100ALLEN 1600 19300...14 rows selected.

Page 52: Introdução ao Oracle 8i

Funções Básicas

Utilizando Parênteses

Você pode alterar as regras de precedência usando parênteses para especificar a ordem na qual devem ser executados os operadores.

O exemplo acima exibe o nome, salário, e a compensação anual dos empregados. Ele calcula a compensação anual somando o salário mensal com uma gratificação mensal de $100, multiplicando o resultado por 12. Devido ao uso dos parênteses, a adição recebe prioridade sobre a multiplicação.

On Targget Treinamento e Consultoria 12

SQL> SELECT ename, sal, 12*(sal+100) 2 FROM emp;ENAME SAL 12*(SAL+100)---------- --------- -----------KING 5000 61200BLAKE 2850 35400CLARK 2450 30600JONES 2975 36900MARTIN 1250 16200...14 rows selected.

Page 53: Introdução ao Oracle 8i

Funções Básicas

Definindo um Valor Nulo

Valores nulos (null values)

Se uma linha não possui valor para uma coluna específica é dito que o valor para esta coluna é nulo, ou que ela contém nulo.

Um valor nulo é um valor que é indisponível, não atribuído, desconhecido, ou inaplicável. Um valor nulo não é o mesmo que zero ou um espaço. Zero é um número, e um espaço é um caractere.

Colunas de qualquer tipo de dado podem conter valores nulos, a menos que a coluna tenha sido definida como NOT NULL ou como PRIMARY KEY (chave primária) quando criada.

Na coluna COMM da tabela EMP, você pode observar que somente um vendedor (SALESMAN) pode ganhar comissão. Outros empregados não devem ganhar comissão. Um valor nulo representa o fato. Turner, que é um vendedor, não ganha nenhuma comissão. Observe que a comissão dele é zero e não nula.

On Targget Treinamento e Consultoria 13

SQL> SELECT ename, job, comm 2 FROM emp;ENAME JOB COMM---------- --------- ---------KING PRESIDENTBLAKE MANAGER...TURNER SALESMAN 0...14 rows selected.

Page 54: Introdução ao Oracle 8i

Funções Básicas

Valores Nulos em Expressões Aritméticas

Se o valor de alguma coluna em uma expressão aritmética é nulo, o resultado da expressão também é nulo. Por exemplo, se você tentar executar uma divisão por zero, você obtém um erro. Porém, se você divide um número por nulo, o resultado é nulo ou desconhecido.

No exemplo acima, o empregado KING não é um vendedor (SALESMAN) e não possui nenhuma comissão. Uma vez que a coluna COMM na expressão aritmética é nula, o resultado também é nulo.

On Targget Treinamento e Consultoria 14

SQL> select ename NAME, 12*sal+comm 2 from emp 3 WHERE ename = 'KING';

NAME 12*SAL+COMM ---------- -----------KING

Page 55: Introdução ao Oracle 8i

Funções Básicas

Definindo um Alias de Coluna

Para exibir o resultado de uma consulta, o SQL*Plus normalmente utiliza o nome da coluna selecionada como seu cabeçalho. Em muitos casos, este título pode não ser descritivo e conseqüentemente pode ser difícil de entender. Você pode mudar o cabeçalho de uma coluna utilizando um alias (apelido) de coluna.

Especifique o alias depois da coluna na lista da cláusula SELECT utilizando um espaço como separador. Por default, cabeçalhos baseados em alias aparecem em maiúsculas. Se o alias possui espaços, caracteres especiais (como # ou $), ou deve diferenciar maiúsculas e minúsculas, coloque o alias entre aspas duplas (" ").

On Targget Treinamento e Consultoria 15

Page 56: Introdução ao Oracle 8i

Funções Básicas

Utilizando Alias de Colunas

O primeiro exemplo exibe o nome e o salário mensal de todos os empregados. Observe que a palavra chave opcional AS foi utilizada antes do nome do alias da coluna. O resultado da consulta seria o mesmo se a palavra chave AS fosse utilizada ou não. Observe também que o comando SQL tem os alias de coluna, nome e salário em minúsculas, sendo que o resultado da consulta exibe os cabeçalhos de coluna em maiúsculas. Como mencionado anteriormente, os títulos de coluna aparecem em maiúsculas por default.

O segundo exemplo exibe o nome e salário anual de todos os empregados. Uma vez que o alias "Annual Salary" contém espaços, foi colocado entre aspas duplas. Observe que o cabeçalho da coluna ficou exatamente igual ao seu alias.

On Targget Treinamento e Consultoria 16

SQL> SELECT ename AS name, sal salary 2 FROM emp;NAME SALARY------------- ---------...

SQL> SELECT ename "Name", 2 sal*12 "Annual Salary" 3 FROM emp;

Name Annual Salary------------- -------------...

Page 57: Introdução ao Oracle 8i

Funções Básicas

Operador de Concatenação

Você pode unir colunas com outras colunas, expressões aritméticas ou valores constantes para criar uma expressão de caracteres usando o operador de concatenação (||). Colunas em qualquer lado do operador são combinadas para fazer uma única coluna de saída.

No exemplo, são concatenadas as colunas ENAME e JOB, sendo que o resultado recebe o alias de "Employees". Observe que o nome do empregado e o cargo são combinados obtendo-se uma única coluna de saída.

A palavra chave AS antes do nome do alias torna a cláusula SELECT mais legível.

On Targget Treinamento e Consultoria 17

SQL> SELECT ename||job AS "Employees" 2 FROM emp;mployees-------------------KINGPRESIDENTBLAKEMANAGERCLARKMANAGERJONESMANAGERMARTINSALESMANALLENSALESMAN...14 rows selected.

Page 58: Introdução ao Oracle 8i

Funções Básicas

Strings de Caracteres Literais

Um literal é qualquer caractere, expressão ou número incluídos na lista da cláusula SELECT que não é um nome de coluna ou um alias de coluna. Ele é impresso para cada linha retornada. Podem ser incluídas strings literais de texto no resultado da consulta e podem ser tratadas como uma coluna da lista do SELECT.

Literais do tipo data e caractere devem ser incluídas dentro de aspas simples (' '), enquanto que literais numéricas não necessitam de aspas.

O exemplo acima mostra os nomes e cargos de todos os empregados. A coluna possui o cabeçalho "Employee Details". Observe os espaços entre as aspas simples no comando SELECT. Os espaços melhoram a visualização do resultado.

No exemplo seguinte, o nome e salário de cada empregado é concatenado com um literal para dar mais significado as linhas retornadas.

On Targget Treinamento e Consultoria 18

SQL> SELECT ename || ' ' || 'is a' || ' ' || job 2 AS "Employee Details" 3 FROM emp;

Employee Details-------------------------KING is a PRESIDENTBLAKE is a MANAGERCLARK is a MANAGERJONES is a MANAGERMARTIN is a SALESMAN...14 rows selected.

SQL> SELECT ename ||': '||'1'||' Month salary = '||sal Monthly 2 FROM emp;

MONTHLY---------------------------------------------------------------KING: 1 Month salary = 5000BLAKE: 1 Month salary = 2850CLARK: 1 Month salary = 2450JONES: 1 Month salary = 2975MARTIN: 1 Month salary = 1250ALLEN: 1 Month salary = 1600TURNER: 1 Month salary = 1500...14 rows selected.

Page 59: Introdução ao Oracle 8i

Funções Básicas

Linhas Duplicadas

A menos que você indique o contrário, o SQL*Plus exibe os resultados de uma consulta sem eliminar as linhas duplicadas. O exemplo acima exibe todos os números de departamento a partir da tabela EMP. Observe que os números de departamento são repetidos.

On Targget Treinamento e Consultoria 19

SQL> SELECT deptno 2 FROM emp; DEPTNO

--------- 10 30 10 20...14 rows selected.

Page 60: Introdução ao Oracle 8i

Funções Básicas

Eliminando Linhas Duplicadas

Para eliminar linhas duplicadas do resultado da consulta, inclua a palavra chave DISTINCT imediatamente após a palavra SELECT. No exemplo acima, a tabela EMP na verdade possui quatorze linhas, mas existe somente três departamentos diferentes na tabela.

Você pode especificar múltiplas colunas depois da palavra DISTINCT. O qualificador DISTINCT afeta todas as colunas selecionadas, e o resultado representa uma combinação distinta das colunas.

On Targget Treinamento e Consultoria 20

SQL> SELECT DISTINCT deptno 2 FROM emp;DEPTNO--------- 10 20 30

SQL> SELECT DISTINCT deptno, job 2 FROM emp;DEPTNO JOB------ --------- 10 CLERK 10 MANAGER 10 PRESIDENT 20 ANALYST... 9 rows selected.

Page 61: Introdução ao Oracle 8i

Funções Básicas

Interação entre SQL e SQL*Plus

SQL e SQL*Plus

SQL é uma linguagem de comandos para comunicação com o Servidor Oracle a partir de qualquer ferramenta ou aplicação. O SQL Oracle possui muitas extensões. Quando você entra um comando SQL, este é armazenado em uma área de memória chamada de SQL buffer e permanece lá até que você entre um novo comando.

SQL*Plus é uma ferramenta Oracle que reconhece e submete comandos SQL ao Servidor Oracle para execução e contém sua própria linguagem de comandos.

Características do SQL

Pode ser usado por uma grande variedade de usuários, inclusive por aqueles com pouca ou nenhuma experiência em programação.

É uma linguagem não procedural. Reduz a quantidade de tempo necessária para criar e manter sistemas. É parecido com o idioma Inglês.

Características do SQL*Plus

Aceita a entrada de comandos SQL a partir de arquivos. Possui um editor de linha para modificar comandos SQL. Controles de configurações de ambiente. Formatação do resultado de consultas em relatórios básicos. Acessa banco de dados locais e remotos.

On Targget Treinamento e Consultoria 21

Page 62: Introdução ao Oracle 8i

Funções Básicas

A tabela seguinte compara SQL e SQL*Plus:

SQL SQL*PlusÉ uma linguagem para comunicação com o Servidor Oracle para acessar os dados

Reconhece comandos SQL e os envia ao Servidor

Está baseado no padrão SQL ANSI (American National Standards Institute)

Interface proprietária Oracle para executar comandos SQL

Manipula dados e a definição de tabelas no banco de dados

Não permite a manipulação de valores no banco de dados

São entrados no SQL buffer em uma ou mais linhasSão entrados em uma linha de cada vez; não são armazenados no SQL buffer

Não possui um caractere de continuaçãoPossui um hífen (-) como caractere de continuação se o comando é maior que uma linha

Não pode ser abreviado Pode ser abreviadoUtiliza um caractere de terminação para executar o comando imediatamente

Não requer caracteres de terminação; os comandos são executados imediatamente

Utiliza funções para executar algumas formatações Utiliza comandos para formatar os dados

On Targget Treinamento e Consultoria 22

Page 63: Introdução ao Oracle 8i

Funções Básicas

Visão Geral do SQL*Plus

Conecte ao Servidor Oracle com o SQL*Plus. Descreva a estrutura de tabelas. Edite comandos SQL. Execute SQL a partir do SQL*Plus. Salve comandos SQL para arquivos e adicione comandos SQL para arquivos já existentes. Execute arquivos salvos. Carregue comandos a partir de um arquivo para o buffer para editar.

SQL*Plus

SQL*Plus é um ambiente no qual você pode fazer o seguinte:

Executar comandos SQL para recuperar, modificar, adicionar e remover dados do banco de dados.

Formatar, executar cálculos, armazenar e imprimir o resultado de consultas na forma de relatórios.

Criar arquivos com scripts para armazenar comandos SQL para uso repetitivo no futuro.

Comandos SQL*Plus podem ser divididos nas seguintes categorias principais:

Categoria PropósitoAmbiente Afetam o comportamento geral dos comandos SQL na sessãoFormatação Formatam os resultados das consultasManipulação de Arquivos Salvam, carregam e executam arquivos de scriptExecução Enviam comandos SQL a partir do SQL buffer para o Servidor OracleEdição Modificam comandos SQL no buffer

InteraçãoPermitem criar e passar variáveis para comandos SQL, imprimir valores de variáveis e imprimir mensagens na tela

DiversosExistem vários comandos para conectar ao banco de dados, manipular o ambiente do SQL*Plus e mostrar as definições de colunas

On Targget Treinamento e Consultoria 23

Page 64: Introdução ao Oracle 8i

Funções Básicas

Conectando com o SQL*Plus

A forma como você executa o SQL*Plus depende do tipo de sistema operacional ou ambiente Windows que você está executando.

Para conectar através do ambiente Windows:

1. Clique Start—>Programs—>Oracle—>SQL*Plus.

2. Preencha o nome do usuário, senha e o banco de dados.

Para conectar em um ambiente de linha de comando:

1. Conecte com sua máquina.

2. Entre o comando SQL*Plus como mostrado na figura acima.

No comando:

username é o nome do seu usuário no banco de dados.

password é sua senha no banco de dados; se você colocar sua senha na linha de comando, ela estará visível.

@database é a string de conexão para o banco de dados.

Nota: Para assegurar a integridade de sua senha, não coloque-a no prompt do sistema operacional. Ao contrário, coloque apenas seu nome de usuário. Entre com sua senha somente no prompt de senha do SQL*Plus.

Quando você tiver conectado com o SQL*Plus, você verá a seguinte mensagem:

On Targget Treinamento e Consultoria 24

SQL*Plus: Release 8.1.5.0.0 - Production on Ter Nov 23 20:49:53 1999

(c) Copyright 1999 Oracle Corporation. All rights reserved.

Page 65: Introdução ao Oracle 8i

Funções Básicas

Exibindo a Estrutura de Tabelas

No SQL*Plus, você pode exibir a estrutura de uma tabela utilizando o comando DESCRIBE. O resultado do comando é uma lista com os nomes de colunas e seus tipos de dados, bem como se a coluna é origatória ou não.

Na sintaxe:

tablename é o nome de qualquer tabela existente, visão, ou sinônimo acessível ao usuário.

O exemplo acima exibe informações sobre a estrutura da tabela DEPT.

No resultado:

Null? indica quando uma coluna deve conter dados; NOT NULL indica que a coluna é obrigatória.

Type mostra o tipo de dado da coluna.

Os tipos de dados estão descritos na tabela seguinte:

Tipo de Dado Descrição

NUMBER(p,s)Valor numérico contendo um número de máximo de dígitos definido por <p>, sendo o número de dígitos à direita do ponto decimal definido por <s>

VARCHAR2(s)valor caractere com tamanho variável e máximo definido por <s>

DATEvalor de data e hora entre 1 de Janeiro de 4712 A.C. e 31 de dezembro de 9999 D.C.

CHAR(s)valor caractere de tamanho fixo e máximo de definido por <s>

On Targget Treinamento e Consultoria 25

DESC[RIBE] tablenameSQL> DESCRIBE deptName Null? Type----------------- -------- ------------DEPTNO NOT NULL NUMBER(2)DNAME VARCHAR2(14)LOC VARCHAR2(13)

Page 66: Introdução ao Oracle 8i

Funções Básicas

Comandos de Edição do SQL*Plus

Comandos SQL*Plus são inseridos uma linha de cada vez e não são armazenados no SQL buffer:

Comando DescriçãoA[PPEND] text Adiciona o texto (text) no final da linha correnteC[HANGE] / old / new Modifica o texto (old) para o novo (new) na linha correnteC[HANGE] / text / Remove o texto (text) da linha correnteCL[EAR] BUFF[ER] Remove todas as linhas do SQL bufferDEL Remove a linha correnteI[NPU T] Insere um número indefinido de linhasI[NPUT] text Insere uma linha com o texto (text)L[IST] Lista todas as linhas do SQL bufferL[IST] n Lista uma linha (especificada por n)L[IST] m n Lista um intervalo de linhas (de m até n)R[UN] Exibe e executa o comando SQL corrente no buffern Especifica qual linha deve tornar-se a correnten text Substitui a linha (n) com o texto (text)0 text Insere uma linha antes da linha 1

On Targget Treinamento e Consultoria 26

Page 67: Introdução ao Oracle 8i

Funções Básicas

Comandos de Arquivo do SQL*Plus

Comandos SQL comunicam com o Servidor Oracle. Comandos SQL*Plus controlam o ambiente, formatam o resultado das consultas e gerenciam arquivos. Você pode utilizar os comandos identificados na tabela seguinte:

Comando Descrição

SAV[E] filename[.ext] [REPLACE | APPEND]

Salva o conteúdo atual do SQL buffer para um arquivo. Utilize a cláusula APPEND para adicionar ao arquivo existente; utilize a cláusula REPLACE para sobrescrever o arquivo existente. A extensão default é .sql.

GET filename[.ext]Escreve o conteúdo de um arquivo previamente salvo para o SQL buffer. A extensão default para o arquivo é .sql.

STA[RT] filename[.ext] Executa um arquivo de comandos previamente salvo.@filename Executa um arquivo de comandos previamente salvo.

ED[IT]Invoca o editor e salva o conteúdo do buffer para um arquivo chamado afiedt.buf.

ED[IT] [filename[.ext]] Invoca o editor para editar o conteúdo de um arquivo salvo.

SPO[OL] [filename[.ext] | OFF | OUT]

Armazena o resultado de consultas em um arquivo. OFF fecha o arquivo de spool. OUT fecha o arquivo de spool enviando-o para a impressora do sistema.

EXIT Encerra o SQL*Plus

On Targget Treinamento e Consultoria 27

Page 68: Introdução ao Oracle 8i

Funções Básicas

Exercícios - 2

1. Inicie uma sessão do SQL*Plus utilizando o usuário e senha fornecidos pelo instrutor.

2. Comandos SQL*Plus acessam o banco de dados.

Verdadeiro / Falso

3. O comando SELECT a seguir executará com sucesso?

Verdadeiro / Falso

4. O comando SELECT abaixo executará com sucesso?

Verdadeiro / Falso

5. Existem três erros de codificação neste comando. Você pode os identificar?

6. Mostre a estrutura da tabela DEPT. Selecione todos os dados da tabela DEPT.

7. Mostre a estrutura da tabela EMP. Crie uma consulta para exibir o nome (ename), cargo (job), data de admissão (hiredate) e número do empregado (empno) para cada empregado, mostrando o número do empregado por primeiro. Salve o comando SQL para um arquivo chamado e2q7.sql.

8. Execute a consulta do arquivo e2q7.sql.

9. Crie uma consulta para exibir cada cargo da tabela EMP uma única vez.

On Targget Treinamento e Consultoria 28

SQL> SELECT ename, job, sal Salary 2 FROM emp;SQL> SELECT * 2 FROM salgrade;SQL> SELECT empno, ename 2 salary x 12 ANNUAL SALARY 3 FROM emp;

Name Null? Type----------- -------- ------------DEPTNO NOT NULL NUMBER(2)DNAME VARCHAR2(14)LOC VARCHAR2(13)

DEPTNO DNAME LOC------ ---------- ------------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON

Name Null? Type--------- -------- -------------EMPNO NOT NULL NUMBER(4)ENAME VARCHAR2(10)JOB VARCHAR2(9)MGR NUMBER(4)HIREDATE DATESAL NUMBER(7,2)COMM NUMBER(7,2)DEPTNO NOT NULL NUMBER(2)

EMPNO ENAME JOB HIREDATE----- ------- ----------- --------- 7839 KING PRESIDENT 17-NOV-81 7698 BLAKE MANAGER 01-MAY-81 7782 CLARK MANAGER 09-JUN-81 7566 JONES MANAGER 02-APR-81 7654 MARTIN SALESMAN 28-SEP-81 7499 ALLEN SALESMAN 20-FEB-81 7844 TURNER SALESMAN 08-SEP-81 7900 JAMES CLERK 03-DEC-81 7521 WARD SALESMAN 22-FEB-81 7902 FORD ANALYST 03-DEC-81 7369 SMITH CLERK 17-DEC-80 7788 SCOTT ANALYST 09-DEC-82 7876 ADAMS CLERK 12-JAN-83 7934 MILLER CLERK 23-JAN-8214 rows selected.

Page 69: Introdução ao Oracle 8i

Funções Básicas

Se houver tempo, complete os seguintes exercícios:

10. Carregue e2q7.sql no SQL buffer. Altere os cabeçalhos das colunas para Emp#, Employee, Job e Hire Date, respectivamente. Execute sua consulta novamente.

11. Exiba o nome do empregado concatenado com o cargo, separados por uma vírgula e um espaço, e nomeie o cabeçalho da coluna Employee and Title.

Se você quiser um desafio extra, complete os exercícios seguintes:

12. Crie uma consulta para exibir todos os dados da tabela EMP. Separe cada coluna por uma vírgula. Coloque no cabeçalho da coluna resultante a string THE_OUTPUT.

On Targget Treinamento e Consultoria 29

JOB-----------ANALYSTCLERKMANAGERPRESIDENTSALESMAN

Emp # Employee Job Hire Date----- --------- ---------- --------------- 7839 KING PRESIDENT 17-NOV-81 7698 BLAKE MANAGER 01-MAY-81 7782 CLARK MANAGER 09-JUN-81 7566 JONES MANAGER 02-APR-81 7654 MARTIN SALESMAN 28-SEP-81 7499 ALLEN SALESMAN 20-FEB-81 7844 TURNER SALESMAN 08-SEP-81 7900 JAMES CLERK 03-DEC-81 7521 WARD SALESMAN 22-FEB-81 7902 FORD ANALYST 03-DEC-81 7369 SMITH CLERK 17-DEC-80 7788 SCOTT ANALYST 09-DEC-82 7876 ADAMS CLERK 12-JAN-83 7934 MILLER CLERK 23-JAN-8214 rows selected.

Employee and Title-------------------KING, PRESIDENTBLAKE, MANAGERCLARK, MANAGERJONES, MANAGERMARTIN, SALESMANALLEN, SALESMANTURNER, SALESMANJAMES, CLERKWARD, SALESMANFORD, ANALYSTSMITH, CLERKSCOTT, ANALYSTADAMS, CLERKMILLER, CLERK14 rows selected.

THE_OUTPUT-------------------------------------------------7839,KING,PRESIDENT,,17-NOV-81,5000,,107698,BLAKE,MANAGER,7839,01-MAY-81,2850,,307782,CLARK,MANAGER,7839,09-JUN-81,2450,,107566,JONES,MANAGER,7839,02-APR-81,2975,,207654,MARTIN,SALESMAN,7698,28-SEP-81,1250,1400,307499,ALLEN,SALESMAN,7698,20-FEB-81,1600,300,307844,TURNER,SALESMAN,7698,08-SEP-81,1500,0,307900,JAMES,CLERK,7698,03-DEC-81,950,,307521,WARD,SALESMAN,7698,22-FEB-81,1250,500,307902,FORD,ANALYST,7566,03-DEC-81,3000,,207369,SMITH,CLERK,7902,17-DEC-80,800,,207788,SCOTT,ANALYST,7566,09-DEC-82,3000,,207876,ADAMS,CLERK,7788,12-JAN-83,1100,,207934,MILLER,CLERK,7782,23-JAN-82,1300,,1014 rows selected.

Page 70: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

3.3. Restringindo e OrdenandoRestringindo e Ordenando DadosDados

On Targget Treinamento e Consultoria

Page 71: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Limitar as linhas recuperadas por uma consulta. Ordene as linhas recuperadas por uma consulta.

Quando recuperar dados do banco de dados, você pode necessitar restringir os registros que serão retornados ou especificar a ordem na qual as linhas serão exibidas. Este capítulo explica os comandos SQL que você utilizará para executar estas ações.

On Targget Treinamento e Consultoria 2

Page 72: Introdução ao Oracle 8i

Funções Básicas

Limitando Linhas Utilizando uma Seleção

No exemplo acima, assuma que você quer exibir todos os empregados do departamento 10. O conjunto de linhas destacadas com o valor 10 na coluna DEPTNO são as únicas retornadas. Este método de restrição é a base da cláusula WHERE em SQL.

On Targget Treinamento e Consultoria 3

Page 73: Introdução ao Oracle 8i

Funções Básicas

Limitando as Linhas Selecionadas

Você pode restringir as linhas recuperadas pela consulta utilizando a cláusula WHERE. A cláusula WHERE contém uma condição que deve ser satisfeita, devendo estar imediatamente após a cláusula FROM.

Na sintaxe:

WHERE restringe a consulta para as linhas que satisfazem a condição.

condition é composta de nomes de coluna, expressões, constantes, e operadores de comparação.

A cláusula WHERE pode comparar valores em colunas, valores literais, expressões aritméticas ou funções. A cláusula WHERE consiste de três elementos:

Nome da coluna Operador de comparação Nome de coluna, constante ou lista de valores

On Targget Treinamento e Consultoria 4

SELECT [DISTINCT] {*, column [alias], ...}FROM table[WHERE condition(s)];

Page 74: Introdução ao Oracle 8i

Funções Básicas

Utilizando a Cláusula WHERE

No exemplo, o comando SELECT recupera o nome, cargo e o número do departamento de todos os empregados cujo cargo é CLERK.

Observe que o cargo CLERK foi especificado em maiúsculas para assegurar que a comparação feita com a coluna cargo da tabela EMP esteja de acordo com os dados nela armazenados. Strings de caractere fazem distinção entre maiúsculas e minúsculas.

On Targget Treinamento e Consultoria 5

SQL> SELECT ename, job, deptno 2 FROM emp 3 WHERE job = 'CLERK';

ENAME JOB DEPTNO---------- --------- ---------JAMES CLERK 30SMITH CLERK 20ADAMS CLERK 20MILLER CLERK 10

Page 75: Introdução ao Oracle 8i

Funções Básicas

Strings de Caractere e Datas

Strings de caractere e datas na cláusula WHERE devem ser inseridas entre aspas simples (''). Constantes numéricas, entretanto, não devem estar entre aspas.

Todas as pesquisas tipo caractere fazem distinção entre maiúsculas e minúsculas. No exemplo a seguir, nenhuma linha é retornada porque a tabela EMP armazena todos os dados em maiúsculas.

O Oracle armazena datas em um formato numérico interno, representando o século, ano, mês, dia, horas, minutos e segundos. A exibição default de datas é DD-MON-YY.

Nota: A modificação do formato default de data será visto no capítulo 4.

Valores numérico não devem ser inclusos dentro de aspas.

On Targget Treinamento e Consultoria 6

SQL> SELECT ename, job, deptno 2 FROM emp 3 WHERE ename = 'JAMES';

SQL> SELECT ename, empno, job, deptno 2 FROM emp 3 WHERE job='clerk';

Page 76: Introdução ao Oracle 8i

Funções Básicas

Operadores de Comparação

Operadores de comparação são utilizados em condições que comparam uma expressão com outra. Eles são usados na cláusula WHERE no seguinte formato:

Sintaxe

Exemplos

On Targget Treinamento e Consultoria 7

… WHERE expr operator value… WHERE hiredate = '01-JAN-95'… WHERE sal >= 1500… WHERE ename = 'SMITH'

Page 77: Introdução ao Oracle 8i

Funções Básicas

Utilizando os Operadores de Comparação

No exemplo, o comando SELECT recupera o nome, salário e comissão a partir da tabela EMP, quando o salário do empregado for menor ou igual ao valor da sua comissão. Observe que não há nenhum valor explícito fornecido para a cláusula WHERE. Os dois valores são comparados são obtidos a partir das colunas SAL e COMM da tabela EMP.

On Targget Treinamento e Consultoria 8

SQL> SELECT ename, sal, comm 2 FROM emp 3 WHERE sal <= comm;

ENAME SAL COMM---------- --------- ---------MARTIN 1250 1400

Page 78: Introdução ao Oracle 8i

Funções Básicas

Outros Operadores de Comparação

On Targget Treinamento e Consultoria 9

Page 79: Introdução ao Oracle 8i

Funções Básicas

Operador BETWEEN

Você pode exibir linhas baseadas em um intervalo de valores utilizando o operador BETWEEN. O intervalo que você especifica é composto por um limite inferior e um limite superior.

O comando SELECT acima recupera linhas da tabela EMP para qualquer empregado cujo salário está entre $1000 e $1500.

Os valores especificados no operador BETWEEN fazem parte do intervalo, sendo também recuperados. Você deve especificar o limite inferior por primeiro.

On Targget Treinamento e Consultoria 10

SQL> SELECT ename, sal 2 FROM emp 3 WHERE sal BETWEEN 1000 AND 1500;

ENAME SAL---------- ---------MARTIN 1250TURNER 1500WARD 1250ADAMS 1100MILLER 1300

Lowerlimit

Higherlimit

Page 80: Introdução ao Oracle 8i

Funções Básicas

Operador IN

Utilize o operador IN para executar a comparação com os valores de uma lista.

O exemplo acima exibe o número do empregado, nome, salário e o número do gerente de todos os empregados cujo o número do gerente é 7902, 7566 ou 7788.

O operador IN pode ser utilizado com qualquer tipo de dado. O exemplo a seguir recupera uma linha a partir da tabela EMP para cada empregado cujo nome encontre-se na lista de nomes da cláusula WHERE.

Se forem utilizadas strings de caractere ou datas na lista, estas devem estar entre aspas simples ('').

On Targget Treinamento e Consultoria 11

SQL> SELECT empno, ename, sal, mgr 2 FROM emp 3 WHERE mgr IN (7902, 7566, 7788);

EMPNO ENAME SAL MGR--------- ---------- --------- --------- 7902 FORD 3000 7566 7369 SMITH 800 7902 7788 SCOTT 3000 7566 7876 ADAMS 1100 7788

SQL> SELECT empno, ename, mgr, deptno 2 FROM emp 3 WHERE ename IN ('FORD' , 'ALLEN');

Page 81: Introdução ao Oracle 8i

Funções Básicas

Operador LIKE

Às vezes você pode não saber o valor exato a pesquisar. Você pode então selecionar linhas que combinem com um padrão de caracteres utilizando o operador LIKE. Podem ser utilizados dois símbolos para construir a string de procura.

Símbolo Descrição% Representa qualquer seqüência de zero ou mais caracteres_ Representa um único caractere qualquer

O comando SELECT acima recupera o nome de empregado da tabela EMP para qualquer empregado cujo nome começa com um “S”. Observe que os nomes que começam com um “s” minúsculo não serão recuperados.

O operador LIKE pode ser utilizado como um atalho para algumas comparações normalmente executadas com o operador BETWEEN. O exemplo a seguir exibe os nomes e as datas de admissão de todos os empregados que foram contratados entre Janeiro de 1981 e Dezembro de 1981.

Combinando Padrões de Caractere

Os símbolos % e _ podem ser utilizados em qualquer combinação com literais de caracteres. O exemplo abaixo exibe os nomes de todos os empregados cujo nome possui a letra “A” como o segundo caractere.

A opção de ESCAPE

Quando você precisar de uma comparação exata para os caracteres "%" e "_", utilize a opção de ESCAPE. Para exibir os nomes de empregados cujo nome contém "A_B", utilize o seguinte comando SQL:

A opção de ESCAPE identifica a barra invertida (\) como o caracter de escape. No padrão, o caractere de escape precede o underscore (_). Isto faz com que o Servidor Oracle interprete o underscore literalmente.

On Targget Treinamento e Consultoria 12

SQL> SELECT ename 2 FROM emp 3 WHERE ename LIKE 'S%';

SQL> SELECT ename, hiredate 2 FROM emp 3 WHERE hiredate LIKE '%81';

SQL> SELECT ename 2 FROM emp 3 WHERE ename LIKE '_A%';

ENAME---------- JAMES WARD

SQL> SELECT ename 2 FROM emp 3 WHERE ename LIKE '%A\_%B' ESCAPE '\';

Page 82: Introdução ao Oracle 8i

Funções Básicas

Operador IS NULL

O operador IS NULL testa os valores que são nulos. Um valor nulo é um valor que é indisponível, não atribuído, desconhecido ou inaplicável. Portanto, você não pode testá-los com (=) porque um valor nulo não pode ser igual ou diferente de qualquer valor. O exemplo acima recupera o nome e o gerente de todos os empregados que não possuem um gerente.

Por exemplo, para exibir o nome, cargo e comissão para todos os empregados que não são intitulados para adquirir uma comissão, utilize o seguinte comando SQL:

On Targget Treinamento e Consultoria 13

SQL> SELECT ename, mgr 2 FROM emp 3 WHERE mgr IS NULL;

ENAME MGR---------- ---------KING

SQL> SELECT ename, job, comm 2 FROM emp 3 WHERE comm IS NULL;

ENAME JOB COMM-------- ----------- ------KING PRESIDENTBLAKE MANAGERCLARK MANAGER...

Page 83: Introdução ao Oracle 8i

Funções Básicas

Operadores Lógicos

Um operador lógico combina o resultado de duas condições para produzir um único resultado ou para inverter o resultado de uma única condição. Três operadores lógicos estão disponíveis em SQL:

AND OR NOT

Todos os exemplos mostrados até o momento, especificaram somente uma condição na cláusula WHERE. Você pode usar várias condições em uma cláusula WHERE utilizandos os operadores AND e OR.

On Targget Treinamento e Consultoria 14

Page 84: Introdução ao Oracle 8i

Funções Básicas

Operador AND

No exemplo, ambas as condições devem ser verdadeiras para qualquer registro a ser selecionado. Portanto, um empregado que tem o cargo CLERK e ganha mais que $1100 será selecionado.

Todas as pesquisas do tipo caractere fazem distinção entre maiúsculas e minúsculas. Nenhuma linha é retornada se CLERK não estiver em maiúsculo. Strings de caracteres devem ser incluídas entre aspas simples.

Combinações de Resultados com o Operador AND

A tabela abaixo mostra o resultado da combinação de duas expressões com o operador AND:

AND TRUE FALSE UNKNOWTRUE TRUE FALSE UNKNOWFALSE FALSE FALSE FALSE

UNKNOW UNKNOW FALSE UNKNOW

On Targget Treinamento e Consultoria 15

SQL> SELECT empno, ename, job, sal 2 FROM emp 3 WHERE sal >= 1100 4 AND job = 'CLERK';

EMPNO ENAME JOB SAL--------- ---------- --------- --------- 7876 ADAMS CLERK 1100 7934 MILLER CLERK 1300

Page 85: Introdução ao Oracle 8i

Funções Básicas

Operador OR

No exemplo, para um registro ser selecionado basta que uma das duas condições seja verdadeira. Portanto, um empregado que possui o cargo CLERK ou ganha mais que $1100 será selecionado.

Combinações de Resultados com o Operador OR

A tabela abaixo mostra o resultado da combinação de duas expressões com o operador OR:

OR TRUE FALSE UNKNOWTRUE TRUE TRUE TRUEFALSE TRUE FALSE UNKNOW

UNKNOW TRUE UNKNOW UNKNOW

On Targget Treinamento e Consultoria 16

SQL> SELECT empno, ename, job, sal 2 FROM emp 3 WHERE sal >= 1100 4 OR job = 'CLERK';

EMPNO ENAME JOB SAL--------- ---------- --------- --------- 7839 KING PRESIDENT 5000 7698 BLAKE MANAGER 2850 7782 CLARK MANAGER 2450 7566 JONES MANAGER 2975 7654 MARTIN SALESMAN 1250...14 rows selected.

Page 86: Introdução ao Oracle 8i

Funções Básicas

Operador NOT

O exemplo acima exibe o nome e o cargo de todos os empregados cujo cargo não seja CLERK, MANAGER ou ANALYST.

Combinações de Resultados com o Operador NOT

A tabela abaixo mostra o resultado da aplicação do operador NOT a uma condição:

NOTTRUE FALSE UNKNOWFALSE TRUE UNKNOW

Nota: O operador NOT também pode ser utilizado com outros operadores SQL como BETWEEN, LIKE e NULL.

On Targget Treinamento e Consultoria 17

SQL> SELECT ename, job 2 FROM emp 3 WHERE job NOT IN ('CLERK','MANAGER','ANALYST');

ENAME JOB---------- ---------KING PRESIDENTMARTIN SALESMANALLEN SALESMANTURNER SALESMANWARD SALESMAN

... WHERE NOT job IN ('CLERK', 'ANALYST')

... WHERE sal NOT BETWEEN 1000 AND 1500

... WHERE ename NOT LIKE '%A%'

... WHERE comm IS NOT NULL

Page 87: Introdução ao Oracle 8i

Funções Básicas

Regras de Precedência

Exemplo de Precedência do Operador AND

No exemplo, existem duas condições:

A primeira condição é aquela onde o cargo deve ser PRESIDENT e o salário deve ser maior que 1500.

A segunda condição é aquela em que o cargo deve ser SALESMAN.

Portanto, lê-se o comando SELECT como segue:

“Selecione a linha se o empregado for um presidente e ganhar mais do que $1500 ou se o empregado for um vendedor.”

On Targget Treinamento e Consultoria 18

SQL> SELECT ename, job, sal 2 FROM emp 3 WHERE job = 'SALESMAN' 4 OR job = 'PRESIDENT' 5 AND sal > 1500;

ENAME JOB SAL---------- --------- ---------KING PRESIDENT 5000MARTIN SALESMAN 1250ALLEN SALESMAN 1600TURNER SALESMAN 1500WARD SALESMAN 1250

Page 88: Introdução ao Oracle 8i

Funções Básicas

Utilizando Parênteses para Alterar a Prioridade

No exemplo, existem duas condições:

A primeira condição é aquela onde o cargo deve ser PRESIDENT ou SALESMAN. A segunda condição é aquela onde o salário deve ser maior que 1500.

Portanto, lê-se o comando SELECT como segue:

“Selecione a linha se o empregado for um presidente ou vendedor e se o empregado ganhar mais do que $1500.”

On Targget Treinamento e Consultoria 19

SQL> SELECT ename, job, sal 2 FROM emp 3 WHERE (job = 'SALESMAN' 4 OR job = 'PRESIDENT') 5 AND sal > 1500;

ENAME JOB SAL---------- --------- ---------KING PRESIDENT 5000ALLEN SALESMAN 1600

Page 89: Introdução ao Oracle 8i

Funções Básicas

Cláusula ORDER BY

A ordem das linhas recuperadas no resultado de uma consulta é indefinida. A cláusula ORDER BY pode ser utilizada para ordenar as linhas. Se utilizada, deve aparecer como a última cláusula do comando SELECT. Você pode ordenar por uma expressão ou por um alias de coluna.

Sintaxe:

Onde:

ORDER BY especifica a ordem na qual as linhas recuperadas serão exibidas.

ASC ordena as linhas em ordem ascendente. Esta é a ordenação padrão.

DESC ordena as linhas em ordem descendente.

Se a cláusula ORDER BY não for utilizada, a ordem em que as linhas serão recuperadas é indefinida, e o Servidor Oracle pode não recuperar as linhas duas vezes na mesma ordem para a mesma consulta. Utilize a cláusula ORDER BY para exibir as linhas em uma ordem específica.

On Targget Treinamento e Consultoria 20

SQL> SELECT ename, job, deptno, hiredate 2 FROM emp 3 ORDER BY hiredate;

ENAME JOB DEPTNO HIREDATE---------- --------- --------- ---------SMITH CLERK 20 17-DEC-80ALLEN SALESMAN 30 20-FEB-81...14 rows selected.

SELECT expr FROM table[WHERE condition(s)][ORDER BY {column, expr} [ASC | DESC]];

Page 90: Introdução ao Oracle 8i

Funções Básicas

Classificando em Ordem Descendente

Ordenação Padrão dos Dados

A ordenação padrão dos dados é ascendente:

Valores numéricos são exibidos com o valor mais baixo primeiro, por exemplo: 1–999. Valores tipo data são exibidos com o valor mais antigo primeiro, por exemplo: 01-JAN-92

antes de 01-JAN-95. Valores caractere são exibidos em ordem alfabética, por exemplo: A primeiro e Z por

último. Valores nulos são exibidos por último para ordenações ascendentes e por primeiro para

ordenações descendentes.

Invertendo a Ordem Padrão

Para inverter a ordem na qual as linhas são exibidas, especifique o palavra chave DESC depois do nome da coluna na cláusula ORDER BY. O exemplo acima ordena o resultado pelo empregado mais recentemente contratado.

On Targget Treinamento e Consultoria 21

SQL> SELECT ename, job, deptno, hiredate 2 FROM emp 3 ORDER BY hiredate DESC;

ENAME JOB DEPTNO HIREDATE---------- --------- --------- ---------ADAMS CLERK 20 12-JAN-83SCOTT ANALYST 20 09-DEC-82MILLER CLERK 10 23-JAN-82JAMES CLERK 30 03-DEC-81FORD ANALYST 20 03-DEC-81KING PRESIDENT 10 17-NOV-81MARTIN SALESMAN 30 28-SEP-81...14 rows selected.

Page 91: Introdução ao Oracle 8i

Funções Básicas

Ordenando pelo Alias de Coluna

Você pode utilizar um alias de coluna na cláusula ORDER BY. O exemplo acima ordena os dados pelo salário anual.

On Targget Treinamento e Consultoria 22

SQL> SELECT empno, ename, sal*12 annsal 2 FROM emp 3 ORDER BY annsal;

EMPNO ENAME ANNSAL--------- ---------- --------- 7369 SMITH 9600 7900 JAMES 11400 7876 ADAMS 13200 7654 MARTIN 15000 7521 WARD 15000 7934 MILLER 15600 7844 TURNER 18000...14 rows selected.

Page 92: Introdução ao Oracle 8i

Funções Básicas

Ordenando por Múltiplas Colunas

Você pode ordenar os resultados das consultas por mais de uma coluna.

Na cláusula ORDER BY, especifique as colunas separando-as por vírgulas. Se você quiser inverter a ordem de uma coluna, especifique DESC depois de seu nome. Você pode ordenar por colunas que não estão incluídas na lista da cláusula SELECT.

Exemplo:

Mostre o nome e o salário de todos os empregados. Ordene o resultado pelo número do departamento e depois por ordem descendente de salário.

On Targget Treinamento e Consultoria 23

SQL> SELECT ename, deptno, sal 2 FROM emp 3 ORDER BY deptno, sal DESC;

ENAME DEPTNO SAL---------- --------- ---------KING 10 5000CLARK 10 2450MILLER 10 1300FORD 20 3000...14 rows selected.

SQL> SELECT ename, sal 2 FROM emp 3 ORDER BY deptno, sal DESC;

Page 93: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 3

1. Crie uma consulta para exibir o nome e o salário dos empregados que estão ganhando mais que $2850. Salve o comando SQL para um arquivo chamado e3q1.sql. Execute sua consulta.

2. Crie uma consulta para exibir o nome do empregado e o número do departamento para o empregado número 7566.

3. Altere a consulta em e3q1.sql para exibir o nome e o salário para todos os empregados cujo salário não está na faixa de valores de $1500 à $2850. Salve o novo comando para um arquivo chamado e3q3.sql. Execute a consulta.

4. Mostre o nome do empregado, o cargo e a data de admissão dos empregados contratados entre 20 de Fevereiro de 1981 e 1 de Maio de 1981. Classifique a consulta em ordem ascendente de data de admissão.

5. Mostre o nome do empregado e o número do departamento de todos os empregados que estão no departamento 10 e 30 em ordem alfabética por nome.

6. Altere a consulta em e3q3.sql para listar o nome e o salário dos empregados que ganham mais do que $1500 e estão no departamento 10 ou 30. Coloque o alias para as colunas Employee e Monthly Salary, respectivamente. Salve o novo comando para um arquivo chamado e3q6.sql. Execute a consulta.

7. Mostre o nome e a data de admissão de cada empregado que tenha sido contratado em 1982.

8. Mostre o nome e o cargo de todos os empregados que não possuem gerente.

9. Mostre o nome, o salário e a comissão para todos os empregados que ganham comissões. Ordene os dados em ordem descendente de salário e comissão.

On Targget Treinamento e Consultoria 24

ENAME SAL-------- ----KING 5000JONES 2975FORD 3000SCOTT 3000

ENAME DEPTNO------ ------JONES 20

ENAME SAL------- -----KING 5000JONES 2975MARTIN 1250JAMES 950WARD 1250FORD 3000SMITH 800SCOTT 3000ADAMS 1100MILLER 130010 rows selected.

ENAME JOB HIREDATE------- --------- ----------------ALLEN SALESMAN 20-FEB-81WARD SALESMAN 22-FEB-81JONES MANAGER 02-APR-81BLAKE MANAGER 01-MAY-81

ENAME DEPTNO-------- ------KING 10BLAKE 30CLARK 10MARTIN 30ALLEN 30TURNER 30JAMES 30WARD 30MILLER 109 rows selected.

Employee Monthly Salary-------- --------------KING 5000BLAKE 2850CLARK 2450ALLEN 1600

ENAME HIREDATE------ ---------SCOTT 09-DEC-82MILLER 23-JAN-82

ENAME JOB----- ---------KING PRESIDENT

Page 94: Introdução ao Oracle 8i

Funções Básicas

Se houver tempo, complete os seguintes exercícios:

10. Mostre o nome de todos os empregados quando a terceira letra de seu nome for um A.

11. Mostre o nome de todos os empregados que possuem duas letras L em seu nome e estão no departamento 30 ou seu gerente é o empregado 7782.

Se você quiser um desafio extra, complete os exercícios seguintes:

12. Mostre o nome, o cargo e o salário para todos os empregados cujo cargo seja CLERK ou ANALYST e seu salário não seja igual a $1000, $3000 ou $5000.

13. Altere a consulta em e3q6.sql para mostrar o nome, salário e comissão para todos os empregados cujo o valor da comissão seja maior que seu salário incrementado por 10%. Salve o novo comando em um arquivo chamado e3q13.sql. Execute a consulta.

On Targget Treinamento e Consultoria 25

ENAME SAL COMM------- ---- ----ALLEN 1600 300TURNER 1500 0MARTIN 1250 1400WARD 1250 500

ENAME-----------BLAKECLARKADAMS

ENAME----------ALLENMILLER

ENAME JOB SAL------ ------- -----JAMES CLERK 950SMITH CLERK 800ADAMS CLERK 1100MILLER CLERK 1300

ENAME SAL COMM------- ----- -----MARTIN 1250 1400

Page 95: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

4.4. Funções BásicasFunções Básicas

On Targget Treinamento e Consultoria

Page 96: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Descrever os vários tipos de funções disponíveis em SQL Utilizar funções do tipo caractere, numéricas e de datas em comandos SELECT Descrever o uso de funções de conversão

Funções tornam o bloco de consulta básico mais poderoso e são utilizadas para manipular valores de dados. Este é o primeiro de dois capítulos que exploram funções. Será visto neste primeiro capítulo funções do tipo caractere, numéricas e de data que retornam valores baseadas em uma única linha, como também funções que convertem dados de um tipo para outro, como por exemplo a conversão de dados caractere para numérico.

On Targget Treinamento e Consultoria 2

Page 97: Introdução ao Oracle 8i

Funções Básicas

Funções SQL

Funções são uma característica bastante útil do SQL e podem ser utilizadas para fazer o seguinte:

Executar cálculos em dados Modifique itens de dados individuais Manipular um resultado para um grupos de linhas Formatar datas e números para exibição Converter o tipo de dado de colunas

Funções SQL recebem argumento(s) e retornam valor(es).

Nota: A maioria das funções descritas neste capítulo são específicas à versão de SQL da Oracle.

On Targget Treinamento e Consultoria 3

Page 98: Introdução ao Oracle 8i

Funções Básicas

Tipos de Funções SQL

Existem dois tipos distintos de funções:

Funções do tipo single-row Funções do tipo multiple-row

Funções do Tipo Single-Row

Estas funções operam em linhas únicas retornando um resultado para cada linha processada. Existem diferentes tipos de funções single-row. Este capítulo explica os tipos listados abaixo:

Caractere Numérica Data Conversão

Funções do Tipo Multiple-Row

Estas funções manipulam grupos de linhas para obter um resultado para cada grupo processado e serão vistas em um capítulo posterior.

On Targget Treinamento e Consultoria 4

Page 99: Introdução ao Oracle 8i

Funções Básicas

Funções do Tipo Single-Row

Funções do tipo single-row são utilizadas para manipular itens de dados. Elas recebem um ou mais argumentos e retornam um único valor para cada linha recuperada pela consulta. Um argumento pode ser um dos seguintes:

Uma constante fornecida pelo usuário Um valor variável Um nome de coluna Uma expressão

Características de Funções Tipo Single-Row

Atuam sobre cada linha recuperada pela consulta. Retornam um resultado por linha. Podem retornar um valor com o tipo de dado diferente do referenciado. Podem receber um ou mais argumentos.

Você pode utilizá-las nas cláusulas SELECT, WHERE e ORDER BY. Você pode também aninhar funções.

Na sintaxe:

function_name é o nome da função.

column é qualquer coluna nomeada do banco de dados.

expression é qualquer string de caractere ou expressão calculada.

arg1, arg2 são quaisquer argumentos a serem utilizadas pela função.

On Targget Treinamento e Consultoria 5

function_name (column|expression, [arg1, arg2,...])

Page 100: Introdução ao Oracle 8i

Funções Básicas

Este capítulo explica as seguintes funções do tipo single-row:

Funções de caracteres: Recebem parâmetros caractere e podem retornar valores numéricos ou caractere.

Funções numéricas: Recebem parâmetros numéricos e retornam valores numéricos. Funções de data: Operam em valores do tipo de dado DATE. Todas as funções de data

retornam um valor do tipo de dado data, exceto a função MONTHS_BETWEEN que retorna um número.

Funções de conversão: Convertem um valor de um tipo de dado para outro. Funções genéricas:

NVL DECODE

On Targget Treinamento e Consultoria 6

Page 101: Introdução ao Oracle 8i

Funções Básicas

Funções de Caracteres

Funções de caracteres aceitam dados do tipo caractere como entrada e podem retornar valores do tipo caractere ou numérico. Funções de caracteres podem ser divididas em:

Funções de conversão entre maiúsculas/minúsculas Funções de manipulação de caracteres

Função PropósitoLOWER(column|expression) Converte strings de caracteres para minúsculasUPPER(column|expression) Converte strings de caracteres para maiúsculas

INITCAP(column|expression)Converte strings de caracteres deixando a primeira letra de cada palavra em maiúscula e as demais em minúsculas

CONCAT(column1|expression1, column2|expression2)

Concatena a primeira string de caracteres com a segunda. Equivalente ao operador de concatenação ( || )

SUBSTR(column|expression,m[,n])

Retorna os caracteres especificados a partir da string de caracteres, começando na posição m,com tamanho de n caracteres. Se m for negativo, a contagem inicia a partir do final da string. Se n for omitido, são retornados todos os caracteres até o final da string

LENGTH(column|expression) Retorna o número de caracteres da stringINSTR(column|expression,m) Retorna a posição numérica do caracter dentro da stringLPAD(column|expression, n,

'string') Retorna uma string com tamanho total de n alinhada à direita

On Targget Treinamento e Consultoria 7

Page 102: Introdução ao Oracle 8i

Funções Básicas

Funções de Conversão entre Maiúsculas/Minúsculas

LOWER, UPPER e INITCAP são as três funções de conversão entre maiúsculas e minúsculas.

LOWER: converte todos os caracteres de uma string para minúsculas UPPER: converte todos os caracteres de uma string para maiúsculas INITCAP: converte a primeira letra de cada palavra para maiúsculas e as demais para

minúsculas

On Targget Treinamento e Consultoria 8

SQL> SELECT 'The job title for ' || INITCAP(ename) || ' is ' 2 || LOWER(job) AS "EMPLOYEE DETAILS" 3 FROM emp;

EMPLOYEE DETAILS-----------------------------------------The job title for King is presidentThe job title for Blake is managerThe job title for Clark is manager...14 rows selected.

Page 103: Introdução ao Oracle 8i

Funções Básicas

Utilizando Funções de Conversão entre Maiúsculas/Minúsculas

O exemplo acima exibe o número de empregado, o nome e número do departamento do empregado BLAKE.

A cláusula WHERE do primeiro comando SQL especifica o nome de empregado como blake. Uma vez que todos os dados na tabela EMP estão armazenados em maiúsculas, o nome ' blake' não possui um correspondente na tabela EMP e como resultado nenhuma linha é selecionada.

A cláusula WHERE do segundo comando SQL especifica que o nome do empregado na tabela EMP deve ser convertido para minúsculas e então comparado com blake. Considerando que ambos os nomes estão em minúsculas agora, uma correspondência é encontrada e uma linha é selecionada. A cláusula WHERE pode ser reescrita da seguinte maneira para obter o mesmo resultado:

O nome no resultado da consulta aparece como foi armazenado no banco de dados. Para exibir o nome somente com a primeira letra em maiúscula, utilize a função INITCAP no comando SELECT.

On Targget Treinamento e Consultoria 9

SQL> SELECT empno, ename, deptno 2 FROM emp 3 WHERE ename = 'blake';no rows selectedno rows selected

SQL> SELECT empno, ename, deptno 2 FROM emp 3 WHERE LOWER(ename) = 'blake';

EMPNO ENAME DEPTNO--------- ---------- --------- 7698 BLAKE 30

… WHERE ename = 'BLAKE'

SQL> SELECT empno, INITCAP(ename), deptno 2 FROM emp 3 WHERE LOWER(ename) = 'blake';

Page 104: Introdução ao Oracle 8i

Funções Básicas

Funções de Manipulação de Caracteres

CONCAT, SUBSTR, LENGTH, INSTR e LPAD são as cinco funções de manipulação de caracteres apresentadas neste capítulo.

CONCAT: Concatena strings de caracteres, sendo limitado ao uso de apenas dois parâmetros.

SUBSTR: Extrai uma string de tamanho determinado. LENGTH: Exibe o tamanho de uma string como um valor numérico. INSTR: Encontra a posição numérica de um caractere na string. LPAD: Retorna uma string de caracteres do tamanho especificado alinhada à direita.

Nota: A função de manipulação de caracteres RPAD é semelhante a função LPAD, porém retorna a string de caracteres alinhada à esquerda.

On Targget Treinamento e Consultoria 10

Page 105: Introdução ao Oracle 8i

Funções Básicas

Utilizando as Funções de Manipulação de Caracteres

O exemplo acima exibe o nome do empregado concatenado com o cargo, o tamanho do nome do empregado e a posição numérica da letra A no nome, para todos os empregados que estão alocados em vendas.

Exemplo:

Modificando o comando SQL acima para exibir os dados para os empregados cujo nome termine com a letra N:

On Targget Treinamento e Consultoria 11

SQL> SELECT ename, CONCAT (ename, job), LENGTH(ename), 2 INSTR(ename, 'A') 3 FROM emp 4 WHERE SUBSTR(job,1,5) = 'SALES';

ENAME CONCAT(ENAME,JOB) LENGTH(ENAME) INSTR(ENAME,'A')---------- ------------------- ------------- ----------------MARTIN MARTINSALESMAN 6 2ALLEN ALLENSALESMAN 5 1TURNER TURNERSALESMAN 6 0WARD WARDSALESMAN 4 2

SQL> SELECT ename, CONCAT(ename, job), LENGTH(ename),INSTR(ename, 'A')

2 FROM emp 3 WHERE SUBSTR(ename, -1, 1) = 'N';

ENAME CONCAT(ENAME,JOB) LENGTH(ENAME) INSTR(ENAME,'A')-------- ------------------- ------------- ----------------MARTIN MARTINSALESMAN 6 2ALLEN ALLENSALESMAN 5 1

Page 106: Introdução ao Oracle 8i

Funções Básicas

Funções Numéricas

Funções numéricas recebem parâmetros numéricos e retornam valores numéricos. Esta seção descreve algumas das funções numéricas.

Função Propósito

ROUND(column|expression, n)

Arredonda a coluna, expressão ou valor para n casas decimais. Se n for omitido, será considerado como 0, ou seja, sem casas decimais. Se n for negativo, os números à esquerda do ponto decimal serão arredondados.

TRUNC(column|expression,n)

Trunca a coluna, expressão ou valor para n casas decimais.Se n for omitido, será considerado como 0. Se n for negativo, os números à esquerda do ponto decimal serão truncados para zero.

MOD(m,n) Retorna o resto da divisão de m por n.

On Targget Treinamento e Consultoria 12

Page 107: Introdução ao Oracle 8i

Funções Básicas

Utilizando a Função ROUND

A função ROUND arredonda uma coluna, expressão ou valor para n casas decimais. Se o segundo argumento é 0 ou não for informado, o valor é arredondado para zero casas decimais. Se o segundo argumento é 2, o valor é arredondado para duas casas decimais. Reciprocamente, se o segundo argumento é -2, o valor é arredondado duas casas decimais para à esquerda.

A função ROUND também pode ser utilizada com funções de data.

On Targget Treinamento e Consultoria 13

SQL> SELECT ROUND(45.923,2), ROUND(45.923,0), 2 ROUND(45.923,-1) 3 FROM DUAL;

ROUND(45.923,2) ROUND(45.923,0) ROUND(45.923,-1)--------------- -------------- ----------------- 45.92 46 50

Page 108: Introdução ao Oracle 8i

Funções Básicas

Utilizando a Função TRUNC

A função TRUNC trunca a coluna, expressão ou valor para n casas decimais.

A função TRUNC opera com argumentos semelhantes aos da função ROUND. Se o segundo argumento é 0 ou não for informado, o valor é truncado para zero casas decimais. Se o segundo argumento é 2, o valor é truncado para duas casas decimais. Reciprocamente, se o segundo argumento é -2, o valor é truncado para duas casas decimais à esquerda.

Como a função ROUND, a função TRUNC também pode ser utilizada com funções de data.

On Targget Treinamento e Consultoria 14

SQL> SELECT TRUNC(45.923,2), TRUNC(45.923), 2 TRUNC(45.923,-1) 3 FROM DUAL;

TRUNC(45.923,2) TRUNC(45.923) TRUNC(45.923,-1)--------------- ------------- ---------------- 45.92 45 40

Page 109: Introdução ao Oracle 8i

Funções Básicas

Utilizando a Função MOD

A função MOD encontra o resto da divisão do valor 1 pelo valor 2. O exemplo acima calcula o resto da divisão do salário pela comissão para todos os empregados cujo cargo seja SALESMAN.

On Targget Treinamento e Consultoria 15

SQL> SELECT ename, sal, comm, MOD(sal, comm) 2 FROM emp 3 WHERE job = 'SALESMAN';

ENAME SAL COMM MOD(SAL,COMM)---------- --------- --------- -------------MARTIN 1250 1400 1250ALLEN 1600 300 100TURNER 1500 0 1500WARD 1250 500 250

Page 110: Introdução ao Oracle 8i

Funções Básicas

Trabalhando com Datas

Formato de Data Oracle

O Oracle armazena datas em um formato numérico interno, representando o século, ano, mês, dia, horas, minutos e segundos.

O formato padrão para exibição e entrada de datas é DD-MON-YY. Datas válidas do Oracle estão entre 1 de janeiro de 4712 A.C. e 31 de dezembro de 9999 D.C.

SYSDATE

SYSDATE é uma função de data que retorna a data e hora atual. Você pode utilizar SYSDATE da mesma maneira que você utiliza qualquer outro nome de coluna. Por exemplo, você pode exibir a data atual selecionando SYSDATE a partir de uma tabela. É habitual selecionar SYSDATE a partir de uma tabela dummy chamada DUAL.

DUAL

A tabela DUAL pertence ao usuário SYS e pode ser acessada por todos os usuários. Contém uma coluna, DUMMY, e uma linha com o valor X. A tabela DUAL é útil quando você quer retornar um valor uma única vez, podendo este valor ser uma constante, pseudocoluna ou expressão que não são derivadas de uma tabela com dados de usuário.

Exemplo:

Mostre a data corrente utilizando a tabela DUAL.

On Targget Treinamento e Consultoria 16

SQL> SELECT SYSDATE 2 FROM DUAL;

Page 111: Introdução ao Oracle 8i

Funções Básicas

Cálculos com Datas

Uma vez que o banco de dados armazena as como números, você pode executar cálculos utilizando os operadores aritméticos como a adição e subtração. Você pode adicionar e subtrair constantes numéricas e datas.

Você pode executar as seguintes operações:

Operação Resultado Descriçãodata + número Data Adiciona um número de dias para uma datadata - número Data Subtrai um número de dias a partir de uma datadata - data Número de dias Subtrai uma data a partir de outradata + número/24 Data Adiciona um número de horas para uma data

On Targget Treinamento e Consultoria 17

Page 112: Introdução ao Oracle 8i

Funções Básicas

Utilizando Operadores Aritméticos com Datas

O exemplo acima exibe o nome e o número de semanas trabalhadas para todos os empregados do departamento 10. Ele subtrai a data atual (SYSDATE) a partir da data na qual o empregado foi contratado e divide o resultado por 7 para calcular o número de semanas que um trabalhador está empregado.

Nota: SYSDATE é uma função SQL que retorna a data e hora atual. Seus resultados podem diferir do exemplo.

On Targget Treinamento e Consultoria 18

SQL> SELECT ename, (SYSDATE-hiredate)/7 WEEKS 2 FROM emp 3 WHERE deptno = 10;

ENAME WEEKS---------- ---------KING 830.93709CLARK 853.93709MILLER 821.36566

Page 113: Introdução ao Oracle 8i

Funções Básicas

Funções de Data

Funções de data operam em datas Oracle. Todas as funções de data retornam um valor do tipo de dado DATE, exceto a função MONTHS_BETWEEN que retorna um valor numérico.

MONTHS_BETWEEN(date1, date2): Encontra o número de meses entre date1 e date2. O resultado pode ser positivo ou negativo. Se date1 é posterior a date2, o resultado é positivo; se date1 é mais recente que date2, o resultado é negativo. A parte não inteira do resultado representa uma porção do mês.

ADD_MONTHS(date, n): Adiciona n número de meses do calendário para a data. n deve ser um inteiro e pode ser negativo.

NEXT_DAY(date, 'char'): Encontra a data do próximo dia da semana ('char') a partir da data do parâmetro date; 'char' pode ser um número representando um dia ou uma string de caracteres.

LAST_DAY(date): Encontra a data do último dia do mês a partir da data especificada no parâmetro date.

ROUND(date [, ' fmt']): Retorna a data arredondada para a unidade especificada pelo formato fmt. Se o formato fmt for omitido, a data é arredondada para a data mais próxima.

TRUNC(date [, ' fmt']): Retorna a data com a porção de tempo do dia truncada à unidade especificada pelo formato fmt. Se o formato fmt for omitido, a data é truncada para o dia mais próximo.

On Targget Treinamento e Consultoria 19

Page 114: Introdução ao Oracle 8i

Funções Básicas

Utilizando Funções de Data

Exemplo:

Para todos os empregados contratados a menos de 200 meses, selecione o número do empregado, a data de admissão, o número de meses trabalhados, data de revisão com seis meses, primeira sexta-feira após a data de admissão e o último dia do mês em que foi contratado.

On Targget Treinamento e Consultoria 20

SQL> SELECT empno, hiredate, 2 MONTHS_BETWEEN(SYSDATE, hiredate) MONTHS, 3 ADD_MONTHS(hiredate, 6) REVIEW, 4 NEXT_DAY(hiredate, 'FRIDAY'), LAST_DAY(hiredate) 5 FROM emp 6 WHERE MONTHS_BETWEEN (SYSDATE, hiredate) < 200;

EMPNO HIREDATE MONTHS REVIEW NEXT_DAY( LAST_DAY(--------- --------- --------- --------- --------- --------- 7839 17-NOV-81 192.24794 17-MAY-82 20-NOV-81 30-NOV-81 7698 01-MAY-81 198.76407 01-NOV-81 08-MAY-81 31-MAY-81...11 rows selected.

Page 115: Introdução ao Oracle 8i

Funções Básicas

As funções ROUND e TRUNC podem ser utilizadas para valores numéricos e de data. Quando utilizadas com datas, elas arredondam ou truncam para o modelo de formato especificado. Portanto, você pode arredondar datas para o mais próximo ano ou mês.

Exemplo:

Compare as datas de admissão para todos os empregados que começaram em 1987. Mostre o número do empregado, a data de admissão e o mês de início utilizando as funções ROUND e TRUNC.

On Targget Treinamento e Consultoria 21

SQL> SELECT empno, hiredate, 2 ROUND(hiredate, 'MONTH'), 3 TRUNC(hiredate, 'MONTH') 4 FROM emp 5 WHERE hiredate like '%87';

EMPNO HIREDATE ROUND(HIR TRUNC(HIR--------- --------- --------- --------- 7788 19-APR-87 01-MAY-87 01-APR-87 7876 23-MAY-87 01-JUN-87 01-MAY-87

Page 116: Introdução ao Oracle 8i

Funções Básicas

Funções de Conversão

Além dos tipos de dados Oracle, as colunas de uma tabela no banco de dados Oracle8i podem ser definidas utilizando tipos de dados ANSI, DB2 e SQL/DS. Entretanto, o Servidor Oracle internamente converte tais tipos de dados para tipos de dados Oracle8i.

Em alguns casos, o Servidor Oracle permite dados de um determinado tipo onde ele esperava dados de um tipo diferente. Isto é permitido porque o Servidor Oracle pode converter os dados automaticamente para o tipo de dado esperado. Esta conversão de tipo de dado pode ser feita implicitamente pelo Servidor Oracle ou explicitamente pelo usuário.

Conversões implícitas de tipo de dado ocorrem de acordo com as regras apresentadas a seguir.

Conversões explícitas de tipo de dado são feitas utilizando as funções de conversão. As funções de conversão convertem um valor de um tipo de dado para outro.

Nota: Embora a conversão de tipo de dado implícita esteja disponível, é recomendado que você faça a conversão explícita para assegurar confiabilidade de seus comandos SQL.

Conversão Implícita de Tipos de Dados

Para atribuições, o Servidor Oracle pode converter automaticamente o seguinte:

VARCHAR2 ou CHAR para NUMBER VARCHAR2 ou CHAR para DATE NUMBER para VARCHAR2 DATE para VARCHAR2

A atribuição tem sucesso se o Servidor Oracle puder converter o tipo de dado do valor utilizado na atribuição para o tipo de dado do destino da atribuição.

Para a avaliação de uma expressão, o Servidor Oracle pode converter automaticamente o seguinte:

VARCHAR2 ou CHAR para NUMBER VARCHAR2 ou CHAR para DATE

Em geral, o Servidor Oracle utiliza a regra para expressões quando uma conversão de tipo de dado é necessária e a regra de conversão em atribuições não pode ser aplicada.

Nota: Conversões de CHAR para NUMBER só tem sucesso se a string de caracteres representa um número válido. Conversões de CHAR para DATE só tem sucesso se a string de caracteres estiver no formato padrão DD-MON-YY.

On Targget Treinamento e Consultoria 22

Page 117: Introdução ao Oracle 8i

Funções Básicas

Conversão Explícita de Tipos de Dados

O SQL provê três funções para converter um valor de um tipo de dado para outro.

Função Propósito

TO_CHAR(number|date,['fmt']) Converte um valor numérico ou data para uma string de caracteres do tipo VARCHAR2 no formato fmt

TO_NUMBER(char)Converte uma string de caracteres contendo apenas dígitos para um número

TO_DATE(char,['fmt'])

Converte uma string de caracteres representando uma data para um valor de data de acordo com o formato fmt especificado (Se fmt for omitido, o formato padrão é DD-MON-YY)

On Targget Treinamento e Consultoria 23

Page 118: Introdução ao Oracle 8i

Funções Básicas

Função TO_CHAR com Datas

Exibindo uma Data em um Formato Específico

Os valores de data no Oracle são exibidos por default no formato DD-MON-YY. A função TO_CHAR permite converter uma data para um formato específico.

Diretrizes:

A máscara de formatação deve ser incluída entre aspas simples e faz distinção entre maiúsculas e minúsculas.

A máscara de formatação pode incluir qualquer elemento de formato de data válido. Os nomes de dias e meses são automaticamente preenchidos com espaços em branco. Para remover espaços em branco ou suprimir zeros à esquerda, utilize o elemento de

formatação fm (fill mode). Você pode redimensionar a largura de exibição do campo caractere resultante com o

comando COLUMN do SQL*Plus. A largura da coluna resultante é por default 80 caracteres.

On Targget Treinamento e Consultoria 24

TO_CHAR(date, 'fmt')

SQL> SELECT empno, TO_CHAR(hiredate, 'MM/YY') Month_Hired 2 FROM emp 3 WHERE ename = 'BLAKE';

Page 119: Introdução ao Oracle 8i

Funções Básicas

Elementos de Formatação de Datas

Exemplos de Elementos de Formatação de Data Válidos

Elemento DescriçãoSCC or CC Século; S prefixa datas AC com -YYYY ou SYYYY Ano; S prefixa datas AC com -YYY ou YY ou Y Últimos 3, 2 ou 1 dígito(s) do anoY,YYY Ano com uma vírgula nesta posiçãoIYYY, IYY, IY, I 4, 3, 2 ou 1 dígito(s) do ano baseado no padrão ISOSYEAR ou YEAR Ano soletrado; S prefixa datas AC com -BC ou AD Indicador AC / DCB.C. ou A.D. Indicador AC / DC com pontosQ Quarto do anoMM Valor do mês com dois dígitosMONTH Nome do mês com brancos para completar o tamanho de 9 caracteresMON Nome do mês abreviado com três letrasRM Número do mês em RomanoWW ou W Semana do ano ou mêsDDD ou DD ou D Dia do ano, mês ou semanaDAY Nome do dia com brancos para completar o tamanho de 9 caracteresDY Nome do dia abreviado com três letrasJ Dia Juliano; o número de dias desde 31 de dezembro de 4713 AC

Formatos de Hora

Utilize os formatos listados na tabela abaixo para exibir informações de hora e literais e para mudar números para números soletrados.

Elemento DescriçãoAM ou PM Indicador meridianoA.M. ou P.M. Indicador meridiano com pontosHH ou HH12 ou HH24 Hora do dia ou hora (1–12) ou hora (0–23)MI Minuto (0–59)SS Segundo (0–59)SSSSS Segundos desde à meia noite (0–86399)

On Targget Treinamento e Consultoria 25

Page 120: Introdução ao Oracle 8i

Funções Básicas

Outros Formatos

Elemento Descrição/ . , A pontuação é reproduzida no resultado"of the" Strings entre aspas duplas são reproduzidas no resultado

Sufixos podem Influenciar a Exibição de Números

Elemento DescriçãoTH Número ordinal (por exemplo, DDTH para 4TH)SP Número soletrado (por exemplo, DDSP para FOUR)SPTH ou THSP Número ordinal soletrado (por exemplo, DDSPTH para FOURTH)

On Targget Treinamento e Consultoria 26

Page 121: Introdução ao Oracle 8i

Funções Básicas

Utilizando a Função TO_CHAR com Datas

O comando SQL acima exibe o nome e as datas de admissão para todos os empregados. A data de admissão é formatada como '17 November 1981'.

Exemplo:

Modificando o comando acima para exibir as datas em um formato que se parece com 'Seventh of February of 1981 08:00:00 AM'.

Observe que o mês segue o modelo de formato especificado para a palavra ‘Month’.

On Targget Treinamento e Consultoria 27

SQL> SELECT ename, 2 TO_CHAR(hiredate, 'fmDD Month YYYY') HIREDATE 3 FROM emp;

ENAME HIREDATE---------- -----------------KING 17 November 1981BLAKE 1 May 1981CLARK 9 June 1981JONES 2 April 1981MARTIN 28 September 1981ALLEN 20 February 1981...14 rows selected.

ENAME HIREDATE---------- ------------------------------------------------KING Seventeenth of November 1981 12:00:00 AMBLAKE First of May 1981 12:00:00 AM...14 rows selected.

SQL> SELECT ename, 2 TO_CHAR(hiredate, 3 'fmDdspth "of" Month YYYY fmHH:MI:SS AM') HIREDATE 4 FROM emp;

Page 122: Introdução ao Oracle 8i

Funções Básicas

Função TO_CHAR com Números

Quando trabalhar com valores numéricos como se fossem strings de caractere, você deve converter esses números para o tipo de dado caractere utilizando a função TO_CHAR que traduz um valor do tipo de dado NUMBER para o tipo de dado VARCHAR2. Esta técnica é especialmente útil em concatenações.

Elementos de Formatação de Números

Se você está convertendo um número para o tipo de dado caractere, você pode utilizar os elementos listados abaixo:

Elemento Descrição Exemplo Resultado

9Posição numérica (o número de 9s determina o tamanho da exibição)

999999 1234

0 Complementa com zeros a partir da posição especificada 099999 001234$ Indicador de dólar flutuante $999999 $1234L Símbolo flutuante da moeda local L999999 FF1234. Ponto decimal na posição especificada 999999.99 1234.00, Vírgula na posição especificada 999,999 1,234

MI Sinal de menos à direita (valores negativos) 999999MI 1234-PR Números negativos entre parênteses 999999PR <1234>

EEEE Notação científica (o formato deve especificar quatro Es) 99.999EEEE 1.234E+03V Multiplica o valor por 10 n vezes (n = número de 9s após V) 9999V99 123400B Exibe o valor zero como brancos, e não como 0 B9999.99 1234.00

On Targget Treinamento e Consultoria 28

TO_CHAR(number, 'fmt')

Page 123: Introdução ao Oracle 8i

Funções Básicas

Utilizando a Função TO_CHAR com Números

Diretrizes

O Servidor Oracle exibe uma string com o caractere (#) ao invés de um número quando o número de dígitos excedem o número de dígitos providos pela máscara.

O Servidor Oracle arredonda o valor decimal armazenado para o número de espaços decimais providos pela máscara.

On Targget Treinamento e Consultoria 29

SQL> SELECT TO_CHAR(sal,'$99,999') SALARY 2 FROM emp 3 WHERE ename = 'SCOTT';

SALARY-------- $3,000

Page 124: Introdução ao Oracle 8i

Funções Básicas

Funções TO_NUMBER e TO_DATE

Você pode querer converter uma string de caracteres para um número ou uma data. Para realizar esta tarefa, você utiliza as funções TO_NUMBER e TO_DATE. A máscara que você pode escolher baseia-se nos elementos de formato apresentados anteriormente.

Exemplo:

Mostre os nomes e as datas de admissão de todos os empregados que foram admitidos em 22 de fevereiro de 1981 (‘February 22, 1981’).

On Targget Treinamento e Consultoria 30

TO_NUMBER(char)

TO_DATE(char[, 'fmt'])

SQL> SELECT ename, hiredate 2 FROM emp 3 WHERE hiredate = TO_DATE('February 22, 1981', 4 'Month dd, YYYY');

ENAME HIREDATE---------- --------WARD 22-FEB-81

Page 125: Introdução ao Oracle 8i

Funções Básicas

Formato de Data RR

O formato de data RR é semelhante ao elemento YY, entretanto, permite especificar séculos diferentes. Você pode utilizar o elemento de formatação de data RR no lugar do YY, de forma que o século do valor retornado varie de acordo com o ano de dois dígitos especificado e os últimos dois dígitos do ano atual. A tabela no gráfico acima resume o comportamento do elemento de RR.

Ano atual Data Especificada (RR) (YY)1994 27-OCT-95 1995 19951994 27-OCT-17 2017 19172001 27-OCT-17 2017 2017

On Targget Treinamento e Consultoria 31

Page 126: Introdução ao Oracle 8i

Funções Básicas

Função NVL

Para converter um valor nulo para outro valor do mesmo tipo, utilize a função NVL

Sintaxe:

Onde:

expr1 é o valor ou expressão de origem que pode conter nulo.

expr2 é o valor de destino utilizado quando o valor de origem for nulo.

Você pode utilizar a função NVL para converter qualquer tipo de dado, porém, o valor de retorno deve sempre ser do mesmo tipo de dado do parâmetro expr1.

Conversões NVL para Vários Tipos de Dados

Tipo de Dado Exemplo de ConversãoNUMBER NVL(number_column, 9)DATE NVL(date_column, '01-JAN-95')CHAR ou VARCHAR2 NVL(character_column, 'Unavailable')

On Targget Treinamento e Consultoria 32

NVL(comm,0)NVL(hiredate,'01-JAN-97')NVL(job,’Cargo Desconhecido')

NVL(expr1, expr2)

Page 127: Introdução ao Oracle 8i

Funções Básicas

Utilizando a Função NVL

Para calcular a compensação anual de todos os empregados, você precisa multiplicar o salário mensal por 12 e então adicionar o valor da comissão.

Observe que a compensação anual só é calculada para aqueles empregados que ganham comissão. Se em uma expressão qualquer valor de coluna for nulo, o resultado também será nulo. Para calcular valores para todos os empregados, você deve converter o valor nulo para um número antes de aplicar o operador aritmético. No exemplo acima, a função NVL é utilizada para converter valores nulos para zero.

On Targget Treinamento e Consultoria 33

SQL> SELECT ename, sal, comm, (sal*12)+NVL(comm,0) 2 FROM emp;ENAME SAL COMM (SAL*12)+NVL(COMM,0)---------- --------- --------- --------------------KING 5000 60000BLAKE 2850 34200CLARK 2450 29400JONES 2975 35700MARTIN 1250 1400 16400ALLEN 1600 300 19500...14 rows selected.

SQL> SELECT ename, sal, comm, (sal*12)+comm 2 FROM emp;ENAME JOB (SAL*12)+COMM---------- --------- -------------KING PRESIDENTBLAKE MANAGERCLARK MANAGER JONES MANAGERMARTIN SALESMAN 16400...14 rows selected.

Page 128: Introdução ao Oracle 8i

Funções Básicas

Função DECODE

A função DECODE decodifica uma expressão de modo semelhante a lógica IF-THEN-ELSE utilizada em diversas linguagens. A função DECODE decodifica a expressão após compará-la com cada valor de pesquisa. Se a expressão for igual ao valor de pesquisa, o resultado correspondente é retornado.

Se o valor default for omitido, um valor nulo será retornado quando o parâmetro col/expression não for igual a nenhum dos valores de pesquisa.

On Targget Treinamento e Consultoria 34

DECODE(col/expression, search1, result1 [, search2, result2,...,] [, default])

Page 129: Introdução ao Oracle 8i

Funções Básicas

Utilizando a Função DECODE

No comando SQL acima, o valor de JOB é decodificado. Se JOB for ANALYST, o aumento de salário é de 10%; se JOB for CLERK, o aumento de salário é de 15%; se JOB for MANAGER, o aumento de salário é de 20%. Para todos os outros cargos, não há nenhum aumento de salário.

O mesmo comando pode ser escrito como um comando IF-THEN-ELSE:

On Targget Treinamento e Consultoria 35

SQL> SELECT job, sal, 2 DECODE(job, 'ANALYST', SAL*1.1, 3 'CLERK', SAL*1.15, 4 'MANAGER', SAL*1.20, 5 SAL) 6 REVISED_SALARY 7 FROM emp;

JOB SAL REVISED_SALARY--------- --------- --------------PRESIDENT 5000 5000MANAGER 2850 3420MANAGER 2450 2940...14 rows selected.

IF job = 'ANALYST' THEN sal = sal*1.1IF job = 'CLERK' THEN sal = sal*1.15IF job = 'MANAGER' THEN sal = sal*1.20ELSE sal = sal

Page 130: Introdução ao Oracle 8i

Funções Básicas

Aninhando Funções

Funções básicas (single-row) podem ser aninhadas em qualquer nível. Funções aninhadas são avaliadas do nível mais interno para o nível mais externo. Abaixo seguem alguns exemplos para mostrar a flexibilidade destas funções.

O exemplo acima exibe o presidente da companhia que não possui nenhum gerente. A avaliação do comando SQL envolve dois passos:

1. Avalia a função interna para converter um valor numérico para uma string de caracteres.

Resultado1 = TO_CHAR(mgr)

2. Avalia a função externa para substituir o valor nulo por uma string de texto.

NVL(Resultado1, 'Sem Gerente')

A expressão inteira torna-se o cabeçalho da coluna, uma vez que nenhum alias de coluna foi especificado.

Exemplo:

Mostre a data da próxima sexta-feira seis meses após a data de admissão. A data resultante deve ser formatada como 'Friday, March 12th, 1982'. Ordene o resultado pela data de admissão.

On Targget Treinamento e Consultoria 36

SQL> SELECT ename, 2 NVL(TO_CHAR(mgr),'Sem Gerente') 3 FROM emp 4 WHERE mgr IS NULL;

ENAME NVL(TO_CHAR(MGR),'SEMGERENTE')---------- ------------------------------KING Sem Gerente

SQL> SELECT TO_CHAR(NEXT_DAY(ADD_MONTHS 2 (hiredate, 6), 'FRIDAY'), 3 'fmDay, Month ddth, YYYY') 4 "Next 6 Month Review" 5 FROM emp 6 ORDER BY hiredate;

Page 131: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 4

1. Escreva uma consulta para exibir a data atual. Coloque o alias de coluna como “Date”.

2. Mostre o número do empregado, o nome, o salário e o salary com um aumento de 15%. Coloque o alias da coluna como “New Salary”. Salve o comando SQL para um arquivo chamado e4q2.sql.

3. Execute a consulta do arquivo e4q2.sql.

4. Altere a consulta em e4q2.sql para adicionar uma nova coluna que subtraia o salário antigo do novo salário. Coloque o alias da coluna como “Increase”. Reexecute a consulta.

5. Mostre o nome do empregado, a data de admissão e data de revisão do salário, que deve ser a primeira segunda-feira após seis meses de trabalho. Coloque o alias da coluna como “REVIEW”. Formate a data para uma padrão semelhante a “Sunday, the Seventh of September, 1981”.

6. Mostre o nome de cada empregado e calcule o número de meses entre a data atual e a data na qual ele foi contratado. Coloque o alias da coluna como “MONTHS_WORKED”. Ordene o resultado pelo número de meses trabalhados. Arredonde o número de meses para o número inteiro mais próximo.

7. Escreva uma consulta que reproduza o seguinte para cada empregado, colocando o alias da coluna como “Dream Salaries”:

<nome do empregado> earns <salário> monthly but wants <3 vezes o salário>.

On Targget Treinamento e Consultoria 37

Date---------28-OCT-97

EMPNO ENAME SAL New Salary----- ------- ----- ---------- 7839 KING 5000 5750 7698 BLAKE 2850 3278 7782 CLARK 2450 2818 7566 JONES 2975 3421 7654 MARTIN 1250 1438 7499 ALLEN 1600 1840 7844 TURNER 1500 1725 7900 JAMES 950 1093 7521 WARD 1250 1438 7902 FORD 3000 3450 7369 SMITH 800 920 7788 SCOTT 3000 3450 7876 ADAMS 1100 1265 7934 MILLER 1300 149514 rows selected.

EMPNO ENAME SAL New Salary Increase----- ------ ----- ---------- -------- 7839 KING 5000 5750 750 7698 BLAKE 2850 3278 428 7782 CLARK 2450 2818 368 7566 JONES 2975 3421 446

ENAME HIREDATE REVIEW----- -------- -----------------------------------------KING 17-NOV-81 Monday, the Twenty-Fourth of May, 1982BLAKE 01-MAY-81 Monday, the Second of November, 1981CLARK 09-JUN-81 Monday, the Fourteenth of December, 1981JONES 02-APR-81 Monday, the Fifth of October, 1981MARTIN 28-SEP-81 Monday, the Twenty-Ninth of March, 1982ALLEN 20-FEB-81 Monday, the Twenty-Fourth of August, 1981TURNER 08-SEP-81 Monday, the Fifteenth of March, 1982JAMES 03-DEC-81 Monday, the Seventh of June, 1982WARD 22-FEB-81 Monday, the Twenty-Fourth of August, 1981FORD 03-DEC-81 Monday, the Seventh of June, 1982SMITH 17-DEC-80 Monday, the Twenty-Second of June, 1981SCOTT 09-DEC-82 Monday, the Thirteenth of June, 1983ADAMS 12-JAN-83 Monday, the Eighteenth of July, 1983MILLER 23-JAN-82 Monday, the Twenty-Sixth of July, 198214 rows selected.

ENAME MONTHS_WORKED------- -------------ADAMS 177SCOTT 178MILLER 188JAMES 190FORD 190KING 191MARTIN 192TURNER 193CLARK 196BLAKE 197JONES 198WARD 199ALLEN 199SMITH 20214 rows selected

Page 132: Introdução ao Oracle 8i

Funções Básicas

Se houver tempo, complete os seguintes exercícios:

8. Crie uma consulta para exibir o nome e o salário para todos os empregados. Formate o salário para 15 caracteres de tamanho, preenchendo os espaços à esquerda com o caractere “$”. Coloque o alias da coluna como “SALARY”.

9. Escreva uma consulta que mostre o nome do empregado com a primeira letra em maiúscula e as demais em minúsculas, juntamente com o tamanho de seu nome, para todos os empregados cujo nome inicie com a letra J, A ou M. Coloque um alias apropriado para cada coluna.

10. Mostre o nome, a data de admissão e o dia da semana no qual o empregado começou a trabalhar. Coloque o alias da coluna como “DAY”. Ordene o resultado pelo dia da semana, começando com “Monday”.

Se você quiser um desafio extra, complete os exercícios seguintes:

11. Crie uma consulta que mostre o nome do empregado e o valor da comissão. Se o empregado não recebe comissão, mostre a string “No Commission”. Coloque o alias de coluna como “COMM”.

5.5.

On Targget Treinamento e Consultoria 38

Dream Salaries----------------------------------------------------KING earns $5,000.00 monthly but wants $15,000.00.BLAKE earns $2,850.00 monthly but wants $8,550.00.CLARK earns $2,450.00 monthly but wants $7,350.00.JONES earns $2,975.00 monthly but wants $8,925.00.MARTIN earns $1,250.00 monthly but wants $3,750.00.ALLEN earns $1,600.00 monthly but wants $4,800.00TURNER earns $1,500.00 monthly but wants $4,500.00.JAMES earns $950.00 monthly but wants $2,850.00.WARD earns $1,250.00 monthly but wants $3,750.00.FORD earns $3,000.00 monthly but wants $9,000.00.SMITH earns $800.00 monthly but wants $2,400.00.SCOTT earns $3,000.00 monthly but wants $9,000.00.ADAMS earns $1,100.00 monthly but wants $3,300.00MILLER earns $1,300.00 monthly but wants $3,900.00.14 rows selected.

ENAME SALARY-------- ---------------SMITH $$$$$$$$$$$$800ALLEN $$$$$$$$$$$1600WARD $$$$$$$$$$$1250JONES $$$$$$$$$$$2975MARTIN $$$$$$$$$$$1250BLAKE $$$$$$$$$$$2850CLARK $$$$$$$$$$$2450SCOTT $$$$$$$$$$$3000KING $$$$$$$$$$$5000TURNER $$$$$$$$$$$1500ADAMS $$$$$$$$$$$1100JAMES $$$$$$$$$$$$950FORD $$$$$$$$$$$3000MILLER $$$$$$$$$$$130014 rows selected.

Name Length------- ------Jones 5Martin 6Allen 5James 5Adams 5Miller 66 rows selected.

ENAME HIREDATE DAY------ --------- -----------MARTIN 28-SEP-81 MONDAYCLARK 09-JUN-81 TUESDAYKING 17-NOV-81 TUESDAYTURNER 08-SEP-81 TUESDAYSMITH 17-DEC-80 WEDNESDAYADAMS 12-JAN-83 WEDNESDAYJONES 02-APR-81 THURSDAYFORD 03-DEC-81 THURSDAYSCOTT 09-DEC-82 THURSDAYJAMES 03-DEC-81 THURSDAYALLEN 20-FEB-81 FRIDAYBLAKE 01-MAY-81 FRIDAYMILLER 23-JAN-82 SATURDAYWARD 22-FEB-81 SUNDAY14 rows selected

ENAME COMM------ -----------SMITH No CommissionALLEN 300WARD 500JONES No CommissionMARTIN 1400BLAKE No CommissionCLARK No CommissionSCOTT No CommissionKING No CommissionTURNER 0ADAMS No CommissionJAMES No CommissionFORD No CommissionMILLER No Commission14 rows selected.

Page 133: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

6.6. Exibindo Dados a Partir deExibindo Dados a Partir de Múltiplas TabelasMúltiplas Tabelas

On Targget Treinamento e Consultoria

Page 134: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Escrever comandos SELECT para acessar dados de mais de uma tabela utilizando diversos tipos de joins.

Visualizar dados que geralmente não correspondem a condição de join utilizando outer joins.

Executar um join de uma tabela com ela mesma (self join).

Este capítulo discute como obter dados de várias tabelas, utilizando os diferentes métodos disponíveis

On Targget Treinamento e Consultoria 2

Page 135: Introdução ao Oracle 8i

Funções Básicas

Obtendo Dados a Partir de Múltiplas Tabelas

Às vezes você precisa utilizar dados de mais de uma tabela. No exemplo acima, o relatório exibe dados de duas tabelas diferentes.

EMPNO existe na tabela EMP. DEPTNO existe nas tabelas EMP e DEPT. LOC existe na tabela DEPT.

Para produzir o relatório, você precisa unir as tabelas EMP e DEPT e acessar os dados a partir de ambas.

On Targget Treinamento e Consultoria 3

Page 136: Introdução ao Oracle 8i

Funções Básicas

O que é um Join?

Quando dados de mais de uma tabela são requeridos, uma condição de join é utilizada. Linhas em uma tabela podem ser unidas à linhas em outra tabela de acordo com valores comuns que existem em colunas correspondentes, que normalmente são colunas de chaves primárias e estrangeiras.

Para exibir dados de duas ou mais tabelas relacionadas, escreva uma condição de join simples na cláusula WHERE.

Sintaxe:

table.column denota a tabela e coluna a partir da qual os dados são recuperados.

table1.column1 é a condição que une (ou relaciona) as tabelas.= table2.column2

Diretrizes

Quando escrever um comando SELECT que relaciona tabelas, preceda o nome das colunas com o nome da tabela para obter maior clareza e melhorar o acesso ao banco de dados.

Se o mesmo nome de coluna existir em mais de uma tabela, o nome de coluna deve ser prefixado com o nome da tabela.

Para unir n tabelas, você precisa de um mínimo de (n-1) condições de join. Portanto, para unir quatro tabelas, um mínimo de três joins são necessários. Esta regra pode não se aplicar se a tabela possuir uma chave primária concatenada. Neste caso mais de uma coluna é necessária para identificar cada linha de forma exclusiva.

On Targget Treinamento e Consultoria 4

SELECT table1.column, table2.columnFROM table1, table2WHERE table1.column1 = table2.column2;

Page 137: Introdução ao Oracle 8i

Funções Básicas

Produto Cartesiano

Quando uma condição de join é invalida ou completamente omitida, o resultado é um produto cartesiano no qual serão exibidas todas as combinações das linhas. Todas as linhas da primeira tabela são unidas à todas as linhas da segunda tabela.

Um produto cartesiano tende a gerar um número grande de linhas, e seu resultado é raramente útil. Você sempre deveria incluir uma condição de join válida na cláusula WHERE, a menos que você tenha uma necessidade específica para combinar todas as filas de todas as tabelas.

On Targget Treinamento e Consultoria 5

Page 138: Introdução ao Oracle 8i

Funções Básicas

Gerando um Produto Cartesiano

Um produto cartesiano é gerado se uma condição de join for omitida. O exemplo no gráfico acima exibe o nome do empregado e o nome do departamento a partir das tabelas EMP e DEPT. Uma vez que nenhuma cláusula WHERE foi especificada, todas as linhas (14 linhas) da tabela EMP são unidas com todas as linhas (4 linhas) da tabela DEPT, gerando um total de 56 linhas na consulta.

On Targget Treinamento e Consultoria 6

SQL> SELECT ename, dname 2 FROM emp, dept;ENAME DNAME---------- --------------KING ACCOUNTINGBLAKE ACCOUNTING...KING RESEARCHBLAKE RESEARCH...56 rows selected.

Page 139: Introdução ao Oracle 8i

Funções Básicas

Tipos de Joins

Existem dois tipos principais de condições de join:

Equijoins Non-equijoins

Métodos adicionais de join incluem o seguinte:

Outer joins Self joins Set Operators

On Targget Treinamento e Consultoria 7

Page 140: Introdução ao Oracle 8i

Funções Básicas

O que é um Equijoin?

Para determinar o nome do departamento de um empregado, você compara o valor na coluna DEPTNO da tabela EMP com os valores de DEPTNO da tabela DEPT. A relação entre as tabelas EMP e DEPT é um equijoin, ou seja, os valores na coluna DEPTNO em ambas as tabelas devem ser iguais. Freqüentemente, este tipo de join envolve complementos de chave primária e estrangeira.

Nota: Equijoins também são chamados de joins simples ou de inner joins.

On Targget Treinamento e Consultoria 8

Page 141: Introdução ao Oracle 8i

Funções Básicas

Recuperando Registros com Equijoins

No exemplo acima:

A cláusula SELECT especifica os nomes de coluna à recuperar: nome de empregado, número do empregado e o número do departamento que são

colunas da tabela EMP. número do departamento, nome do departamento e a localização que são colunas da

tabela DEPT. A cláusula FROM especifica as duas tabelas que o banco de dados deve acessar:

Tabela EMP. Tabela DEPT.

A cláusula WHERE especifica como as tabelas serão unidas: EMP.DEPTNO = DEPT.DEPTNO

Uma vez que a coluna DEPTNO é comum a ambas as tabelas, deve ser prefixada com o nome da tabela para evitar ambigüidade.

On Targget Treinamento e Consultoria 9

SQL> SELECT emp.empno, emp.ename, emp.deptno, 2 dept.deptno, dept.loc 3 FROM emp, dept 4 WHERE emp.deptno = dept.deptno;

EMPNO ENAME DEPTNO DEPTNO LOC----- ------ ------ ------ --------- 7839 KING 10 10 NEW YORK 7698 BLAKE 30 30 CHICAGO 7782 CLARK 10 10 NEW YORK 7566 JONES 20 20 DALLAS...14 rows selected.

Page 142: Introdução ao Oracle 8i

Funções Básicas

Qualificando Nomes de Colunas Ambíguos

Você precisa qualificar os nomes das colunas na cláusula WHERE com o nome da tabela para evitar ambigüidade. Sem os prefixos de tabela, a coluna DEPTNO poderia ser da tabela DEPT ou da tabela EMP. É necessário adicionar o prefixo de tabela para executar a consulta.

Se não existir nenhum nome de coluna comum entre as duas tabelas, não há necessidade de qualificar as colunas. Entretanto, você ganhará desempenho utilizando o prefixo de tabela porque você informa exatamente para o Servidor Oracle onde procurar pelas colunas.

A exigência para qualificar os nomes de coluna ambíguos também é aplicável para colunas que podem ser ambíguas em outras cláusulas como SELECT ou ORDER BY.

On Targget Treinamento e Consultoria 10

Page 143: Introdução ao Oracle 8i

Funções Básicas

Condições Adicionais de Pesquisa com o Operador AND

Em adição ao join, você pode ter critérios adicionais na cláusula WHERE. Por exemplo, para exibir o número do empregado, o nome, o número do departamento e a localização do departamento, apenas para o empregado KING, você precisa de uma condição adicional na cláusula WHERE.

On Targget Treinamento e Consultoria 11

SQL> SELECT empno, ename, emp.deptno, loc 2 FROM emp, dept 3 WHERE emp.deptno = dept.deptno 4 AND INITCAP(ename) = 'King';

EMPNO ENAME DEPTNO LOC--------- ---------- --------- ------------- 7839 KING 10 NEW YORK

Page 144: Introdução ao Oracle 8i

Funções Básicas

Utilizando Alias de Tabela

Qualificar os nomes de coluna com os nomes de tabela pode consumir muito tempo, particularmente se os nomes de tabelas forem longos. Você pode utilizar alias de tabela em vez de nomes de tabela. Da mesma maneira que um alias de coluna fornece um outro nome para uma coluna, um alias de tabela fornece um outro nome para uma tabela. Alias de tabela ajudam a manter o código SQL menor, utilizando menos memória.

Observe que no exemplo os alias de tabela são identificados na cláusula FROM. O nome da tabela é especificado por completo, seguido por um espaço e então pelo alias de tabela. A tabela EMP recebeu o alias E, enquanto que a tabela DEPT recebeu o alias D.

Diretrizes:

Alias de tabelas podem ter até 30 caracteres de tamanho, porém, quanto menor melhor. Se um alias de tabela for utilizado para um nome de tabela específico na cláusula FROM,

então este alias de tabela deve ser utilizado para substituir o nome da tabela em todo o comando SELECT.

Alias de tabelas devem ser significativos. O alias de tabela só é válido para o comando SELECT no qual foi declarado.

On Targget Treinamento e Consultoria 12

SQL> SELECT emp.empno, emp.ename, emp.deptno, 2 dept.deptno, dept.loc 3 FROM emp, dept 4 WHERE emp.deptno = dept.deptno;

SQL> SELECT e.empno, e.ename, e.deptno, 2 d.deptno, d.loc 3 FROM emp e, dept d 4 WHERE e.deptno = d.deptno;

Page 145: Introdução ao Oracle 8i

Funções Básicas

Relacionando mais de Duas Tabelas

Às vezes você pode precisar unir mais de duas tabelas. Por exemplo, para exibir o nome, os pedidos emitidos, os números dos itens de pedido, o total de cada item e o total de cada pedido do cliente TKB SPORT SHOP, você terá que relacionar as tabelas CUSTOMER, ORD e ITEM.

On Targget Treinamento e Consultoria 13

SQL> SELECT c.name, o.ordid, i.itemid, i.itemtot, o.total 2 FROM customer c, ord o, item i 3 WHERE c.custid = o.custid 4 AND o.ordid = i.ordid 5 AND c.name = 'TKB SPORT SHOP';

NAME ORDID ITEMID ITEMTOT TOTAL------------ --------- --------- --------- ---------TKB SPORT SHOP 610 3 58 101.4TKB SPORT SHOP 610 1 35 101.4TKB SPORT SHOP 610 2 8.4 101.4

Page 146: Introdução ao Oracle 8i

Funções Básicas

Non-Equijoins

A relação entre a tabela EMP e a tabela SALGRADE é um non-equijoin, significando que nenhuma coluna da tabela EMP corresponde diretamente a uma coluna da tabela SALGRADE. A relação entre as duas tabela é que a coluna SAL da tabela EMP está entre as colunas LOSAL e HISAL da tabela SALGRADE. A relação é obtida utilizando um operador diferente de igual (=).

On Targget Treinamento e Consultoria 14

Page 147: Introdução ao Oracle 8i

Funções Básicas

Recuperando Registros com Non-Equijoins

O exemplo acima cria um non-equijoin para avaliar o nível do salário de um empregado. O salário deve estar entre qualquer faixa de valor de menor e maior salário.

É importante observar que todos os empregados aparecem precisamente uma única vez quando a consulta é executada. Nenhum empregado é repetido na lista. Existem duas razões para isto:

Nenhuma das linhas da tabela de níveis de salário contém graus que se sobrepõem. Ou seja, o valor do salário de um empregado só pode estar entre os valores de menor e maior salário de uma das linhas da tabela de níveis de salário.

Todos os salários dos empregados estão dentro dos limites fornecidos pela tabela de níveis de salário. Ou seja, nenhum empregado ganha menos que o menor valor contido na coluna LOSAL ou mais que o maior valor contido na coluna HISAL.

Nota: Outros operadores como <= e >= podem ser utilizados, porém o operador BETWEEN é o mais simples. Lembre-se de especificar o menor valor primeiro e o maior valor por último quando utilizar o operador BETWEEN. Alias de tabela foram especificados por razões de desempenho, não por causa de possíveis ambigüidades.

On Targget Treinamento e Consultoria 15

SQL> SELECT e.ename, e.sal, s.grade 2 FROM emp e, salgrade s 3 WHERE e.sal BETWEEN s.losal AND s.hisal;

ENAME SAL GRADE---------- --------- ---------JAMES 950 1SMITH 800 1ADAMS 1100 1...14 rows selected.

Page 148: Introdução ao Oracle 8i

Funções Básicas

Outer Joins

Se uma linha não satisfaz a condição de join, esta linha não aparecerá no resultado da consulta. Por exemplo, na condição de equijoin das tabelas EMP e DEPT, o departamento OPERAÇÕES não aparece porque ninguém trabalha neste departamento.

On Targget Treinamento e Consultoria 16

SQL> SELECT e.ename, e.deptno, d.dname 2 FROM emp e, dept d 3 WHERE e.deptno = d.deptno;

ENAME DEPTNO DNAME---------- --------- -------------KING 10 ACCOUNTINGBLAKE 30 SALESCLARK 10 ACCOUNTINGJONES 20 RESEARCH... ALLEN 30 SALESTURNER 30 SALESJAMES 30 SALES...14 rows selected.

Page 149: Introdução ao Oracle 8i

Funções Básicas

Recuperando Registros sem Correspondência Direta Utilizando Outer Joins

A(s) linha(s) sem correspondência podem ser recuperadas se um operador de outer join for utilizado na condição de join. O operador é o sinal de adição colocado entre parênteses (+), e é colocado no “lado” do join que é deficiente de informação. Este operador possui o efeito de criar uma ou mais linhas nulas, para as quais uma ou mais linhas da tabela não deficiente podem ser unidas.

Sintaxe:

table1.column = é a condição que relaciona (joins) as tabelas.

table2.column (+) é o símbolo de outer join; ele pode ser colocado em qualquer lado da condição da cláusula, porém, não pode ser colocado em ambos os lados. Coloque o símbolo de outer join logo após o nome da coluna da tabela que pode não possuir dados para corresponder as linhas da outra tabela.

On Targget Treinamento e Consultoria 17

SELECT table.column, table.columnFROM table1, table2WHERE table1.column(+) = table2.column;

SELECT table.column, table.columnFROM table1, table2WHERE table1.column = table2.column(+);

Page 150: Introdução ao Oracle 8i

Funções Básicas

Utilizando Outer Joins

O exemplo acima exibe o nome dos empregados e o número e nome dos departamentos. O departamento OPERATIONS que não possui nenhum empregado também é exibido.

Restrições do Outer Join

O operador outer join só pode aparecer em um dos lados da expressão, o lado que não possui informação correspondente. Ele retorna essas linhas a partir de uma tabela que não possui correspondência direta para a outra tabela.

Uma condição envolvendo um outer join não pode utilizar o operador IN ou ser unida para outra condição pelo operador OR.

On Targget Treinamento e Consultoria 18

SQL> SELECT e.ename, d.deptno, d.dname 2 FROM emp e, dept d 3 WHERE e.deptno(+) = d.deptno 4 ORDER BY e.deptno;

ENAME DEPTNO DNAME---------- --------- -------------KING 10 ACCOUNTINGCLARK 10 ACCOUNTING... 40 OPERATIONS15 rows selected.

Page 151: Introdução ao Oracle 8i

Funções Básicas

Self Joins

Às vezes você precisa relacionar uma tabela com ela mesma. Para encontrar o nome do gerente de cada empregado você precisa unir a tabela EMP com ela mesma. Por exemplo, para achar o nome do gerente do empregado BLAKE, você precisa:

Encontrar o empregado BLAKE na tabela EMP pesquisando através da coluna ENAME. Encontrar o número do gerente de BLAKE através da coluna MGR. O número do gerente

de BLAKE é 7839. Encontrar o nome do gerente com EMPNO 7839 recuperando a coluna ENAME. O

número do empregado KING é 7839. Portanto, KING é o gerente de BLAKE.

Neste processo, você pesquisa duas vezes na mesma tabela. A primeira vez você pesquisa na tabela para encontrar BLAKE na coluna ENAME e o valor de MGR 7839. Na segunda vez você pesquisa na coluna EMPNO pelo valor 7839 e recupera o conteúdo da coluna ENAME com o valor KING.

On Targget Treinamento e Consultoria 19

Page 152: Introdução ao Oracle 8i

Funções Básicas

Relacionando uma Tabela com Ela Mesma

O exemplo acima relaciona a tabela EMP com ela mesma. Para simular duas tabelas na cláusula FROM, existem dois alias, chamados WORKER e MANAGER, para a mesma tabela, EMP.

On Targget Treinamento e Consultoria 20

SQL> SELECT worker.ename || ' works for ' || manager.ename 2 FROM emp worker, emp manager 3 WHERE worker.mgr = manager.empno;

WORKER.ENAME||'WORKSFOR'||MANAG-------------------------------BLAKE works for KINGCLARK works for KINGJONES works for KINGMARTIN works for BLAKE...13 rows selected.

Page 153: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 5

1. Escreva uma consulta para exibir o nome, o número do departamento e o nome do departamento para todos os empregados.

2. Crie uma lista única de todos os cargos que estão no departamento 30.

3. Escreva uma consulta para exibir o nome do empregado, o nome do departamento e a localização de todos os empregados que ganham comissão.

4. Mostre o nome do empregado e o nome do departamento para todos os empregados que possuem a letra A no nome. Salve o comando SQL em um arquivo chamado e5q4.sql.

5. Escreva uma consulta para exibir o nome, o cargo, o número do departamento e o nome do departamento para todos os empregados que trabalham em DALLAS.

6. Mostre o nome e o número do empregado juntamento com o nome e o número de seu gerente. Coloque o alias de coluna como “Employee”, “Emp#”, “Manager” e “Mgr#”, respectivamente. Salve o comando SQL para um arquivo chamado e5q6.sql.

7. Modifique a consulta em e5q6.sql para exibir todos os empregados, incluindo o empregado com nome KING, que não possui gerente. Salve a nova consulta para um arquivo chamado e5q7.sql e execute-a.

On Targget Treinamento e Consultoria 21

ENAME DEPTNO DNAME------ ------ ---------CLARK 10 ACCOUNTINGKING 10 ACCOUNTINGMILLER 10 ACCOUNTINGSMITH 20 RESEARCHADAMS 20 RESEARCHFORD 20 RESEARCHSCOTT 20 RESEARCHJONES 20 RESEARCHALLEN 30 SALESBLAKE 30 SALESMARTIN 30 SALESJAMES 30 SALESTURNER 30 SALESWARD 30 SALES14 rows selected.

JOB LOC--------- -------------CLERK CHICAGOMANAGER CHICAGOSALESMAN CHICAGO

ENAME DNAME LOC------ ------ -------------ALLEN SALES CHICAGOWARD SALES CHICAGOMARTIN SALES CHICAGOTURNER SALES CHICAGO

ENAME DNAME------- ------------CLARK ACCOUNTINGADAMS RESEARCHALLEN SALESWARD SALESJAMES SALESMARTIN SALESBLAKE SALES7 rows selected.

ENAME JOB DEPTNO DNAME------- ------- ------- ----------SMITH CLERK 20 RESEARCHADAMS CLERK 20 RESEARCHFORD ANALYST 20 RESEARCHSCOTT ANALYST 20 RESEARCHJONES MANAGER 20 RESEARCH

Employee Emp# Manager Mgr#-------- ------ ------- ----SCOTT 7788 JONES 7566FORD 7902 JONES 7566ALLEN 7499 BLAKE 7698WARD 7521 BLAKE 7698JAMES 7900 BLAKE 7698TURNER 7844 BLAKE 7698MARTIN 7654 BLAKE 7698MILLER 7934 CLARK 7782ADAMS 7876 SCOTT 7788JONES 7566 KING 7839CLARK 7782 KING 7839BLAKE 7698 KING 7839SMITH 7369 FORD 790213 rows selected.

Page 154: Introdução ao Oracle 8i

Funções Básicas

Se houver tempo, complete os seguintes exercícios:

8. Crie uma consulta que mostre o nome do empregado, o número do departamento e todos os empregados que trabalham no mesmo departamento do empregado. Forneça para cada coluna um alias apropriado.

9. Mostre a estrutura da tabela SALGRADE. Crie uma consulta que mostre o nome, o cargo, o número do departamento, o salário e o nível do salário (grau) para todos os empregados.

Se você quiser um desafio extra, complete os exercícios seguintes:

10. Crie uma consulta para exibir o nome e a data de admissão de qualquer empregado admitido após o empregado BLAKE.

11. Mostre os nomes dos empregados e as datas de admissão juntamente com o nome e a data de admissão do gerente para todos os empregados que foram admitidos antes do seu gerente. Coloque o alias das colunas como “Employee”, “Emp Hiredate”, “Manager” e “Mgr Hiredate”, respectivamente.

12. Crie uma consulta que mostre o nome dos empregados e o valor dos salários indicado através de asteriscos. Cada asterisco deve representar cem dólares. Ordene os dados em ordem descendente de salário. Coloque o alias da coluna como “EMPLOYEE_AND_THEIR_SALARIES”.

On Targget Treinamento e Consultoria 22

Employee Emp# Manager Mgr#-------- ------ ------- -----SCOTT 7788 JONES 7566FORD 7902 JONES 7566ALLEN 7499 BLAKE 7698WARD 7521 BLAKE 7698JAMES 7900 BLAKE 7698TURNER 7844 BLAKE 7698MARTIN 7654 BLAKE 7698MILLER 7934 CLARK 7782ADAMS 7876 SCOTT 7788JONES 7566 KING 7839CLARK 7782 KING 7839BLAKE 7698 KING 7839SMITH 7369 FORD 7902KING 783914 rows selected.

DEPARTMENT EMPLOYEE COLLEAGUE---------- -------- --------- 10 CLARK KING 10 CLARK MILLER 10 KING CLARK 10 KING MILLER 10 MILLER CLARK 10 MILLER KING 20 ADAMS FORD 20 ADAMS JONES 20 ADAMS SCOTT 20 ADAMS SMITH 20 FORD ADAMS 20 FORD JONES 20 FORD SCOTT...56 rows selected.

Name Null? Type----------- -------- -------GRADE NUMBERLOSAL NUMBERHISAL NUMBER

ENAME JOB DNAME SAL GRADE------ ---------- ---------- ----- -----MILLER CLERK ACCOUNTING 1300 2CLARK MANAGER ACCOUNTING 2450 4KING PRESIDENT ACCOUNTING 5000 5SMITH CLERK RESEARCH 800 1SCOTT ANALYST RESEARCH 3000 4FORD ANALYST RESEARCH 3000 4ADAMS CLERK RESEARCH 1100 1JONES MANAGER RESEARCH 2975 4JAMES CLERK SALES 950 1BLAKE MANAGER SALES 2850 4TURNER SALESMAN SALES 1500 3ALLEN SALESMAN SALES 1600 3WARD SALESMAN SALES 1250 2MARTIN SALESMAN SALES 1250 214 rows selected.

ENAME HIREDATE------- ---------SMITH 17-DEC-80ALLEN 20-FEB-81WARD 22-FEB-81JONES 02-APR-81

Employee Emp Hiredate Manager Mgr Hiredate-------- ------------- ------- ------------ALLEN 20-FEB-81 BLAKE 01-MAY-81WARD 22-FEB-81 BLAKE 01-MAY-81JONES 02-APR-81 KING 17-NOV-81CLARK 09-JUN-81 KING 17-NOV-81BLAKE 01-MAY-81 KING 17-NOV-81SMITH 17-DEC-80 FORD 03-DEC-816 rows selected.

EMPLOYEE_AND_THEIR_SALARIES----------------------------------------------------------KING *************************************************FORD *****************************SCOTT *****************************JONES ****************************BLAKE ***************************CLARK ***********************ALLEN ***************TURNER **************MILLER ************MARTIN ***********WARD ***********ADAMS **********JAMES ********SMITH *******14 rows selected.

Page 155: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

7.7. Agregando Dados UtilizandoAgregando Dados Utilizando Funções de GrupoFunções de Grupo

On Targget Treinamento e Consultoria

Page 156: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Identificar as funções de grupo disponíveis. Descrever o uso de funções de grupo. Agrupar dados utilizando a cláusula GROUP BY. Incluir ou excluir linhas agrupadas utilizando a cláusula HAVING.

On Targget Treinamento e Consultoria 2

Page 157: Introdução ao Oracle 8i

Funções Básicas

O que são Funções de Grupo?

Diferentemente das funções básicas (single-row), as funções de grupo atuam em conjuntos de linhas para obter um resultado por grupo. Estes conjuntos podem ser a tabela inteira ou a tabela dividida em grupos.

On Targget Treinamento e Consultoria 3

Page 158: Introdução ao Oracle 8i

Funções Básicas

Tipos de Funções de Grupo

Cada uma das funções aceita um argumento. A tabela abaixo identifica as opções que podem ser utilizadas na sintaxe:

Função DescriçãoAVG( [DISTINCT | ALL] n ) Valor médio de n, ignorando valores nulosCOUNT({*|[DISTINCT|ALL]expr}) Número de linhas, onde expr computa somente os valores

diferente de nulo. Para contar todas as linhas selecionadas utilize *, incluindo linhas duplicadas e com valores nulos

MAX( [DISTINCT | ALL] expr) Valor máximo de expr, ignorando valores nulosMIN( [DISTINCT | ALL] expr) Valor mínimo de expr, ignorando valores nulosSTDDEV( [DISTINCT | ALL] n) Desvio padrão de n, ignorando valores nulosSUM( [DISTINCT | ALL] n) Soma dos valores de n, ignorando valores nulosVARIANCE( [DISTINCT | ALL] n) Variância de n, ignorando valores nulos

On Targget Treinamento e Consultoria 4

Page 159: Introdução ao Oracle 8i

Funções Básicas

Utilizando Funções de Grupo

Diretrizes para Utilização de Funções de Grupo

DISTINCT faz a função avaliar somente valores não duplicados; ALL faz a função considerar todos os valores, inclusive os duplicados. O padrão é ALL e portanto não precisa ser especificado.

Os tipos de dados para os argumentos podem ser CHAR, VARCHAR2, NUMBER ou DATE onde expr for especificado.

Todas as funções de grupo exceto COUNT(*) ignoram valores nulos. Para substituir um valor nulo, utilize a função NVL.

On Targget Treinamento e Consultoria 5

SELECT group_function(column)FROM table[WHERE condition][ORDER BY expr];

Page 160: Introdução ao Oracle 8i

Funções Básicas

Utilizando as Funções AVG e SUM

Você pode utilizar as funções AVG, SUM, MIN e MAX em colunas que podem armazenar dados numéricos. O exemplo acima exibe a média, o maior, o menor e a soma dos salários mensais para todos os vendedores (SALESMEN).

On Targget Treinamento e Consultoria 6

SQL> SELECT AVG(sal), MAX(sal), 2 MIN(sal), SUM(sal) 3 FROM emp 4 WHERE job LIKE 'SALES%';

AVG(SAL) MAX(SAL) MIN(SAL) SUM(SAL)-------- --------- --------- --------- 1400 1600 1250 5600

Page 161: Introdução ao Oracle 8i

Funções Básicas

Utilizando as Funções MIN e MAX

Você pode utilizar as funções MAX e MIN para qualquer tipo de dado. O exemplo acima exibe o mais recente e o mais antigo empregado.

O exemplo abaixo exibe o nome do primeiro empregado e o nome do último empregado em uma lista alfabética de todos os empregados.

Nota: As funções AVG, SUM, VARIANCE e STDDEV só podem ser utilizadas com tipos de dados numéricos.

On Targget Treinamento e Consultoria 7

SQL> SELECT MIN(hiredate), MAX(hiredate) 2 FROM emp;MIN(HIRED MAX(HIRED--------- ---------17-DEC-80 12-JAN-83

SQL> SELECT MIN(ename), MAX(ename) 2 FROM emp;MIN(ENAME) MAX(ENAME)---------- ----------ADAMS WARD

Page 162: Introdução ao Oracle 8i

Funções Básicas

Utilizando a Função COUNT

A função COUNT possui dois formatos:

COUNT(*) COUNT(expr)

COUNT(*) retorna o número de linhas em uma tabela, incluindo linhas duplicadas e linha que contêm valores nulos.

COUNT(expr), ao contrário, retorna o número de linhas com valor diferente de nulo na coluna identificada por expr.

O exemplo acima exibe o número de empregados do departamento 30.

O exemplo abaixo exibe o número de empregados do departamento 30 que podem ganhar comissão. Observe que o resultado fornece um número total de 4 linhas porque dois empregados do departamento 30 não podem ganhar comissão e possuem um valor nulo na coluna COMM.

Exemplos:

Mostre o número de departamentos na tabela EMP.

On Targget Treinamento e Consultoria 8

SQL> SELECT COUNT(*) 2 FROM emp 3 WHERE deptno = 30;

COUNT(*)--------- 6

SQL> SELECT COUNT(comm) 2 FROM emp 3 WHERE deptno = 30;

COUNT(COMM)----------- 4

SQL> SELECT COUNT(deptno) 2 FROM emp;

COUNT(DEPTNO)------------- 14

Page 163: Introdução ao Oracle 8i

Funções Básicas

Mostre o número de departamentos distintos na tabela EMP.

On Targget Treinamento e Consultoria 9

SQL> SELECT COUNT(DISTINCT (deptno)) 2 FROM emp;COUNT(DISTINCT(DEPTNO))----------------------- 3

Page 164: Introdução ao Oracle 8i

Funções Básicas

Funções de Grupo e Valores Nulos

Todas as funções de grupo exceto COUNT(*) ignoram os valores nulos da coluna. No exemplo acima, a média é calculada baseada somente nas linhas da tabela onde um valor válido está armazenado na coluna COMM. A média é calculada dividindo a comissão total paga a todos os empregados pelo número de empregados que recebem comissão (4).

On Targget Treinamento e Consultoria 10

SQL> SELECT AVG(comm) 2 FROM emp;AVG(COMM)--------- 550

Page 165: Introdução ao Oracle 8i

Funções Básicas

Utilizando a Função NVL com Funções de Grupo

A função NVL força as funções de grupo a considerarem os valores nulos no cálculo. No exemplo acima, a média é calculada baseada em todas as linhas da tabela embora existam valores nulos armazenados na coluna COMM. A média é calculada dividindo a comissão total paga para todos os empregados pelo número total de empregados na empresa (14).

On Targget Treinamento e Consultoria 11

SQL> SELECT AVG(NVL(comm,0)) 2 FROM emp;AVG(NVL(COMM,0))---------------- 157.14286

Page 166: Introdução ao Oracle 8i

Funções Básicas

Criando Grupos de Dados

Até agora, todas as funções de grupo trataram a tabela como um grande grupo de informação. Às vezes, você precisa dividir a tabela em grupos menores. Isto pode ser feito utilizando a cláusula GROUP BY.

On Targget Treinamento e Consultoria 12

Page 167: Introdução ao Oracle 8i

Funções Básicas

Criando Grupos de Dados: Cláusula GROUP BY

Você pode utilizar a cláusula GROUP BY para dividir as linhas de uma tabela em grupos. Você pode então utilizar as funções de grupo para devolver informação sumarizada para cada grupo.

Sintaxe:

group_by_expression especifica as colunas cujos valores determinam a base para o agrupamento das linhas.

Diretrizes

Se você incluir uma função de grupo em uma cláusula SELECT, você não pode selecionar resultados individuais a menos que a coluna individual apareça na cláusula GROUP BY. Você receberá uma mensagem de erro caso não inclua a coluna na lista.

Utilizando a cláusula WHERE, você pode excluir linhas antes de fazer a divisão dos grupos.

Você deve incluir as colunas na cláusula GROUP BY. Você não pode utilizar o alias de uma coluna na cláusula GROUP BY. Por default, as linhas são classificadas em ordem ascendente das colunas incluídas na lista

da cláusula GROUP BY. Você pode sobrepor esta ordenação utilizando a cláusula ORDER BY.

On Targget Treinamento e Consultoria 13

SELECT column, group_function(column)FROM table[WHERE condition][GROUP BY group_by_expression][ORDER BY expr];

Page 168: Introdução ao Oracle 8i

Funções Básicas

Utilizando a Cláusula GROUP BY

Quando utilizar a cláusula GROUP BY, tenha certeza que todas as colunas da lista da cláusula SELECT que não estão em funções de grupo estejam na lista da cláusula GROUP BY. O exemplo acima exibe o número do departamento e a média de salário de cada departamento. A seguir é apresentado como o comando SELECT acima, contendo uma cláusula GROUP BY, é avaliado:

A cláusula SELECT especifica as colunas a serem recuperadas: A coluna contendo o número do departamento da tabela EMP. A média de todos os salários no grupo especificado na cláusula GROUP BY.

A cláusula FROM especifica as tabela que o banco de dados deve acessar: tabela EMP. A cláusula WHERE especifica as linhas a serem recuperadas. Uma vez que não existe

nenhuma cláusula WHERE, por default todas as linhas serão recuperadas. A cláusula GROUP BY especifica como as linhas devem ser agrupadas. As linhas estão

sendo agrupadas através do número do departamento e, portanto, a função AVG que está sendo aplicada à coluna salário calculará a média de salário para cada departamento.

A coluna especificada na cláusula GROUP BY não necessita estar na lista da cláusula SELECT. Por exemplo, o comando SELECT acima exibe a média de salários de cada departamento sem exibir os números de departamento respectivos. Porém, sem os números de departamento, os resultados não parecem significativos.

Você pode utilizar as funções de grupo na cláusula ORDER BY.

On Targget Treinamento e Consultoria 14

SQL> SELECT deptno, AVG(sal) 2 FROM emp 3 GROUP BY deptno;

DEPTNO AVG(SAL)--------- --------- 10 2916.6667 20 2175 30 1566.6667

SQL> SELECT AVG(sal) 2 FROM emp 3 GROUP BY deptno;

AVG(SAL)--------- 2916.6667 21751566.6667

SQL> SELECT deptno, AVG(sal) 2 FROM emp 3 GROUP BY deptno 4 ORDER BY AVG(sal);

DEPTNO AVG(SAL)---------- ------------ 30 1566.6667 20 2175 10 2916.6667

Page 169: Introdução ao Oracle 8i

Funções Básicas

Agrupando por Mais de Uma Coluna

Grupos Dentro de Grupos

Às vezes existe a necessidade de visualizar resultados de grupos dentro de outros grupos. O gráfico acima mostra um relatório que exibe o salário total que é pago para cada cargo, dentro de cada departamento.

A tabela EMP é agrupada primeiro pelo número do departamento e então dentro deste agrupamento ela é agrupada pelo cargo. Por exemplo, os empregados com cargo CLERK do departamento 20 se agrupam e um único resultado (salário total) é produzido para o grupo.

On Targget Treinamento e Consultoria 15

Page 170: Introdução ao Oracle 8i

Funções Básicas

Utilizando a Cláusula GROUP BY em Múltiplas Colunas

Grupos Dentro de Grupos

Você pode retornar resultados sumarizados para grupos e subgrupos listando mais de uma coluna na cláusula GROUP BY. A ordem de classificação padrão dos resultados baseia-se na ordem das colunas da cláusula GROUP BY. A seguir é apresentado como o comando SELECT acima, contendo a cláusula GROUP BY, é avaliado:

A cláusula SELECT especifica as colunas a serem recuperadas: Número do departamento da tabela EMP Cargo da tabela EMP A soma de todos os salários para o grupo especificado na cláusula GROUP BY

A cláusula FROM especifica as tabelas que o banco de dados deve acessar: tabela EMP. A cláusula GROUP BY especifica como as linhas devem ser agrupadas:

Primeiro, as linhas são agrupadas através do número do departamento. Segundo, dentro dos grupos de número do departamento, as linhas são agrupadas pelo

cargo.

Desta forma a função SUM está sendo aplicada à coluna de salário para todos os cargos dentro de cada grupo de número do departamento.

On Targget Treinamento e Consultoria 16

SQL> SELECT deptno, job, sum(sal) 2 FROM emp 3 GROUP BY deptno, job;

DEPTNO JOB SUM(SAL)--------- --------- --------- 10 CLERK 1300 10 MANAGER 2450 10 PRESIDENT 5000 20 ANALYST 6000 20 CLERK 1900...9 rows selected.

Page 171: Introdução ao Oracle 8i

Funções Básicas

Consultas Ilegais Utilizando Funções de Grupo

Sempre que você utilizar colunas individuais (DEPTNO) e funções de grupo (COUNT) no mesmo comando SELECT, você deve incluir uma cláusula GROUP BY que especifique as colunas individuais (neste caso, DEPTNO). Se a cláusula GROUP BY não for informada, então a mensagem de erro “not a single-group group function” aparece e um asterisco (*) aponta para a coluna que causou o erro. Você pode corrigir o erro acima adicionando uma cláusula GROUP BY.

Qualquer coluna ou expressão na lista da cláusula SELECT que não é uma função de agregação deve estar especificada na cláusula GROUP BY.

A cláusula WHERE não pode ser utilizada para restringir grupos. O comando SELECT acima resulta em um erro porque utiliza a cláusula WHERE para restringir a exibição das médias de salários dos departamentos que possuem a média de salário maior que $2000.

Você pode corrigir este erro utilizando a cláusula HAVING para restringir grupos.

On Targget Treinamento e Consultoria 17

SQL> SELECT deptno, COUNT(ename) 2 FROM emp 3 GROUP BY deptno;

DEPTNO COUNT(ENAME)---------- ------------ 10 3 20 5 30 6

SQL> SELECT deptno, AVG(sal) 2 FROM emp 3 GROUP BY deptno 4 HAVING AVG(sal) > 2000;

DEPTNO AVG(SAL)---------- -------------- 10 2916.6667 20 2175

Page 172: Introdução ao Oracle 8i

Funções Básicas

Excluindo Resultados de Grupos

Da mesma forma que você utiliza a cláusula WHERE para restringir as linhas selecionadas, você utiliza a cláusula HAVING para restringir grupos. Para encontrar o maior salário de cada departamento, mas exibir somente os departamentos que possuem o seu maior salário com mais de $2900, você precisa fazer o seguinte:

Encontrar o maior salário para cada departamento agrupando pelo número de departamento.

Restringir os grupos para esses departamentos, listando somente os que tiverem o maior salário maior que $2900.

On Targget Treinamento e Consultoria 18

Page 173: Introdução ao Oracle 8i

Funções Básicas

Excluindo Resultados de Grupos: Cláusula HAVING

Você utiliza a cláusula HAVING para especificar quais grupos serão exibidos. Portanto, você restringe os grupos baseado em informações agregadas.

Sintaxe:

group_condition restringe as linhas de grupos retornadas para aqueles grupos onde a condição especificada retornar TRUE.

O Servidor Oracle executa os seguintes passos quando você utiliza a cláusula HAVING:

As linhas são agrupadas. A função de grupo é aplicada ao grupo. Os grupos que correspondem ao critério especificado na cláusula HAVING são exibidos.

A cláusula HAVING pode preceder a cláusula GROUP BY, mas é recomendado que você coloque a cláusula GROUP BY primeiro porque é mais lógico. Os grupos são formados e as funções de grupo são calculadas antes da cláusula HAVING ser aplicada.

On Targget Treinamento e Consultoria 19

SELECT column, group_functionFROM table[WHERE condition][GROUP BY group_by_expression][HAVING group_condition][ORDER BY column];

Page 174: Introdução ao Oracle 8i

Funções Básicas

Utilizando a Cláusula HAVING

O exemplo acima exibe os números de departamento e o maior salário daqueles departamentos cujo o maior salário seja maior que $2900.

Você pode utilizar a cláusula GROUP BY sem utilizar uma função de grupo na lista da cláusula SELECT.

Se você restringir linhas baseado no resultado de uma função de grupo, você deve especificar uma cláusula GROUP BY e também um cláusula HAVING.

O exemplo abaixo exibe o número do departamento e a média de salário para os departamentos cujo o salário máximo seja maior que $2900.

On Targget Treinamento e Consultoria 20

SQL> SELECT deptno, max(sal) 2 FROM emp 3 GROUP BY deptno 4 HAVING max(sal) > 2900;

DEPTNO MAX(SAL)--------- --------- 10 5000 20 3000

SQL> SELECT deptno, AVG(sal) 2 FROM emp 3 GROUP BY deptno 4 HAVING MAX(sal) > 2900;

DEPTNO AVG(SAL)--------- --------- 10 2916.6667 20 2175

Page 175: Introdução ao Oracle 8i

Funções Básicas

O exemplo abaixo exibe o cargo e o salário mensal total de cada cargo para os cargos excedam o total de $5000. O exemplo exclui o cargo SALESMEN e ordena o resultado pelo salário mensal total.

On Targget Treinamento e Consultoria 21

SQL> SELECT job, SUM(sal) PAYROLL 2 FROM emp 3 WHERE job NOT LIKE 'SALES%' 4 GROUP BY job 5 HAVING SUM(sal) > 5000 6 ORDER BY SUM(sal);

JOB PAYROLL--------- ---------ANALYST 6000MANAGER 8275

Page 176: Introdução ao Oracle 8i

Funções Básicas

Aninhando Funções de Grupo

Funções de grupo podem ser aninhadas em qualquer nível. O exemplo acima exibe a maior média de salário.

On Targget Treinamento e Consultoria 22

SQL> SELECT max(avg(sal)) 2 FROM emp 3 GROUP BY deptno;

MAX(AVG(SAL))------------- 2916.6667

Page 177: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 6

Determine a validade das seguintes declarações, circulando a palavra Verdadeiro ou Falso.

1. Funções de grupo atuam sobre muitas linhas para produzir um único resultado.

Verdadeiro / Falso

2. Funções de grupo incluem nulos nos cálculos.

Verdadeiro / Falso

3. A cláusula WHERE restringe as linhas antes de incluí-las em um cálculo de grupo.

Verdadeiro / Falso

4. Mostre o maior, o menor, a soma e a média do salário de todos os empregados. Coloque o alias das colunas como "Maximum", "Minimum", "Sum" e "Average", respectivamente. Arredonde os resultados para a posição decimal. Salve o comando SQL em um arquivo chamado e6q4.sql.

5. Modifique a consulta em e6q4.sql para exibir o menor, o maior, a soma e a média do salário para cada tipo de cargo. Salve o novo comando para e6q5.sql. Execute a consulta.

6. Escreva uma consulta para exibir o número de pessoas com o mesmo cargo.

7. Determine o número de gerentes sem listá-los. Coloque o alias da coluna como “Number of Managers”.

8. Escreva uma consulta que mostre a diferença entre o maior e menor salários. Coloque o alias da coluna como “DIFFERENCE”.

Se houver tempo, complete os seguintes exercícios:

9. Mostre o número do gerente e o mais baixo salário dentre os empregados associados para aquele gerente. Exclua qualquer um onde o código do gerente não é conhecido. Exclua qualquer grupo onde o salário mínimo é menor que $1000. Ordene o resultado em ordem descendente de salário.

On Targget Treinamento e Consultoria 23

Maximum Minimum Sum Average------- ------- ----- ------- 5000 800 29025 2073

JOB Maximum Minimum Sum Average---------- -------- -------- ------- --------ANALYST 3000 3000 6000 3000CLERK 1300 800 4150 1038MANAGER 2975 2450 8275 2758PRESIDENT 5000 5000 5000 5000SALESMAN 1600 1250 5600 1400

JOB COUNT(*)---------- --------ANALYST 2CLERK 4MANAGER 3PRESIDENT 1SALESMAN 4

Number of Managers------------------ 6

DIFFERENCE---------- 4200

Page 178: Introdução ao Oracle 8i

Funções Básicas

10. Escreva uma consulta para exibir o nome do departamento, o nome da localização, o número de empregados e a média de salário para todos os empregados daquele departamento. Coloque os alias de coluna como “DNAME”, “LOC”, “Number of People” e “Salary”, respectivamente.

Se você quiser um desafio extra, complete os exercícios seguintes:

11. Crie uma consulta que mostre o número total de empregados e o número total de empregados contratados em 1980, 1981, 1982 e 1983. Forneça cabeçalhos de coluna apropriados.

12. Crie uma consulta tipo matriz para exibir o cargo, o salário para aquele cargo baseado no número de departamento e o salário total para aquele cargo para todos os departamentos, fornecendo para cada coluna um cabeçalho apropriado.

On Targget Treinamento e Consultoria 24

MGR MIN(SAL)-------- -------- 7566 3000 7839 2450 7782 1300 7788 1100

DNAME LOC Number of People Salary------------ --------- ---------------- --------ACCOUNTING NEW YORK 3 2916.67RESEARCH DALLAS 5 2175SALES CHICAGO 6 1566.67

TOTAL 1980 1981 1982 1983----- ----- ----- ----- ----- 14 1 10 2 1

Job Dept 10 Dept 20 Dept 30 Total--------- ------- -------- -------- -------ANALYST 6000 6000CLERK 1300 1900 950 4150MANAGER 2450 2975 2850 8275PRESIDENT 5000 5000SALESMAN 5600 5600

Page 179: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

8.8. SubconsultasSubconsultas

On Targget Treinamento e Consultoria

Page 180: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Descrever os tipos de problemas que subconsultas podem resolver Definir subconsultas Listar os tipos de subconsultas Escrever subconsultas do tipo single-row e multiple-row

Neste capítulo serão apresentadas características avançadas do comando SELECT. Você pode escrever subconsultas na cláusula WHERE de outro comando SQL para obter valores baseado em um valor condicional desconhecido. Este capítulo discute as consultas do tipo single-row (que devem recuperar apenas uma linha) e multiple-row (que podem recuperar mais de uma linha).

On Targget Treinamento e Consultoria 2

Page 181: Introdução ao Oracle 8i

Funções Básicas

Utilizando uma Subconsulta para Resolver um Problema

Suponha você quer escrever uma consulta para encontrar quem ganha um salário maior que o salário de Jones.

Para resolver este problema, você precisa de duas consultas: uma consulta para encontrar quanto Jones ganha e uma segunda consulta para encontrar quem ganha mais que aquela quantia.

Você pode resolver este problema combinando as duas consultas e colocando uma consulta dentro da outra.

Uma consulta interna ou subconsulta retorna um valor que é utilizado pela consulta externa ou consulta principal. Utilizar uma subconsulta é equivalente a executar duas consultas seqüênciais e utilizar o resultado da primeira consulta como o valor de procura da segunda consulta.

On Targget Treinamento e Consultoria 3

Page 182: Introdução ao Oracle 8i

Funções Básicas

Subconsultas

Uma subconsulta é um comando SELECT embutido em uma cláusula de outro comando SELECT. Você pode construir comandos poderosos utilizando subconsultas. Eles podem ser muito úteis quando você precisa selecionar linhas de uma tabela com uma condição que depende dos dados da própria tabela.

Você pode colocar subconsultas em várias cláusulas SQL:

Cláusula WHERE Cláusula HAVING Cláusula FROM

Sintaxe:

operator inclui um operador de comparação como >, = ou IN

Nota: Operadores de comparação entram em duas classes: operadores do tipo single-row (>, =, >=, <, <>, <=) e operadores do tipo multiple-row (IN, ANY, ALL).

A subconsulta é freqüentemente chamada de SELECT aninhado, sub-select, ou comando SELECT interno. A subconsulta geralmente é executada primeiro, e seu resultado é utilizado para completar a condição da consulta principal ou externa.

On Targget Treinamento e Consultoria 4

SELECT select_listFROM tableWHERE expr operator

(SELECT select_list FROM table);

Page 183: Introdução ao Oracle 8i

Funções Básicas

Utilizando uma Subconsulta

No exemplo acima, a consulta interna determina o salário do empregado 7566. A consulta externa recebe o resultado da consulta interna e utiliza este resultado para exibir todos os empregados que ganham mais que esta quantia.

On Targget Treinamento e Consultoria 5

SQL> SELECT ename 2 FROM emp 3 WHERE sal > 4 (SELECT sal 5 FROM emp 6 WHERE empno = 7566);

ENAME----------KINGFORDSCOTT

2975

Page 184: Introdução ao Oracle 8i

Funções Básicas

Diretrizes para Utilização de Subconsultas

Uma subconsulta deve ser incluída entre parênteses. Uma subconsulta deve estar no lado direito do operador de comparação. Subconsultas não podem conter uma cláusula ORDER BY. Você pode ter somente uma

cláusula ORDER BY para um comando SELECT, e se especificada ela deve ser a última cláusula do comando SELECT principal.

Duas classes de operadores de comparação são utilizadas em subconsultas: os operadores do tipo single-row e os operadores do tipo multiple-row.

On Targget Treinamento e Consultoria 6

Page 185: Introdução ao Oracle 8i

Funções Básicas

Tipos de Subconsultas

Subconsultas single-row: consultas que retornam apenas uma linha a partir do comando SELECT interno.

Subconsultas multiple-row: consultas que retornam mais de uma linha a partir do comando SELECT interno.

Subconsultas multiple-column: consultas que retornam mais de uma coluna a partir do comando SELECT interno.

On Targget Treinamento e Consultoria 7

Page 186: Introdução ao Oracle 8i

Funções Básicas

Subconsultas Single-Row

Uma subconsulta do tipo single-row retorna uma linhas a partir do comando SELECT interno. Este tipo de subconsulta utiliza um operador do tipo single-row. O gráfico acima exibe uma lista dos operadores single-row.

Exemplo:

Mostre os empregados cujo cargo seja igual ao cargo do empregado 7369.

On Targget Treinamento e Consultoria 8

SQL> SELECT ename, job 2 FROM emp 3 WHERE job = 4 (SELECT job 5 FROM emp 6 WHERE empno = 7369);

ENAME JOB---------- ---------JAMES CLERKSMITH CLERKADAMS CLERKMILLER CLERK

Page 187: Introdução ao Oracle 8i

Funções Básicas

Executando Subconsultas Single-Row

Um comando SELECT pode ser considerado como um bloco de consulta. O exemplo acima exibe os empregados cujo cargo é o mesmo do empregado 7369 e cujo salário é maior que o do empregado 7876.

O exemplo consiste de três blocos de consulta: a consulta externa e as duas consultas internas. Os blocos de consulta internos são executados primeiro, produzindo os resultados da consulta: CLERK e 1100, respectivamente. O bloco de consulta externo é então processado e utiliza os valores retornados pelas consultas internas para completar as suas condições de pesquisa.

Ambas as consultas internas retornam valores únicos (CLERK e 1100, respectivamente), sendo chamadas de subconsultas single-row.

Nota: As consultas externa e interna podem obter dados de tabelas diferentes.

On Targget Treinamento e Consultoria 9

SQL> SELECT ename, job 2 FROM emp 3 WHERE job = 4 (SELECT job 5 FROM emp 6 WHERE empno = 7369) 7 AND sal > 8 (SELECT sal 9 FROM emp 10 WHERE empno = 7876);

ENAME JOB---------- ---------MILLER CLERK CLERK

1100

Page 188: Introdução ao Oracle 8i

Funções Básicas

Utilizando Funções de Grupo em uma Subconsulta

Você pode exibir dados de uma consulta principal utilizando uma função de grupo em uma subconsulta para retornar uma única linha. A subconsulta está entre parênteses e é colocada após o operador de comparação.

O exemplo acima exibe o nome do empregado, o cargo e o salário de todos os empregados cujo salário é igual ao menor salário. A função de grupo MIN retorna um único valor (800) para a consulta externa.

On Targget Treinamento e Consultoria 10

SQL> SELECT ename, job, sal 2 FROM emp 3 WHERE sal = 4 (SELECT MIN(sal) 5 FROM emp);

ENAME JOB SAL---------- --------- ---------SMITH CLERK 800

800

Page 189: Introdução ao Oracle 8i

Funções Básicas

Cláusula HAVING com Subconsultas

Além da cláusula WHERE, você também pode utilizar subconsultas na cláusula HAVING. O Servidor Oracle executa a subconsulta, e os resultados são retornados para a cláusula HAVING da consulta principal.

A comando SQL acima exibe todos os departamentos que possuem um salário mínimo maior que o salário mínimo do departamento 20.

Exemplo:

Encontre o cargo com a menor média de salário.

On Targget Treinamento e Consultoria 11

SQL> SELECT deptno, MIN(sal) 2 FROM emp 3 GROUP BY deptno 4 HAVING MIN(sal) > 5 (SELECT MIN(sal) 6 FROM emp 7 WHERE deptno = 20);

DEPTNO MIN(SAL)--------- --------- 10 1300 30 950

SQL> SELECT job, AVG(sal) 2 FROM emp 3 GROUP BY job 4 HAVING AVG(sal) = (SELECT MIN(AVG(sal)) 5 FROM EMP 6 GROUP BY job);

800

Page 190: Introdução ao Oracle 8i

Funções Básicas

Qual o Erro deste Comando?

Um erro comum em subconsultas é mais de uma linha ser retornada para uma subconsulta do tipo single-row.

No comando SQL acima, a subconsulta possui uma cláusula GROUP BY (deptno), que implica que a subconsulta devolverá múltiplas linhas, uma para cada grupo encontrado. Neste caso, o resultado da subconsulta será 800, 1300, e 950.

A consulta externa recebe os resultados da subconsulta (800, 950, 1300) e utiliza estes resultados em sua cláusula WHERE. A cláusula WHERE contém um operador igual (=), operador de comparação do tipo single-row que compara apenas um valor. O operador (=) não aceita mais de um valor a partir subconsulta e conseqüentemente gera o erro.

Para corrigir este erro, mude o operador (=) para IN.

On Targget Treinamento e Consultoria 12

Page 191: Introdução ao Oracle 8i

Funções Básicas

Este Comando Funcionará?

Um problema comum com subconsultas é nenhuma linha ser retornada pela consulta interna.

No comando SQL acima, a subconsulta contém uma cláusula WHERE (ename = ' SMYTHE'). Presumivelmente, a intenção é achar o empregado cujo nome é Smythe. O comando parece estar correto, mas não seleciona nenhuma linha quando é executado.

O problema é que Smythe está escrito de forma incorreta. Não existe nenhum empregado chamado Smythe. Assim, a subconsulta não retorna nenhuma linha. A consulta externa recebe os resultados da subconsulta (null) e utiliza estes resultados na cláusula WHERE. A consulta externa não encontra nenhum empregado com um cargo igual a nulo e assim não retorna nenhuma linha.

On Targget Treinamento e Consultoria 13

Page 192: Introdução ao Oracle 8i

Funções Básicas

Subconsultas do Tipo Multiple-Row

Subconsultas que retornam mais que uma linha são chamadas subconsultas multiple-row. Você utiliza operadores multiple-row, em vez de operadores single-row, com uma subconsulta multiple-row. O operador multiple-row aceita um ou mais valores.

Exemplo:

Encontre os empregados que ganham um salário igual ao menor salário para os departamentos.

A consulta interna é executada primeiro e produz um resultado que contém três linhas: 800, 950 e 1300. O bloco da consulta principal é então processado e utiliza os valores retornados pela consulta interna para completar sua condição de pesquisa. De fato, a consulta principal se pareceria com o seguinte para o Servidor Oracle:

On Targget Treinamento e Consultoria 14

SQL> SELECT ename, sal, deptno 2 FROM emp 3 WHERE sal IN (SELECT MIN(sal) 4 FROM emp 5 GROUP BY deptno);

SQL> SELECT ename, sal, deptno 2 FROM emp 3 WHERE sal IN (800, 950, 1300);

Page 193: Introdução ao Oracle 8i

Funções Básicas

Utilizando o Operador ANY em Subconsultas Multiple-Row

O operador ANY compara um valor para cada valor retornado por uma subconsulta. O exemplo acima exibe os empregados cujo salário é menor que o salário de qualquer empregado com o cargo CLERK e que não são deste cargo. O maior salário que um empregado com o cargo CLERK ganha é $1300. O comando SQL exibe todos os empregados que não possuem o cargo CLERK mas ganhem menos que $1300.

< ANY significa menos que o máximo. > ANY significa mais que o mínimo. = ANY é equivalente a IN.

On Targget Treinamento e Consultoria 15

SQL> SELECT empno, ename, job 2 FROM emp 3 WHERE sal < ANY 4 (SELECT sal 5 FROM emp 6 WHERE job = 'CLERK') 7 AND job <> 'CLERK';

EMPNO ENAME JOB--------- ---------- --------- 7654 MARTIN SALESMAN 7521 WARD SALESMAN 950

8001100

1300

Page 194: Introdução ao Oracle 8i

Funções Básicas

Utilizando o Operador ALL em Subconsultas Multiple-Row

O operador ALL compara um valor com todos os valores retornados por uma subconsulta. O exemplo acima exibe os empregados cujo salário é maior que o salário médio de todos os departamentos. O maior salário médio de um departamento é $2916.66, assim a consulta retorna aqueles empregados cujo salário é maior que $2916.66.

> ALL significa mais que o máximo. < ALL significa menos que o mínimo.

O operador NOT pode ser utilizado com os operadores IN, ANY e ALL.

On Targget Treinamento e Consultoria 16

SQL> SELECT empno, ename, job 2 FROM emp 3 WHERE sal > ALL 4 (SELECT avg(sal) 5 FROM emp 6 GROUP BY deptno);

EMPNO ENAME JOB--------- ---------- --------- 7839 KING PRESIDENT 7566 JONES MANAGER 7902 FORD ANALYST 7788 SCOTT ANALYST

2916.6667

2175

1566.6667

Page 195: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 7

1. Escreva uma consulta para exibir o nome do empregado e a data de admissão para todos os empregados que estão no mesmo departamento do empregado BLAKE, excluindo-o do resultado.

2. Crie uma consulta para exibir o número do empregado e o nome para todos os empregados que ganham mais que a média de salário. Classifique o resultado em ordem descendente de salário.

3. Escreva uma consulta que mostre o número do empregado e o nome para todos os empregados que trabalham em um departamento com qualquer empregado cujo nome contenha uma letra T. Salve o comando SQL para um arquivo chamado e7q3.sql.

4. Mostre o nome do empregado, o número do departamento e o cargo para todos os empregados cujo o departamento localize-se em DALLAS.

5. Mostre o nome do empregado e o salário de todos os empregados gerenciados por KING.

6. Mostre o número do departamento, o nome e o cargo para todos os empregados que estão em um dos departamentos SALES.

Se houver tempo, complete os seguintes exercícios:

7. Modifique a consulta em e7q3.sql para exibir o número do empregado, o nome e o salário para todos os empregados que ganham mais que a média de salário e que trabalham em um departamento com qualquer empregado com um letra T em seu nome. Salve o novo comando para e7q7.sql e execute.

On Targget Treinamento e Consultoria 17

ENAME HIREDATE------- ---------------MARTIN 28-SEP-81ALLEN 20-FEB-81TURNER 08-SEP-81JAMES 03-DEC-81WARD 22-FEB-816 rows selected.

EMPNO ENAME----- ----------- 7839 KING 7902 FORD 7788 SCOTT 7566 JONES 7698 BLAKE 7782 CLARK6 rows selected.

EMPNO ENAME------ -------- 7566 JONES 7788 SCOTT 7876 ADAMS 7369 SMITH 7902 FORD 7698 BLAKE 7654 MARTIN 7499 ALLEN 7844 TURNER 7900 JAMES 7521 WARD11 rows selected.

ENAME DEPTNO JOB------ ------ ---------JONES 20 MANAGERFORD 20 ANALYSTSMITH 20 CLERKSCOTT 20 ANALYSTADAMS 20 CLERK

ENAME SAL------ ----BLAKE 2850CLARK 2450JONES 2975

DEPTNO ENAME JOB------ -------- --------- 30 BLAKE MANAGER 30 MARTIN SALESMAN 30 ALLEN SALESMAN 30 TURNER SALESMAN 30 JAMES CLERK 30 WARD SALESMAN6 rows selected.

EMPNO ENAME SAL----- ------ ---- 7566 JONES 2975 7788 SCOTT 3000 7902 FORD 3000 7698 BLAKE 2850

Page 196: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

9.9. Subconsultas Multiple-ColumnSubconsultas Multiple-Column

On Targget Treinamento e Consultoria

Page 197: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Escrever uma subconsulta multiple-column Descrever e explicar o comportamento de subconsultas quando valores nulos são

recuperados Escrever subconsultas em uma cláusula FROM

On Targget Treinamento e Consultoria 2

Page 198: Introdução ao Oracle 8i

Funções Básicas

Subconsultas Multiple-Column

Até agora você escreveu subconsultas do tipo single-row e subconsultas do tipo multiple-row onde só uma coluna foi comparada na cláusula WHERE ou na cláusula HAVING do comando SELECT. Se você quiser comparar duas ou mais colunas, você deve escrever uma combinação na cláusula WHERE utilizando os operadores lógicos. Subconsultas do tipo multiple-column permitem combinar condições WHERE duplicadas em uma única cláusula WHERE.

Sintaxe:

On Targget Treinamento e Consultoria 3

SELECT column, column, ...FROM tableWHERE (column, column, ...) IN

(SELECT column, column, ... FROM table WHERE condition);

Page 199: Introdução ao Oracle 8i

Funções Básicas

Utilizando Subconsultas Multiple-Column

O exemplo acima é uma subconsulta do tipo multiple-column, uma vez que a subconsulta retorna mais de uma coluna. Ele compara a coluna SAL e a coluna COMM. Ele exibe o nome, o número do departamento, o salário e a comissão de qualquer empregado cujo salário e comissão correspondam ambos ao salário e comissão de qualquer empregado do departamento 30.

O resultado do comando SQL acima será o seguinte:

On Targget Treinamento e Consultoria 4

SQL> SELECT ename, deptno, sal, comm 2 FROM emp 3 WHERE (sal, NVL(comm,-1)) IN 4 (SELECT sal, NVL(comm,-1) 5 FROM emp 6 WHERE deptno = 30);

ENAME DEPTNO SAL COMM---------- --------- --------- ---------JAMES 30 950WARD 30 1250 500MARTIN 30 1250 1400TURNER 30 1500 0ALLEN 30 1600 300BLAKE 30 28506 rows selected.

Page 200: Introdução ao Oracle 8i

Funções Básicas

Comparações de Colunas

Comparações de coluna em uma subconsulta multiple-column podem ser do tipo pairwise ou nonpairwise. No gráfico acima, uma comparação tipo pairwise foi executada na cláusula WHERE. Cada linha candidata do comando SELECT deve ter o mesmo salário e a mesma comissão de um empregado do departamento 30.

Se você quiser uma comparação tipo nonpairwise (um cross product), você deve utilizar uma cláusula WHERE com múltiplas condições.

On Targget Treinamento e Consultoria 5

Page 201: Introdução ao Oracle 8i

Funções Básicas

Subconsulta com Comparação Tipo Nonpairwise

O exemplo acima faz uma comparação tipo nonpairwise das colunas. Exibe o nome, o número do departamento, o salário, e a comissão de qualquer empregado cujo salário e comissão correspondam ao salário e comissão de qualquer empregado do departamento 30.

O resultado do comando SQL acima será o seguinte:

Os resultados das últimas duas consultas são idênticos embora as condições de comparação fossem diferentes. Os resultados foram obtidos por causa dos dados específicos da tabela EMP.

On Targget Treinamento e Consultoria 6

SQL> SELECT ename, deptno, sal, comm 2 FROM emp 3 WHERE sal IN (SELECT sal 4 FROM emp 5 WHERE deptno = 30) 6 AND NVL(comm,-1) IN 7 (SELECT NVL(comm,-1) 8 FROM emp 9 WHERE deptno = 30);

ENAME DEPTNO SAL COMM---------- --------- --------- ---------JAMES 30 950BLAKE 30 2850TURNER 30 1500 0ALLEN 30 1600 300WARD 30 1250 500MARTIN 30 1250 14006 rows selected.

Page 202: Introdução ao Oracle 8i

Funções Básicas

Modificando a Tabela EMP

Exemplo:

Assuma que o salário e a comissão do empregado o CLARK foram modificados de forma que ele tenha o mesmo salário que um empregado do departamento 30 e a mesma comissão que um empregado diferente do departamento 30.

O salário para CLARK é agora igual ao de TURNER ($1500) e a comissão de CLARK é igual a de ALLEN ($300).

Agora execute uma comparação do tipo pairwise e uma comparação do tipo nonpairwise para determinar o número de linhas retornadas por cada consulta.

Nota: A sintaxe para atualizar dados em uma tabela será discutida em um capítulo subseqüente.

On Targget Treinamento e Consultoria 7

ENAME SAL COMM---------- --------- ---------...CLARK 1500 300...ALLEN 1600 300TURNER 1500 0...14 rows selected.

Page 203: Introdução ao Oracle 8i

Funções Básicas

Subconsulta Tipo Pairwise

O resultado da subconsulta pairwise ainda permanece o mesmo, retornando seis linhas.

On Targget Treinamento e Consultoria 8

SQL> SELECT ename, deptno, sal, comm 2 FROM emp 3 WHERE (sal, NVL(comm,-1)) IN 4 (SELECT sal, NVL(comm,-1) 5 FROM emp 6 WHERE deptno = 30);

ENAME DEPTNO SAL COMM---------- --------- --------- ---------JAMES 30 950WARD 30 1250 500MARTIN 30 1250 1400TURNER 30 1500 0ALLEN 30 1600 300BLAKE 30 28506 rows selected.

Page 204: Introdução ao Oracle 8i

Funções Básicas

Subconsulta Tipo Nonpairwise

Os resultados da subconsulta nonpairwise incluem o empregado CLARK. O salário de CLARK é igual ao de TURNER e sua comissão é igual a de ALLEN.

On Targget Treinamento e Consultoria 9

SQL> SELECT ename,deptno, sal, comm 2 FROM emp 3 WHERE sal IN (SELECT sal 4 FROM emp 5 WHERE deptno = 30) 6 AND NVL(comm,-1) IN 7 (SELECT NVL(comm,-1) 8 FROM emp 9 WHERE deptno = 30);

ENAME DEPTNO SAL COMM---------- --------- --------- ---------JAMES 30 950BLAKE 30 2850TURNER 30 1500 0CLARK 10 1500 300...7 rows selected.

Page 205: Introdução ao Oracle 8i

Funções Básicas

Valores Nulos em uma Subconsulta

O comando SQL acima tenta exibir todos os empregados que não possuem nenhum subordinado. Logicamente, este comando SQL deveria ter retornado oito linhas. Entretanto, o comando SQL não retorna nenhuma linha. Um dos valores retornados pela consulta interna é um valor nulo e conseqüentemente toda a consulta não retorna nenhuma linha. A razão é que todas as condições que comparam um valor nulo resultam em nulo. Portanto, sempre que for provável que valores nulos façam parte do conjunto resultante de uma subconsulta, não utilize o operador NOT IN. O operador NOT IN equivalente a != ALL.

Observe que o valor nulo como parte do conjunto resultante de uma subconsulta não será um problema se você estiver utilizando o operador IN. O operador IN é equivalente a = ANY. Por exemplo, para exibir os empregados que possuem subordinados, utilize o seguinte comando SQL:

On Targget Treinamento e Consultoria 10

SQL> SELECT employee.ename 2 FROM emp employee 3 WHERE employee.empno NOT IN 4 (SELECT manager.mgr 5 FROM emp manager);no rows selected.no rows selected.

SQL> SELECT employee.ename 2 FROM emp employee 3 WHERE employee.empno IN (SELECT manager.mgr 4 FROM emp manager);

ENAME ----------KING …6 rows selected.

Page 206: Introdução ao Oracle 8i

Funções Básicas

Utilizando uma Subconsulta na Cláusula FROM

Você pode utilizar uma subconsulta na cláusula FROM de um comando SELECT. O exemplo acima exibe os nomes dos empregados, os salários, os números de departamento e as médias de salários para todos os empregados que ganham mais que a média de salário do seu departamento.

On Targget Treinamento e Consultoria 11

SQL> SELECT a.ename, a.sal, a.deptno, b.salavg 2 FROM emp a, (SELECT deptno, avg(sal) salavg 3 FROM emp 4 GROUP BY deptno) b 5 WHERE a.deptno = b.deptno 6 AND a.sal > b.salavg;

ENAME SAL DEPTNO SALAVG---------- --------- --------- ----------KING 5000 10 2916.6667JONES 2975 20 2175SCOTT 3000 20 2175...6 rows selected.

Page 207: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 8

1. Escreva uma consulta para exibir o nome, o número do departamento e o salário de qualquer empregado cujo o número do departamento e o salário correspondam ambos ao número do departamento e ao salário de qualquer empregado que ganha comissão.

2. Mostre o nome, o nome do departamento e o salário de qualquer empregado cujo salário e comissão correspondam ambos ao salário e comissão de qualquer empregado localizado em DALLAS.

3. Crie uma consulta para exibir o nome, a data de admissão e o salário para todos os empregados que possuem o mesmo salário e comissão que SCOTT.

4. Crie uma consulta para exibir os empregados que ganham um salário maior que o salário de qualquer empregado com o cargo CLERK. Classifique o resultado do maior para o menor salário.

On Targget Treinamento e Consultoria 12

ENAME DEPTNO SAL-------- ------ ------MARTIN 30 1250WARD 30 1250TURNER 30 1500ALLEN 30 1600

ENAME DNAME SAL------- --------- ------SMITH RESEARCH 800ADAMS RESEARCH 1100JONES RESEARCH 2975FORD RESEARCH 3000SCOTT RESEARCH 3000

ENAME HIREDATE SAL------- --------- ------FORD 03-DEC-81 3000

ENAME JOB SAL---------- --------- ---------KING PRESIDENT 5000FORD ANALYST 3000SCOTT ANALYST 3000JONES MANAGER 2975BLAKE MANAGER 2850CLARK MANAGER 2450ALLEN SALESMAN 1600TURNER SALESMAN 15008 rows selected.

Page 208: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

10.10. Produzindo Resultados maisProduzindo Resultados mais Legíveis com SQL*PlusLegíveis com SQL*Plus

On Targget Treinamento e Consultoria

Page 209: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Produzir consultas que requerem uma variável de entrada Customizar o ambiente do SQL*Plus Produzir resultados mais legíveis Criar e executar arquivos de script Salvar customizações

Neste capítulo, você aprenderá a incluir comandos SQL*Plus para produzir um resultado de SQL mais legível.

Você pode criar um arquivo de comandos que contém um cláusula WHERE que restringe as linhas exibidas. Para alterar a condição cada vez que o arquivo de comando é executado, você utiliza variáveis de substituição. Variáveis de substituição podem substituir valores na cláusula WHERE, uma string de texto e até mesmo o nome de uma coluna ou tabela.

On Targget Treinamento e Consultoria 2

Page 210: Introdução ao Oracle 8i

Funções Básicas

Relatórios Interativos

Utilizando SQL*Plus, você pode criar relatórios que solicitem ao usuário que forneça seus próprios valores para restringir o intervalo de dados retornados. Para criar relatórios interativos, você pode embutir variáveis de substituição em um arquivo de comandos ou em um comando SQL isolado. Uma variável pode ser vista como um recipiente no qual os valores são armazenados temporariamente.

On Targget Treinamento e Consultoria 3

Page 211: Introdução ao Oracle 8i

Funções Básicas

Utilizando Variáveis de Substituição com (&)

Quando executam um relatório, os usuários freqüentemente necessitam restringir os dados retornados dinamicamente. O SQL*Plus provê esta flexibilidade por meio de variáveis de usuário. Utilize o símbolo (&) para identificar cada variável em seu comando SQL. Você não precisa definir o valor de cada variável.

Sintaxe Descrição

&user_variable

Indica uma variável em um comando SQL; se a variável não existe, o SQL*Plus solicita ao usuário um valor (o SQL*Plus descarta uma nova variável uma vez que ela tenha sido utilizada).

O exemplo acima cria um comando SQL para solicitar ao usuário um número de empregado em tempo de execução e exibe o número do empregado, o nome, o salário, e o número do departamento para aquele empregado.

Com o uso de um único símbolo (&), o usuário é solicitado cada vez que o comando é executado, se a variável não existir.

On Targget Treinamento e Consultoria 4

SQL> SELECT empno, ename, sal, deptno 2 FROM emp 3 WHERE empno = &employee_num;

Enter value for employee_num: 73697369

EMPNO ENAME SAL DEPTNO--------- ---------- --------- --------- 7369 SMITH 800 20

Page 212: Introdução ao Oracle 8i

Funções Básicas

Utilizando o Comando SET VERIFY

Para confirmar as mudanças no comando SQL, utilizar o comando do SQL*Plus SET VERIFY. Ao executar SET VERIFY ON o SQL*Plus passa a exibir o texto de um comando antes e depois de efetuar a troca das variáveis de substituição pelos valores.

O exemplo acima exibe o antigo como também o novo valor da coluna EMPNO.

On Targget Treinamento e Consultoria 5

SQL> SET VERIFY ONSQL> SELECT empno, ename, sal, deptno 2 FROM emp 3 WHERE empno = &employee_num;

Enter value for employee_num: 7369old 3: WHERE empno = &employee_numnew 3: WHERE empno = 7369...

Page 213: Introdução ao Oracle 8i

Funções Básicas

Valores Caractere e Data com Variáveis de Substituição

Em uma cláusula WHERE, valores tipo data e caractere devem ser incluídos entre aspas simples. A mesma regra aplica-se às variáveis de substituição.

Para evitar a necessidade de entrar aspas em tempo de execução, inclua a variável entre aspas simples dentro do próprio comando SQL.

O exemplo acima apresenta uma consulta para recuperar o nome do empregado, o número do departamento e o salário anual de todos os empregados baseado no cargo fornecido pelo usuário no prompt.

Nota: Você também pode utilizar funções como UPPER e LOWER com o (&). Utilize UPPER('&job_title') de forma que o usuário não tenha que entrar o cargo em maiúsculas.

On Targget Treinamento e Consultoria 6

SQL> SELECT ename, deptno, sal*12 2 FROM emp 3 WHERE job = '&job_title';

Enter value for job_title: ANALYSTANALYST

ENAME DEPTNO SAL*12---------- --------- ---------SCOTT 20 36000FORD 20 36000

Page 214: Introdução ao Oracle 8i

Funções Básicas

Especificando Nomes de Colunas, Expressões e Textos emTempo de Execução

Utilize variáveis de substituição para completar:

Uma condição WHERE Uma cláusula ORDER BY Uma expressão de coluna Um nome de tabela Um comando SELECT inteiro

Além da cláusula WHERE dos comandos SQL, você pode utilizar as variáveis de substituição para substituir nomes de coluna, expressões ou texto.

Exemplo:

Mostre o número do empregado e qualquer outra coluna e qualquer outra condição para os empregados.

Se você não entrar um valor para a variável de substituição, você receberá um erro quando executar o comando acima.

On Targget Treinamento e Consultoria 7

SQL> SELECT empno, &column_name 2 FROM emp 3 WHERE &condition;

Enter value for column_name: jobEnter value for condition: deptno = 10

EMPNO JOB--------- --------- 7839 PRESIDENT 7782 MANAGER 7934 CLERK

Page 215: Introdução ao Oracle 8i

Funções Básicas

O exemplo abaixo exibe o número do empregado, o nome, o cargo e qualquer outra coluna especificada pelo usuário em tempo de execução, a partir da tabela EMP. O usuário também pode especificar a condição para recuperação de linhas e o nome da coluna pela qual os dados resultantes devem ser ordenados.

On Targget Treinamento e Consultoria 8

SQL> SELECT empno, ename, job, &column_name 2 FROM emp 3 WHERE &condition 4 ORDER BY &order_column;

Enter value for column_name: salsalEnter value for condition: sal >= 3000sal >= 3000Enter value for order_column: enameename

EMPNO ENAME JOB SAL--------- ---------- --------- --------- 7902 FORD ANALYST 3000 7839 KING PRESIDENT 5000 7788 SCOTT ANALYST 3000

Page 216: Introdução ao Oracle 8i

Funções Básicas

Utilizando Variáveis de Substituição com (&&)

Você pode utilizar variáveis de substituição com o símbolo (&&) se você quiser reutilizar o valor da variável sem solicitá-lo ao usuário cada vez. O usuário receberá uma única vez o prompt para o valor. No exemplo acima, o usuário é solicitado a fornecer uma única vez o valor para a variável column_name. O valor fornecido pelo usuário (deptno) é utilizado para exibir e ordenar os dados.

O SQL*Plus armazena o valor fornecido utilizando o comando DEFINE; ele o reutilizará sempre que você referenciar o nome da variável. Se necessário, você pode utilizar o comando UNDEFINE para apagar uma variável de usuário.

On Targget Treinamento e Consultoria 9

SQL> SELECT empno, ename, job, &&column_name 2 FROM emp 3 ORDER BY &column_name;

Enter value for column_name: deptnodeptno EMPNO ENAME JOB DEPTNO--------- ---------- --------- --------- 7839 KING PRESIDENT 10 7782 CLARK MANAGER 10 7934 MILLER CLERK 10...14 rows selected.

Page 217: Introdução ao Oracle 8i

Funções Básicas

Definindo Variáveis de Usuário

Você pode predefinir variáveis de usuário antes de executar um comando SELECT. O SQL*Plus provê dois comandos para definir e setar variáveis de usuário: DEFINE e ACCEPT.

Se você precisar especificar espaços quando utilizar o comando DEFINE, você deve colocar os espaços dentro de aspas simples.

Comando DescriçãoDEFINE variable = value Cria uma variável de usuário do tipo de dado CHAR e

atribui um valor a ela

DEFINE variable Mostra a variável, seu valor e seu tipo de dado

DEFINEMostra todas as variáveis de usuário com seus valores e tipos de dados

ACCEPT (veja a sintaxe a seguir)Lê uma linha de entrada do usuário e a armazena em uma variável

On Targget Treinamento e Consultoria 10

Page 218: Introdução ao Oracle 8i

Funções Básicas

O Comando ACCEPT

Sintaxe:

variable é o nome da variável que armazena o valor. Se ela não existir, o SQL*Plus a criará.

datatype deve ser NUMBER, CHAR ou DATE. CHAR possui um tamanho máximo de 240 bytes. DATE é verificado através de um modelo de formato, e o tipo de dado é CHAR.

FOR[MAT] especifica a máscara de formatação, por exemplo: A10 ou 9.999.

PROMPT text exibe o texto antes do usuário poder entrar o valor.

HIDE suprime o que o usuário digita, por exemplo, uma senha.

Nota: Não prefixe o parâmetro de substituição do SQL*Plus com (&) quando referenciar o parâmetro no comando ACCEPT.

On Targget Treinamento e Consultoria 11

ACCEPT variable [datatype] [FORMAT format] [PROMPT text] {HIDE}

Page 219: Introdução ao Oracle 8i

Funções Básicas

Utilizando o Comando ACCEPT

O comando ACCEPT lê uma variável chamada DEPT. O prompt exibido quando solicitar para o usuário a variável é "Provide the department name:". A comando SELECT então recebe o valor de departamento que o usuário digitou e o utiliza para recuperar a linha apropriada da tabela DEPT.

Se o usuário entrar um valor válido para o nome do departamento, o comando SELECT executa da mesma forma que qualquer outro comando SELECT, pegando o valor entrado pelo usuário e o utilizando na cláusula WHERE para comparar com DNAME.

Observe que o caráctere & não aparece com a variável DEPT no comando ACCEPT. O & só aparece no comando SELECT.

Diretrizes:

Ambos os comandos ACCEPT e DEFINE criarão uma variável se a variável não existir; estes comandos redefinem automaticamente uma variável caso já exista.

Quando utilizar o comando DEFINE, utilize aspas simples ('') para incluir uma string que contenha espaços.

Utilize o comando ACCEPT para: Fornecer um prompt customizado quando receber entrada de usuário; caso contrário,

você verá uma mensagem padrão “Enter value for variable” Explicitamente defina uma variável do tipo NUMBER ou DATE Oculte a entrada do usuário por razões de segurança

On Targget Treinamento e Consultoria 12

ACCEPT dept PROMPT 'Provide the department name: '

SELECT *FROM deptWHERE dname = UPPER('&dept')/

Provide the department name: SalesSales

DEPTNO DNAME LOC--------- -------------- ------------- 30 SALES CHICAGO

Page 220: Introdução ao Oracle 8i

Funções Básicas

Comandos DEFINE e UNDEFINE

As variáveis permanecem definidas até que você:

Execute o comando UNDEFINE para a variável Encerre o SQL*Plus

Quando você remove variáveis, você pode verificar suas mudanças com o comando DEFINE. Quando você encerra o SQL*Plus, as variáveis definidas durante aquela sessão são perdidas. Para definir essas variáveis para cada sessão, modifique seu arquivo login.sql de forma que essas variáveis sejam criadas durante a inicialização.

On Targget Treinamento e Consultoria 13

Page 221: Introdução ao Oracle 8i

Funções Básicas

Utilizando o Comando DEFINE

Você pode utilizar o comando DEFINE para criar uma variável e então utilizar esta variável como você utilizaria qualquer outra variável. O exemplo acima cria uma variável DEPTNAME que contém o nome do departamento, SALES. O comando SQL então utiliza esta variável para exibir o número e a localização do departamento SALES.

Para apagar a variável, você utiliza o comando UNDEFINE:

On Targget Treinamento e Consultoria 14

SQL> DEFINE deptname = salesSQL> DEFINE deptnameDEFINE DEPTNAME = "sales" (CHAR)SQL> SELECT * 2 FROM dept 3 WHERE dname = UPPER('&deptname');

DEPTNO DNAME LOC--------- ----------- ------------- 30 SALES CHICAGO

SQL> UNDEFINE deptnameSQL> DEFINE deptnamesymbol deptname is UNDEFINED

Page 222: Introdução ao Oracle 8i

Funções Básicas

Customizando o Ambiente do SQL*Plus

Você pode controlar o ambiente no qual SQL*Plus está operando utilizando os comandos SET.

Sintaxe:

system_variable é uma variável que controla um aspecto do ambiente da sessão.

value é um valor para a variável de sistema.

Você pode verificar a configuração atual com o comando SHOW. O comando SHOW no exemplo acima confere se ECHO estava configurado para ON ou para OFF.

Para ver todos os valores de variáveis SET, utilize o comando SHOW ALL.

On Targget Treinamento e Consultoria 15

SET system_variable valueSQL> SET ECHO ONSQL> SHOW ECHOecho ONecho ON

Page 223: Introdução ao Oracle 8i

Funções Básicas

Variáveis do Comando SET

Variáveis SET e Valores Descrição

ARRAY[SIZE] {20 | n}Configura o tamanho da leitura de dados a partir do banco de dados

COLSEP {_ | text}Configura o texto para ser impresso entre as colunas. O padrão é um espaço simples

FEED[BACK] { 6 | n | OFF | ON} Exibe o número de registros retornados por uma consulta quando a consulta retorna pelo menos n registros

HEA[DING] {OFF | ON}Determina quando os cabeçalhos de coluna devem ser exibidos nos relatórios

LIN[ESIZE] {80 | n} Configura o número de caracteres por linha para n

LONG {80 | n}Configura o tamanho máximo para a exibição de valores do tipo LONG

PAGES[IZE] {24 | n} Especifica o número de linhas por página de saída

PAU[SE] {OFF | ON | text}Permite que você controle o scroll do seu terminal (Você deve pressionar [Return] após visualizar cada pausa).

TERM[OUT] {OFF|ON} Determina quando o resultado deve ser exibido na tela

Nota: O valor n representa um valor numérico. Os valores sublinhados apresentados acima indicam os valores default. Se você não fornecer nenhum valor com a variável, o SQL*Plus assume o valor default.

On Targget Treinamento e Consultoria 16

Page 224: Introdução ao Oracle 8i

Funções Básicas

Salvando as Customizações no Arquivo login.sql

O arquivo login.sql possui SETs padrão e outros comandos do SQL*Plus que você pode necessitar para todas as sessões. O arquivo é lido e os comandos são implementados durante o login. Quando você encerra sua sessão, todas as configurações customizadas são perdidas.

Modificando as Configurações Default

As configurações implementadas pelo arquivo login.sql podem ser modificadas durante a sessão atual. Mudanças efetuadas ficam ativas apenas para aquela sessão. Assim que você a encerra, essas configurações são perdidas.

Adiciona configurações permanentes para o arquivo login.sql.

On Targget Treinamento e Consultoria 17

Page 225: Introdução ao Oracle 8i

Funções Básicas

Comandos de Formatação do SQL*Plus

Obtendo Resultados mais Legíveis

Você pode controlar as características do relatório utilizando os seguintes comandos:

Comando DescriçãoCOL[UMN] [column option] Controla a formatação de colunasTTI[TLE] [text | OFF | ON] Especifica um cabeçalho a ser apresentado no topo de cada página

BTI[TLE] [text | OFF | ON]Especifica um rodapé a ser apresentado no final de cada página do relatório

BRE[AK] [ON report_element] Suprime valores duplicados e divide linhas de dados com linhas em branco

Diretrizes

Todos os comandos de formatação permanecem em efeito até o final da sessão do SQL*Plus ou até que o formato fixado seja sobrescrito ou limpo.

Lembre-se de voltas suas configuração do SQL*Plus para os valores default depois de todo relatório.

Não existe nenhum comando para configurar uma variável do SQL*Plus para seu valor default; você deve conhecer o valor específico ou encerrar sua sessão e conectar novamente.

Se você fornecer um alias para sua coluna, você deve referenciar o nome do alias, não o nome da coluna.

On Targget Treinamento e Consultoria 18

Page 226: Introdução ao Oracle 8i

Funções Básicas

Comando COLUMN

Opção DescriçãoCLE[AR] Limpa qualquer formatação de colunaFOR[MAT] format Modifica a exibição dos dados de uma colunaHEA[DING] text Configura o cabeçalho da coluna. O caractere pipe (|) pode forçar

uma quebra de linha no cabeçalho se você não utilizar justificaçãoJUS[TIFY] {align} Justifica o cabeçalho da coluna (não os dados) à esquerda,

centralizado ou à direitaNOPRI[NT] Oculta a colunaNUL[L] text Especifica o texto a ser exibido para valores nulosPRI[NT] Mostra a colunaTRU[NCATED] Trunca a string no final da primeira linha de exibiçãoWRA[PPED] Coloca o final da string na próxima linha

On Targget Treinamento e Consultoria 19

COL[UMN] [{column|alias} [option]]

Page 227: Introdução ao Oracle 8i

Funções Básicas

Utilizando o Comando COLUMN

Crie cabeçalhos de coluna:

Mostre a configuração atual para a coluna ENAME:

Limpe as configurações para a coluna ENAME:

Comando DescriçãoCOL[UMN] column Exibe as configurações atuais para a coluna especificadaCOL[UMN] Exibe as configurações atuais para todas as colunasCOL[UMN] column CLE[AR] Limpa as configurações para a coluna especificada CLE[AR] COL[UMN] Limpa as configurações para todas as colunas

Se você tiver um comando muito longo, você pode continuá-lo na próxima linha terminando a linha atual com um hífen (-).

On Targget Treinamento e Consultoria 20

COLUMN ename HEADING 'Employee|Name' FORMAT A15COLUMN sal JUSTIFY LEFT FORMAT $99,990.00COLUMN mgr FORMAT 999999999 NULL 'No manager'

COLUMN enameCOLUMN ename CLEAR

Page 228: Introdução ao Oracle 8i

Funções Básicas

Máscaras do Comando COLUMN

O gráfico acima exibe exemplos de formatação de colunas.

O Servidor Oracle exibe uma string com o caractere (#) no lugar de um número inteiro cujos dígitos excedem o número de dígitos providos pela máscara. Também exibe uma string com o caractere (#) no lugar de um valor cuja máscara é alfanumérica mas o valor atual é numérico.

On Targget Treinamento e Consultoria 21

Page 229: Introdução ao Oracle 8i

Funções Básicas

Utilizando o Comando BREAK

Para suprimir duplicidades:

Para produzir sumários gerais:

Para dividir as linhas nas quebras do relatório:

Utilize o comando BREAK para dividir as linhas e suprimir valores duplicados. Para assegurar que o comando BREAK funcione corretamente, ordene pelas colunas nas quais você está quebrando.

Sintaxe:

Onde:

page avança uma página quando os valores da quebra mudam.

skip n avança n linhas quando os valores da quebra mudam.Quebras podem ser ativadas em:- Coluna- Linha- Página- Relatório

duplicate exibe valores duplicados.

Limpe todas as configuraçoes de BREAK utilizando o comando CLEAR:

On Targget Treinamento e Consultoria 22

SQL> BREAK ON ename ON jobSQL> BREAK ON reportSQL> BREAK ON ename SKIP 4 ON job SKIP2

BREAK on column[|alias|row] [skip n|dup|page] on .. [on report]

CLEAR BREAK

Page 230: Introdução ao Oracle 8i

Funções Básicas

Utilizando os Comandos TTITLE e BTITLE

Configure o cabeçalho do relatório:

Configure o rodapé do relatório:

Utilize o comando TTITLE para formatar cabeçalhos de página e o comando BTITLE para rodapés. Rodapés aparecem ao final de cada página de acordo com o valor de PAGESIZE.

A sintaxe para BTITLE e TTITLE é idêntica. Você pode utilizar o caractere pipe (|) para dividir o texto do título em várias linhas.

Sintaxe:

text representa o texto de título. Coloque entre aspas simples se o texto for mais de uma palavra.

O exemplo de TTITLE acima configura o cabeçalho do relatório para exibir Salary centralizado em uma linha e Report centralizado na linha seguinte. O exemplo de BTITLE configura o rodapé do relatório para exibir Confidential. TTITLE automaticamente coloque a data e número da página no relatório.

On Targget Treinamento e Consultoria 23

TTI[TLE] [text|OFF|ON]SQL> TTITLE 'Salary|Report'SQL> BTITLE 'Confidential'

Page 231: Introdução ao Oracle 8i

Funções Básicas

Criando um Arquivo de Script para Executar um Relatório

Você pode entrar cada um dos comandos do SQL*Plus no prompt de SQL ou colocá-lo todos, incluindo o comando SELECT, em um arquivo de comandos (ou script). Um arquivo de script consiste em pelo menos um comando SELECT e vários comandos do SQL*Plus.

Passos para Criar um Arquivo de Script

1. Crie o comando SQL SELECT no prompt de SQL. Assegure-se de que os dados necessários para o relatório estejam corretos antes de salvar o comando para um arquivo e aplicar os comandos de formatação. Assegura-se que a classificação da cláusula ORDER BY esteja de acordo com as quebras que você venha a definir para o relatório.

2. Salve o comando SELECT para um arquivo de script.

3. Edite o arquivo de script para colocar os comandos do SQL*Plus.

4. Adicione os comandos de formatação necessários antes do comando SELECT. Assegure-se de não colocar comandos do SQL*Plus dentro do comando SELECT.

5. Verifica que o comando SELECT seja seguido por um caractere de execução, ou o caracter (;) ou uma barra (/).

6. Adicione comandos para limpar as formatações após o caracter de execução do comando SELECT. Como alternativa, você pode chamar um arquivo padrão que contém todos os comandos de limpeza de formatação.

7. Salve o arquivo de script com suas modificações.

8. No SQL*Plus, execute o arquivo de script entrando o comando START filename ou @filename. Este comando é necessário para ler e executar o arquivo de script.

Diretrizes

Você pode incluir linhas em branco entre os comandos do SQL*Plus em um script.

Você pode abreviar comandos do SQL*Plus.

Inclua comandos de limpeza de formatação ao término do arquivo para restaurar o ambiente original do SQL*Plus.

On Targget Treinamento e Consultoria 24

Page 232: Introdução ao Oracle 8i

Funções Básicas

Relatório de Exemplo

Exemplo:

Crie um arquivo de script para criar um relatório que mostre o cargo, o nome e o salário para todo empregado cujo salário é menor que $3000. Adicione um cabeçalho centralizado, de duas linhas, com a string "Employee Report" e um rodapé também centralizado com a string "Confidential". Renomeie a coluna cargo para "Job Category" dividida em duas linhas. Renomeie a coluna com o nome do empregado para "Employee". Renomeie a coluna salário para "Salary", formatando-a como o seguinte exemplo: $2,500.00.

On Targget Treinamento e Consultoria 25

SET PAGESIZE 37SET LINESIZE 60SET FEEDBACK OFFTTITLE 'Employee|Report'BTITLE 'Confidential'COLUMN job HEADING 'Job|Category' FORMAT A15COLUMN ename HEADING 'Employee' FORMAT A15COLUMN sal HEADING 'Salary' FORMAT $99,999.99REM ** Insert SELECT statementSELECT job, ename, salFROM empWHERE sal < 3000ORDER BY job, ename/

Page 233: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 9

Determine se as seguintes declarações são verdadeiras ou falsas:

1. Uma variável de substituição criada com o símbolo (&) é solicitada ao usuário uma única vez.

Verdadeiro / Falso

2. O comando ACCEPT é um comando SQL.

Verdadeiro / Falso

3. Escreva um arquivo de script para mostrar o nome do empregado, o cargo e a data de admissão para todos os empregados que foram admitidos entre um determinado período. Concatene o nome e o cargo, separando-os por uma vírgula e espaço, e coloque o alias da coluna como “Employees”. Solicite ao usuário os dois intervalos do período utilizando o comando ACCEPT. Utilize o formato MM/DD/YY. Salve o script para um arquivo chamado e9q3.sql.

4. Escreva um script para mostrar o nome do empregado, o cargo e o nome do departamento. A condição de pesquisa deve permitir que a procura não faça distinção entre maiúsculas e minúsculas. Salve o script para um arquivo chamado e9q4.sql.

5. Modifique o arquivo e9q4.sql para criar um relatório contendo o nome do departamento, o nome do empregado, a data de admissão, o salário e o salário anual para todos os empregados em uma determinada localização. Solicite ao usuário a localização. Coloque o alias das colunas como “DEPARTMENT NAME”, “EMPLOYEE NAME”, “START DATE”, “SALARY”, “ANNUAL SALARY”, colocando os alias em múltiplas linhas. Save o novo script para um arquivo chamado e9q5.sql.

On Targget Treinamento e Consultoria 26

Please enter the low date range ('MM/DD/YY'): 01/01/81Please enter the high date range ('MM/DD/YY'): 01/01/82EMPLOYEES HIREDATE----------------- ---------------KING, PRESIDENT 17-NOV-81BLAKE, MANAGER 01-MAY-81CLARK, MANAGER 09-JUN-81JONES, MANAGER 02-APR-81MARTIN, SALESMAN 28-SEP-81ALLEN, SALESMAN 20-FEB-81TURNER, SALESMAN 08-SEP-81JAMES, CLERK 03-DEC-81WARD, SALESMAN 22-FEB-81FORD, ANALYST 03-DEC-8110 rows selected.

Please enter the location name: DallasEMPLOYEE NAME JOB DEPARTMENT NAME------------- ------------ ---------------JONES MANAGER RESEARCHFORD ANALYST RESEARCHSMITH CLERK RESEARCHSCOTT ANALYST RESEARCHADAMS CLERK RESEARCH

Page 234: Introdução ao Oracle 8i

Funções Básicas

On Targget Treinamento e Consultoria 27

Please enter the location name: ChicagoDEPARTMENT EMPLOYEE START ANNUALNAME NAME DATE SALARY SALARY---------- ----------- --------- --------- ----------SALES BLAKE 01-MAY-81 $2,850.00 $34,200.00 MARTIN 28-SEP-81 $1,250.00 $15,000.00 ALLEN 20-FEB-81 $1,600.00 $19,200.00 TURNER 08-SEP-81 $1,500.00 $18,000.00 JAMES 03-DEC-81 $950.00 $11,400.00 WARD 22-FEB-81 $1,250.00 $15,000.00

Page 235: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

11.11. Manipulando DadosManipulando Dados

On Targget Treinamento e Consultoria

Page 236: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Descrever cada comando DML Inserir linhas em uma tabela Atualizar linhas de uma tabela Remover linhas de uma tabela Controlar transações

Neste capítulo, você aprenderá a inserir linhas em uma tabela, atualizará linhas existentes e apagará linhas de uma tabela. Você também aprenderá a controlar transações com os comandos COMMIT, SAVEPOINT e ROLLBACK.

On Targget Treinamento e Consultoria 2

Page 237: Introdução ao Oracle 8i

Funções Básicas

Linguagem de Manipulação de Dados

Linguagem de manipulação de dados (DML) é uma parte essencial do SQL. Quando você necessita adicionar, atualizar ou apagar dados no banco de dados, você executa um comando DML. Um conjunto de comandos DML formam uma unidade lógica de trabalho chamada de transação.

Considere um banco de dados bancário. Quando um cliente do banco transfere dinheiro de uma poupança para uma conta corrente, a transação poderia consistir de três operações separadas: diminur da poupança, aumentar na conta corrente e registrar a transação no diário de transações. O Servidor Oracle deve garantir que todos os três comandos SQL sejam executados para manter as contas equilibradas. Quando algo impede um dos comandos da transação de executar, devem ser desfeitas as mudanças causadas pelos outros comandos da transação.

On Targget Treinamento e Consultoria 3

Page 238: Introdução ao Oracle 8i

Funções Básicas

Inserindo uma Nova Linha em uma Tabela

O gráfico acima insere um departamento novo para a tabela DEPT.

On Targget Treinamento e Consultoria 4

Page 239: Introdução ao Oracle 8i

Funções Básicas

Comando INSERT

Você pode adicionar linhas novas para uma tabela executando um comando INSERT.

Sintaxe:

table é o nome da tabela.

column é o nome da coluna da tabela que receberá os valores.

value é o valor correspondente para a coluna.

Nota: Este comando com a cláusula VALUES adiciona apenas uma linha de cada vez para a tabela.

On Targget Treinamento e Consultoria 5

INSERT INTO table [(column [, column...])]VALUES (value [, value...]);

Page 240: Introdução ao Oracle 8i

Funções Básicas

Inserindo Novas Linhas

Uma vez que você pode inserir uma linha nova que contenha valores para cada coluna da tabela, a lista de colunas não é obrigatória na cláusula INSERT. Porém, se você não utiliar a lista de colunas, os valores devem ser listados de acordo com a ordem default das colunas na tabela.

Por questões de clareza, utilize a lista de colunas na cláusula INSERT. Coloque valores caractere e data entre aspas simples; não inclua valores numéricos entre aspas.

On Targget Treinamento e Consultoria 6

SQL> INSERT INTO dept (deptno, dname, loc) 2 VALUES (50, 'DEVELOPMENT', 'DETROIT');1 row created.1 row created.

SQL> DESCRIBE dept

Name Null? Type------------------------------- -------- ------------DEPTNO NOT NULL NUMBER(2)DNAME VARCHAR2(14)LOC VARCHAR2(13)

Page 241: Introdução ao Oracle 8i

Funções Básicas

Inserindo Linhas com Valores Nulos

Método implícito:

Método explícito:

Método DescriçãoImplícito Omita a coluna da lista de colunasExplícito Especifique a palavra chave NULL na lista da cláusula VALUES.

Especifique uma string vazia ('') na lista da cláusula VALUES para valores do tipo caractere e data

Tenha certeza que a coluna de destino permita valores nulos verificando o status da coluna Null? do comando DESCRIBE do SQL*Plus.

O Servidor Oracle automaticamente verifica todos os tipos de dados, intervalos de valores e regras de integridade de dados. Qualquer coluna que não é listada explicitamente recebe um valor nulo na linha nova.

On Targget Treinamento e Consultoria 7

SQL> INSERT INTO dept (deptno, dname ) 2 VALUES (60, 'MIS');1 row created.1 row created.

SQL> INSERT INTO dept 2 VALUES (70, 'FINANCE', NULL);1 row created.1 row created.

Page 242: Introdução ao Oracle 8i

Funções Básicas

Inserindo Valores Especiais

Você pode utilizar pseudo colunas para entrar valores especiais em sua tabela.

O exemplo acima armazena informações para o empregado GREEN na tabela EMP. Ele armazena a data e hora atual na coluna HIREDATE, utilizando a função SYSDATE.

Você também pode utillizar a função USER quando inserir linhas em uma tabela. A função USER armazena o nome do usuário atual.

Confirmando Inserções para uma Tabela

On Targget Treinamento e Consultoria 8

SQL> INSERT INTO emp (empno, ename, job, 2 mgr, hiredate, sal, comm, 3 deptno) 4 VALUES (7196, 'GREEN', 'SALESMAN', 5 7782, SYSDATE, 2000, NULL, 6 10);1 row created.1 row created.

SQL> SELECT empno, ename, job, hiredate, comm 2 FROM emp 3 WHERE empno = 7196;

EMPNO ENAME JOB HIREDATE COMM--------- ---------- --------- --------- -------- 7196 GREEN SALESMAN 01-DEC-97

Page 243: Introdução ao Oracle 8i

Funções Básicas

Inserindo Valores de Data Específicos

Adicione um novo empregado:

Verifique sua inserção:

O formato DD-MON-YY é normalmente utilizado para inserir um valor de data. Com este formato, lembre-se que o século fica sendo o século atual. Uma vez que a data também possui informação de hora, a hora default é meia-noite (00:00:00).

Se uma data precisa ser entrada em outro século ou com uma hora específica, utilize a função TO_DATE.

O exemplo acima armazena informações para o empregado AROMANO na tabela EMP. O valor da coluna HIREDATE fica sendo 3 de fevereiro de 1997.

Se o formato RR for utilizado, o século pode então não ser o atual.

On Targget Treinamento e Consultoria 9

SQL> INSERT INTO emp 2 VALUES (2296,'AROMANO','SALESMAN',7782, 3 TO_DATE('FEB 3,97', 'MON DD, YY'), 4 1300, NULL, 10);1 row created.1 row created.

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO----- ------- -------- ---- --------- ---- ---- ------ 2296 AROMANO SALESMAN 7782 03-FEB-97 1300 10

Page 244: Introdução ao Oracle 8i

Funções Básicas

Inserindo Valores Utilizando Variáveis de Substituição

Você pode produzir um comando INSERT que permite ao usuário adicionar valores interativamente utilizando variáveis de substituição do SQL*Plus.

O exemplo acima armazena informações para um departamento na tabela DEPT. Ele solicita ao usuário o número do departamento, o nome do departamento e sua localização.

Para valores caractere e data, o símbolo (&) e o nome da variável deve ficar entre aspas simples.

On Targget Treinamento e Consultoria 10

SQL> INSERT INTO dept (deptno, dname, loc) 2 VALUES (&department_id, 3 '&department_name', '&location');

Enter value for department_id: 8080Enter value for department_name: EDUCATIONEDUCATIONEnter value for location: ATLANTAATLANTA

1 row created.

Page 245: Introdução ao Oracle 8i

Funções Básicas

Criando um Script com Prompts Customizados

Você pode salvar seu comando com variáveis de substituição para um arquivo e então executá-lo. Cada vez que você executa o comando, ele solicitará novos valores. Customize os prompts utilizando o comando ACCEPT do SQL*Plus.

O exemplo acima armazena informações para um departamento na tabela DEPT. Ele solicita ao usuário o número do departamento, o nome do departamento e sua localização utilizando mensagens customizadas.

Não prefixe parâmetros de substituição do SQL*Plus com o símbolo (&) quando referenciá-los no comando ACCEPT. Utilize um hífen (-) para continuar um comando do SQL*Plus na próxima linha.

On Targget Treinamento e Consultoria 11

Please enter the department number: 90Please enter the department name: PAYROLLPlease enter the location: HOUSTON

1 row created.

Page 246: Introdução ao Oracle 8i

Funções Básicas

Copiando Linhas a Partir de Outra Tabela

Você pode utilizar o comando INSERT para adicionar linhas para uma tabela onde os valores são derivados de outras tabelas. Ao invés de utilizar a cláusula VALUES, utilize uma subconsulta.

Sintaxe:

Onde:

table é o nome da tabela.

column é o nome da coluna da tabela que receberá valores.

subquery é uma subconsulta que retorna linhas para uma tabela.

O número de colunas e seus tipos de dados na lista da cláusula INSERT deve corresponder ao número de valores e seus tipos de dados na subconsulta.

On Targget Treinamento e Consultoria 12

SQL> INSERT INTO managers(id, name, salary, hiredate) 2 SELECT empno, ename, sal, hiredate 3 FROM emp 4 WHERE job = 'MANAGER';3 rows created.3 rows created.

INSERT INTO table [ column (, column) ]subquery;

Page 247: Introdução ao Oracle 8i

Funções Básicas

Alterando Dados em uma Tabela

O gráfico acima modifica o número do departamento de CLARK de 10 para 20.

On Targget Treinamento e Consultoria 13

Page 248: Introdução ao Oracle 8i

Funções Básicas

Comando UPDATE

Você pode modificar linhas existentes utilizando o comando UPDATE.

Sintaxe:

table é o nome da tabela.

column é o nome da coluna a alterar.

value é o valor correspondente ou subconsulta para a coluna.

condition identifica as linhas a serem atualizadas; é composto de nomes de colunas, expressões, constantes, subconsultas e operadores de comparação.

Confirme a operação de atualização examinando a tabela e exibindo as linhas atualizadas.

Nota: Em geral, utilize a chave primária para identificar uma única linha. Utilizar outras colunas pode causar a atualização indesejada de várias linhas. Por exemplo, identificar uma única linha da tabela EMP através do nome é perigoso porque mais de um empregado pode ter o mesmo nome.

On Targget Treinamento e Consultoria 14

UPDATE tableSET column = value [, column = value][WHERE condition];

Page 249: Introdução ao Oracle 8i

Funções Básicas

Alterando Linhas em uma Tabela

Linhas especificas são modificadas quando você utiliza uma cláusula WHERE.

Todas as linhas da tabela são modificadas se você omitir a cláusula WHERE.

O comando UPDATE modifica linhas especificas, se a cláusula WHERE for especificada. O exemplo acima transfere o empregado 7782 (CLARK) para o departamento 20.

Se você omitir a cláusula WHERE, todas as linhas da tabela serão modificadas.

Nota: A tabela EMPLOYEE tem os mesmos dados que a tabela EMP.

On Targget Treinamento e Consultoria 15

SQL> UPDATE emp 2 SET deptno = 20 3 WHERE empno = 7782;1 row updated.1 row updated.

SQL> UPDATE employee 2 SET deptno = 20;14 rows updated.14 rows updated.

SQL> SELECT ename, deptno 2 FROM employee;ENAME DEPTNO---------- ---------KING 20BLAKE 20CLARK 20JONES 20MARTIN 20ALLEN 20TURNER 20...14 rows selected.

Page 250: Introdução ao Oracle 8i

Funções Básicas

Atualizando com Subconsultas Multiple-Column

Subconsultas multiple-column podem ser implementadas na cláusula SET de um comando UPDATE.

Sintaxe:

On Targget Treinamento e Consultoria 16

SQL> UPDATE emp 2 SET (job, deptno) = 3 (SELECT job, deptno 4 FROM emp 5 WHERE empno = 7499) 6 WHERE empno = 7698;1 row updated.1 row updated.

UPDATE tableSET (column, column, ...) =

(SELECT column, column, FROM table WHERE condition)

WHERE condition;

Page 251: Introdução ao Oracle 8i

Funções Básicas

Atualizando Linhas com Valores de Outra Tabela

Você pode utilizar subconsultas em comandos UPDATE para atualizar linhas em uma tabela. O exemplo acima atualiza a tabela EMPLOYEE baseado nos valores da tabela EMP, modificando o número do departamento de todos os empregados com o mesmo cargo do empregado 7788 para o número do departamento do empregado 7788.

On Targget Treinamento e Consultoria 17

SQL> UPDATE employee 2 SET deptno = (SELECT deptno 3 FROM emp 4 WHERE empno = 7788) 5 WHERE job = (SELECT job 6 FROM emp 7 WHERE empno = 7788);2 rows updated.2 rows updated.

Page 252: Introdução ao Oracle 8i

Funções Básicas

Atualizando Linhas: Erro de Constraint de Integridade

Se você tentar atualizar um registro com um valor que invalide uma constraint de integridade, você receberá um erro.

No exemplo acima, o departamento número 55 não existe na tabela pai, DEPT, portanto você recebe o erro "parent key violation", ORA-02291.

Nota: Constraints de integridade asseguram que os dados sigam um conjunto pré-determinado de regras. Um capítulo subseqüente apresentará mais detalhes sobre as constraints de integridade.

On Targget Treinamento e Consultoria 18

Page 253: Introdução ao Oracle 8i

Funções Básicas

Removendo uma Linha de uma Tabela

O gráfico acima remove o departamento DEVELOPMENT da tabela DEPT (assumindo que não existem constraints definidas na tabela DEPT).

On Targget Treinamento e Consultoria 19

Page 254: Introdução ao Oracle 8i

Funções Básicas

Comando DELETE

Você pode remover linhas utilizando o comando DELETE.

Sintaxe:

table é o nome da tabela.

condition identifica as linhas a serem apagadas; é composto de nomes de colunas, expressões, constantes, subconsultas e operadores de comparação.

On Targget Treinamento e Consultoria 20

DELETE [FROM] table[WHERE condition];

Page 255: Introdução ao Oracle 8i

Funções Básicas

Removendo Linhas de uma Tabela

Linhas específicas são removidas quando você utiliza a cláusula WHERE.

Todas as linhas da tabela são removidas se você omitir a cláusula WHERE.

Você pode remover linhas específicas utilizando a cláusula WHERE no comando DELETE. O exemplo acima remove o departamento DEVELOPMENT da tabela DEPARTMENT. Você pode confirmar a operação de deleção tentando exibir as linhas removidas utilizando o comando SELECT.

Exemplo:

Remova todos os empregados que foram admitidos após 1 de Janeiro de 1997.

Nota: A tabela DEPARTMENT possui os mesmos dados da tabela DEPT.

On Targget Treinamento e Consultoria 21

SQL> DELETE FROM department 2 WHERE dname = 'DEVELOPMENT';1 row deleted.1 row deleted.

SQL> DELETE FROM department;4 rows deleted.4 rows deleted.SQL> SELECT * 2 FROM department 3 WHERE dname = 'DEVELOPMENT';no rows selected.

SQL> DELETE FROM emp 2 WHERE hiredate > TO_DATE('01.01.97', 'DD.MM.YY');1 row deleted.

Page 256: Introdução ao Oracle 8i

Funções Básicas

Removendo Linhas com Base nos Valores de Outra Tabela

Você pode utilizar subconsultas para remover linhas de uma tabela baseado em valores de outra tabela. O exemplo acima remove todos os empregados que estão no departamento 30. A subconsulta procura na tabela DEPT para encontrar o número do departamento SALES. A subconsulta retorna o número do departamento para a consulta principal que remove as linhas de dados da tabela EMPLOYEE com base neste número de departamento.

On Targget Treinamento e Consultoria 22

SQL> DELETE FROM employee 2 WHERE deptno = 3 (SELECT deptno 4 FROM dept 5 WHERE dname ='SALES');6 rows deleted.6 rows deleted.

Page 257: Introdução ao Oracle 8i

Funções Básicas

Removendo Linhas: Erro de Constraint de Integridade

Se você tentar remover um registro com um valor que invalide uma constraint de integridade, você receberá um erro.

O exemplo acima tenta remover o departamento número 10 da tabela DEPT, mas resulta em um erro porque o departamento é utilizado como chave estrangeira na tabela EMP. Se o registro pai que você tentou apagar possuir registros filhos, então você recebe a mensagem de erro "child reccord found violation", ORA-02292.

On Targget Treinamento e Consultoria 23

Page 258: Introdução ao Oracle 8i

Funções Básicas

Transações de Banco de Dados

O Servidor Oraclle garante a consistência dos dados baseado em transações. Transações fornecem maior flexibilidade e controle para a modificação dos dados, assegurando a consistência dos mesmos no caso de falha do processo do usuário ou falha do sistema.

Transações consistem em comandos DML que compõem uma mudança consistente dos dados. Por exemplo, uma transferência de fundos entre duas contas deve incluir o débito para uma conta e o crédito para outra conta no mesmo valor. Ambas as ações devem falhar ou devem ter sucesso juntas. O crédito não pode ser efetuado sem o correspondente débito.

Tipos de Transações

Tipo DescriçãoData manipulation language (DML)

Consiste de um número de comandos DML que o Servidor Oracle trata como uma única entidade ou unidade lógica de trabalho

Data definition language (DDL)

Consiste de um único comando DDL

Data control language (DCL)

Consiste de um único comando DCL

Quando uma Transação Inicia ou Termina?

Uma transação inicia quando o primeiro comando SQL é executado e termina quando um dos seguintes eventos acontece:

Um comando COMMIT ou ROLLBACK é executado Uma comando DDL, como CREATE, é executado Uma comando DCL é executado O usuário encerra o SQL*Plus Uma máquina ou o sistema falha

Depois que uma transação termina, o próximo comando SQL executado iniciará a próxima transação automaticamente.

Um comando DDL ou DCL é automaticamente confirmado (commit) e portanto implicitamente termina a transação.

On Targget Treinamento e Consultoria 24

Page 259: Introdução ao Oracle 8i

Funções Básicas

Vantagens do COMMIT e ROLLBACK

Garantem a consistência dos dados Visualização dos dados modificados antes de tornar as modificações permanentes Agrupam logicamente operações relacionadas

On Targget Treinamento e Consultoria 25

Page 260: Introdução ao Oracle 8i

Funções Básicas

Controlando Transações

Você pode controlar a lógica das transações utilizando os comandos COMMIT, SAVEPOINT e ROLLBACK.

Comando Descrição

COMMITTermina a transação corrente tornando todas as modificações pendentes permanentes

SAVEPOINT name Coloca uma marca dentro da transação corrente

ROLLBACK [TO SAVEPOINT name]

ROLLBACK termina a transação corrente desfazendo todas as modificações pendentes. ROLLBACK TO SAVEPOINT name desfaz todas as modificações após a marca de savepoint

Nota: SAVEPOINT não faz parte do padrão SQL ANSI.

On Targget Treinamento e Consultoria 26

Page 261: Introdução ao Oracle 8i

Funções Básicas

Processamento Implícito de Transações

Situação Circunstâncias

Commit automáticoComando DDL ou comando DCL é executadoSaída normal do SQL*Plus, sem explicitamente executar um COMMIT ou ROLLBACK

Rollback automático Saída anormal do SQL*Plus ou falha do sistema

Nota: Um terceiro comando está disponível no SQL*Plus. O comando do SQL*Plus AUTOCOMMIT pode ser alternado para ON ou OFF. Se for setado para ON, cada comando DML individual sofre commit assim que for executado. Você não pode desfazer as mudanças. Se for setado para OFF, o COMMIT pode ser executado explicitamente. Também, o COMMIT é efetuado quando um comando DDL é executado ou quando você encerra o SQL*Plus.

Falhas do Sistema

Quando uma transação é interrompida por uma falha de sistema, a transação inteira é desfeita automaticamente. Isto previne o erro de causar mudanças não desejadas para os dados e retorna as tabelas para o seu estado no momento do último commit. Desta forma, o SQL protege a integridade das tabelas.

On Targget Treinamento e Consultoria 27

Page 262: Introdução ao Oracle 8i

Funções Básicas

Situação dos Dados Antes do COMMIT ou ROLLBACK

Toda mudança dos dados feita durante a transação é temporária até a transação sofrer commit.

Situação dos Dados Antes do COMMIT ou ROLLBACK

Operações de manipulação de dados inicialmente afetam o buffer do banco de dados; portanto, o estado anterior dos dados pode ser recuperado.

O usuário atual pode visualizar os resultados das operações de manipulação de dados examinando as tabelas.

Outros usuários não podem visualizar os resultados das operações de manipulação de dados efetuadas pelo usuário atual. O Servidor Oracle fornece leitura consistente para assegurar que cada usuário visualize os dados como ficaram após o último commit.

As linhas afetadas são bloqueadas; outros usuários não podem modificar os dados destas linhas.

On Targget Treinamento e Consultoria 28

Page 263: Introdução ao Oracle 8i

Funções Básicas

Situação dos Dados Após o COMMIT

Efetive as mudanças pendentes utilizando o comando COMMIT. Após o COMMIT:

Modificações para os dados são efetivadas no banco de dados. O estado anterior dos dados fica permanentemente perdido. Todos os usuários podem visualizar os resultados da transação. Os locks nas linhas afetadas são liberados; as linhas ficam disponíveis para outros usuários

executarem novas mudanças nos dados. Todos o savepoints são eliminados.

On Targget Treinamento e Consultoria 29

Page 264: Introdução ao Oracle 8i

Funções Básicas

Efetivando os Dados

Faça as alterações:

Efetive as alterações:

O exemplo acima atualiza a tabela EMP alterando o número do departamento para o empregado 7782 (CLARK) para 10. Depois ele torna a mudança permanente executando o comando COMMIT.

Exemplo:

Crie um novo departamento chamado ADVERTISING com pelo menos um empregado. Torne as mudanças nos dados permanente.

On Targget Treinamento e Consultoria 30

SQL> UPDATE emp 2 SET deptno = 10 3 WHERE empno = 7782;1 row updated.1 row updated.

SQL> COMMIT;Commit complete.Commit complete.SQL> INSERT INTO department(deptno, dname, loc) 2 VALUES (50, 'ADVERTISING', 'MIAMI');1 row created.

SQL> UPDATE employee 2 SET deptno = 50 3 WHERE empno = 7876;1 row updated.

SQL> COMMIT;Commit complete.

Page 265: Introdução ao Oracle 8i

Funções Básicas

Situação dos Dados Após o ROLLBACK

Descarte todas as mudanças pendentes utilizando o comando ROLLBACK. Após o ROLLBACK:

Modificações para os dados são desfeitas. O estado anterior dos dados é restaurado. Os locks nas linhas afetadas são liberados.

Exemplo:

Ao tentar remover um registro da tabela TESTE, você pode acidentalmente apagar toda a tabela. Você pode corrigir o engano, e então executar o comando novamente de forma correta, tornando as mudanças permanentes.

On Targget Treinamento e Consultoria 31

SQL> DELETE FROM employee;14 rows deleted.14 rows deleted.SQL> ROLLBACK;Rollback complete.Rollback complete.

SQL> DELETE FROM test;25,000 rows deleted.SQL> ROLLBACK;Rollback complete.SQL> DELETE FROM test 2 WHERE id = 100;1 row deleted.SQL> SELECT * 2 FROM test 3 WHERE id = 100;No rows selected.SQL> COMMIT;Commit complete.

Page 266: Introdução ao Oracle 8i

Funções Básicas

Desfazendo as Alterações Até uma Marca

Você pode criar uma marca dentro da transação corrente utilizando o comando SAVEPOINT. A transação pode ser dividida então em seções menores. Você pode descartar as mudanças pendentes até aquela marca utilizando o comando ROLLBACK TO SAVEPOINT.

Se você criar um segundo savepoint com o mesmo nome de um savepoint anterior, o savepoint mais anterior é removido.

On Targget Treinamento e Consultoria 32

SQL> UPDATE...SQL> SAVEPOINT update_done;Savepoint created.Savepoint created.SQL> INSERT...SQL> ROLLBACK TO update_done;Rollback complete.Rollback complete.

Page 267: Introdução ao Oracle 8i

Funções Básicas

Rollback a Nível de Comando

Parte de uma transação pode ser descartada por um rollback implícito se um erro de execução de comando for detectado. Se um comando DML falhar durante sua execução em uma transação, seu efeito será descartado por um rollback a nível de comando, mas as mudanças feitas pelos comandos DML anteriores na transação não serão descartadas. Eles podem ser confirmados ou descartados explicitamente pelo usuário.

O Oracle executa um COMMIT implícito antes e depois de qualquer comando de definição de dados (DDL). Portanto, se seu comando DDL não executar prosperamente, você não poderá desfazer as mudanças anteriores porque o servidor já emitiu um commit.

Termine suas transações explicitamente executando um comando COMMIT ou ROLLBACK.

On Targget Treinamento e Consultoria 33

Page 268: Introdução ao Oracle 8i

Funções Básicas

Leitura Consistente

Usuários de banco de dados efetuam dois tipos de acesso ao banco de dados:

Operações de leitura (comando SELECT) Operações de escrita (comandos INSERT, UPDATE e DELETE)

Você necessita de leitura consistente para que o seguinte aconteça:

A leitura e gravação do banco de dados é garantida com uma visão consistente dos dados. Leituras não visualizam dados que ainda estão em processo de atualização. Escritas para o banco de dados garantem que as mudanças são efetuadas de uma forma

consistente. Mudanças feitas por um usuário não conflitam com mudanças que outro usuário está

fazendo.

O propósito da leitura consistente é assegurar que cada usuário visualize os dados como eles ficaram antes do último commit, antes da operação DML começar.

On Targget Treinamento e Consultoria 34

Page 269: Introdução ao Oracle 8i

Funções Básicas

Implementação de Leitura Consistente

Leitura consistente é uma implementação automática. Mantém uma cópia parcial do banco de dados em segmentos de rollback.

Quando uma operação de inserção, atualização ou deleção é feita no banco de dados, o Servidor Oracle faz uma cópia dos dados antes deles serem modificados e a armazena em um segmento de rollback.

Todos os usuários, exceto o que executou a mudança, ainda visualizam o banco de dados como estava antes do início das mudanças; eles visualizam um "snapshot" dos dados a partir dos segmentos de rollback.

Antes das mudanças sofrerem commit no banco de dados, somente o usuário que está modificando os dados visualiza o banco de dados com as alterações, qualquer outro usuário visualiza um snapshot no segmento de rollback. Isto garante que os leitores dos dados leiam dados consistentes que não estão sofrendo mudanças atualmente.

Quando um comando DML sofre commit, as mudanças feitas ao banco de dados tornam-se visíveis para qualquer usuário executando um comando SELECT. O espaço ocupado pelos dados “antigos” no arquivo do segmento de rollback é liberado para ser reutilizado.

Se a transação sofrer rollback, as mudanças são desfeitas.

O original, versão antiga, dos dados no segmento de rollback é escrito de volta à tabela. Todos os usuários visualizam o banco de dados como estava antes da transação iniciar.

On Targget Treinamento e Consultoria 35

Page 270: Introdução ao Oracle 8i

Funções Básicas

Lock

O que São Locks?

Locks são mecanismos que previnem interação destrutiva entre transações que acessam o mesmo recurso, ou um objeto de usuário (como tabelas ou linhas) ou objetos de sistema não visíveis aos usuários (como estruturas de dados compartilhados e linhas do dicionário de dados).

Como o Oracle Efetua o Lock dos Dados

Lock em um banco de dados Oracle é totalmente automático e não requer nenhuma ação por parte do usuário. Lock implícito ocorre para todos os comandos SQL exceto SELECT. O mecanismo padrão de lock Oracle automaticamente utiliza o mais baixo nível aplicável de restritividade, fornecendo um nível maior de concorrência, também provendo o máximo em integridade de dados. O Oracle também permite ao usuário efetuar locks dos dados manualmente.

Modos de Lock

O Oracle utiliza dois modos de lock em um banco de dados multiusuário.

Modo de Lock Descrição

exclusivePrevine que um recurso seja compartilhado.A primeira transação a efetuar um lock de um recurso exclusivamente, é a única transação que pode alterar o recurso até que o lock exclusivo seja liberado.

share lock

Permite que o recurso seja compartilhado.Múltiplos usuários lendo dados podem compartilhar os dados, mantendo locks compartilhados para prevenir acesso concorrente por um usuário efetuando escrita (que necessita um lock exclusivo).Várias transações podem obter locks compartilhados sobre o mesmo recurso.

On Targget Treinamento e Consultoria 36

Page 271: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 10

Insira dados na tabela MY_EMPLOYEE.

1. Execute o script lab10_1.sql para construir a tabela MY_EMPLOYEE que será utilizado nos exercícios.

2. Descreva a estrutura da tabela MY_EMPLOYEE para identificar os nomes das colunas.

3. Adicione a primeira linha de dados na tabela MY_EMPLOYEE a partir do exemplo de dados abaixo. Não liste as colunas na cláusula INSERT.

ID LAST_NAME FIRST_NAME USERID SALARY1 Patel Ralph rpatel 7952 Dancs Betty bdancs 8603 Biri Ben bbiri 11004 Newman Chad cnewman 7505 Ropeburn Audry aropebur 1550

4. Popule a tabela MY_EMPLOYEE com a segunda linha do exemplo de dados acima. Neste momento, liste as colunas explicitamente na cláusula INSERT.

5. Confirme sua inserção para a tabela.

6. Crie um script chamado loademp.sql para inserir linhas na tabela MY_EMPLOYEE interativamente. Solicite ao usuário o primeiro nome do empregado, o último nome e o salário. Concatene a primeira letra do primeiro nome com os primeiros sete caracteres do último nome para produzir o valor para a coluna USERID.

7. Popule a tabela com as próximas duas linhas de exemplo de dados executando o script criado.

On Targget Treinamento e Consultoria 37

Name Null? Type------------ --------- ------ID NOT NULL NUMBER(4)LAST_NAME VARCHAR2(25)FIRST_NAME VARCHAR2(25)USERID VARCHAR2(8)SALARY NUMBER(9,2)

ID LAST_NAME FIRST_NAME USERID SALARY--- ----------- ---------- ------ ------ 1 Patel Ralph rpatel 795 2 Dancs Betty bdancs 860

Page 272: Introdução ao Oracle 8i

Funções Básicas

8. Confirme suas inserções para a tabela.

9. Torne as inserções permanentes.

Atualize e remova dados da tabela MY_EMPLOYEE.

10. Modifique o último nome do empregado 3 para “Drexler”.

11. Modifique o salário para 1000 para todos os empregados com o salário menor que 900.

12. Verifique suas modificações para a tabela.

13. Remova o empregado “Betty Dancs” da tabela MY_EMPLOYEE.

14. Confirme suas modificações para a tabela.

15. Execute o commit de todas as modificações pendentes.

16. Popule a tabela com a última linha do exemplo de dados executando o script criado no exercício 6.

On Targget Treinamento e Consultoria 38

ID LAST_NAME FIRST_NAME USERID SALARY--- ---------- ---------- ------ ------ 1 Patel Ralph rpatel 795 2 Dancs Betty bdancs 860 3 Biri Ben bbiri 1100 4 Newman Chad cnewman 750

LAST_NAME SALARY--------- ------Patel 1000Dancs 1000Biri 1100Newman 1000

ID LAST_NAME FIRST_NAME USERID SALARY--- ---------- ---------- ------ ------ 1 Patel Ralph rpatel 1000 3 Drexler Ben bbiri 1100 4 Newman Chad cnewman 1000

Page 273: Introdução ao Oracle 8i

Funções Básicas

17. Confirme sua inserção para a tabela.

18. Marque um ponto intermediário no processamento da transação.

19. Apague a tabela inteira.

20. Confirme que a tabela está vazia.

21. Descarte a mais recente operação DELETE sem descartar a operação de INSERT anterior.

22. Confirme que a nova linha permanece intacta.

23. Torne a inserção dos dados permanente.

On Targget Treinamento e Consultoria 39

ID LAST_NAME FIRST_NAME USERID SALARY--- --------- ----------- -------- ------ 1 Patel Ralph rpatel 1000 3 Drexler Ben bbiri 1100 4 Newman Chad cnewman 1000 5 Ropeburn Audry aropebur 1500

ID LAST_NAME FIRST_NAME USERID SALARY--- --------- ---------- --------- ------ 1 Patel Ralph rpatel 795 3 Biri Bem bbiri 1100 4 Newman Chad cnewman 750 5 Ropeburn Audry aropebur 1500

Page 274: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

12.12. Criando e GerenciandoCriando e Gerenciando TabelasTabelas

On Targget Treinamento e Consultoria

Page 275: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Descrever os principais objetos do banco de dados Criar tabelas Descrever os tipos de dados que podem ser utilizados na definição de colunas Alterar a definição de tabelas Remover, renomear e truncar tabelas

On Targget Treinamento e Consultoria 2

Page 276: Introdução ao Oracle 8i

Funções Básicas

Objetos do Banco de Dados

Um banco de dados Oracle pode conter várias estruturas de dados. Cada estrutura deve ser pensada no design do banco de dados de forma que possa ser criada durante a fase de construção e desenvolvimento do mesmo.

Tabela: Armazena os dados View: Subconjunto dos dados de um ou mais tabelas Sequence: Gera valores para chaves primárias Index: Melhora o desempenho de algumas consultas Synonym: Fornece nomes alternativos para os objetos

Estruturas de Tabelas Oracle8i

Tabelas podem ser criadas a qualquer momento, até mesmo enquanto os usuários estiverem utilizando o banco de dados.

Você não precisa especificar o tamanho da tabela. O tamanho pode ser definido posteriormente pela quantidade de espaço alocado para o banco de dados como um todo. Porém, é importante calcular quanto espaço utilizará uma tabela com o passar do tempo.

Estruturas de tabelas podem ser modificadas de forma online.

Nota: Outros objetos de banco de dados estão disponíveis mas não serão estudados neste curso.

On Targget Treinamento e Consultoria 3

Page 277: Introdução ao Oracle 8i

Funções Básicas

Convenções de Nomes

Nomeie tabelas e colunas de acordo com o padrão de nomenclatura para qualquer objeto do banco de dados Oracle:

Nomes de tabela e colunas devem começar com uma letra e podem ter de 1 até 30 caracteres de tamanho.

Nomes deven conter somente os caracteres A–Z, a–z, 0–9, _ (underscore), $ e #. Nomes não devem possuir o mesmo nome de outro objeto criado pelo mesmo usuário do

Servidor Oracle. Nomes não devem ser uma palavra reservada do Oracle.

Diretrizes de Nomenclatura

Utilize nomes descritivos para tabelas e outros objetos do banco de dados. Nomeie a mesma entidade consistentemente em tabelas diferentes. Por exemplo, a coluna

do número do departamento é chamada DEPTNO na tabela EMP e na tabela DEPT.

Nota: Nomes não fazem distinção entre maiúsculas e minúsculas. Por exemplo, EMP é tratado da mesma forma que eMP ou eMp.

On Targget Treinamento e Consultoria 4

Page 278: Introdução ao Oracle 8i

Funções Básicas

Comando CREATE TABLE

Crie tabelas para armazenar dados executando o comando SQL CREATE TABLE. Este comando é um dos comandos da linguagem de definição de dados (DDL), que serão discutidos nos próximos capítulos. Comandos DDL são um subconjunto dos comandos SQL utilizados para criar, modificar ou remover estruturas de banco de dados Oracle8i. Estes comandos possuem um efeito imediato no banco de dados, e eles também registram informações no dicionário de dados.

Para criar uma tabela, o usuário deve possuir o privilégio CREATE TABLE e uma área de armazenamento na qual criará os objetos. O administrador do banco de dados utiliza comandos da linguagem de controle de dados (DCL), que serão discutidos em um capítulo posterior, para conceder privilégios aos usuários.

Sintaxe:

schema é igual ao nome do usuário dono do objeto.

table é o nome da tabela.

DEFAULT expr especifica um valor default se um valor for omitido no comando INSERT.

column é o nome da coluna.

datatype é o tipo de dado e tamanho da coluna.

On Targget Treinamento e Consultoria 5

CREATE TABLE [schema.]table(column datatype [DEFAULT expr]);

Page 279: Introdução ao Oracle 8i

Funções Básicas

Referenciando Tabelas de Outro Usuário

Um schema é uma coleção de objetos. Objetos do schema são as estruturas lógicas que diretamente se referem aos dados em um banco de dados. Objetos de schema incluem tabelas, visões, sinônimos, sequences, stored procedures, índices, clusters e database links.

Se uma tabela não pertence ao usuário, o nome do dono (owner) deve prefixar a tabela.

On Targget Treinamento e Consultoria 6

Page 280: Introdução ao Oracle 8i

Funções Básicas

Opção DEFAULT

Uma coluna pode receber um valor default através da opção DEFAULT. Esta opção impede que valores nulos entrem nas colunas se uma linha é inserida sem um valor para esta coluna. O valor default pode ser uma literal, uma expressão ou uma função SQL, como SYSDATE e USER, mas o valor não pode ser o nome de outra coluna ou uma pseudocoluna, como NEXTVAL ou CURRVAL. A expressão default deve corresponder ao tipo de dado da coluna.

On Targget Treinamento e Consultoria 7

… hiredate DATE DEFAULT SYSDATE, …

Page 281: Introdução ao Oracle 8i

Funções Básicas

Criando Tabelas

Crie a tabela:

Confirme a criação da tabela:

O exemplo acima cria a tabela DEPT, com três colunas chamadas DEPTNO, DNAME e LOC. Confirme a criação da tabela executando o comando DESCRIBE.

Uma vez que o comando de criação de tabelas é do tipo DDL, um commit automático ocorre quando este comando é executado.

On Targget Treinamento e Consultoria 8

SQL> CREATE TABLE dept 2 (deptno NUMBER(2), 3 dname VARCHAR2(14), 4 loc VARCHAR2(13));Table created.Table created.

SQL> DESCRIBE dept

Name Null? Type--------------------------- -------- ---------DEPTNO NOT NULL NUMBER(2)DNAME VARCHAR2(14)LOC VARCHAR2(13)

Page 282: Introdução ao Oracle 8i

Funções Básicas

Consultando o Dicionário de Dados

Visualize as tabelas criadas pelo usuário:

Visualize os tipos de objetos distintos criados pelo usuário:

Visualize as tabelas, visões, sinônimos e sequences criadas pelo usuário:

Você pode consultas as tabelas do dicionário de dados para visualizar vários objetos do banco de dados criados por você. As tabelas do dicionário de dados mais freqüentemente utilizadas são:

USER_TABLES USER_OBJECTS USER_CATALOG

Nota: USER_CATALOG possui um sinônimo chamado CAT. Você pode utilizar este sinônimo em vez de USER_CATALOG em comandos SQL.

On Targget Treinamento e Consultoria 9

SQL> SELECT * 2 FROM user_tables;SQL> SELECT DISTINCT object_type 2 FROM user_objects;SQL> SELECT * 2 FROM user_catalog;SQL> SELECT * 2 FROM CAT;

Page 283: Introdução ao Oracle 8i

Funções Básicas

Tipos de Dados

Tipo de Dado Descrição

VARCHAR2(size)Dados caractere de tamanho variável (um tamanho (size) máximo deve ser especificado. Tamanho default e mínimo é 1, enquanto o máximo é 4000).

CHAR(size)Dados caractere de tamanho fixo de size bytes (tamanho default e mínimo é 1, enquanto o máximo é 2000).

NUMBER(p,s)

Número possuindo uma precisão de p e escala de s; a precisão é o número total de dígitos decimais, e a escala é o número de dígitos a direita do ponto decimal (a precisão deve estar na faixa de 1 até 38 e a escala na faixa de -84 até 127).

DATEValores de data e hora entre 1 de Janeiro de 4712 A.C. e 31 de Dezembro de 9999 D.C.

LONG Dados caractere de tamanho variável de até 2 gigabytesCLOB Dados caractere single-byte de até 4 gigabytes

RAW(size) Dados binários com tamanho especificado por size. Tamanho máximo é 2000 (um tamanho máximo deve ser especificado.)

LONG RAW Dados binários de tamanho variável de até 2 gigabytesBLOB Dados binários de até 4 gigabytes

BFILEDados binários armazenados em um arquivo externo de até 4 gigabytes

On Targget Treinamento e Consultoria 10

Page 284: Introdução ao Oracle 8i

Funções Básicas

Criando uma Tabela Utilizando uma Subconsulta

Um segundo método para criar uma tabela é aplicar a cláusula AS subquery para criar a tabela e já inserir as linhas retornadas pela subconsulta.

Sintaxe:

table é o nome da tabela.

column é o nome da coluna, valor default e constraints de integridade.

subquery é o comando SELECT que define o conjunto de linhas a ser inserido na tabela nova.

Diretrizes

A tabela será criada com os nomes de coluna especificados, e as linhas recuperadas pelo comando SELECT serão inseridas na tabela.

A definição da coluna pode conter somente o nome e o valor default. Se as especificações de coluna forem determinadas, o número de colunas deve ser igual ao

número de colunas da lista da cláusula SELECT da subconsulta. Se nenhuma especificação de coluna é determinada, os nomes das colunas da tabela serão

iguais aos nomes de coluna da subconsulta.

Criando uma Tabela a Partir de Linhas em Outra Tabela

O exemplo acima cria uma tabela, DEPT30, que contém detalhes de todos os empregados que trabalham no departamento 30. Observe que os dados para a tabela DEPT30 estão sendo obtidos a partir da tabela EMP.

Você pode verificar a existência de uma tabela do banco de dados e suas definições de colunas utilizando o comando DESCRIBE do SQL*Plus.

Forneça uma alias de coluna, quando estiver selecionando uma expressão.

On Targget Treinamento e Consultoria 11

CREATE TABLE table[column(, column...)]AS subquery;

SQL> CREATE TABLE dept30 2 AS 3 SELECT empno, ename, sal*12 ANNSAL, hiredate 4 FROM emp 5 WHERE deptno = 30;Table created.Table created.

SQL> DESCRIBE dept30Name Null? Type---------------------------- -------- ------------EMPNO NOT NULL NUMBER(4)ENAME VARCHAR2(10)ANNSAL NUMBERHIREDATE DATE

Page 285: Introdução ao Oracle 8i

Funções Básicas

Comando ALTER TABLE

Depois de criar as suas tabelas, você pode necessitar mudar a estrutura da tabela porque você omitiu uma coluna ou sua definição de coluna precisa ser modificada. Você pode fazer isto utilizando o comando ALTER TABLE.

Você pode adicionar colunas para uma tabela utilizando o comando ALTER TABLE com a cláusula ADD.

Sintaxe:

table é o nome da tabela.

column é o nome da nova coluna.

datatype é o tipo de dado e tamanho da nova coluna.

DEFAULT expr especifica o valor default para uma nova coluna.

Você pode modificar colunas existentes em uma tabela utilizando o comando ALTER TABLE com a cláusula MODIFY.

Nota: O gráfico acima fornece uma sintaxe abreviada para o ALTER TABLE. Em um capítulo posterior será discutido mais a respeito deste comando.

On Targget Treinamento e Consultoria 12

ALTER TABLE tableADD (column datatype [DEFAULT expr]

[, column datatype]...);

ALTER TABLE tableMODIFY (column datatype [DEFAULT expr]

[, column datatype]...);

Page 286: Introdução ao Oracle 8i

Funções Básicas

Adicionando uma Coluna

O gráfico acima adiciona a coluna JOB para a tabela DEPT30. Observe que a nova coluna torna-se a última coluna na tabela.

Você utiliza a cláusula ADD para adicionar colunas:

A nova coluna torna-se a última coluna:

Diretrizes para Adicionar uma Coluna

Você pode adicionar ou modificar colunas, mas você não pode removê-las de uma tabela. Você não pode especificar onde a coluna irá aparecer. A nova coluna se torna a última

coluna.

O exemplo acima adiciona uma coluna chamada JOB para a tabela DEPT30. A coluna JOB se torna a última coluna da tabela.

Nota: Se uma tabela já possui linhas quando uma coluna é adicionada, então a nova coluna é inicialmente nula em todas as linhas.

On Targget Treinamento e Consultoria 13

SQL> ALTER TABLE dept30 2 ADD (job VARCHAR2(9));Table altered.Table altered.

EMPNO ENAME ANNSAL HIREDATE JOB--------- ---------- --------- --------- ---- 7698 BLAKE 34200 01-MAY-81 7654 MARTIN 15000 28-SEP-81 7499 ALLEN 19200 20-FEB-81 7844 TURNER 18000 08-SEP-81...6 rows selected.

Page 287: Introdução ao Oracle 8i

Funções Básicas

Modificando uma Coluna

Você pode modificar uma definição de coluna utilizando o comando ALTER TABLE com a cláusula MODIFY. A modificação de coluna pode incluir mudanças para o tipo de dado, o tamanho e valor default.

Diretrizes

Aumente a largura ou precisão de uma coluna numérica. Diminua a largura de uma coluna se ela possuir somente valores nulos ou se a tabela não

possuir nenhuma linha. Modifique o tipo de dado se a coluna possuir somente valores nulos. Converta uma coluna do tipo de dado CHAR para VARCHAR2 ou converta uma coluna

VARCHAR2 para o tipo de dado CHAR se a coluna possuir somente valores nulos ou se você não modificar o tamanho.

Uma mudança para o valor default de uma coluna afeta somente as inserções subseqüentes para a tabela.

On Targget Treinamento e Consultoria 14

ALTER TABLE dept30MODIFY (ename VARCHAR2(15));Table altered.Table altered.

Page 288: Introdução ao Oracle 8i

Funções Básicas

Removendo uma Tabela

O comando DROP TABLE remove a definição de uma tabela Oracle8i. Quando você remove uma tabela, o banco de dados remove todos os dados da tabela e todos os índices associados.

Sintaxe:

Onde:

table é o nome da tabela.

Diretrizes

Todo o dados são apagados da tabela. Quaisquer visões ou sinônimos permanecerão, porém estarão inválidos. Qualquer transação pendente sofre commit. Somente o criador da tabela ou um usuário com o privilégio DROP ANY TABLE pode

remover uma tabela.

O comando DROP TABLE, uma vez executado, é irreversível. O Servidor Oracle não questiona a ação quando você emite o comando DROP TABLE. Se você for o dono daquela tabela ou possui um privilégio de alto nível, então a tabela é removida imediatamente. Todas os comandos DDL emitem um commit tornando a transação permanente.

On Targget Treinamento e Consultoria 15

SQL> DROP TABLE dept30;Table dropped.Table dropped.DROP TABLE table;

Page 289: Introdução ao Oracle 8i

Funções Básicas

Modificando o Nome de um Objeto

Os comandos DDL adicionais incluem o comando RENAME, utilizado para renomear uma tabela, visão, sequence ou sinônimo.

Sintaxe:

Onde:

old_name é o nome antigo da tabela, visão, sequence ou sinônimo.

new_name é o novo nome da tabela, visão, sequence ou sinônimo.

Você deve ser o dono do objeto que você quer renomear.

On Targget Treinamento e Consultoria 16

SQL> RENAME dept TO department;Table renamed.Table renamed.RENAME old_name TO new_name;

Page 290: Introdução ao Oracle 8i

Funções Básicas

Truncando uma Tabela

Outro comando DDL é o comando TRUNCATE TABLE, utilizado para remover todas as linhas de uma tabela e liberar o espaço de armazenamento utilizado por ela. Quando utilizar o comando TRUNCATE TABLE, você não pode efetuar roll back das linhas removidas.

Sintaxe:

Onde:

table é o nome da tabela.

Você deve ser o dono da tabela ou possuir o privilégio de sistema DELETE TABLE para truncar uma tabela.

O comando DELETE também pode remover todas as linhas de uma tabela, porém ele não libera o espaço de armazenamento ocupado por ela.

On Targget Treinamento e Consultoria 17

SQL> TRUNCATE TABLE department;Table truncated.Table truncated.TRUNCATE TABLE table;

Page 291: Introdução ao Oracle 8i

Funções Básicas

Adicionando Comentários para Tabelas

Você pode adicionar um comentário de até 2000 bytes sobre uma coluna, tabela, visão ou snapshot utilizando o comando COMMENT. O comentário é armazenado no dicionário de dados e pode ser visualizado em uma das seguintes visões do dicionário de dados na coluna COMMENTS:

ALL_COL_COMMENTS USER_COL_COMMENTS ALL_TAB_COMMENTS USER_TAB_COMMENTS

Sintaxe:

Onde:

table é o nome da tabela.

column é o nome da coluna de uma tabela.

text é o texto do comentário.

Você pode remover um comentário do banco de dados atribuindo uma string vazia ('').

On Targget Treinamento e Consultoria 18

SQL> COMMENT ON TABLE emp 2 IS 'Employee Information';Comment created.Comment created.

COMMENT ON TABLE table | COLUMN table.columnIS 'text';

SQL> COMMENT ON TABLE emp IS ' ';

Page 292: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 11

1. Crie a tabela DEPARTMENT baseado no gráfico abaixo. Salve a sintaxe para um arquivo chamado e11q1.sql e então execute-o para criar a tabela. Confirme que a tabela foi criada.

Nome da Coluna ID NAMETipo de ChaveNulos/UniqueTabela (FK)Coluna (FK)Tipo de Dado Number Varchar2Tamanho 7 25

2. Popule a tabela DEPARTMENT com dados a partir da tabela DEPT. Inclua somente as colunas necessárias.

3. Crie a tabela EMPLOYEE baseado no gráfico abaixo. Salve a sintaxe em um arquivo chamado e11q3.sql e execute-o para criar a tabela. Confirme que a tabela foi criada.

Nome da Coluna ID LAST_NAME FIRST_NAME DEPT_IDTipo de ChaveNulos/UniqueTabela (FK)Coluna (FK)Tipo de Dado Number Varchar2 Varchar2 NumberTamanho 7 25 25 7

On Targget Treinamento e Consultoria 19

Name Null? Type---------- -------- -----------ID NUMBER(7)NAME VARCHAR2(25)

Name Null? Type------------- -------- ------------ID NUMBER(7)LAST_NAME VARCHAR2(25)FIRST_NAME VARCHAR2(25)DEPT_ID NUMBER(7)

Page 293: Introdução ao Oracle 8i

Funções Básicas

4. Modifique a coluna LAST_NAME da tabela EMPLOYEE para permitir o uso de nomes de maior tamanho. Confirme sua modificação.

5. Confirme que as tabelas DEPARTMENT e EMPLOYEE estão armazenadas no dicionário de dados (USER_TABLES).

6. Crie a tabela EMPLOYEE2 baseado na estrutura da tabela EMP, incluindo somente as colunas EMPNO, ENAME e DEPTNO. Coloque o nome das colunas na tabela nova como ID, LAST_NAME e DEPT_ID, respectivamente.

7. Remova a tabela EMPLOYEE.

8. Altere o nome da tabela EMPLOYEE2 para EMPLOYEE.

9. Adicione um comentário para a definição das tabelas DEPARTMENT e EMPLOYEE que as descreva. Confirme sua adição no dicionário de dados.

On Targget Treinamento e Consultoria 20

Name Null? Type------------- -------- -----------ID NUMBER(7)LAST_NAME VARCHAR2(50)FIRST_NAME VARCHAR2(25)DEPT_ID NUMBER(7)

TABLE_NAME-------------------------DEPARTMENTEMPLOYEE

Page 294: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

13.13. Implementando ConstraintsImplementando Constraints

On Targget Treinamento e Consultoria

Page 295: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Descrever constraints Criar e administrar constraints

On Targget Treinamento e Consultoria 2

Page 296: Introdução ao Oracle 8i

Funções Básicas

O Que são Constraints?

O Servidor Oracle utiliza constraints para prevenir entrada de dados inválidos em tabelas.

Você pode utilizar constraints para fazer o seguinte:

Garantir regras à nível de tabela sempre que uma linha for inserida, atualizada ou apagada desta tabela. A constraint deve ser satisfeita para a operação para ter sucesso.

Previnir a deleção de uma tabela se existirem dependências em outras tabelas. Prover regras para ferramentas Oracle, como o Developer/2000.

Constraints de Integridade de Dados

Constraint DescriçãoNOT NULL Especifica que a coluna não pode conter valores nulos

UNIQUE KeyEspecifica uma coluna ou combinação de colunas cujo os valores devem ser únicos para todas as linhas da tabela

PRIMARY KEY Identifica de forma única cada linha da tabela

FOREIGN KEYEstabelece e garante um relacionamento de chave estrangeira entre a coluna e uma coluna da tabela referenciada

CHECK Especifica uma condição que deve ser verdadeira

On Targget Treinamento e Consultoria 3

Page 297: Introdução ao Oracle 8i

Funções Básicas

Diretrizes para Constraints

Todas as constraints são armazenadas no dicionário de dados. As constraints são fáceis de referenciar se você tiver fornecido um nome significativo. Nomes de constraints devem seguir as regras padrão de nomenclatura de objetos. Se você não fornecer um nome para a constraint, o Oracle gera um nome com o formato SYS_Cn, onde n é um inteiro para criar um nome de constraint único.

Contraints podem ser definidas no momento de criação da tabela ou depois que a tabela for criada.

Você pode visualizar as constraints definidas para uma tabela específica consultando a tabela do dicionário de dados USER_CONSTRAINTS.

On Targget Treinamento e Consultoria 4

Page 298: Introdução ao Oracle 8i

Funções Básicas

Definindo Constraints

O gráfico acima fornece a sintaxe para a definição de constraints durante a criação de uma tabela.

Sintaxe:

schema é o nome do usuário dono.

table é o nome da tabela.

DEFAULT expr especifica um valor default se um valor for omitido no comando INSERT.

column é o nome da coluna.

datatype é o tipo de dado e tamanho da coluna.

column_constraint é uma constraint de integridade declarada como parte da definição da coluna.

table_constraint é uma constraint de integridade declarada como parte da definição da tabela.

Normalmente as constraints são criadas ao mesmo tempo que a tabela. Podem ser adicionadas constraints a uma tabela após sua criação e também podem ser temporariamente desabilitadas.

Podem ser definidas constraints em dois níveis diferentes:

Nível da Constraint

Descrição

Coluna Referencia uma única coluna e é definida dentro da especificação da própria coluna; pode-se definir qualquer tipo de constraint de integridade.

Tabela Referencia uma ou mais colunas e é definida separadamente das definições de colunas na tabela; pode-se definir qualquer tipo de constraint, exceto NOT NULL

Sintaxe:

constraint_name é o nome da constraint.

constraint_type é o tipo da constraint.

Constraint a nível de coluna:

Constraint a nível de tabela:

On Targget Treinamento e Consultoria 5

CREATE TABLE [schema.]table(column datatype [DEFAULT expr][column_constraint],…[table_constraint]);

CREATE TABLE emp(empno NUMBER(4),ename VARCHAR2(10),…deptno NUMBER(7,2) NOT NULL,CONSTRAINT emp_empno_pk

PRIMARY KEY (EMPNO));

column [CONSTRAINT constraint_name] constraint_type,column,... [CONSTRAINT constraint_name] constraint_type (column, ...),

Page 299: Introdução ao Oracle 8i

Funções Básicas

Constraint NOT NULL

A constraint NOT NULL assegura que valores nulos não são permitidos na coluna. Colunas sem a constraint NOT NULL podem conter valores nulos por default.

A constraint NOT NULL pode ser especificada somente a nível de coluna, e não a nível de tabela.

O exemplo acima aplica a constraint NOT NULL para as colunas ENAME e DEPTNO da tabela EMP. Uma vez que estas constraints não possuem nomes definidos, o Servidor Oracle criará nomes para elas.

Você pode especificar o nome de uma constraint na sua própria especificação:

Nota: Todos os exemplos de constraints descritos neste capítulo podem não estar presentes nas tabelas de exemplo fornecidas com este curso. Se desejar, estas constraints podem ser adicionadas as tabelas.

On Targget Treinamento e Consultoria 6

SQL> CREATE TABLE emp( 2 empno NUMBER(4), 3 ename VARCHAR2(10) NOT NULL, 4 job VARCHAR2(9), 5 mgr NUMBER(4), 6 hiredate DATE, 7 sal NUMBER(7,2), 8 comm NUMBER(7,2), 9 deptno NUMBER(7,2) NOT NULL);

... deptno NUMBER(7,2)CONSTRAINT emp_deptno_nn NOT NULL...

Page 300: Introdução ao Oracle 8i

Funções Básicas

Constraint UNIQUE Key

Uma constraint de integridade do tipo UNIQUE faz com que cada valor em uma coluna ou conjunto de colunas (chave) seja único, ou seja, duas linhas de uma tabela não podem ter valores duplicados na coluna especificada ou no conjunto de colunas. A coluna (ou conjunto de colunas) incluída na definição da constraint UNIQUE é chamada de chave única. Se uma chave única possuir mais de uma coluna, o grupo de colunas será chamado de chave única composta.

Constraints UNIQUE permitem a inserção de nulos a menos que você também defina uma constraint NOT NULL para as mesmas colunas. De fato, qualquer número de linhas pode receber nulos para colunas sem a constraint NOT NULL porque nulos não são considerados iguais a nada. Um nulo em uma coluna (ou em todas as colunas de uma chave única composta) sempre satisfaz a constraint UNIQUE.

Nota: Devido ao mecanismo de procura das constraints UNIQUE com mais de uma coluna, você não pode ter valores idênticos nas colunas não nulas de uma constraint de chave única composta parcialmente nula.

Constraints UNIQUE podem ser definidas a nível de coluna ou tabela. Uma chave única composta é criada utilizando a definição a nível de tabela.

O exemplo acima aplica a constraint UNIQUE para a coluna DNAME da tabela DEPT. O nome da constraint é definido como DEPT_DNAME_UK.

Nota: O Servidor Oracle implementa a constraint UNIQUE criando implicitamente um índice único na chave única.

On Targget Treinamento e Consultoria 7

SQL> CREATE TABLE dept( 2 deptno NUMBER(2), 3 dname VARCHAR2(14), 4 loc VARCHAR2(13), 5 CONSTRAINT dept_dname_uk UNIQUE(dname));

Page 301: Introdução ao Oracle 8i

Funções Básicas

Constraint PRIMARY KEY

Uma constraint PRIMARY KEY cria uma chave primária para a tabela. Somente uma chave primária pode ser criada para cada tabela. A constraint PRIMARY KEY é uma coluna ou conjunto de colunas que identificam de forma única cada linha em uma tabela. Esta constraint obriga a unicidade da coluna ou combinação de colunas e assegura que nenhuma coluna que faça parte da chave primária possa conter um valor nulo.

Constraints PRIMARY KEY podem ser definidas a nível de coluna ou a nível de tabela. Uma chave primária composta é criada utilizando a definição a nível de tabela.

O exemplo acima define uma constraint PRIMARY KEY na coluna DEPTNO da tabela DEPT. O nome da constraint é definido como DEPT_DEPTNO_PK.

Nota: Um índice único é criado automaticamente para uma coluna de chave primária.

On Targget Treinamento e Consultoria 8

SQL> CREATE TABLE dept( 2 deptno NUMBER(2), 3 dname VARCHAR2(14), 4 loc VARCHAR2(13), 5 CONSTRAINT dept_dname_uk UNIQUE (dname), 6 CONSTRAINT dept_deptno_pk PRIMARY KEY(deptno));

Page 302: Introdução ao Oracle 8i

Funções Básicas

Constraint FOREIGN KEY

Uma FOREIGN KEY, ou constraint de integridade referencial, designa uma coluna ou combinação de colunas como chave estrangeira e estabelece uma relação entre uma chave primária ou uma chave única para a mesma tabela ou para uma tabela diferente. No gráfico acima, DEPTNO foi definida como a chave estrangeira na tabela EMP (tabela dependente ou filha); ela faz referência a coluna DEPTNO da tabela DEPT (tabela referenciada ou pai).

Um valor de chave estrangeira deve corresponder a um valor existente na tabela pai ou deve ser nulo.

Chaves estrangeiras são baseadas nos valores dos dados e são puramente lógicas, não físicas ou ponteiros.

Constraints FOREIGN KEY podem ser definidas à nível de coluna ou de tabela. Uma chave estrangeira composta é criada utilizando a definição a nível de tabela.

O exemplo acima define uma constraint de chave estrangeira na coluna DEPTNO da tabela EMP. O nome da constraint é definido como EMP_DEPTNO_FK.

On Targget Treinamento e Consultoria 9

SQL> CREATE TABLE emp( 2 empno NUMBER(4), 3 ename VARCHAR2(10) NOT NULL, 4 job VARCHAR2(9), 5 mgr NUMBER(4), 6 hiredate DATE, 7 sal NUMBER(7,2), 8 comm NUMBER(7,2), 9 deptno NUMBER(7,2) NOT NULL, 10 CONSTRAINT emp_deptno_fk FOREIGN KEY (deptno) 11 REFERENCES dept (deptno));

Page 303: Introdução ao Oracle 8i

Funções Básicas

Palavras Chave de Constraints FOREIGN KEY

A chave estrangeira é definida na tabela dependente (filha), e a tabela que contém a coluna referenciada é a tabela pai. Uma chave estrangeira é definida utilizando-se uma combinação das seguintes palavras chaves:

FOREIGN KEY: utilizada para definir a coluna da tabela filha quando a constraint for definida a nível de tabela.

REFERENCES: identifica a tabela e coluna da tabela referenciada (pai). ON DELETE CASCADE: indica que quando uma linha da tabela pai é apagada, as linhas

dependentes da tabela filha também serão apagadas.

Sem a opção ON DELETE CASCADE, uma linha da tabela pai não pode ser apagada se estiver sendo referenciada na tabela filha.

On Targget Treinamento e Consultoria 10

Page 304: Introdução ao Oracle 8i

Funções Básicas

Constraint CHECK

A constraint CHECK define uma condição que cada linha deve satisfazer. A condição pode utilizar a mesma construção que as condições de consultas, com as seguintes exceções:

Referências para as pseudo colunas CURRVAL, NEXTVAL, LEVEL e ROWNUM Chamadas para as funções SYSDATE, UID, USER e USERENV Consultas que referenciam outros valores em outras linhas

Uma única coluna pode ter múltiplas constraints CHECK que referenciam a coluna em sua definição. Não há nenhum limite quanto ao número de contraints CHECK que você pode definir em uma coluna.

Constraints CHECK podem ser definidas a nível de coluna ou a nível de tabela.

On Targget Treinamento e Consultoria 11

..., deptno NUMBER(2),CONSTRAINT emp_deptno_ck

CHECK (DEPTNO BETWEEN 10 AND 99),...

Page 305: Introdução ao Oracle 8i

Funções Básicas

Adicionando uma Constraint

Você pode adicionar uma constraint para tabelas existentes utilizando o comando ALTER TABLE com a cláusula ADD.

Sintaxe:

table é o nome da tabela.

constraint é o nome da constraint.

type é o tipo de constraint.

column é o nome da coluna afetada pela constraint.

A sintaxe do nome da constraint é opcional, embora recomendada. Se você não fornecer um nome para suas constraints, o sistema gerará nomes para elas.

Diretrizes

Você pode adicionar, remover, habilitar ou desabilitar uma constraint, mas você não pode modificar sua estrutura.

Você pode adicionar uma constraint NOT NULL para uma coluna existente utilizando a cláusula MODIFY do comando ALTER TABLE.

Nota: Você pode definir uma coluna NOT NULL somente se a tabela não possuir nenhuma linha porque não podem ser especificados dados para linhas existentes ao mesmo tempo que a coluna é adicionada.

O exemplo acima cria uma constraint FOREIGN KEY na tabela EMP. A constraint garante que um gerente (mgr) exista como um empregado (empno) válido na tabela EMP.

On Targget Treinamento e Consultoria 12

ALTER TABLE table ADD [CONSTRAINT constraint] type (column);SQL> ALTER TABLE emp 2 ADD CONSTRAINT emp_mgr_fk 3 FOREIGN KEY(mgr) REFERENCES emp(empno);Table altered.Table altered.

Page 306: Introdução ao Oracle 8i

Funções Básicas

Removendo uma Constraint

Remova a constraint do gerente da tabela EMP:

Remova a constraint PRIMARY KEY da tabela DEPT e remova a constraint FOREIGN KEY associada da coluna EMP.DEPTNO:

Para remover uma constraint, você pode identificar o seu nome a partir das visões do dicionário de dados USER_CONSTRAINTS e USER_CONS_COLUMNS. Então utilize o comando ALTER TABLE com a cláusula DROP. A opção CASCADE da cláusula DROP também remove qualquer constraint dependente.

Sintaxe:

Onde:

table é o nome da tabela.

column é o nome da coluna afetada pela constraint.

constraint é o nome da constraint.

Quando você remove uma constraint de integridade, esta constraint não mais é verificada pelo Servidor Oracle e não fica mais disponível no dicionário de dados.

On Targget Treinamento e Consultoria 13

SQL> ALTER TABLE emp 2 DROP CONSTRAINT emp_mgr_fk;Table altered.Table altered.

SQL> ALTER TABLE dept 2 DROP PRIMARY KEY CASCADE;Table altered.Table altered.

ALTER TABLE tableDROP PRIMARY KEY | UNIQUE (column) |CONSTRAINT constraint [CASCADE];

Page 307: Introdução ao Oracle 8i

Funções Básicas

Desabilitando Constraints

Você pode desabilitar uma constraint sem removê-la ou recriá-la utilizando o comando ALTER TABLE com a cláusula DISABLE.

Sintaxe:

Onde:

table é o nome da tabela.

constraint é o nome da constraint.

Diretrizes

Você pode utilizar a cláusula DISABLE no comando CREATE TABLE e no comando ALTER TABLE.

A cláusula CASCADE desabilita as constraints de integridade dependentes.

On Targget Treinamento e Consultoria 14

SQL> ALTER TABLE emp 2 DISABLE CONSTRAINT emp_empno_pk CASCADE;Table altered.Table altered.

ALTER TABLE tableDISABLE CONSTRAINT constraint [CASCADE];

Page 308: Introdução ao Oracle 8i

Funções Básicas

Habilitando Constraints

Você pode habilitar uma constraint sem removê-la ou recriá-la utilizando o comando ALTER TABLE com a cláusula ENABLE.

Sintaxe:

Onde:

table é o nome da tabela.

constraint é o nome da constraint.

Diretrizes

Se você habilita uma constraint, esta constraint aplica-se a todos os dados da tabela. Todos os dados da tabela devem ajustar-se a constraint.

Se você habilita uma constraint UNIQUE key ou PRIMARY KEY, um índice do tipo UNIQUE ou PRIMARY KEY é criado automaticamente.

Você pode utilizar a cláusula ENABLE no comando CREATE TABLE e no comando ALTER TABLE.

On Targget Treinamento e Consultoria 15

SQL> ALTER TABLE emp 2 ENABLE CONSTRAINT emp_empno_pk;Table altered.Table altered.

ALTER TABLE tableENABLE CONSTRAINT constraint;

Page 309: Introdução ao Oracle 8i

Funções Básicas

Visualizando Constraints

Após criar uma tabela, você pode confirmar sua existência executando um comando DESCRIBE. A única constraint que você pode verificar desta forma é a constraint NOT NULL. Para visualizar todas as constraints de sua tabela, consulte a tabela USER_CONSTRAINTS.

O exemplo acima exibe todos as constraints da tabela EMP.

Nota: Constraints que não receberam nomes na sua criação recebem um nome atribuído pelo sistema. Na coluna CONSTRAINT_TYPE, C representa CHECK, P representa PRIMARY KEY, R representa integridade referencial (FOREIGN KEY) e U representa UNIQUE key. Observe que as constraints NOT NULL na verdade são constraints CHECK.

On Targget Treinamento e Consultoria 16

SQL> SELECT constraint_name, constraint_type, 2 search_condition 3 FROM user_constraints 4 WHERE table_name = 'EMP';

CONSTRAINT_NAME C SEARCH_CONDITION------------------------ - ----------------------SYS_C00674 C EMPNO IS NOT NULL SYS_C00675 C DEPTNO IS NOT NULLEMP_EMPNO_PK P...

Page 310: Introdução ao Oracle 8i

Funções Básicas

Visualizando as Colunas Associadas com Constraints

Você pode visualizar os nomes de colunas envolvidos em constraints consultando a visão do dicionário de dados USER_CONS_COLUMNS. Esta visão é especialmente útil para constraints que possuem o nome atribuído pelo sistema.

On Targget Treinamento e Consultoria 17

SQL> SELECT constraint_name, column_name 2 FROM user_cons_columns 3 WHERE table_name = 'EMP';

CONSTRAINT_NAME COLUMN_NAME------------------------- ----------------------EMP_DEPTNO_FK DEPTNOEMP_EMPNO_PK EMPNOEMP_MGR_FK MGRSYS_C00674 EMPNOSYS_C00675 DEPTNO

Page 311: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 12

1. Adicione a nível de tabela uma constraint PRIMARY KEY para a tabela EMPLOYEE utilizando a coluna ID. A constraint deve ficar habilitada na criação.

2. Crie uma constraint PRIMARY KEY na tabela DEPARTMENT utilizando a coluna ID. A constraint deve ficar habilitada na criação.

3. Adicione uma referência de chave estrangeira para a tabela EMPLOYEE que garanta que o empregado não seja associado para um departamento não existente.

4. Confirme que as constraints foram adicionadas consultando a visão USER_CONSTRAINTS. Observe os tipos e nomes das constraints. Salve o comando em um arquivo chamado e12q4.sql.

5. Modifique a tabela EMPLOYEE. Adicione uma coluna SALARY com o tipo de dado NUMBER(7).

On Targget Treinamento e Consultoria 18

CONSTRAINT_NAME C----------------------- -DEPARTMENT_ID_PK PEMPLOYEE_ID_PK PEMPLOYEE_DEPT_ID_FK R

Page 312: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

14.14. Criando VisõesCriando Visões

On Targget Treinamento e Consultoria

Page 313: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Descrever uma visão Criar uma visão Recuperar dados através de uma visão Alterar a definição de uma visão Inserir, atualizar e remover dados através de uma visão Remover uma visão

On Targget Treinamento e Consultoria 2

Page 314: Introdução ao Oracle 8i

Funções Básicas

Objetos do Banco de Dados

On Targget Treinamento e Consultoria 3

Page 315: Introdução ao Oracle 8i

Funções Básicas

O que é uma Visão?

Você pode apresentar subconjuntos lógicos ou combinações de dados criando visões das tabelas. Uma visão é uma tabela lógica baseada em uma tabela ou outra visão. Uma visão não possui dados próprios mas é como uma janela pela qual os dados das tabelas podem ser visualizados ou modificados. As tabelas nas quais uma visão é baseada são chamadas de tabelas básicas. A visão é armazenada como um comando SELECT no dicionário de dados.

On Targget Treinamento e Consultoria 4

Page 316: Introdução ao Oracle 8i

Funções Básicas

Porquê Utilizar Visões?

Para restringir o acesso ao banco de dados Para tornar simples consultas complexas Para permitir independência de dados Para apresentar visões diferentes do mesmo dado

Vantagens de Visões

Restringem o acesso para o banco de dados porque a visão pode exibir uma porção seletiva do banco de dados.

Permitem aos usuários fazer consultas simples para recuperar os resultados de consultas complexas. Por exemplo, visões permitem aos usuários consultar informações de múltiplas tabelas sem saber escrever um comando de join.

Provê independência dos dados para os usuários e programas de aplicação. Uma visão pode ser utilizada para recuperar dados de várias tabelas.

Provê acesso aos dados para grupos de usuários de acordo com seus critérios particulares.

On Targget Treinamento e Consultoria 5

Page 317: Introdução ao Oracle 8i

Funções Básicas

Visões Simples e Visões Complexas

Existem duas classificações para as visões: simples e complexas. A diferença básica está relacionada as operações DML (INSERT, UPDATE e DELETE).

Uma visão simples:

Deriva dados de uma única tabela Não utiliza funções ou grupos de dados Pode executar operações DML através da visão

Uma visão complexa:

Deriva dados de várias tabelas Utiliza funções ou grupos de dados Normalmente não permite operações DML através da visão

On Targget Treinamento e Consultoria 6

Page 318: Introdução ao Oracle 8i

Funções Básicas

Criando uma Visão

Você pode criar uma visão inserindo uma subconsulta dentro do comando CREATE VIEW.

Sintaxe:

OR REPLACE recria a visão caso ela já exista.

FORCE cria a visão mesmo que as tabelas básicas não existam.

NOFORCE cria a visão somente se as tabelas básicas existem. Este é o default.

view é o nome da visão.

alias especifica nomes para as expressões selecionadas pela consulta da visão. O número de alias deve corresponder ao número de expressões selecionadas pela visão.

subquery é um comando SELECT completo. Você pode utilizar alias para as colunas na lista da cláusula SELECT.

WITH CHECK OPTION especifica que somente as linhas acessíveis para a visão podem ser inseridas ou atualizadas.

constraint é o nome atribuído a constraint da cláusula CHECK OPTION.

WITH READ ONLY assegura que nenhuma operação DML possa ser executada nesta visão.

O exemplo acima cria uma visão que contém o número do empregado, o nome e o cargo para todos os empregados do departamento 10.

On Targget Treinamento e Consultoria 7

CREATE [OR REPLACE] [FORCE|NOFORCE] VIEW view[(alias[, alias]...)]

AS subquery[WITH CHECK OPTION [CONSTRAINT constraint]][WITH READ ONLY]

SQL> CREATE VIEW empvu10 2 AS SELECT empno, ename, job 3 FROM emp 4 WHERE deptno = 10;View created.View created.

Page 319: Introdução ao Oracle 8i

Funções Básicas

Você pode exibir a estrutura de uma visão utilizando o comando DESCRIBE do SQL*Plus.

Diretrizes para Criação de Visões

A subconsulta que define uma visão podem conter uma sintaxe complexa do comando SELECT, incluindo joins, grupos e subconsultas.

A subconsulta que define uma visão não pode conter uma cláusula ORDER BY. A cláusula ORDER BY deve ser especificada quando você recuperar dados da visão.

Se você não especificar um nome de constraint para a visão criada com CHECK OPTION, o sistema atribui um nome default no formato SYS_Cn.

Você pode utilizar a opção OR REPLACE para modificar a definição da visão sem ter que removê-la e recriá-la ou ter que repassar os privilégios de objeto previamente concedidos.

Você pode controlar os nomes de colunas incluindo alias de coluna dentro da subconsulta.

O exemplo acima cria uma visão contendo o número do empregado com o alias EMPLOYEE_NUMBER, o nome com o alias NAME e o salário com o alias SALARY para todos os empregados do departamento 30.

Alternativamente, você pode controlar os nomes das colunas incluindo alias de coluna na cláusula CREATE VIEW.

On Targget Treinamento e Consultoria 8

SQL> DESCRIBE empvu10Name Null? Type------------------------------- -------- ------------EMPNO NOT NULL NUMBER(4)ENAME VARCHAR2(10)JOB VARCHAR2(9)

SQL> CREATE VIEW salvu30 2 AS SELECT empno EMPLOYEE_NUMBER, ename NAME, 3 sal SALARY 4 FROM emp 5 WHERE deptno = 30;View created.View created.

Page 320: Introdução ao Oracle 8i

Funções Básicas

Recuperando Dados de uma Visão

Você pode recuperar dados de uma visão da mesma forma que qualquer tabela. Você pode exibir o conteúdo de toda a visão ou apenas linhas e colunas específicas.

On Targget Treinamento e Consultoria 9

SQL> SELECT * 2 FROM salvu30;EMPLOYEE_NUMBER NAME SALARY--------------- ---------- --------- 7698 BLAKE 2850 7654 MARTIN 1250 7499 ALLEN 1600 7844 TURNER 1500 7900 JAMES 950 7521 WARD 12506 rows selected.

Page 321: Introdução ao Oracle 8i

Funções Básicas

Consultando uma Visão

Visões no Dicionário de Dados

Uma vez criada a visão, você pode consultar a tabela do dicionário de dados chamada USER_VIEWS para obter o nome da visão e sua definição. O texto do comando SELECT que constitui a visão é armazenado em uma coluna tipo LONG.

Acesso aos Dados em Visões

Quando você acessa dados, utilizando uma visão, o Servidor Oracle executa as seguintes operações:

1. recupera a definição da visão da tabela do dicionário de dados USER_VIEWS.2. confere os privilégios de acesso para a tabela básica da visão.3. converte a consulta para a visão em uma operação equivalente para a tabela ou tabelas

básicas. Em outras palavras, os dados são recuperados a partir das, ou uma atualização é feita para, as tabelas básicas.

On Targget Treinamento e Consultoria 10

Page 322: Introdução ao Oracle 8i

Funções Básicas

Modificando uma Visão

A opção OR REPLACE permite recriar uma visão mesmo se outra já existir com este nome, substituindo a versão anterior. Isto significa que a visão pode ser alterada sem ser removida, recriando-a e mantendo os privilégios de objeto.

Nota: Quando atribuir alias de colunas na cláusula CREATE VIEW, lembre-se que os alias são listados na mesma ordem das colunas na subconsulta.

On Targget Treinamento e Consultoria 11

SQL> CREATE OR REPLACE VIEW empvu10 2 (employee_number, employee_name, job_title) 3 AS SELECT empno, ename, job 4 FROM emp 5 WHERE deptno = 10;View created.View created.

Page 323: Introdução ao Oracle 8i

Funções Básicas

Criando uma Visão Complexa

O exemplo acima cria uma visão complexa com os nomes de departamento, o salário mínimo, o salário máximo e salário médio por departamento. Observe os nomes alternativos que foram especificados para a visão. Esta é uma exigência se qualquer coluna da visão é derivada de uma função ou uma expressão.

Você pode ver a estrutura da visão utilizando o comando DESCRIBE do SQL*Plus. Mostre o conteúdo da visão executando um comando SELECT.

On Targget Treinamento e Consultoria 12

SQL> CREATE VIEW dept_sum_vu 2 (name, minsal, maxsal, avgsal) 3 AS SELECT d.dname, MIN(e.sal), MAX(e.sal), 4 AVG(e.sal) 5 FROM emp e, dept d 6 WHERE e.deptno = d.deptno 7 GROUP BY d.dname;View created.View created.

SQL> SELECT * 2 FROM dept_sum_vu;NAME MINSAL MAXSAL AVGSAL-------------- --------- --------- ---------ACCOUNTING 1300 5000 2916.6667RESEARCH 800 3000 2175SALES 950 2850 1566.6667

Page 324: Introdução ao Oracle 8i

Funções Básicas

Regras para Executar Operações DML em uma Visão

Você pode executar operações DML nos dados através de uma visão desde que estas operações sigam certas regras.

Você pode remover uma linha de uma visão a menos que ela contenha um dos seguintes:

Funções de grupo Uma cláusula GROUP BY A palavra chave DISTINCT

Você pode modificar dados em uma visão a menos que ela contenha quaisquer das condições mencionadas para a deleção de linhas ou qualquer uma das seguintes:

Colunas definidas por expressões, por exemplo: SALARY * 12 A pseudo coluna ROWNUM

Você pode adicionar dados por uma visão a menos que ela contenha quaisquer das condições mencionadas anteriormente ou se existirem colunas NOT NULL, sem um valor default, na tabela básica que não foram selecionadas pela visão. Todos os valores exigidos devem estar presentes na visão. Lembre-se que você está adicionando valores diretamente na tabela referenciada pela visão.

On Targget Treinamento e Consultoria 13

Page 325: Introdução ao Oracle 8i

Funções Básicas

Utilizando a Cláusula WITH CHECK OPTION

É possível executar consistências de integridade referencial através de visões. Você pode também garantir constraint a nível de banco de dados. A visão pode ser utilizada para proteger a integridade dos dados, mas seu uso é muito limitado.

A cláusula WITH CHECK OPTION especifica que INSERTS e UPDATES executados pela visão não podem criar linhas que a visão não possa selecionar, e portanto ela permite constraints de integridade e consistências de validação de dados a serem garantidas nos dados inseridos ou atualizados.

Se houver uma tentativa de executar operações DML em linhas que a visão não seleciona, um erro é exibido, com o nome da constraint se ele tiver sido especificado.

Nota: Nenhuma linha é atualizada porque se o número do departamento fosse alterado para 10, a visão não poderia mais ver aquele empregado. Portanto, com a cláusula WITH CHECK OPTION, a visão pode visualizar somente empregados do departamento 20 e não permite que o número do departamento desses empregados seja modificado pela visão.

On Targget Treinamento e Consultoria 14

SQL> CREATE OR REPLACE VIEW empvu20 2 AS SELECT * 3 FROM emp 4 WHERE deptno = 20 5 WITH CHECK OPTION CONSTRAINT empvu20_ck;View created.View created.

SQL> UPDATE empvu20 2 SET deptno = 10 3 WHERE empno = 7788; update empvu20 * ERROR at line 1: ORA-01402: view WITH CHECK OPTION where-clause violation

Page 326: Introdução ao Oracle 8i

Funções Básicas

Impedindo Operações DML

Você pode assegurar que nenhuma operação DML execute sobre a visão criando ela com a opção WITH READ ONLY. O exemplo acima modifica a visão EMPVU10 para prevenir qualquer operação DML na visão.

Qualquer tentativa de remover uma linha da visão resultará em um erro.

On Targget Treinamento e Consultoria 15

SQL> CREATE OR REPLACE VIEW empvu10 2 (employee_number, employee_name, job_title) 3 AS SELECT empno, ename, job 4 FROM emp 5 WHERE deptno = 10 6 WITH READ ONLY;View created.View created.

SQL> DELETE FROM empvu10 2 WHERE employee_number = 7782;DELETE FROM empvu10 *ERROR at line 1:ORA-01752:Cannot delete from view without exactly one key-preserved table

Page 327: Introdução ao Oracle 8i

Funções Básicas

Removendo uma Visão

Você utiliza o comando DROP VIEW para remover uma visão. O comando remove a definição da visão do banco de dados. Remover visões não possui nenhum efeito nas tabelas nas quais a visão estava baseada. Visões ou outras aplicações baseadas em visões apagadas tornam-se invalidas. Somente o dono ou um usuário com o privilégio DROP ANY VIEW pode remover uma visão.

Sintaxe:

view é o nome da visão.

On Targget Treinamento e Consultoria 16

DROP VIEW view;SQL> DROP VIEW empvu10;View dropped.View dropped.

Page 328: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 13

1. Crie uma visão chamada EMP_VU baseada no número do empregado, nome e no número do departamento a partir da tabela EMP. Modifique o cabeçalho para o nome do empregado para “EMPLOYEE”.

2. Mostre o conteúdo da visão EMP_VU.

3. Selecione a coluna VIEW_NAME e TEXT a partir da tabela do dicionário de dados USER_VIEWS.

4. Utilizando a visão EMP_VU, execute uma consulta para exibir todos os nomes de empregados e números de departamentos.

On Targget Treinamento e Consultoria 17

EMPNO EMPLOYEE DEPTNO----- -------- ------ 7839 KING 10 7698 BLAKE 30 7782 CLARK 10 7566 JONES 20 7654 MARTIN 30 7499 ALLEN 30 7844 TURNER 30 7900 JAMES 30 7521 WARD 30 7902 FORD 20 7369 SMITH 20 7788 SCOTT 20 7876 ADAMS 20 7934 MILLER 1014 rows selected.

VIEW_NAME TEXT----------- -------------------------------------EMP_VU SELECT empno, ename employee, deptno FROM emp

EMPLOYEE DEPTNO---------- ---------KING 10BLAKE 30CLARK 10JONES 20MARTIN 30...14 rows selected.

Page 329: Introdução ao Oracle 8i

Funções Básicas

5. Crie uma visão chamada DEPT20 que contenha o número do empregado, o nome e o número do departamento para todos os empregados do departamento 20. Coloque os alias das colunas da visão como “EMPLOYEE_ID”, “EMPLOYEE” e “DEPARTMENT_ID”. Não permita que um empregado seja atribuído a outro departamento pela visão.

6. Mostre a estrutura e o conteúdo da visão DEPT20.

7. Tente alterar o departamento do empregado SMITH para 30 através da visão.

Se houver tempo, complete os seguintes exercícios:

8. Crie uma visão chamada SALARY_VU baseada no nome do empregado, nome do departamento, salário e nível do salário para todos os empregados. Coloque o alias das colunas como “Employee”, “Department”, “Salary” e “Grade”, respectivamente.

On Targget Treinamento e Consultoria 18

Name Null? Type--------------- -------- ------------EMPLOYEE_ID NOT NULL NUMBER(4)EMPLOYEE VARCHAR2(10)DEPARTMENT_ID NOT NULL NUMBER(2)

EMPLOYEE_ID EMPLOYEE DEPARTMENT_ID----------- -------- ------------- 7566 JONES 20 7902 FORD 20 7369 SMITH 20 7788 SCOTT 20 7876 ADAMS 20

Page 330: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

15.15. Outros Objetos do Banco deOutros Objetos do Banco de DadosDados

On Targget Treinamento e Consultoria

Page 331: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Descrever alguns dos objetos do banco de dados e seu uso Criar, alterar e utilizar sequences Criar e alterar índices Criar sinônimos privados e públicos

On Targget Treinamento e Consultoria 2

Page 332: Introdução ao Oracle 8i

Funções Básicas

Objetos do Banco de Dados

On Targget Treinamento e Consultoria 3

Page 333: Introdução ao Oracle 8i

Funções Básicas

O que é uma Sequence?

Um gerador de seqüências pode ser utilizado para gerar números seqüênciais automaticamente para linhas em tabelas. Uma sequence é um objeto do banco de dados criado por um usuário podendo ser compartilhado por múltiplos usuários Uma sequence é um objeto do banco de dados criado por um usuário podendo ser compartilhado por múltiplos usuários.

Um uso típico para sequence é criar um valor para uma chave primária, que deve ser único para cada linha.

A sequence é gerada e é incrementada por uma rotina interna do Oracle8i. Este objeto pode reduzir o tempo de desenvolvimento uma vez que reduz a quantidade de código de aplicação necessária para gerar uma rotina que implemente uma seqüência.

Os números das seqüências são armazenados e gerados independentemente das tabelas. Portanto, a mesma sequence pode ser utilizadas em tabelas diferentes.

On Targget Treinamento e Consultoria 4

Page 334: Introdução ao Oracle 8i

Funções Básicas

Comando CREATE SEQUENCE

Automaticamente gere números seqüênciais utilizando o comando CREATE SEQUENCE.

Sintaxe:

sequence é o nome do gerador da seqüência.

INCREMENT BY n especifica o intervalo entre os números da seqüência onde n é um inteiro. Se esta cláusula for omitida, a seqüência será incrementada por 1.

START WITH n especifica o primeiro número da seqüência a ser gerado. Se esta cláusula for omitida, a seqüência começará em 1.

MAXVALUE n especifica o valor de máximo que seqüência pode gerar.

NOMAXVALUE especifica um valor de máximo de 10^27 para uma sequence ascendente e -1 para uma sequence descendente. Esta é a opção default.

MINVALUE n especifica o valor mínimo da seqüência.

NOMINVALUE especifica um valor mínimo de 1 para uma sequence ascendente e -(10^26) para uma sequence descendente. Esta é a opção default.

CYCLE | NOCYCLE especifica que a sequence continua gerando valores depois de atingir seu valor máximo ou mínimo ou que ela não deve gerar valores adicionais. NOCYCLE é a opção default.

CACHE n | NOCACHE especifica quantos valores o Servidor Oracle deve alocar e manter em memória. Por default, o Servidor Oracle mantém 20 valores em memória (cache).

On Targget Treinamento e Consultoria 5

CREATE SEQUENCE sequence[INCREMENT BY n][START WITH n][{MAXVALUE n | NOMAXVALUE}][{MINVALUE n | NOMINVALUE}][{CYCLE | NOCYCLE}][{CACHE n | NOCACHE}];

Page 335: Introdução ao Oracle 8i

Funções Básicas

Criando uma Sequence

O exemplo acima cria uma sequence chamada DEPT_DEPTNO para ser utilizada para a coluna DEPTNO da tabela DEPT. A seqüência começa em 91, não permite cache e não permite que ela seja cíclica.

Não utilize a opção CYCLE se a sequence for utilizada para gerar valores de chave primária a menos que você possua um mecanismo que remova linhas antigas mais rapidamente que os ciclos da sequence.

On Targget Treinamento e Consultoria 6

SQL> CREATE SEQUENCE dept_deptno 2 INCREMENT BY 1 3 START WITH 91 4 MAXVALUE 100 5 NOCACHE 6 NOCYCLE;Sequence created.Sequence created.

Page 336: Introdução ao Oracle 8i

Funções Básicas

Confirmando Sequences

Uma vez criada, a sequence é documentada no dicionário de dados. Considerando-se que uma sequence é um objeto do banco de dados, você pode identificá-la na tabela do dicionário de dados USER_OBJECTS.

Você pode também confirmar as configurações da sequence selecionando a partir da tabela do dicionário de dados USER_SEQUENCES.

On Targget Treinamento e Consultoria 7

SQL> SELECT sequence_name, min_value, max_value, 2 increment_by, last_number 3 FROM user_sequences;

SEQUENCE_NAME MIN_VALUE MAX_VALUE INCREMENT_BY LAST_NUMBER-------------- ----------- --------- ------------ -----------CUSTID 1 1.000E+27 1 109DEPT_DEPTNO 1 100 1 91ORDID 1 1.000E+27 1 622PRODID 1 1.000E+27 1 200381

Page 337: Introdução ao Oracle 8i

Funções Básicas

Pseudocolunas NEXTVAL e CURRVAL

Uma vez criada a sequence, você pode utilizá-la para gerar números seqüênciais para suas tabelas. Referencie os valores da sequence utilizando as pseudocolunas NEXTVAL e CURRVAL.

A pseudocoluna NEXTVAL é utilizada para extrair sucessivos números da sequence especificada. Você deve qualificar NEXTVAL com o nome da sequence. Quando você referência sequence.NEXTVAL, um novo número da sequence é gerado e colocado em CURRVAL.

A pseudocoluna CURRVAL é utilizada para se referenciar a um número da sequence que o usuário atual gerou anteriormente. NEXTVAL deve ser utilizada para gerar um número da sequence na sessão do usuário atual antes de CURRVAL poder ser referenciada. Você deve qualificar CURRVAL com o nome da sequence. Quando sequence.CURRVAL é referenciada, o último valor retornado ao processo daquele usuário é exibido.

Regras para Utilizar NEXTVAL e CURRVAL

Você pode utilizar NEXTVAL e CURRVAL no seguinte:

Na lista da cláusula SELECT de um comando SELECT que não seja parte de uma subconsulta

Na lista da cláusula SELECT de uma subconsulta em um comando INSERT Na cláusula VALUES de um comando INSERT Na cláusula SET de um comando UPDATE

Você não pode utilizar NEXTVAL e CURRVAL no seguinte:

Na lista da cláusula SELECT de uma visão Em um comando SELECT com a palavra chave DISTINCT Em um comando SELECT com as cláusulas GROUP BY, HAVING ou ORDER BY Em uma subconsulta no comando SELECT, DELETE ou UPDATE Na expressão da opção DEFAULT em um comando CREATE TABLE ou ALTER

TABLE

On Targget Treinamento e Consultoria 8

Page 338: Introdução ao Oracle 8i

Funções Básicas

Utilizando uma Sequence

O exemplo acima insere um novo departamento na tabela DEPT, utilizando a sequence DEPT_DEPTNO para gerar um novo número de departamento.

Você pode visualizar o valor atual da sequence:

Suponha agora você quer contratar empregados para prover de pessoal o departamento novo. O comando INSERT que pode ser executado repetidamente para todos os novos empregados pode incluir o seguinte código:

Nota: O exemplo acima assume que uma sequence EMP_EMPNO já foi criada para gerar um número de empregado novo.

Mantendo em Memória os Valores da Sequence

Mantenha seqüências em memória para permitir acesso mais rápido aos valores da sequence. O cache é populado na primeira referência à sequence. Cada solicitação para o próximo valor da sequence é recuperado da memória. Após a última seqüência ser utilizada, a próxima solicitação para a sequence busca outro cache de seqüências para a memória.

Previna Falhas nos Valores da Sequence

Embora os geradores de seqüência forneçam números seqüênciais sem falhas, esta ação ocorre independente de um commit ou rollback. Portanto, se você efetuar o rollback de um comando que contém uma sequence, o número será perdido.

Outro evento que pode causar falhas na numeração da sequence é uma fallha do sistema. Se a sequence possui valores no cache de memória, esses valores serão perdidos na falha do sistema.

Uma vez que as sequences não são relacionadas diretamente às tabelas, a mesma sequence pode ser utilizada em múltiplas tabelas. Se isto ocorrer, cada tabela pode conter falhas nos números seqüênciais.

Visualizando o Próximo Valor Disponível da Sequence sem Incrementá-lo

É possível visualizar o próximo valor disponível da sequence sem incrementá-lo, porém somente se a sequence foi criada com NOCACHE, examinando a tabela USER_SEQUENCES.

On Targget Treinamento e Consultoria 9

SQL> INSERT INTO dept (deptno, dname, loc) 2 VALUES (dept_deptno.NEXTVAL, 3 'MARKETING', 'SAN DIEGO');1 row created.1 row created.

SQL> SELECT dept_deptno.CURRVAL 2 FROM dual;CURRVAL------- 91

SQL> INSERT INTO emp ... 2 VALUES (emp_empno.NEXTVAL, dept_deptno.CURRVAL, ...

Page 339: Introdução ao Oracle 8i

Funções Básicas

Modificando uma Sequence

Se você atingir o limite MAXVALUE para uma sequence, não serão alocados valores adicionais da sequence e você receberá um erro que indica que o valor de MAXVALUE foi excedido. Para continuar utilizando a sequence, você pode modificá-la utilizando o comando ALTER SEQUENCE.

Sintaxe:

Onde:

sequence é o nome do gerador da sequence.

On Targget Treinamento e Consultoria 10

SQL> ALTER SEQUENCE dept_deptno 2 INCREMENT BY 1 3 MAXVALUE 999999 4 NOCACHE 5 NOCYCLE;Sequence altered.Sequence altered.

ALTER SEQUENCE sequence [INCREMENT BY n] [{MAXVALUE n | NOMAXVALUE}] [{MINVALUE n | NOMINVALUE}] [{CYCLE | NOCYCLE}] [{CACHE n | NOCACHE}];

Page 340: Introdução ao Oracle 8i

Funções Básicas

Diretrizes para Modificar uma Sequence

Você deve ser o dono ou possuir o privilégio ALTER para a sequence para poder modificá-la.

Somente os próximos números da sequence serão afetados pelo comando ALTER SEQUENCE.

A opção START WITH não pode ser modificada utilizando o comando ALTER SEQUENCE. A sequence deve ser removida e recriada para reiniciar em um número diferente.

Algumas validações são executadas. Por exemplo, um novo MAXVALUE não pode ser menor que o número atual da sequence.

On Targget Treinamento e Consultoria 11

SQL> ALTER SEQUENCE dept_deptno 2 INCREMENT BY 1 3 MAXVALUE 90 4 NOCACHE 5 NOCYCLE;ALTER SEQUENCE dept_deptno*ERROR at line 1:ORA-04009: MAXVALUE cannot be made to be less than the current value

Page 341: Introdução ao Oracle 8i

Funções Básicas

Removendo uma Sequence

Para remover uma sequence do dicionário de dados, utilize o comando DROP SEQUENCE. Você deve ser o dono da sequence ou ter o privilégio DROP ANY SEQUENCE para removê-la.

Sintaxe:

Onde:

sequence é o nome do gerador da seqüência.

On Targget Treinamento e Consultoria 12

SQL> DROP SEQUENCE dept_deptno;Sequence dropped.Sequence dropped.DROP SEQUENCE sequence;

Page 342: Introdução ao Oracle 8i

Funções Básicas

O que é um Índice?

Um índice do Servidor Oracle é um objeto de um schema que pode acelerar a recuperação das linhas utilizando um ponteiro. Podem ser criados explicitamente ou automaticamente. Se você não possuir um índice em uma coluna, então um método de acesso chamado full table scan ocorrerá.

Um índice fornece acesso direto e rápido para as linhas de uma tabela. Seu propósito é reduzir a necessidade de I/O de disco utilizando um caminho indexado para localizar os dados rapidamente. O índice é automaticamente utilizado e mantido pelo Servidor Oracle. Uma vez criado, nenhuma atividade direta é requerida por parte do usuário.

Índices são lógica e fisicamente independentes da tabela que indexam. Isto significa que eles podem ser criados ou removidos a qualquer momento e não causam nenhum efeito nas tabelas ou outros índices.

Nota: Quando você remove uma tabela, os índices correspondentes também são removidos.

On Targget Treinamento e Consultoria 13

Page 343: Introdução ao Oracle 8i

Funções Básicas

Como os Índices são Criados?

Podem ser criados dois tipos de índices. Um tipo são os índices únicos. O Servidor Oracle cria este tipo de índice automaticamente quando você define para uma coluna em uma tabela uma constraint PRIMARY KEY ou UNIQUE key. O nome do índice é o nome fornecido para a constraint.

O outro tipo de índice que um usuário pode criar é um índice não único (nonunique). Por exemplo, você pode criar um índice em uma coluna definida como FOREIGN KEY para melhor a performance de um join em uma consulta.

On Targget Treinamento e Consultoria 14

Page 344: Introdução ao Oracle 8i

Funções Básicas

Criando um Índice

Crie um índice em uma ou mais colunas:

Aumente a velocidade de acesso da consulta na coluna ENAME da tabela EMP:

Crie um índice em uma ou mais colunas executando o comando CREATE INDEX.

Sintaxe:

index é o nome do índice.

table é o nome da tabela.

column é o nome da coluna da tabela a ser indexada.

On Targget Treinamento e Consultoria 15

CREATE INDEX indexON table (column[, column]...);SQL> CREATE INDEX emp_ename_idx 2 ON emp(ename);Index created.Index created.

Page 345: Introdução ao Oracle 8i

Funções Básicas

Diretrizes para a Criação de Índices

Mais nem sempre é Melhor

Muitos índices em uma tabela nem sempre significam melhora na velocidade das consultas. Para cada operação DML que é confirmada em uma tabela os índices devem ser atualizados. Quanto mais índices você associou à uma tabela, mais esforço o Servidor Oracle terá que realizar para atualizar todos os índices após uma operação DML.

Quando Criar um Índice

A coluna é freqüentemente utilizada na cláusula WHERE ou em uma condição de join. A coluna possui uma grande faixa de valores. A coluna possui um grande número de valores nulos. Duas ou mais colunas são freqüentemente utilizadas juntas em uma cláusula WHERE ou

condição de join. A tabela é grande e a maioria das consultas recuperam menos que 2% a 4% das linhas.

Lembre-se que se você quiser garantir unicidade, você deve definir uma constraint do tipo UNIQUE na definição da tabela. Então, um índice único será criado automaticamente.

Quando não Criar um Índice

A tabela for pequena. As colunas não são utilizadas freqüentemente como uma condição da consulta. A maioria das consultas recuperam mais que 2% a 4% das linhas. A tabela é freqüentemente atualizada. Se você possui um ou mais índices em uma tabela,

os comandos DML que acessam a tabela utilizam relativamente mais tempo para sua execução devido a manutenção dos índices.

On Targget Treinamento e Consultoria 16

Page 346: Introdução ao Oracle 8i

Funções Básicas

Confirmando Índices

Confirme a existência de índices a partir da visão do dicionário de dados USER_INDEXES. Você também pode conferir as colunas envolvidas em um índice examinando a visão USER_IND_COLUMNS.

O exemplo acima exibe todos os índices previamente criados, nomes das colunas afetadas e a unicidade para a tabela EMP.

On Targget Treinamento e Consultoria 17

SQL> SELECT ic.index_name, ic.column_name, 2 ic.column_position col_pos, ix.uniqueness 3 FROM user_indexes ix, user_ind_columns ic 4 WHERE ic.index_name = ix.index_name 5 AND ic.table_name = 'EMP';

INDEX_NAME COLUMN_NAME COL_POS UNIQUENES----------------- --------------- ------- ----------EMP_EMPNO_PK EMPNO 1 UNIQUEEMP_ENAME_IDX ENAME 1 NONUNIQUE

Page 347: Introdução ao Oracle 8i

Funções Básicas

Removendo um Índice

Remova um índice do dicionário de dados:

Remova o índice EMP_ENAME_IDX do dicionário de dados:

Você não pode modificar índices. Para alterar um índice, você deve removê-lo e então criá-lo novamente. Remova a definição de um índice do dicionário de dados executando o comando DROP INDEX. Para remover um índice, você deve ser o dono do índice ou possuir o privilégio DROP ANY INDEX.

Sintaxe:

index é o nome do índice.

On Targget Treinamento e Consultoria 18

SQL> DROP INDEX index;SQL> DROP INDEX emp_ename_idx;Index dropped.Index dropped.

Page 348: Introdução ao Oracle 8i

Funções Básicas

Sinônimos

Para referenciar uma tabela criada por outro usuário, você deve prefixar o nome da tabela com o nome do usuário que a criou seguido por um ponto. Criando um sinônimo você elimina a necessidade de qualificar o nome do objeto com o schema e o provê um nome alternativo para uma tabela, visão, sequence, procedure ou outros objetos. Este método pode ser especialmente útil com nomes de objeto longos, como visões.

Sintaxe:

PUBLIC cria um sinônimo acessível a todos os usuários.

synonym é o nome do sinônimo a ser criado.

object identifica o objeto para o qual o sinônimo deve ser criado.

Diretrizes

O objeto não pode estar contido em uma package. Um nome de sinônimo privado deve ser distinto de todos os outros objetos criados pelo

mesmo usuário.

On Targget Treinamento e Consultoria 19

CREATE [PUBLIC] SYNONYM synonymFOR object;

Page 349: Introdução ao Oracle 8i

Funções Básicas

Criando e Removendo Sinônimos

O exemplo acima cria um sinônimo para a visão DEPT_SUM_VU para uma referência mais rápida.

O DBA pode criar um sinônimo público acessível para todos os usuários. O exemplo abaixo cria um sinônimo público chamado DEPT para a tabela DEPT do usuário ALICE:

Removendo um Sinônimo

Para remover um sinônimo, utilize o comando DROP SYNONYM. Somente um DBA pode remover um sinônimo público.

On Targget Treinamento e Consultoria 20

SQL> CREATE SYNONYM d_sum 2 FOR dept_sum_vu;Synonym Created.Synonym Created.

SQL> CREATE PUBLIC SYNONYM dept 2 FOR alice.dept;Synonym created.

SQL> DROP SYNONYM dept;Synonym dropped.

Page 350: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 14

1. Crie uma seqüência para ser utilizada com a coluna da chave primária da tabela DEPARTMENT. A seqüência deve iniciar em 60 e possuir um valor máximo de 200. Forneça para a seqüência um incremento de 10 e o nome como DEPT_ID_SEQ.

2. Crie um arquivo de script para exibir a seguinte informação sobre suas seqüências: o nome da seqüência, o valor máximo, o incremento e o último número fornecido. Coloque o nome do arquivo como e14q2.sql. Execute o script criado.

3. Escreva um script interativo para inserir uma linha na tabela DEPARTMENT. Coloque o nome do arquivo como e14q3.sql. Utilize a seqüência que você criou para a coluna ID. Crie um prompt customizado para solicitar o nome do departamento. Execute o script adicionando dois departamentos chamados “Education” e “Administration”. Confirme as inserções.

4. Crie um índice não único para a coluna definida como FOREIGN KEY na tabela EMPLOYEE.

5. Mostre os índices que existem no dicionário de dados para a tabela EMPLOYEE. Salve o comando para um script chamado e14q5.sql.

On Targget Treinamento e Consultoria 21

SEQUENCE_NAME MAX_VALUE INCREMENT_BY LAST_NUMBER------------- --------- ------------ -----------CUSTID 1.000E+27 1 109DEPT_ID_SEQ 200 1 60ORDID 1.000E+27 1 622PRODID 1.000E+27 1 200381

INDEX_NAME TABLE_NAME UNIQUENES-------------------- ------------ ---------EMPLOYEE_DEPT_ID_IDX EMPLOYEE NONUNIQUEEMPLOYEE_ID_PK EMPLOYEE UNIQUE

Page 351: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

16.16. Controlando o Acesso dosControlando o Acesso dos UsuáriosUsuários

On Targget Treinamento e Consultoria

Page 352: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Criar usuários Criar roles para facilitar a configuração e manutenção do modelo de segurança Executar GRANT e REVOKE de privilégios de objeto

On Targget Treinamento e Consultoria 2

Page 353: Introdução ao Oracle 8i

Funções Básicas

Controlando o Acesso dos Usuários

Em um ambiente multiusuário, você deve manter a segurança do acesso ao banco de dados. A segurança do servidor de banco de dados Oracle permite fazer o seguinte:

Controlar o acesso ao banco de dados Fornecer acesso a objetos específicos do banco de dados Confirmar os privilégios fornecidos e recebidos com o dicionário de dados do Oracle Criar sinônimos para os objetos do banco de dados

A segurança do banco de dados pode ser classificada em duas categorias: segurança do sistema e segurança dos dados. A segurança do sistema cobre o acesso e uso do banco de dados a nível de sistema, como nomes de usuários e senhas, espaço de disco alocado aos usuários e operações de sistema permitidas aos usuários. A segurança do banco de dados cobre o acesso e uso dos objetos do banco de dados e as ações que esses usuários podem executar sobre os objetos.

On Targget Treinamento e Consultoria 3

Page 354: Introdução ao Oracle 8i

Funções Básicas

Privilégios

Privilégios fornecem a permissão para executar comandos SQL específicos. O administrador de banco de dados é um usuário de alto nível com capacidade para conceder aos usuários acesso ao banco de dados e seus objetos. Os usuários necessitam de privilégios de sistemas para obter acesso ao banco de dados e de privilégios de objeto para manipular o conteúdo dos objetos do banco de dados. Também pode ser fornecido aos usuários o privilégio para conceder privilégios adicionais a outros usuários ou roles, que são chamadas de grupos de privilégios relacionados.

Schema

Um schema é uma coleção de objetos, como tabelas, visões e sequences. O schema é associado a um usuário do banco de dados e possui o mesmo nome deste usuário.

On Targget Treinamento e Consultoria 4

Page 355: Introdução ao Oracle 8i

Funções Básicas

Privilégios de Sistema

Mais de 80 privilégios de sistemas estão disponíveis para os usuários e roles. Privilégios de sistemas são normalmente concedidos pelo administrador de banco de dados.

Privilégios Típicos do DBA

Privilégio de Sistema Operações Autorizadas

CREATE USERPermite criar outros usuários Oracle (este privilégio é necessário para a role DBA)

DROP USER Remover outro usuárioDROP ANY TABLE Remover uma tabela em qualquer schema

BACKUP ANY TABLEEfetuar o backup de qualquer tabela em qualquer schema com o utilitário de exportação

On Targget Treinamento e Consultoria 5

Page 356: Introdução ao Oracle 8i

Funções Básicas

Criando Usuários

O DBA cria o usuário executando o comando CREATE USER. O usuário não possui nenhum privilégio neste momento. O DBA pode então conceder vários privilégios para o usuário. Estes privilégios determinam o que o usuário pode fazer a nível de banco de dados.

No exemplo acima é fornecida uma sintaxe abreviada para a criação de um usuário.

Sintaxe:

user é o nome do usuário a ser criado.

password especifica que o usuário deve efetuar o login com esta senha.

On Targget Treinamento e Consultoria 6

CREATE USER userIDENTIFIED BY password;SQL> CREATE USER scott 2 IDENTIFIED BY tiger;User created.User created.

Page 357: Introdução ao Oracle 8i

Funções Básicas

Privilégios de Sistema do Usuário

Uma vez criado o usuário, o DBA pode conceder privilégios a ele.

Sintaxe:

privilege é o privilégio de sistema a ser concedido.

user é o nome do usuário

Na tabela abaixo são apresentados os principais privilégios de sistema necessários para um desenvolvedor de aplicação:

Privilégio de Sistema Operações AutorizadasCREATE SESSION Conectar ao banco de dadosCREATE TABLE Criar tabelas no schema do usuárioCREATE SEQUENCE Criar sequences no schema do usuárioCREATE VIEW Criar visões no schema do usuário

CREATE PROCEDURECriar uma stored procedure, função ou package no schema do usuário

On Targget Treinamento e Consultoria 7

GRANT privilege [, privilege...]TO user [, user...];

Page 358: Introdução ao Oracle 8i

Funções Básicas

Concedendo Privilégios de Sistema

O DBA utiliza o comando GRANT para conceder privilégios de sistema para o usuário. Uma vez que os privilégios tenham sido concedidos, o usuário pode utilizá-los imediatamente.

No exemplo acima, o usuário SCOTT recebeu os privilégios para criar tabelas, sequences e visões.

On Targget Treinamento e Consultoria 8

SQL> GRANT create table, create sequence, create view 2 TO scott;Grant succeeded.Grant succeeded.

Page 359: Introdução ao Oracle 8i

Funções Básicas

O que é uma Role?

Uma role é um grupo nomeado de privilégios relacionados que podem ser concedidos ao usuário. Este método torna a concessão e remoção de privilégios mais fácil de executar e manter.

Um usuário pode ter acesso a várias roles e vários usuários podem ser associados a mesma role. As roles são normalmente criadas para uma aplicação de banco de dados.

Criando e Concedendo uma Role

Primeiro, o DBA deve criar a role. Depois o DBA pode associar privilégios e usuários para a role.

Sintaxe:

Onde:

role é o nome da role a ser criada.

Agora que a role foi criada, o DBA pode utilizar o comando GRANT para associar os usuários e conceder os privilégios para a role.

On Targget Treinamento e Consultoria 9

CREATE ROLE role;

Page 360: Introdução ao Oracle 8i

Funções Básicas

Criando e Concedendo Privilégios para uma Role

O exemplo acima cria uma role chamada MANAGER e então permite aos gerentes criar tabelas e visões. Depois a role MANAGER é concedida aos usuários BLAKE e CLARK. Agora BLAKE e CLARK podem criar tabelas e visões.

On Targget Treinamento e Consultoria 10

SQL> CREATE ROLE manager;Role created.Role created.SQL> GRANT create table, create view 2 TO manager;Grant succeeded.Grant succeeded.

SQL> GRANT manager TO BLAKE, CLARK;Grant succeeded.Grant succeeded.

Page 361: Introdução ao Oracle 8i

Funções Básicas

Modificando Senhas

Cada usuário possui uma senha que é inicializada pelo DBA quando o usuário é criado. Você pode modificar sua senha utilizando o comando ALTER USER.

Sintaxe:

Onde:

user é o nome do usuário.

password especifica a nova senha.

Embora este comando possa ser utilizado para modificar sua senha, existem outras opções. Você deve possuir o privilégio ALTER USER para modificar qualquer outra opção.

On Targget Treinamento e Consultoria 11

SQL> ALTER USER scott 2 IDENTIFIED BY lion;User altered.User altered.

ALTER USER user IDENTIFIED BY password;

Page 362: Introdução ao Oracle 8i

Funções Básicas

Privilégios de Objeto

Um privilégio de objeto é um privilégio ou direito para executar uma determinada ação em uma tabela, visão, sequence ou procedure específica. Cada objeto possui um conjunto particular de privilégios concedíveis. O gráfico acima lista os privilégios para vários tipos de objetos. Observe que os únicos privilégios que se aplicam a uma sequence são SELECT e ALTER. UPDATE, REFERENCES e INSERT podem ser restringidos especificando-se um subconjunto de colunas. Um SELECT pode ser restringido criando-se uma visão com um subconjunto de colunas e concedendo-se o privilégio de SELECT somente na visão. Uma concessão em um sinônimo é convertida para uma concessão na tabela referenciada pelo sinônimo.

Diferentes privilégios de objeto estão disponíveis para tipos diferentes de objetos do schema. Um usuário automaticamente possui todos os privilégios de objeto para os objetos contidos em seu próprio schema. Um usuário pode conceder qualquer privilégio de objeto sobre qualquer objeto que ele possua para qualquer outro usuário ou role. Se a concessão incluir a opção GRANT OPTION, quem receber o privilégio de objeto pode futuramente concedê-lo a outros usuários; caso contrário, ele somente poderá utilizar o privilégio e não poderá concedê-lo a outros usuários.

Sintaxe:

object_priv é um privilégio de objeto a ser concedido.

ALL todos os privilégios de objeto.

columns especificam as colunas da tabela ou visão sobre as quais os privilégios devem ser concedidos.

ON object é o objeto sobre o qual os privilégios devem ser concedidos.

TO identifica a quem o privilégio deve ser concedido.

PUBLIC concede o privilégio de objeto para todos os usuários.

WITH GRANT OPTION permite para quem receber o privilégio concedê-lo a outros usuários e roles.

On Targget Treinamento e Consultoria 12

GRANT object_priv [(columns)]ON objectTO {user | role | PUBLIC}[WITH GRANT OPTION];

Page 363: Introdução ao Oracle 8i

Funções Básicas

Concedendo Privilégios de Objeto

Conceda privilégios de consulta para a tabela EMP:

Conceda privilégios de atualização de colunas específicas para usuários e roles:

Diretrizes

Para conceder privilégios em um objeto, o objeto deve estar em seu próprio schema ou você deve ter recebido o privilégio sobre o objeto com a opção WITH GRANT OPTION.

Um dono do objeto pode conceder qualquer privilégio sobre o objeto para qualquer outro usuário ou role do banco de dados.

O dono de um objeto automaticamente adquire todos os privilégios sobre o objeto.

O primeiro exemplo acima concede para os usuários SUE e RICH o privilégio para consultar sua tabela EMP. O segundo exemplo concede o privilégio UPDATE em colunas específicas da tabela DEPT para o usuário SCOTT e para a role MANAGER.

Nota: DBAs geralmente concedem privilégios de sistema; qualquer usuário que possui um objeto pode conceder privilégios sobre seus próprios objetos.

On Targget Treinamento e Consultoria 13

SQL> GRANT select 2 ON emp 3 TO sue, rich;Grant succeeded.Grant succeeded.

SQL> GRANT update (dname, loc) 2 ON dept 3 TO scott, manager;Grant succeeded.Grant succeeded.

Page 364: Introdução ao Oracle 8i

Funções Básicas

Utilizando as Opções WITH GRANT OPTION e PUBLIC

Palavra Chave WITH GRANT OPTION

Um privilégio que é concedido com WITH GRANT OPTION pode ser passado para outros usuários e roles por quem o recebeu. Privilégios de objeto concedidos através de WITH GRANT OPTION são revogados quando o privilégio é revogado do concedente.

O exemplo acima permite ao usuário SCOTT acessar a tabela DEPT com os privilégios para consultar e adicionar linhas para a tabela. Permita também ao usuário SCOTT repassar para outros usuários estes privilégios.

Palavra Chave PUBLIC

Um dono de uma tabela pode conceder acesso para todos os usuários utilizando a palavra chave PUBLIC.

O exemplo acima permite a todos os usuários do sistema consultar dados da tabela DEPT do usuário ALICE.

On Targget Treinamento e Consultoria 14

SQL> GRANT select, insert 2 ON dept 3 TO scott 4 WITH GRANT OPTION;Grant succeeded.Grant succeeded.

SQL> GRANT select 2 ON alice.dept 3 TO PUBLIC;Grant succeeded.Grant succeeded.

Page 365: Introdução ao Oracle 8i

Funções Básicas

Confirmando Privilégios Concedidos

Se você tentar executar uma operação não autorizada, por exemplo, remover uma linha de uma tabela para a qual você não possui o privilégio DELETE, o Servidor Oracle não permitirá que a operação execute.

Se você receber a mensagem de erro do Servidor Oracle “table or view does not exist”, o seguinte pode ter ocorrido:

Você forneceu um nome de tabela ou visão que não existe Você tentou executar uma operação em uma tabela ou visão para a qual você não possui o

privilégio apropriado

Você pode acessar o dicionário de dados para visualizar os privilégios que você possui. O gráfico acima descreve as várias tabelas do dicionário de dados que podem ser consultadas para este fim.

On Targget Treinamento e Consultoria 15

Page 366: Introdução ao Oracle 8i

Funções Básicas

Como Revogar Privilégios de Objeto

Remova privilégios concedidos a outros usuários utilizando o comando REVOKE. Quando você utiliza o comando REVOKE, os privilégios que você especificou são revogados dos usuários que você informa e de qualquer outro usuário para quem estes privilégios podem ter sido concedidos através do uso de GRANT OPTION.

Sintaxe:

CASCADE CONSTRAINTS é necessária para remover qualquer constraint de integridade referente feita ao objeto por meio do privilégio REFERENCES.

On Targget Treinamento e Consultoria 16

REVOKE {privilege [, privilege...] | ALL}ON objectFROM {user[, user...] | role | PUBLIC}[CASCADE CONSTRAINTS];

Page 367: Introdução ao Oracle 8i

Funções Básicas

Revogando Privilégios de Objeto

O exemplo acima revoga os privilégios SELECT e INSERT fornecidos ao usuário SCOTT na tabela DEPT.

Nota: Se um usuário receber um privilégio com a opção WITH GRANT OPTION, este usuário também pode conceder o privilégio com WITH GRANT OPTION, de forma que pode-se formar uma cadeia longa de concessões, mas nenhuma concessão circular é permitida. Se o dono do objeto revogar um privilégio de um usuário que concedeu o privilégio a outros usuários, o REVOKE remove o privilégio também destes outros usuários.

Por exemplo, se o usuário A concede o privilégio SELECT em uma tabela para o usuário B incluindo a opção WITH GRANT OPTION, o usuário B pode conceder ao usuário C o privilégio SELECT também com WITH GRANT OPTION, e o usuário C pode conceder então ao usuário D o privilégio SELECT. Se o usuário A revogar o privilégio do usuário B, então os privilégios concedidos aos usuários C e D também são revogados.

On Targget Treinamento e Consultoria 17

SQL> REVOKE select, insert 2 ON dept 3 FROM scott;Revoke succeeded.Revoke succeeded.

Page 368: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 15

1. Que privilégio um usuário necessita para conectar ao Servidor Oracle? Este privilégio é um privilégio de sistema ou objeto?

2. Que privilégio é necessário fornecer para um usuário poder criar tabelas?

3. Se você criar uma tabela, quem pode fornecer privilégios para outros usuários sobre esta tabela?

4. Você é um DBA e está criando vários usuários que necessitam dos mesmos privilégios de sistema. O que você pode utilizar para facilitar seu trabalho?

5. Que comando você utiliza para alterar a sua senha?

6. Conceda a outro usuário acesso para a sua tabela DEPT. Solicite a este outro usuário que também conceda a você acesso de consulta para a tabela DEPT dele.

7. Consulte todas as linhas da sua tabela DEPT.

8. Adicione uma nova linha para a tabela DEPT. O grupo 1 deve inserir “Education” como o departamento número 50. O grupo 2 deve inserir “Administration” também como o departamento número 50. Torne as modificações permanentes.

9. Crie um sinônimo para a tabela DEPT do outro grupo.

On Targget Treinamento e Consultoria 18

DEPTNO DNAME LOC------ ---------- --------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON

Page 369: Introdução ao Oracle 8i

Funções Básicas

10. Consulte todas as linhas da tabela DEPT do outro grupo utilizando o sinônimo.

11. Consulte a visão do dicionário de dados USER_TABLES para visualizar as tabelas que você possui.

12. Consulte a visão do dicionário de dados ALL_TABLES para visualizar todas as tabelas que você possui acesso. Exclua as tabelas que foram criadas por você.

13. Revogue o privilégio SELECT do outro grupo.

On Targget Treinamento e Consultoria 19

Resultado do comando SELECT para o grupo 1.DEPTNO DNAME LOC------ -------------- --------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON 50 ADMINISTRATION

Resultado do comando SELECT para o grupo 2.DEPTNO DNAME LOC------ -------------- --------- 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 SALES CHICAGO 40 OPERATIONS BOSTON 50 EDUCATION

TABLE_NAME----------------BONUSCUSTOMERDEPARTMENTDEPTDUMMYEMPEMPLOYEEITEMMY_EMPLOYEEORDPRICEPRODUCTSALGRADE13 rows selected.

TABLE_NAME OWNER---------- -----------DEPT <user2>

Page 370: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

17.17. Declarando VariáveisDeclarando Variáveis

On Targget Treinamento e Consultoria

Page 371: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Reconhecer um bloco PL/SQL básico e suas seções Descrever o significado de variáveis em PL/SQL Distinguir entre variáveis PL/SQL e não PL/SQL Declarar variáveis PL/SQL Executar um bloco PL/SQL

On Targget Treinamento e Consultoria 2

Page 372: Introdução ao Oracle 8i

Funções Básicas

Estrutura de um Bloco PL/SQL

PL/SQL é uma linguagem de blocos estruturados, significando que programas pode ser divididos em blocos lógicos. Um bloco PL/SQL é composto de até três seções: declarativa (opcional), executável (obrigatória) e de tratamento de exceções (opcional). Somente as palavras chaves BEGIN e END são obrigatórias. Você pode declarar variáveis locais no bloco que as utiliza. Condições de erro (conhecidas como exceções) podem ser tratadas especificamente dentro do bloco para a qual elas se aplicam. Você pode armazenar e modificar valores dentro de um bloco PL/SQL declarando e referenciando variáveis e outros identificadores.

A tabela abaixo descreve as três seções de bloco.

Seção Descrição Inclusão

DeclarativaContém todas as variáveis, constantes, cursores e exceções definidas pelo usuário que são referenciadas nas seções executável e declarativa

Opcional

ExecutávelContém os comandos SQL para manipular os dados no banco de dados e os comandos PL/SQL para manipular os dados no bloco

Obrigatória

Tratamento de Exceções

Especifica as ações a serem executadas quando erros e condições anormais acontecerem na seção executável

Opcional

On Targget Treinamento e Consultoria 3

Page 373: Introdução ao Oracle 8i

Funções Básicas

Executando Comandos e Blocos PL/SQL a partir do SQL*Plus

Coloque um ponto-e-vírgula (;) no final de um comando SQL ou comando de controle PL/SQL.

Coloque um barra (/) para executar o bloco PL/SQL anônimo no SQL buffer. Quando o bloco é executado com sucesso, sem erros não tratados ou erros de compilação, a mensagem resultante deve ser como a seguinte:

Coloque um ponto (.) para fechar o SQL buffer. Um bloco PL/SQL é tratado como um comando contínuo no buffer, e os ponto-e-vírgula dentro do bloco não fecham ou executam o buffer.

Nota: Em PL/SQL, um erro é chamado de exceção.

Palavras chaves de seção como DECLARE, BEGIN e EXCEPTION não são seguidas por ponto-e-vírgula. Entretanto, END e todas os outros comandos PL/SQL exigem um ponto-e-vírgula para terminar o comando. Você pode escrever vários comandos na mesma linha. Porém, este método não é recomendado para clareza e edição.

On Targget Treinamento e Consultoria 4

PL/SQL procedure successfully completed

Page 374: Introdução ao Oracle 8i

Funções Básicas

Tipos de Blocos

Cada unidade de PL/SQL pode possuir um ou mais blocos. Estes blocos podem ser completamente separados ou aninhados um dentro do outro. As unidades básicas (procedures e funções, também conhecidas como subprogramas, e blocos anônimos) que fazem um programa PL/SQL são blocos lógicos, que podem conter qualquer número de subblocos aninhados. Portanto um bloco pode representar uma pequena parte de outro bloco, que por sua vez pode ser parte de uma unidade inteira de código. Dos dois tipos de construções disponíveis em PL/SQL, blocos anônimos e subprogramas, apenas blocos anônimos são discutidos neste curso.

Blocos anônimos

Blocos anônimos são blocos sem um nome específico. Eles são declarados em um ponto de uma aplicação onde eles serão executados e passados ao PL/SQL engine em tempo de execução. Você pode inserir um bloco anônimo dentro de um programa dos pré-compiladores e dentro do SQL*Plus ou Server Manager. Triggers dos componentes do Developer/2000 consistem deste tipo de bloco.

Subprogramas

Subprogramas são blocos PL/SQL nomeados que podem receber parâmetros e serem invocados. Você pode os declarar como procedures ou funções. Geralmente você utiliza uma procedure para executar uma ação e uma função para calcular um valor.

Você pode armazenar subprogramas no nível do servidor ou da aplicação. Utilizando os componentes do Developer/2000 (Forms, Reports e Graphics) você pode declarar procedures e funções como parte da aplicação (um form ou report), e executá-las a partir de outras procedures, funções e triggers dentro da mesma aplicação sempre que necessário.

Nota: Uma função é semelhante a uma procedure, a não ser pelo fato de que uma função deve retornar um valor.

On Targget Treinamento e Consultoria 5

Page 375: Introdução ao Oracle 8i

Funções Básicas

Construções de Programas

A tabela abaixo exibe uma variedade de construções diferentes de programas PL/SQL que utilizam um bloco PL/SQL básico. Eles estão disponíveis dependendo do ambiente onde serão executados.

Construção Descrição Disponibilidade

Blocos Anônimos

Blocos PL/SQL não nomeados que são inseridos dentro de um aplicação ou executados de forma interativa

Todos os ambientes PL/SQL

Stored procedure ou função

Bloco PL/SQL nomeado armazenado dentro do Servidor Oracle que pode receber parâmetros e ser invocado repetidamente pelo nome

Servidor Oracle

Procedure ou função de Aplicação

Bloco PL/SQL nomeado armazenado dentro de uma aplicação Developer/2000 ou biblioteca compartilhada que pode receber parâmetros e ser invocado repetidamente pelo nome

Componentes do Developer/2000

PackageMódulo PL/SQL nomeado que agrupa procedures, funções e identificadores relacionados

Servidor Oracle e componentes do Developer/2000

Trigger de Banco de Dados

Bloco PL/SQL que é associado com uma tabela do banco de dados e executado automaticamente quando ativado por comandos DML

Servidor Oracle

Trigger de Aplicação

Bloco PL/SQL que é associado com um evento de aplicação e executado automaticamente

Componentes do Developer/2000

On Targget Treinamento e Consultoria 6

Page 376: Introdução ao Oracle 8i

Funções Básicas

Utilização de Variáveis

Com PL/SQL você pode declarar variáveis e então utilizá-las em comando SQL e procedurais em qualquer lugar onde uma expressão pode ser utilizada.

Armazenamento temporário de dadosDados podem ser temporariamente armazenados em uma ou mais variáveis para posterior utilização no fluxo de processamento dos dados.

Manipulação de valores armazenadosVariáveis podem ser utilizadas para cálculos e outras manipulações de dados sem acessar o banco de dados.

ReutilizaçãoUma vez declaradas, as variáveis podem ser utilizadas repetidamente dentro de uma aplicação simplesmente referenciando-as dentro de outros comandos, inclusive outros comandos de declaração.

Facilidade de manutençãoQuando utilizar %TYPE e %ROWTYPE (maiores informação sobre %ROWTYPE será visto em um capítulo subseqüente) você declara variáveis, baseando as declarações nas definições de colunas do banco de dados. Variáveis PL/SQL ou variáveis de cursor previamente declaradas dentro do escopo atual também podem utilizar o atributo %TYPE e %ROWTYPE como especificadores de tipo de dado. Se uma definição mudar, a variável declarada com um destes atributos também se modifica em tempo de execução. Isto fornece independência de dados, reduz custos de manutenção e permite que programas se adptem as mudanças do banco de dados para satisfazer novas necessidades do negócio.

On Targget Treinamento e Consultoria 7

Page 377: Introdução ao Oracle 8i

Funções Básicas

Tratando Variáveis em PL/SQL

Declare e inicialize variáveis dentro da seção de declaração.Você pode declarar variáveis na parte declarativa de qualquer bloco PL/SQL, subprograma ou package. Declarações alocam espaço de armazenamento para um valor, especificam seu tipo de dado e nomeiam a localização de armazenamento de forma que você possa referenciá-la. Declarações também podem atribuir um valor inicial e impor a constraint NOT NULL.

Atribua novos valores a variáveis dentro da seção executável.O valor existente da variável é substituído pelo novo.Você deve declarar uma variável antes de referenciá-la em outros comandos, inclusive outros comandos de declaração.

Passe valores para subprogramas PL/SQL através de parâmetros.Existem três modos de passar parâmetros: IN (default), OUT e IN OUT. Você utiliza um parâmetro IN para passar valores para o subprograma chamado. Você utiliza um parâmetro OUT para retornar valores para quem executou o subprograma. E você utiliza o parâmetro IN OUT para passar valores iniciais para o subprograma chamado e retornar valores atualizados ao chamador.

Visualize os resultados de um bloco PL/SQL através de variáveis de saída.Você pode usar variáveis de referência como entrada ou saída de comandos SQL de manipulação de dados.

On Targget Treinamento e Consultoria 8

Page 378: Introdução ao Oracle 8i

Funções Básicas

Tipos de Variáveis

Todas as variáveis PL/SQL possuem um tipo de dado, que especifica um formato de armazenamento, constraints e faixas de valores válidos. O PL/SQL suporta quatro categorias de tipos de dados: escalares, compostos, de referência e LOB (large object), que você pode utilizar para declarar variáveis, constantes e ponteiros.

Tipos de dados escalares armazenam um único valor. Os principais tipos de dados desta categoria correspondem aos tipos das colunas de tabelas do Servidor Oracle; PL/SQL também suporta variáveis do tipo BOOLEAN.

Tipos de dados compostos como registros permitem definir e manipular grupos de campos em blocos PL/SQL.

Tipos de dados de referência armazenam valores, chamados de ponteiros, que designam outros itens de programa.

Tipos de dados LOB armazenam valores, chamados de localizadores, que especificam a localização de objetos grandes (imagens gráficas por exemplo) que são armazenados fora da linha.

Variáveis não PL/SQL incluem variáveis host de linguagem declaradas em programas pré-compiladores, campos de tela em aplicações Forms e variáveis host do SQL*Plus.

Variáveis de substituição no SQL*Plus permitem armazenar porções da sintaxe do comando e então editá-las antes do comando ser executado.

On Targget Treinamento e Consultoria 9

Page 379: Introdução ao Oracle 8i

Funções Básicas

Declarando Variáveis PL/SQL

Você precisa declarar todos os identificadores PL/SQL dentro da seção de declaração antes de referenciá-los dentro do bloco PL/SQL. Você possui a opção de atribuir um valor inicial. Você não precisa atribuir um valor a uma variável para declará-la. Se você referenciar outras variáveis em uma declaração, tenha certeza de tê-las declarado previamente em outro comando.

Sintaxe:

identifier é o nome da variável.

CONSTANT garante que o valor da variável não pode ser modificado; constantes devem ser inicializadas.

datatype é um tipo de dado escalar, composto, de referência ou LOB.

NOT NULL garante que a variável deve conter um valor; variáveis NOT NULL devem ser inicializadas.

expr é qualquer expressão PL/SQL que pode ser uma literal, outra variável ou uma expressão envolvendo operadores e funções.

Diretrizes

A expressão atribuída pode ser uma literal, outra variável ou uma expressão envolvendo operadores e funções.

Nomeie o identificador de acordo com as mesmas regras utilizadas para objetos SQL. Você pode utilizar convenções de nomenclatura, como por exemplo v_name para

representar uma variável e c_name para representar uma variável constante. Inicialize a variável com uma expressão utilizando o operador de atribuição (:=) ou com a

palavra reservada DEFAULT. Se você não atribuir um valor inicial, a nova variável será nula por default até que você atribua uma valor posteriormente.

Se você utilizar a constraint NOT NULL, você deve atribuir um valor. Declarando apenas um identificador por linha o código torna-se mais legível e facil de

manter. Em declarações de constantes, a palavra chave CONSTANT deve preceder o especificador

de tipo. A declaração abaixo nomeia uma constante com o tipo de dado REAL (sub-tipo de NUMBER) e atribui o valor de 50000 para a constante. Uma constante deve ser inicializada em sua declaração, caso contrário ocorre um erro de compilação quando a declaração for executada.

On Targget Treinamento e Consultoria 10

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

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

v_sal CONSTANT REAL := 50000.00;

Page 380: Introdução ao Oracle 8i

Funções Básicas

Regras de Nomenclatura

Dois objetos podem possuir o mesmo nome, desde que sejam definidos em blocos diferentes. Onde eles coexistem, somente o objeto declarado no bloco atual pode ser utilizado.

Você não deve utilizar o mesmo nome (identificador) para uma variável que o nome de colunas de tabelas utilizadas no bloco. Se ocorrer a situação de variáveis PL/SQL em comandos SQL possuírem o mesmo nome de uma coluna, o Servidor Oracle assume que somente a coluna está sendo referenciada. Embora o código de exemplo acima funcione; o código escrito utilizando o mesmo nome para uma tabela do banco de dados e para o nome de uma variável não é fácil de ler nem de manter.

Considere a adoção de convenções de nomenclatura para vários objetos como no exemplo abaixo. Utilizando v_ como prefixo para representar variáveis e g_ para representar variáveis globais, você evita conflitos de nomes objetos do banco de dados.

Nota: Identificadores não deve ser maiores que 30 caracteres. O primeiro caractere deve ser uma letra; os demais caracteres podem ser letras, números ou símbolos especiais.

On Targget Treinamento e Consultoria 11

DECLARE v_hiredate date g_deptno number(2) NOT NULL := 10;BEGIN...

Page 381: Introdução ao Oracle 8i

Funções Básicas

Atribuindo Valores para Variáveis

Para atribuir ou reatribuir um valor para uma variável, você escreve um comando de atribuição PL/SQL. Você deve explicitamente nomear a variável para receber o novo valor à esquerda do operador de atribuição (:=).

Sintaxe:

identifier é o nome de uma variável escalar.

expr pode ser uma variável, literal ou chamada de função, mas não uma coluna do banco de dados.

Outra forma de atribuir valores para variáveis é selecionar ou recuperar valores do banco de dados para elas. No exemplo abaixo, você calcula 10% de gratificação quando seleciona o salário de um empregado e a atribui para uma variável chamada "BONUS".

Então você pode utilizar a variável BONUS em outro cálculo ou inserir seu valor em uma tabela do banco de dados.

Nota: Para atribuir um valor para uma variável a partir do banco de dados, utilize o comando SELECT ou FETCH.

On Targget Treinamento e Consultoria 12

identifier := expr;v_hiredate := '31-DEC-98';v_ename := 'Maduro';SQL> SELECT sal * 0.10 2 INTO bonus 3 FROM emp 4 WHERE empno = 7369;

Page 382: Introdução ao Oracle 8i

Funções Básicas

Utilizando Variáveis e Palavras Chaves

Variáveis são inicializadas cada vez que um bloco ou subprograma é executado. Por default, variáveis são inicializadas com NULL. A menos que você inicialize uma variável explicitamente, seu valor é indefinido (nulo).

Utilize o operador de atribuição (:=) para variáveis que não possuem um valor padrão.

Uma vez que o formato de data default configurado dentro do Servidor Oracle pode diferir de banco de dados para banco de dados, você deve atribuir valores de data de forma genérica, como no exemplo anterior.

DEFAULT: Você pode utililzar a palavra chave DEFAULT ao invés do operador de atribuição para inicializar variáveis. Utilize DEFAULT para variáveis que possuem um valor padrão.

NOT NULL: Imponha a constraint NOT NULL quando uma variável deve conter um valor. Você não pode atribuir nulos para uma variável definida como NOT NULL. A constraint NOT NULL deve ser seguida por uma cláusula de inicialização.

Nota: String literais devem ser incluídas entre aspas simples. Se existir uma aspa simples dentro da string, repita uma aspa duas vezes, por exemplo: 'Account wasn''t found'.

On Targget Treinamento e Consultoria 13

v_hiredate := to_date('15-SEP-99', 'DD-MON-YY');g_mgr NUMBER(4) DEFAULT 7839;v_location VARCHAR2(13) NOT NULL := 'CHICAGO';

Page 383: Introdução ao Oracle 8i

Funções Básicas

Tipos de Dados Escalares

Um tipo de dado escalar armazena um único valor e não possui componentes internos. Tipos de dados escalares podem ser classificados em quatro categorias: numérico, caractere, data e booleano. Tipos de dados caractere e numérico possuem subtipos que associam um tipo básico a uma constraint. Por exemplo, INTEGER e POSITIVE são subtipos do tipo básico NUMBER.

Tipo de Dado DescriçãoVARCHAR2 (maximum_length)

Tipo básico para dados caractere de tamanho variável de até 32767 bytes. Não existe tamanho default para variáveis e constantes tipo VARCHAR2.

NUMBER[(precision, scale)]

Tipo básico para números fixos e de ponto flutuante.

DATETipo básico para data e hora. Valores tipo DATE incluem a hora do dia em segundos desde a meia-noite. A faixa de valores de datas está entre 4712 AC e 9999 DC.

CHAR [(maximum_length)]

Tipo básico para dados caractere de tamanho fixo de até 32767 bytes. Se você não especificar um maximum_length, o tamanho default é setado para 1.

LONGTipo básico para dados caractere de tamanho variável de até 32760 bytes. O tamanho máximo de uma coluna tipo LONG do banco de dados é 2147483647 bytes.

LONG RAWTipo básico para dados binários e strings tipo byte de até 32760 bytes. Dados LONG RAW não são interpretados pelo PL/SQL.

BOOLEANTipo básico que armazena um de três valores possíveis utilizado para cálculos lógicos: TRUE, FALSE ou NULL.

BINARY_INTEGER Tipo básico para inteiros entre -2147483647 e 2147483647.

PLS_INTEGERTipo básico para inteiros com sinal entre -2147483647 e 2147483647. Valores PLS_INTEGER necessitam de menos espaço de armazenamento e são mais rápidos que valores NUMBER e BINARY_INTEGER.

Nota: O tipo de dado LONG é semelhante ao VARCHAR2, a não ser pelo tamanho máximo de um valor LONG que é de 32,760 bytes. Portanto, valores maiores que 32,760 não podem ser selecionados a partir de uma coluna do banco de dados tipo LONG em uma variável PL/SQL tipo LONG.

On Targget Treinamento e Consultoria 14

Page 384: Introdução ao Oracle 8i

Funções Básicas

Declaração de Variáveis Escalares

Os exemplos de declaração de variáveis apresentados acima são definidos como segue:

Variável declarada para armazenar um cargo de empregado. Variável declarada para contar as repetições de um loop e inicializada com 0. Variável declarada para acumular o salário total para um departamento e inicializada com

0. Variável declarada para armazenar a data de expedição de um pedido e inicializada com

uma data uma semana à frente. Variável constante declarada para uma taxa de imposto que não se modifica durante a

execução do bloco PL/SQL. Flag declarado para indicar se uma parte dos dados está válida ou inválida e inicializada

com TRUE.

On Targget Treinamento e Consultoria 15

v_job VARCHAR2(9);v_count BINARY_INTEGER := 0;v_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;

Page 385: Introdução ao Oracle 8i

Funções Básicas

Atributo %TYPE

Quando você declara variáveis PL/SQL para armazenar valores de coluna estima, você deve garantir que a variável seja do tipo de dado correto. Caso contrário, um erro PL/SQL poderá acontecer durante a execução.

Ao invés de codificar o tipo de dado e a precisão de uma variável, você pode utilizar o atributo %TYPE para declarar uma variável de acordo com outra variável previamente declarada ou coluna do banco de dados. O atributo %TYPE é freqüentemente utilizado quando o valor armazenado em uma variável é derivado de uma tabela do banco de dados ou se a variável é destinada a ser escrita nela. Para utilizar o atributo no lugar do tipo de dado necessário na declaração da variável, prefixe a variável com o nome da tabela e coluna do banco de dados. Se estiver se referenciando a uma variável previamente declarada, prefixe o atributo com o nome da variável.

O PL/SQL determina o tipo de dado e tamanho da variável quando o bloco é compilado, e desta forma permanece sempre compatível com a coluna utilizada para popular a variável. Esta é definitivamente uma vantagem para escrever e manter o código, uma vez que não há necessidade de se alterar o programa para refletir mudanças no tipo de dado da coluna a nível do banco de dados. Você também pode declarar uma variável de acordo com outra previamente declarada prefixando o atributo %TYPE com o nome desta variável.

On Targget Treinamento e Consultoria 16

Page 386: Introdução ao Oracle 8i

Funções Básicas

Declarando Variáveis com o Atributo %TYPE

Declare variáveis para armazenar o nome de um empregado.

Declare variáveis para armazenar o saldo de uma conta bancária, como também o saldo mínimo que inicia com 10.

A constraint NOT NULL da coluna não se aplica as variáveis declaradas utilizando o atributo %TYPE. Portanto, se você declara um variável utilizando o atributo %TYPE utilizando uma coluna do banco de dados definida como NOT NULL, você pode atribuir o valor NULL para a variável.

On Targget Treinamento e Consultoria 17

...v_ename emp.ename%TYPE;...

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

Page 387: Introdução ao Oracle 8i

Funções Básicas

Declarando Variáveis BOOLEAN

Com PL/SQL você pode comparar variáveis em comandos SQL e procedurais. Estas comparações, chamadas expressões boleanas, consistem em expressões simples ou complexas separadas por operadores relacionais. Em um comando SQL, você pode utilizar expressões boleanas para especificar as linhas de uma tabela que devem ser afetadas pelo comando. Em um comando procedural, expressões boleanas são a base para o controle condicional.

Exemplos:

A expressão seguinte retorna TRUE:

Declare e inicialize uma variável boleana:

On Targget Treinamento e Consultoria 18

v_sal1 := 50000;v_sal2 := 60000;v_sal1 < v_sal2v_comm_sal BOOLEAN := (v_sal1 < v_sal2);

Page 388: Introdução ao Oracle 8i

Funções Básicas

Tipos de Dados Compostos

Tipos de dados compostos (também conhecidos como coleções) são TABLE, RECORD, nested TABLE (tabela aninhada) e VARRAY. Você utiliza o tipo de dado RECORD para tratar dados relacionadas, porém diferentes, como uma unidade lógica. Você utiliza o tipo de dado TABLE para referênciar e manipular coleções de dados como um objeto. Os tipos de dados RECORD e TABLE serão apresentados em detalhes em um capítulo subseqüente.

On Targget Treinamento e Consultoria 19

Page 389: Introdução ao Oracle 8i

Funções Básicas

Variáveis com Tipos de Dados LOB

Com os tipos de dados LOB (large object) do Oracle8i você pode armazenar blocos de dados não estruturados (como textos, imagens gráficas, vídeos e sons) de até 4 gigabytes de tamanho. Tipos de dados LOB permitem acesso eficiente aos dados e podem ser atributos de um tipo de objeto. LOBs também suportam acesso randômico aos dados.

O tipo de dado CLOB (character large object) é utilizado para armazenar blocos grandes de dados caractere do tipo single-byte no banco de dados.

O tipo de dado BLOB (binary large object) é utilizado para armazenar objetos binários grandes no banco de dados dentro ou fora da linha.

O tipo de dado BFILE (binary file) é utilizado para armazenar objetos binários grandes em arquivos do sistema operacional fora do banco de dados.

O tipo de dado NCLOB (national language character large object) é utilizado para armazenar blocos grandes de dados NCHAR do tipo single-byte ou multi-byte de tamanho fixo no banco de dados, dentro ou fora da linha.

On Targget Treinamento e Consultoria 20

Page 390: Introdução ao Oracle 8i

Funções Básicas

Variáveis Tipo Bind

Uma variável tipo bind é uma variável que você declara em um ambiente host, e então a utiliza para passar valores em tempo de execução, para um ou mais programas PL/SQL que podem utilizá-la como qualquer outra variável. Você pode referenciar variáveis declaradas em um ambiente host ou chamador em comandos PL/SQL, a menos que o comando esteja dentro de uma procedure, função ou package. Isto inclui variáveis host de linguagem declaradas em programas pré-compiladores, campos de tela em aplicações Developer/2000 Forms e variáveis bind do SQL*Plus.

Criando Variáveis Bind

No ambiente do SQL*Plus, para declarar uma variável bind, você utiliza o comando VARIABLE. Por exemplo, você declara uma variável do tipo NUMBER da seguinte forma:

Tanto o SQL quanto o SQL*Plus podem referenciar uma variável bind, e o SQL*Plus pode exibir seu valor.

Exibindo Variáveis Bind

No ambiente do SQL*Plus, para exibir o valor atual de variáveis bind, você utiliza o comando PRINT. O exemplo abaixo ilustra um comando PRINT:

On Targget Treinamento e Consultoria 21

VARIABLE return_code NUMBERSQL> VARIABLE n NUMBER...SQL> PRINT n

Page 391: Introdução ao Oracle 8i

Funções Básicas

Referenciando Variáveis Não PL/SQL

Para referenciar variáveis host, você deve prefixar a referência com o caractere (:) para distinguir de variáveis PL/SQL declaradas.

Exemplos:

On Targget Treinamento e Consultoria 22

:g_monthly_sal := v_sal / 12;:host_var1 := v_sal;:global_var1 := 'YES';

Page 392: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 16

1. Analise cada uma das seguintes declarações. Determine qual delas não estão corretas e explique o motivo.

a.

b.

c.

d.

e.

On Targget Treinamento e Consultoria 23

DECLARE v_id NUMBER(4);DECLARE v_x, v_y, v_z VARCHAR2(10);DECLARE v_birthdate DATE NOT NULL;DECLARE v_in_stock BOOLEAN := 1;DECLARE TYPE name_table_type IS TABLE OF VARCHAR2(20) INDEX BY BINARY_INTEGER; dept_name_table name_table_type;

Page 393: Introdução ao Oracle 8i

Funções Básicas

2. Em cada uma das seguintes atribuições, determine o tipo de dado resultante da expressão.

a.

b.

c.

d.

e.

f.

3. Crie um bloco anônimo para exibir a frase “My PL/SQL Block Works” para a tela.

On Targget Treinamento e Consultoria 24

v_days_to_go := v_due_date - SYSDATE;

v_sender := USER || ': ' || TO_CHAR(v_dept_no);v_sum := $100,000 + $250,000;

v_flag := TRUE;v_n1 := v_n2 > (2 * v_n3);v_value := NULL;G_MESSAGE-----------------------My PL/SQL Block Works

Page 394: Introdução ao Oracle 8i

Funções Básicas

Se houver tempo, complete os seguintes exercícios:

4. Crie um bloco que declare duas variáveis. Atribua o valor destas variáveis PL/SQL para variáveis host do SQL*Plus e mostre os resultados das variáveis PL/SQL na tela. Execute o bloco PL/SQL. Salve o bloco PL/SQL para um arquivo chamado e16q4.sql.

Atribua valores para estas variáveis como segue:

On Targget Treinamento e Consultoria 25

V_CHAR Character (tamanho variável)V_NUM NumberVariável Valor-------- -------------------------------------V_CHAR A literal '42 is the answer'V_NUM Os dois primeiros caracteres de V_CHAR

Page 395: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

18.18. Escrevendo ComandosEscrevendo Comandos ExecutáveisExecutáveis

On Targget Treinamento e Consultoria

G_CHAR---------------------42 is the answer

G_NUM---------42

Page 396: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Reconhecer o significado da seção executável Escrever comandos dentro da seção executável Descrever as regras do aninhamento de blocos Executar e testar um bloco PL/SQL Utilizar convenções de codificação

On Targget Treinamento e Consultoria 2

Page 397: Introdução ao Oracle 8i

Funções Básicas

Sintaxe e Diretrizes de um Bloco PL/SQL

Uma vez que PL/SQL é uma extensão do SQL, as regras de sintaxe gerais que se aplicam ao SQL também são aplicáveis a linguagem PL/SQL.

Unidades léxicas (por exemplo, identificadores ou literais) podem ser separadas por um ou mais espaços ou outros delimitadores que não podem ser confundidos como sendo parte da unidade léxica. Você não pode inserir espaços em unidades léxicas com exceção de strings literais e comentários.

Comandos podem ser divididas em várias linhas, porém palavras chaves não devem ser divididas.

Delimitadores

Delimitadores são símbolos simples ou compostos que possuem significado especial para PL/SQL.

Símbolos Simples Símbolos CompostosSímbolo Significado Símbolo Significado

+ Operador de Adição <> Operador Relacional- Operador de Subtração/Negação != Operador Relacional* Operador de Multiplicação || Operador de Concatenação/ Operador de Divisão -- Indicador de Comentário em Linha= Operador Relacional /* Delimitador de Ínico de Comentário@ Indicador de Acesso Remoto */ Delimitador de Final de Comentário; Terminador de Comando := Operador de Atribuição

Identificadores

Identificadores são utilizados para nomear itens e unidades de programas PL/SQL, que incluem constantes, variáveis, exceções, cursores, variáveis de cursor, subprogramas e packages.

Identificadores podem conter até 30 caracteres, mas devem iniciar com um caractere alfabético.

Não escolha o mesmo nome para um identificador que colunas de uma tabela utilizada no bloco. Se identificadores PL/SQL que estão no mesmo comando SQL possuem o mesmo nome de uma coluna, então o Oracle assume que somente a coluna está sendo referenciada.

Não podem ser utilizadas palavras reservadas como identificadores a menos que elas sejam colocadas entre aspas duplas (por exemplo, "SELECT").

On Targget Treinamento e Consultoria 3

Page 398: Introdução ao Oracle 8i

Funções Básicas

Literais

Um literal é um valor numérico, caractere, string ou boleano explícito não representado por um identificador.

Literais caractere incluem todos os caracteres imprimíveis no conjunto de caracteres PL/SQL: letras, números, espaços e símbolos especiais. Literais caractere e data devem ser colocados entre aspas simples.

Literais numéricos podem ser representados por um valor simples (por exemplo, -32.5) ou através de notação científica (por exemplo, 2E5, significando 2*10 para a potência 5 = 200000).

On Targget Treinamento e Consultoria 4

v_ename := 'Henderson';

Page 399: Introdução ao Oracle 8i

Funções Básicas

Comentando o Código

Comente o código para documentar cada fase e auxiliar na depuração. Comente o código PL/SQL com dois hífens (--) se o comentário está em uma única linha, ou inclua o comentário entre os símbolos / * e * / se o comentário estiver em várias linhas. Bem colocados, comentários são extremamente valiosos para a clareza do código e futuras manutenções.

Exemplo:

Calcule o salário anual a partir do salário mensal.

On Targget Treinamento e Consultoria 5

... v_sal NUMBER(9,2);BEGIN /* Calcule o salário anual baseado no salário mensal fornecido pelo usuário */ v_sal := v_sal*12;END; -- Este é o final da transação

Page 400: Introdução ao Oracle 8i

Funções Básicas

Funções SQL em PL/SQL

A maioria das funções disponíveis em SQL também são válidas em expressões PL/SQL:

Funções numéricas Funções de caractere Funções de conversão de tipos de dados Funções de data Funções genéricas

As seguintes funções não estão disponíveis em comandos procedurais:

DECODE Funções de grupo: AVG, MIN, MAX, COUNT, SUM, STDDEV e VARIANCE. Funções

de grupo aplicam-se a grupos de linhas em uma tabela e portanto só estão disponíveis dentro de comandos SQL em um bloco PL/SQL

Exemplo:

Calcule a soma de todos os números armazenados na PL/SQL table NUMBER_TABLE. Este exemplo produz um erro de compilação.

On Targget Treinamento e Consultoria 6

v_total := SUM(number_table);

Page 401: Introdução ao Oracle 8i

Funções Básicas

Funções PL/SQL

O PL/SQL fornece muitas funções para auxiliar a manipulação de dados. Estas funções dividem-se nas seguintes categorias:

Informações de Erros Numéricas Caractere Conversão Data Genéricas

Exemplos:

Construa o endereço para uma empresa.

Converta o nome do empregado para minúsculas.

CHR é a função SQL que converte um código ASCII para o caractere correspondente; 10 é o código para uma quebra de linha.

On Targget Treinamento e Consultoria 7

v_mailing_address := v_name||CHR(10)||v_address||CHR(10)||v_state||CHR(10)||v_zip;

v_ename := LOWER(v_ename);

Page 402: Introdução ao Oracle 8i

Funções Básicas

Conversão de Tipos de Dados

O PL/SQL tenta converter dinamicamente os tipos de dados se eles forem diferentes dentro de um comando. Por exemplo, se você atribuir um valor do tipo NUMBER para uma variável do tipo CHAR, então o PL/SQL dinamicamente traduz o número em uma representação de caracteres, de forma que ele possa ser armazenado em uma variável tipo CHAR. A situação inversa também se aplica.

Desde que sejam compatíveis, você também pode atribuir caracteres para variáveis tipo DATE, e vice-versa.

Dentro de uma expressão, você deve garantir que os tipos de dados sejam os mesmos. Se tipos de dados diferentes estiverem em uma expressão, você deve utilizar a função de conversão apropriada para converter os dados.

Sintaxe:

Onde:

value é uma string de caracteres, números ou datas.

fmt é o modelo de formato utilizado para converter o valor.

Armazene um valor que composto do nome do usuário e da data atual. Este código causa um erro de compilação.

Para corrigir o erro, converta SYSDATE para uma striing de caracteres com a função de conversão TO_CHAR.

O PL/SQL tenta converter se possível, mas o sucesso depende das operações que são executadas. É uma boa prática de programação executar explicitamente as conversões de tipos de dados, porque elas podem afetar o desempenho de forma favoravel e podem permanecer válidas até mesmo com uma mudança em versões do software.

On Targget Treinamento e Consultoria 8

TO_CHAR (value, fmt)

TO_DATE (value, fmt)

TO_NUMBER (value, fmt)

v_comment := USER||': '||SYSDATE;v_comment := USER||': '||TO_CHAR(SYSDATE);

Page 403: Introdução ao Oracle 8i

Funções Básicas

Blocos Aninhados e Escopo de Variáveis

Blocos Aninhados

Um das vantagens que PL/SQL possui sobre SQL é a possibilidade de aninhar declarações. Você pode aninhar blocos onde quer que um comando executável seja permitido e tornando o bloco aninhado desta forma um comando. Portanto você pode dividir uma parte executável de um bloco em blocos menores. A seção de exceção também pode conter blocos aninhados.

Escopo de Variáveis

O escopo de um objeto é a região do programa que pode se referenciar ao objeto. Você pode referenciar a variável declarada dentro da seção executável.

Identificadores

Um identificador é visível no bloco no qual é declarado e em todos os subblocos aninhados, procedures e funções. Se o bloco não encontrar o identificador declarado localmente, ele procura na seção declarativa do bloco externo (bloco pai). O bloco nunca procura para baixo nos blocos inclusos (blocos filhos) ou lateralmente para blocos de mesmo nível.

O escopo se aplica para todos os objetos declarados, incluindo variáveis, cursores, exceções definidas pelo usuário e constantes.

Nota: Qualifique um identificador utilizando como prefixo o label do bloco.

Blocos Aninhados e Escopo de Variáveis

No bloco aninhado mostrado no gráfico acima, a variável y pode referenciar a variável x. A variável x, entretanto, não pode referenciar a variável y. Se a variável y no bloco aninhado tivesse recebido o mesmo nome da variável x do bloco externo o valor seria válido somente durante a execução do bloco aninhado.

Escopo

O escopo de um identificador é aquela região de uma unidade de programa (bloco, subprograma ou package) na qual você pode referenciar o identificador.

On Targget Treinamento e Consultoria 9

Page 404: Introdução ao Oracle 8i

Funções Básicas

Operadores em PL/SQL

As operações dentro de uma expressão são executadas em uma ordem específica que depende de sua precedência (prioridade). A tabela abaixo mostra a ordem default de operações de cima para baixo.

Operador Operação**, NOT Exponenciação, negação lógica*, / Multiplicação, divisão+, -, || Adição, subtração, concatenação=, !=, <, >, <=, >=, IS NULL, LIKE, BETWEEN, IN

Comparação

AND Operador lógico ANDOR Operador lógico OR

Nota: Não é necessário utilizar parênteses com expressões boleanas, embora eles tornem o texto fácil de ler.

Exemplos

Incremente o índice para um loop.

Atribua o valor de um flag boleano.

Valide o número de um empregado se ele possuir um valor.

Quando trabalhar com valores nulos, você pode evitar alguns enganos comuns lembrando-se das seguintes regras:

Comparações que envolvem nulos sempre retornam NULL Aplicando o operador lógico NOT para um nulo o retorno é NULL Em comandos de controle condicionais, se a condição retornar NULL, a seqüência de

comandos associada não é executada

On Targget Treinamento e Consultoria 10

v_count := v_count + 1;v_equal := (v_n1 = v_n2);v_valid := (v_empno IS NOT NULL);

Page 405: Introdução ao Oracle 8i

Funções Básicas

Utilizando Variáveis Bind

Para referenciar uma variável bind em PL/SQL, você deve prefixar seu nome com o caractere (:).

Exibindo Variáveis Bind

No SQL*Plus você pode exibir o valor da variável bind utilizando o comando PRINT.

On Targget Treinamento e Consultoria 11

DECLARE v_sal emp.sal%TYPE;BEGIN SELECT sal INTO v_sal FROM emp WHERE empno = 7369; :salary := v_sal;END;

SQL> PRINT salary

SALARY------ 800

Page 406: Introdução ao Oracle 8i

Funções Básicas

Diretrizes de Programação

Torne a manutenção do código mais simples:

Documentando o código com comentários Desenvolvendo convenções para o código Desenvolvendo convenções de nomenclatura para identificadores e outros objetos Melhore a clareza do programa identando o código

Siga estas regras de programação para produzir um código mais claro e reduzir a manutenção quando desenvolver um bloco PL/SQL.

Convenções de Código

A tabela abaixo fornece diretrizes para escrever o código em maiúsculas ou minúsculas para ajudar a distinguir palavras chaves de nomes de objetos.

Categoria Convenção ExemplosComandos SQL Maiúsculas SELECT, INSERTPalavras chave PL/SQL Maiúsculas DECLARE, BEGIN, IFTipos de dados Maiúsculas VARCHAR2, BOOLEANIdentificadores e parâmetros Minúsculas v_sal, emp_cursor, g_sal, p_empnoTabela e colunas do banco Minúsculas emp, orderdate, deptno

On Targget Treinamento e Consultoria 12

Page 407: Introdução ao Oracle 8i

Funções Básicas

Convenções de Nomenclatura

Evite ambigüidade:

Os nomes de variáveis locais e parâmetros possuem precedência sobre os nomes de tabelas do banco de dados.

Os nomes de colunas possuem precedência sobre os nomes de variáveis locais.

A tabela abaixo exibe um conjunto de prefixos e sufixos para distinguir identificadores de outros identificadores, de objetos de banco de dados e de outros nomes de objetos.

Identificador Convenção de Nomes ExemploVariável v_name v_salConstante c_name c_company_nameCursor name_cursere emp_cursorExceção e_name e_too_manyTipo de PL/SQL table name_table_type amount_table_typePL/SQL table Name_table order_total_tableTipo de PL/SQL record name_record_type emp_record_typePL/SQL record name_record customer_recordParâmetro de substituição do SQL*Plus

p_name p_sal

Variável global do SQL*Plus g_name g_year_sal

On Targget Treinamento e Consultoria 13

Page 408: Introdução ao Oracle 8i

Funções Básicas

Identando o Código

Para maior clareza idente cada nível do código. Compare os seguintes comandos IF:

Exemplos:

On Targget Treinamento e Consultoria 14

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

BEGIN IF x=0 THEN y=1; END IF;END;

DECLARE v_detpno NUMBER(2); v_location VARCHAR2(13);BEGIN SELECT deptno,

location INTO v_deptno,

v_location FROM dept WHERE dname = 'SALES';...END;

Page 409: Introdução ao Oracle 8i

Funções Básicas

Determine o Escopo das Variáveis

Avalie o bloco PL/SQL acima. Determine cada um dos seguintes valores de acordo com as regras de escopo.

1. O valor de V_MESSAGE no sub-bloco.

2. O valor de V_TOTAL_COMP no bloco principal.

3. O valor de V_COMM no sub-bloco.

4. O valor de V_COMM no bloco principal.

5. O valor de V_MESSAGE no bloco principal.

On Targget Treinamento e Consultoria 15

Page 410: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 17

Bloco PL/SQL

1. Avalie o bloco PL/SQL acima e determine cada um dos seguintes valores de acordo com as regras de escopo.

a. O valor de V_WEIGHT no sub-bloco

b. O valor de V_NEW_LOCN no sub-bloco

c. O valor de V_WEIGHT no bloco principal

d. O valor de V_MESSAGE no bloco principal

e. O valor de V_NEW_LOCN no bloco principal

On Targget Treinamento e Consultoria 16

DECLARE v_weight NUMBER(3) := 600; v_message VARCHAR2(255) := 'Product 10012';BEGIN

SUB-BLOCO 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; END;

v_weight := v_weight + 1; v_message := v_message || ' is in stock'; v_new_locn := 'Western ' || v_new_locn;

END;

Page 411: Introdução ao Oracle 8i

Funções Básicas

Exemplo de Escopo

2. Suponha que você inseriu um sub-bloco dentro de um bloco, como apresentado acima. Você declarou duas variáveis, V_CUSTOMER e V_CREDIT_RATING, no bloco principal. Você também declarou duas variáveis, V_CUSTOMER e V_NAME, no sub-bloco. Determine os valores para cada um dos seguintes casos.

a. O valor de V_CUSTOMER no sub-bloco

b. O valor de V_NAME no sub-bloco

c. O valor de V_CREDIT_RATING no sub-bloco

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

On Targget Treinamento e Consultoria 17

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_customer v_name v_credit_rating

END;

v_customer v_name v_credit_rating

END;

Page 412: Introdução ao Oracle 8i

Funções Básicas

3. Crie e execute um bloco PL/SQL que receba dois números através de variáveis de substituição do SQL*Plus. O primeiro número deve ser dividido pelo segundo número e então o segundo número deve ser adicionado ao resultado. O resultado deve ser escrito para uma variável PL/SQL e mostrado na tela.

4. Construa um bloco PL/SQL que calcule a gratificação total para um ano. O salário anual e o percentual de bônus anual são passados para o bloco PL/SQL através de variáveis de substituição e o bônus precisa ser convertido de um número inteiro para um número decimal (por exemplo, 15 para .15). Se o salário for nulo, atribua ele para zero antes de calcular a gratificação total. Execute o bloco PL/SQL. Lembre-se: utilize a função NVL para tratar valores nulos.

Nota: Para testar a função NVL escreva NULL no prompt; pressionando [Return] resulta em um erro de expressão.

On Targget Treinamento e Consultoria 18

Please enter the first number: 2Please enter the second number: 4

PL/SQL procedure successfully completed.

V_RESULT-------- 4.5

Please enter the salary amount: 50000Please enter the bonus percentage: 10

PL/SQL procedure successfully completed.

G_TOTAL------- 55000

Page 413: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

19.19. Interagindo com o ServidorInteragindo com o Servidor OracleOracle

On Targget Treinamento e Consultoria

Page 414: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Escrever um comando SELECT em PL/SQL Declarar o tipo de dado e tamanho de variáveis PL/SQL dinamicamente Escrever comandos DML em PL/SQL Controlar transações em PL/SQL Determinar o resultado de comandos SQL DML

On Targget Treinamento e Consultoria 2

Page 415: Introdução ao Oracle 8i

Funções Básicas

Comandos SQL em PL/SQL

Quando você precisar extrair informações ou aplicar mudanças para o banco de dados, você deve utilizar SQL. O PL/SQL suporta completamente a linguagem de manipulação de dados e os comandos de controle de transação do SQL. Você pode utilizar comandos SELECT para popular variáveis com valores consultados a partir de uma linha de uma tabela. Seus comandos DML (manipulação de dados) podem processar várias linhas.

Comparando Tipos de Comando SQL e PL/SQL

Um bloco PL/SQL não é uma unidade de transação. Commits, savepoints e rollbacks são independentes de blocos, mas você pode executar estes comandos dentro de um bloco.

O PL/SQL não suporta a linguagem de definição de dados (DDL), como CREATE TABLE, ALTER TABLE ou DROP TABLE.

O PL/SQL não suporta a linguagem de controle de dados (DCL), como GRANT e REVOKE.

On Targget Treinamento e Consultoria 3

Page 416: Introdução ao Oracle 8i

Funções Básicas

Comandos SELECT em PL/SQL

Utilize o comando SELECT para recuperar dados do banco de dados.

Sintaxe:

select_list é uma lista com pelo menos uma coluna, e pode incluir expressões SQL, funções de linha ou funções de grupo.

variable_name é a variável escalar para armazenar o valor recuperado.

record_name é o PL/SQL RECORD para armazenar todos os valores recuperados.

table especifica o nome da tabela do banco de dados.

condition é composta de nomes de coluna, expressões, constantes e operadores de comparação, inclusive variáveis e constantes PL/SQL.

Tire proveito de toda a sintaxe fornecida pelo Servidor Oracle para o comando SELECT.

Lembre-se que variáveis host devem ser prefixadas com o caractere (:).

Cláusula INTO

O cláusula INTO é obrigatória e deve estar entre as cláusulas SELECT e FROM. É utilizada para especificar os nomes das variáveis para armazenar os valores que o SQL retorna da cláusula SELECT. Você deve fornecer uma variável para cada item selecionado, e a ordem delas deve corresponder aos itens selecionados.

Você utiliza a cláusula INTO para popular variáveis PL/SQL ou variáveis host.

Consultas devem Retornar uma e Somente uma Linha

Comandos SELECT dentro de um bloco PL/SQL seguem a seguinte regra: consultas devem retornar uma e somente uma linha. Mais de uma linha ou nenhuma linha causa um erro.

O PL/SQL trata destes erros retornando exceções padrões que você pode tratar na seção de tratamento de exceções do bloco com as exceções NO_DATA_FOUND e TOO_MANY_ROWS. Você deve codificar comandos SELECT de forma que retornem uma única linha.

On Targget Treinamento e Consultoria 4

SELECT select_listINTO {variable_name[, variable_name]...

| record_name}FROM tableWHERE condition;

DECLARE v_deptno NUMBER(2); v_loc VARCHAR2(15);BEGIN SELECT deptno, loc INTO v_deptno, v_loc FROM dept WHERE dname = 'SALES';...END;

Page 417: Introdução ao Oracle 8i

Funções Básicas

Recuperando Dados em PL/SQL

Recupere a data do pedido e a data de expedição para o pedido especificado:

Diretrizes

Siga estas diretrizes para recuperar dados em PL/SQL:

Termine cada comando SQL com um ponto-e-vírgula (;). A cláusula INTO é obrigatória para o comando SELECT embutido em PL/SQL. A cláusula WHERE é opcional e pode ser utilizada para especificar variáveis de entrada,

constantes, literais ou expressões PL/SQL. Especifique o mesmo número de variáveis na cláusula INTO que colunas do banco de

dados na cláusula SELECT. Esteja seguro que elas correspondam a posição da coluna e que os tipos de dados sejam compatíveis.

Para assegurar que os tipos de dados dos identificadores correspondam aos tipos de dados das colunas utilize o atributo %TYPE. O tipo de dado e número de variáveis na cláusula INTO devem corresponder aos da lista da cláusula SELECT.

Utilize funções de grupo, como SUM, em um comando SQL, porque funções de grupo aplicam-se a grupos de linhas de uma tabela.

Nota: Funções de grupo não podem ser utilizadas em sintaxes PL/SQL, elas são utilizadas em comandos SQL dentro de um bloco PL/SQL.

Exemplo:

Retorne a soma dos salários de todos os empregados do departamento especificado.

On Targget Treinamento e Consultoria 5

DECLARE v_orderdate ord.orderdate%TYPE; v_shipdate ord.shipdate%TYPE;BEGIN SELECT orderdate, shipdate INTO v_orderdate, v_shipdate FROM ord WHERE id = 157; ...END;

DECLARE v_sum_sal emp.sal%TYPE; v_deptno NUMBER NOT NULL := 10;BEGIN SELECT SUM(sal) -- group function INTO v_sum_sal FROM emp WHERE deptno = v_deptno;END;

Page 418: Introdução ao Oracle 8i

Funções Básicas

Manipulando Dados Utilizando PL/SQL

Você manipula dados no banco de dados utilizando comandos DML (manipulação de dados). Você pode executar OS comandos DML INSERT, UPDATE e DELETE sem restrições em PL/SQL. Incluindo os comandos COMMIT ou ROLLBACK no código PL/SQL, os locks de linha (e locks de tabela) são liberados.

O comando INSERT adiciona novas linhas de dados para a tabela. O comando UPDATE modifica linhas existentes da tabela. O comando DELETE remove linhas não desejadas da tabela.

On Targget Treinamento e Consultoria 6

Page 419: Introdução ao Oracle 8i

Funções Básicas

Inserindo Dados

Adicione informações de um novo empregado para a tabela EMP:

Utilize funções SQL, como USER e SYSDATE. Gere valores de chaves primárias utilizando sequences do banco de dados. Derive valores no bloco PL/SQL. Adicione valores default de coluna.

Nota: Não existe a possibilidade de ambigüidade entre identificadores e nomes de coluna no comando INSERT. Qualquer identificador na cláusula INSERT deve ser um nome de coluna do banco de dados.

On Targget Treinamento e Consultoria 7

DECLARE v_empno emp.empno%TYPE;BEGIN SELECT empno_sequence.NEXTVAL INTO v_empno FROM dual; INSERT INTO emp (empno, ename, job, deptno) VALUES(v_empno, 'HARDING', 'CLERK', 10);END;

Page 420: Introdução ao Oracle 8i

Funções Básicas

Atualizando Dados

Aumente o salário dos empregados que possuem o cargo ANALYST na tabela EMP:

Pode haver ambigüidade na cláusula SET do comando UPDATE porque embora o identificador na esquerda do operador de atribuição 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 que a cláusula WHERE é utilizada para determinar quais linhas são afetadas. Se nenhuma linha for modificada, nenhum erro acontece, ao contrário do comando SELECT em PL/SQL.

Nota: Atribuição de variáveis PL/SQL sempre utilizam := e atribuições de colunas SQL sempre utilizam =. Lembre-se que nomes de colunas e nomes de identificadores são idênticos na cláusula WHERE, o Servidor Oracle pesquisa primeiro no banco de dados pelo nome.

On Targget Treinamento e Consultoria 8

DECLARE v_sal_increase emp.sal%TYPE := 2000;BEGIN UPDATE emp SET sal = sal + v_sal_increase WHERE job = 'ANALYST';END;

Page 421: Introdução ao Oracle 8i

Funções Básicas

Removendo Dados

Remova as linhas que pertencem ao departamento 10 da tabela EMP:

Remova um pedido específico:

On Targget Treinamento e Consultoria 9

DECLARE v_deptno emp.deptno%TYPE := 10;BEGIN DELETE FROM emp WHERE deptno = v_deptno;END;

DECLARE v_ordid ord.ordid%TYPE := 605;BEGIN DELETE FROM item WHERE ordid = v_ordid;END;

Page 422: Introdução ao Oracle 8i

Funções Básicas

Convenções de Nomenclatura

Evite ambigüidade no cláusula WHERE aderindo a uma convenção de nomes que faça distinção entre colunas do banco de dados e nomes de variáveis PL/SQL.

Colunas do banco de dados e identificadores deve possuir nomes distintos. Erros de sintaxe podem surgir porque o PL/SQL confere primeiro o banco de dados por

uma coluna de tabela.

Exemplo:

Recupere a data do pedido e a data de expedição a partir da tabela ORD quando a data de expedição for igual a data atual. Este exemplo causa uma exceção não tratada em tempo de execução.

O PL/SQL confere se um identificador é uma coluna do banco de dados; caso contrário, é assumido que é um identificador do PL/SQL.

Nota: Não existe possibilidade de ambigüidade na cláusula SELECT porque qualquer identificador na cláusula SELECT deve ser um nome de coluna do banco de dados. Não existe possibilidade de ambigüidade na cláusula INTO porque identificadores na cláusula INTO devem ser variáveis PL/SQL. Somente na cláusula WHERE existe a possibilidade de confusão.

On Targget Treinamento e Consultoria 10

DECLARE order_date ord.orderdate%TYPE; ship_date ord.shipdate%TYPE; v_date DATE := SYSDATE;BEGIN SELECT orderdate, shipdate INTO order_date, ship_date FROM ord WHERE shipdate = v_date; -- unhandled exception:

-- NO_DATA_FOUNDEND;SQL> /DECLARE*ERROR at line 1:ORA-01403: no data foundORA-06512: at line 6

Page 423: Introdução ao Oracle 8i

Funções Básicas

Comandos COMMIT e ROLLBACK

Você controla a lógica de transações com os comandos SQL COMMIT e ROLLBACK, fazendo alguns grupos de modificações para o banco de dados permanente enquanto descartando outros. Com o Servidor Oracle, transações DML iniciam no primeiro comando após um COMMIT ou ROLLBACK e terminam no próximo COMMIT ou ROLLBACK executado com sucesso. Estas ações podem acontecer dentro de um bloco PL/SQL ou como resultado de eventos do ambiente de host (por exemplo, encerrando uma sessão do SQL*Plus automaticamente ocorre o COMMIT da transação pendente).

Comando COMMIT

O COMMIT encerra a transação corrente tornando todas as mudanças pendentes no banco de dados permanentes.

Sintaxe:

Onde:

WORK é para compatibilidade com o padrão ANSI.

Nota: Os comandos de controle de transação são todos válidos dentro do PL/SQL, embora o ambiente host pode colocar alguma restrição no seu uso.

Você também pode incluir comandos de lock explícitos (como LOCK TABLE e SELECT...FOR UPDATE) em um bloco. Eles permanecem em efeito até o final da transação. Também, um bloco PL/SQL necessariamente não implica em uma transação.

On Targget Treinamento e Consultoria 11

COMMIT [WORK];ROLLBACK [WORK];

Page 424: Introdução ao Oracle 8i

Funções Básicas

Cursor SQL

Sempre que você executa um comando SQL, o Servidor Oracle abre uma área de memória na qual o comando é analisado e executado. Esta área é chamada cursor.

Quando a parte executável de um bloco emite um comando SQL, o PL/SQL cria um cursor implícito que possui o identificador SQL. O PL/SQL administra este cursor automaticamente. Um cursor explícito é declarado explicitamente e é nomeado pelo programador. Existem quatro atributos disponível em PL/SQL que pode ser aplicado a cursores.

Nota: Maiores informações sobre cursores explícitos serão apresentadas em um capítulo subseqüente.

On Targget Treinamento e Consultoria 12

Page 425: Introdução ao Oracle 8i

Funções Básicas

Atributos do Cursor SQL

Atributos do cursor SQL permitem avaliar o que ocorreu quando o cursor implícito foi utilizado pela última vez. Você utiliza estes atributos em comando PL/SQL da mesma forma que as funções. Você não os pode utilizar em comandos SQL.

Você pode utilizar os atributos SQL%ROWCOUNT, SQL%FOUND, SQL%NOTFOUND e SQL%ISOPEN na seção de tratamento de exceções de um bloco para obter informações sobre a execução de um comando de manipulação de dados. O PL/SQL não considera um comando DML que não afetou nenhuma linha como uma falha, ao contrário do comando SELECT que retorna uma exceção.

Exemplo:

Remova as linhas que possuem o número de pedido especificado a partir da tabela ITEM. Mostre o número de linhas removidas.

On Targget Treinamento e Consultoria 13

VARIABLE rows_deletedDECLARE v_ordid NUMBER := 605;BEGIN DELETE FROM item WHERE ordid = v_ordid; rows_deleted := SQL%ROWCOUNT ||' rows deleted.');END;PRINT rows_deleted

Page 426: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 18

1. Crie um bloco PL/SQL que seleciona o maior número de departamento na tabela DEPT e armazene ele em uma variável do SQL*Plus. Mostre o resultado na tela. Salve o bloco PL/SQL para um arquivo chamado e18q1.sql.

2. Crie um bloco PL/SQL que insira um novo departamento na tabela DEPT. Salve o bloco PL/SQL para um arquivo chamado e18q2.sql.

a. Utilize o número de departamento recuperado no exercício 1 e adicione 10 para ele como entrada do número do departamento para o novo departamento.

b. Utilize um parâmetro para o nome do departamento.

c. Deixe a localização nula por enquanto.

d. Execute o bloco PL/SQL.

e. Mostre o novo departamento que você criou.

3. Crie um bloco PL/SQL que atualize a localização para um departamento existente. Save o bloco PL/SQL para um arquivo chamado e18q3.sql.

a. Utilize um parâmetro para o número do departamento.

b. Utilize um parâmetro para a localização do departamento.

c. Teste o bloco PL/SQL.

On Targget Treinamento e Consultoria 14

G_MAX_DEPTNO------------ 40

Please enter the department number: 50Please enter the department name: EDUCATION

PL/SQL procedure successfully completed.

DEPTNO DNAME LOC------ ---------- ----- 50 EDUCATION

Please enter the department number: 50Please enter the department location: HOUSTON

PL/SQL procedure successfully completed.

Page 427: Introdução ao Oracle 8i

Funções Básicas

d. Mostre o número, o nome e a localização para o departamento atualizado.

4. Crie um bloco PL/SQL que remova o departamento criado no exercício 2. Salve o bloco PL/SQL para um arquivo chamado e18q4.sql.

a. Utilize um parâmetro para o número do departamento.

b. Mostre na tela o número de linhas afetadas.

c. Teste o bloco PL/SQL.

d. O que acontece se você fornecer um número de departamento que não existe?

e. Confirme que o departamento foi removido.

On Targget Treinamento e Consultoria 15

DEPTNO DNAME LOC------ --------- --------------- 50 EDUCATION HOUSTON

Please enter the department number: 50PL/SQL procedure successfully completed.

G_RESULT-------------------------------------------------1 row(s) deleted.

Please enter the department number: 99PL/SQL procedure successfully completed.

G_RESULT-------------------------------------------------0 row(s) deleted.

no rows selected

Page 428: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

20.20. Escrevendo Estruturas deEscrevendo Estruturas de ControleControle

On Targget Treinamento e Consultoria

Page 429: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Identificar a utilização e os tipos de estruturas de controle Construir um comando IF Construir e identificar diferentes comandos de loop Utilizar tabelas lógicas Controlar o fluxo de um bloco utilizando loops aninhados e labels

On Targget Treinamento e Consultoria 2

Page 430: Introdução ao Oracle 8i

Funções Básicas

Controlando o Fluxo de Execução PL/SQL

Você pode modificar o fluxo lógico dos comandos dentro de um bloco PL/SQL com várias estruturas de controle. Este capítulo apresenta dois tipos de estruturas de controle PL/SQL; construções condicionais com o comando IF e estruturas de controle de LOOPs.

Existem três formas de comandos IF:

IF-THEN-END IF IF-THEN-ELSE-END IF IF-THEN-ELSIF-END IF

On Targget Treinamento e Consultoria 3

Page 431: Introdução ao Oracle 8i

Funções Básicas

Comandos IF

A estrutura do comando IF do PL/SQL é semelhante à estrutura dos comandos IF de outras linguagens procedurais. Ele permite ao PL/SQL executar ações seletivamente baseado em condições.

Sintaxe:

condition é uma variável ou expressão boleana (TRUE, FALSE ou NULL). Ela é associada com uma seqüência de comandos, que são executados somente se a expressão retornar TRUE.

THEN é uma cláusula que associa a expressão boleana que a precede com a seqüência de comandos que a seguem.

statments podem ser um ou mais comandos PL/SQL ou SQL. Eles podem conter outros comandos IF formando vários IFs, ELSEs e ELSIFs aninhados.

ELSIF é uma palavra chave que introduz uma expressão boleana. Se a primeira condição retornar FALSE ou NULL então a palavra chave ELSIF fornece condições adicionais.

ELSE é uma palavra chave que determina que a seqüência de comandos que a segue deve ser executada caso todas as condições anteriores retornem FALSE ou NULL.

Exemplo:

On Targget Treinamento e Consultoria 4

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

IF v_ename = 'OSBORNE' THEN v_mgr := 22;END IF;

Page 432: Introdução ao Oracle 8i

Funções Básicas

Comandos IF Simples

Exemplo:

Atribua o cargo para SALESMAN, o número do departamento para 35 e a comissão para 20% do salário atual se o nome do empregado for MILLER.

No exemplo acima, o PL/SQL executa duas ações (atribuindo as variáveis v_job, v_deptno e v_new_comm) somente se condição for TRUE. Se a condição for FALSE ou NULL, o PL/SQL as ignora. Em qualquer caso, o controle retoma ao próximo comando no programa após o END IF.

Diretrizes

Você pode executar ações seletivamente baseado em condições conhecidas. Quando escrever o código, lembre-se da ortografia das palavras chaves:

ELSIF é uma única palavra. END IF são duas palavras.

Se a condição boleana de controle for TRUE, a seqüência de comandos associada é executada; se a condição boleana de controle for FALSE ou NULL, a seqüência de comandos associada é ignorada. Qualquer número de cláusulas ELSIF é permitido.

Pode haver no máximo uma cláusula ELSE. Idente os comandos executados condicionalmente para maior clareza do código.

On Targget Treinamento e Consultoria 5

. . .IF v_ename = 'MILLER' THEN v_job := 'SALESMAN'; v_deptno := 35; v_new_comm := sal * 0.20;END IF;. . .

Page 433: Introdução ao Oracle 8i

Funções Básicas

Fluxo de Execução do Comando IF-THEN-ELSE

Se a condição for FALSE ou NULL, você pode utilizar a cláusula ELSE para executar outras ações. Da mesma forma que o comando IF simples, o controle retoma no programa após o END IF.

Comandos IF Aninhados

Qualquer conjunto de ações do resultado do primeiro comando IF pode incluir outros comandos IF antes das ações especificadas serem executadas. As cláusula THEN e ELSE podem incluir comandos IF. Cada comando IF aninhado deve ser terminado com um END IF correspondente.

On Targget Treinamento e Consultoria 6

IF condition1 THEN statement1;ELSE statement2;END IF;

IF condition1 THEN statement1;ELSE IF condition2 THEN statement2; END IF;END IF;

Page 434: Introdução ao Oracle 8i

Funções Básicas

Comandos IF-THEN-ELSE

Exemplos:

Atribua um flag para pedidos onde exista menos de 5 dias entre a data do pedido e a data de expedição.

Atribua o cargo para MANAGER se o nome do empregado for KING. Se o nome do empregado é diferente de KING atribua o cargo para CLERK.

On Targget Treinamento e Consultoria 7

...IF v_shipdate – v_orderdate < 5 THEN v_ship_flag := ‘Acceptable’;ELSE v_ship_flag := ‘Unacceptable’;END IF;...

IF v_ename = 'KING' THEN v_job := 'MANAGER';ELSE v_job := 'CLERK';END IF;

Page 435: Introdução ao Oracle 8i

Funções Básicas

Fluxo de Execução do Comando IF-THEN-ELSIF

Na tela de entrada de uma aplicação Oracle Forms, forneça o número do departamento do novo empregado para determinar sua gratificação.

No exemplo, a variável v_comm é utilizada para popular um campo da tela com o valor da gratificação do empregado e :dept.deptno representa o valor fornecido no campo da tela.

On Targget Treinamento e Consultoria 8

...IF :dept.deptno = 10 THEN v_comm := 5000;ELSIF :dept.deptno = 20 THEN v_comm := 7500;ELSE v_comm := 2000;END IF;...

Page 436: Introdução ao Oracle 8i

Funções Básicas

Comandos IF-THEN-ELSIF

Exemplo:

Para um determinado valor fornecido, retorne um valor calculado.

Quando possível, utilize a cláusula ELSIF ao invés de aninhar comandos IF. O código fica mais fácil de ler e entender, e a lógica é identificada claramente. Se a ação na cláusula ELSE consiste puramente em outro comando IF, é mais conveniente utilizar a cláusula ELSIF. Isto torna o código mais claro eliminando a necessidade de END IFs aninhados ao término de cada conjunto adicional de condições e ações.

Nota: Qualquer expressão aritmética contendo valores nulos retorna NULL.

On Targget Treinamento e Consultoria 9

. . .IF v_start > 100 THEN v_start := 2 * v_start;ELSIF v_start >= 50 THEN v_start := .5 * v_start;ELSE v_start := .1 * v_start;END IF;. . .

IF condition1 THEN statement1;ELSIF condition2 THEN statement2;ELSIF condition3 THEN statement3;END IF;

Page 437: Introdução ao Oracle 8i

Funções Básicas

Construindo Condições Lógicas

Você pode construir uma condição boleana simples combinando expressões numéricas, caractere ou de data com um operador de comparação. Em geral, trate valores nulos com o operador IS NULL.

Nulos em Expressões e Comparações

A condição IS NULL retorna TRUE somente se a variável que está sendo verificado for NULL.

Qualquer expressão que possui um valor nulo retorna NULL, exceto uma expressão de concatenação que trata o valor nulo como uma string vazia.

Exemplos:

As expressões acima retornam NULL se v_sal for nulo em qualquer um dos exemplos.

No próximo exemplo a expressão não retorna NULL mesmo se a variável v_string for nula.

On Targget Treinamento e Consultoria 10

v_sal > 1000v_sal * 1.1'PL'||v_string||'SQL'

Page 438: Introdução ao Oracle 8i

Funções Básicas

Tabelas de Lógica

Condições Boleanas com Operadores Lógicos

Você pode construir uma condição boleana complexa combinando condições boleanas simples com os operadores lógicos AND, OR e NOT. Nas tabelas de lógica mostradas no gráfico acima, FALSE possui precedência em uma condição AND e TRUE possui precedência em uma condição OR. AND retorna TRUE somente se ambas as expressões forem TRUE. OR retorna FALSE somente se ambas as expressões forem FALSE. NULL AND TRUE sempre retorna NULL porque o resultado de uma das expressão não é conhecido, não sabendo-se se ela retornou TRUE ou não.

Nota: A negação de NULL (NOT NULL) resulta em um valor nulo porque valores nulos são indeterminados.

On Targget Treinamento e Consultoria 11

Page 439: Introdução ao Oracle 8i

Funções Básicas

Condições Boleanas

Qual é o valor de V_FLAG em cada caso?

A tabela lógica AND pode auxiliar você a avaliar as possibilidades para as condições boleanas apresentadas.

On Targget Treinamento e Consultoria 12

v_flag := v_reorder_flag AND v_available_flag;

Page 440: Introdução ao Oracle 8i

Funções Básicas

Controle de Repetições: Comandos de LOOP

O PL/SQL fornece diversos comandos de estruturas de loop para repetir um comando ou seqüência de comandos várias vezes.

Construções de loop são o segundo tipo de estruturas de controle:

O loop básico fornece ações repetitivas sem condições globais O FOR loop fornece controle de repetições de ações basedo em um contador O WHILE loop fornecem controle de repetições de ações baseado em uma condição O comando EXIT encerra um loop

Nota: Outro tipo de FOR LOOP, o cursor FOR LOOP será discutido em um capítulo subseqüente.

On Targget Treinamento e Consultoria 13

Page 441: Introdução ao Oracle 8i

Funções Básicas

Loop Básico

Sintaxe:

Onde:

condition é uma variável ou expressão boleana (TRUE, FALSE ou NULL)

A forma mais simples dos comandos de loop é o loop básico (ou infinito), que possui uma seqüência de comandos entre as palavras chaves LOOP e END LOOP. Cada vez que o fluxo de execução atinge o comando END LOOP, o controle é retornado para o comando LOOP correspondente. Um loop básico executa pelo menos uma vez seus comandos, até mesmo se a condição já for conhecida ao entrar no loop. Sem o comando EXIT, o loop torna-se infinito.

Comando EXIT

Você pode encerrar um loop utilizando o comando EXIT. O controle passa para o próximo comando após o comando END LOOP. Você pode executar um EXIT como uma ação dentro de um comando IF, ou como um comando independente dentro do loop. O comando EXIT deve ser colocado dentro do loop. No caso anterior, você pode adicionar a cláusula WHEN para permitir o encerramento condicional do loop. Quando o comando EXIT é encontrado, a condição da cláusula WHEN é avaliada. Se a condição retornar TRUE, o loop encerra e o controle passa ao próximo comando após o loop. Um loop básico pode conter múltiplos comandos EXIT.

Exemplo:

O exemplo de loop básico apresentado acima é definido como segue: insira as 10 primeiras linhas de itens para o pedido número 101.

Nota: Um loop básico permite a execução de seus comandos pelo menos uma vez, mesmo se a condição for conhecida ao entrar no loop.

On Targget Treinamento e Consultoria 14

LOOP -- delimitador statement1; -- comandos . . . -- comandos EXIT [WHEN condition]; -- comando EXITEND LOOP; -- delimitador

DECLARE v_ordid item.ordid%TYPE := 101; v_counter NUMBER(2) := 1;BEGIN LOOP INSERT INTO item (ordid, itemid) VALUES (v_ordid, v_counter); v_counter := v_counter + 1; EXIT WHEN v_counter > 10; END LOOP;END;

Page 442: Introdução ao Oracle 8i

Funções Básicas

FOR Loop

Sintaxe:

FOR loops possuem a mesma estrutura geral que o loop básico. Em adição, eles possuem uma declaração de controle antes da palavra chave LOOP para determinar o número de repetições que o PL/SQL deve executar.

Sintaxe:

counter é um inteiro implicitamente declarado cujo valor é automaticamente incrementado ou reduzido (diminui se a palavra chave REVERSE for utilizada) por 1 em cada repetição do loop até que o limite superior ou inferior é atingido.

REVERSE causa a redução do índice para cada repetição a partir do limite superior até o limite inferior. Observe que o limite inferior ainda é referenciado por primeiro.

lower_bound especifica o limite inferior para a faixa de valores do índice.

upper_bound especifica o limite superior para a faixa de valores do índice.

Não declare o contador (índice); ele é declarado implicitamente como um inteiro.

Nota: A seqüência de comandos é executada cada vez que o contador é incrementado, como determinado pelos dois limites. Os limites inferior e superior do loop podem ser literais, variáveis ou expressões, mas devem retornar inteiros. Se o limite inferior retornar um inteiro maior que o limite superior, a seqüência de comandos não será executada.

No exemplo abaixo, statement1 é executado apenas uma vez.

Nota: Os limites inferior e superior de um comando LOOP não necessitam ser literais numéricas. Eles podem ser expressões que retornem valores numéricos.

Exemplo:

Diretrizes

Referencie o contador somente dentro do loop; ele é indefinido fora dele. Utilize uma expressão para referenciar o valor existente de um contador. Não referencie o contador como o destino de uma atribuição.

Exemplo:

Insira as 10 primeiras linhas de itens para o pedido número 101.

On Targget Treinamento e Consultoria 15

FOR counter in [REVERSE] lower_bound..upper_bound LOOP statement1; statement2; . . .END LOOP;

FOR i IN 3..3 LOOP statement1;END LOOP;

DECLARE v_lower NUMBER := 1; v_upper NUMBER := 100;BEGIN FOR i IN v_lower..v_upper LOOP ... END LOOP;END;

Page 443: Introdução ao Oracle 8i

Funções Básicas

On Targget Treinamento e Consultoria 16

DECLARE v_ordid item.ordid%TYPE := 101;BEGIN FOR i IN 1..10 LOOP INSERT INTO item(ordid, itemid) VALUES(v_ordid, i); END LOOP;END;

Page 444: Introdução ao Oracle 8i

Funções Básicas

WHILE Loop

Você pode utilizar o WHILE loop para repetir uma seqüência de comandos até que a condição de controle não seja mais TRUE. A condição é avaliada no início de cada repetição. O loop encerra quando a condição for FALSE. Se a condição for FALSE já no início do loop, então nenhuma repetição é executada.

Sintaxe:

condition é uma variável ou expressão boleano (TRUE, FALSE ou NULL).

statement pode ser um ou mais comandos PL/SQL ou SQL.

Se as variáveis envolvidas nas condições não se modificarem durante a execução do loop, então a condição permanece TRUE e o loop não termina.

Nota: Se a condição retornar NULL, o loop é ignorado e o controle passa para o próximo comando.

Exemplo:

No exemplo acima, a quatidade aumenta com cada repetição do loop até que a quantidade multiplicada pelo preço seja maior que o valor máximo permitido para o item.

On Targget Treinamento e Consultoria 17

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

ACCEPT p_price PROMPT 'Enter the price of the item: 'ACCEPT p_itemtot PROMPT 'Enter the maximum total for

purchase of item: 'DECLARE ... v_qty NUMBER(8) := 1; v_running_total NUMBER(7,2) := 0;BEGIN ... WHILE v_running_total < &p_itemtot LOOP ... v_qty := v_qty + 1; v_running_total := v_qty * &p_price; END LOOP; ...

A condição éA condição éavaliada noavaliada noinício de cadainício de cadarepetição.repetição.

Page 445: Introdução ao Oracle 8i

Funções Básicas

Loops Aninhados e Labels

Você pode aninhar loop em vários níveis. Você pode aninhar FOR loops dentro de WHILE loops e WHILE loops dentro de FOR loops. Normalmente o término de um loop aninhado não encerra o loop externo, a menos que uma exceção seja disparada. Entretanto, você pode colocar labels em loops e sair do loop externo com o comando EXIT.

Nomes de labels seguem as mesmas regras que os outros identificadores. Um label é colocado antes de um comando, na mesma linha ou em uma linha separada. Coloque labels em loops antes da palavra LOOP dentro de delimitadores de label (<<label>>).

Se o loop possuir um label, seu nome pode ser opcionalmente incluído após o comando END LOOP.

Exemplo:

On Targget Treinamento e Consultoria 18

...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;

Page 446: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 19

1. Execute o script lab19_1.sql para criar a tabela MESSAGES. Escreva um bloco PL/SQL para inserir números na tabela MESSAGES.

a. Insira os números de 1 a 10 excluindo o 6 e 8.

b. Execute um COMMIT antes do final do bloco.

c. Selecione os dados da tabela MESSAGES para verificar se o bloco executou corretamente.

2. Crie um bloco PL/SQL que calcule a commissão para o empregado especificado baseado no salário do empregado.

a. Execute o script lab19_2.sql para inserir um novo empregado na tabela EMP.

b. Receba o número do empregado como uma variável de substituição do SQL*Plus.

c. Se o salário do empregado for menor que $1,000, atribua para a comissão do empregado o valor de 10% do seu salário.

d. Se o salário do empregado está entre $1,000 e $1,500, atribua para a comissão do empregado o valor de 15% do seu salário.

e. Se o salário do empregado for maior que $1,500, atribua para a comissão do empregado o valor de 20% do seu salário.

f. Se o salário do empregado for NULL, atribua para a comissão do empregado para 0.

g. Efetue o commit das modificações.

h. Teste o bloco PL/SQL para cada um dos seguintes casos e verifique cada atualização da comissão.

Número do Empregado Salário Comissão Resultante7369 800 807934 1300 1957499 1600 3208000 NULL NULL

On Targget Treinamento e Consultoria 19

RESULTS--------- 1 2 3 4 5 7 9 10

Page 447: Introdução ao Oracle 8i

Funções Básicas

Se houver tempo, complete os seguintes exercícios:

3. Modifique o arquivo e16q4.sql para inserir o texto “Number is odd” ou “Numer is even” na tabela MESSAGES dependendo se o valor informado é ímpar ou par. Consulte a tabela MESSAGES para determinar se o bloco PL/SQL executou corretamente.

4. Adicione uma nova coluna para a tabela EMP para armazenar asteriscos (*).

5. Crie um bloco PL/SQL que armazene na coluna STARS da tabela EMP um asterisco para cada $100 do salário do empregado. Arredonde o salário para o número inteiro mais próximo. Salve o bloco PL/SQL para um arquivo chamado e19q5.sql.

a. Receba o número do empregado como uma variável de substituição do SQL*Plus.

b. Inicialize a variável que conterá a string de asteriscos.

c. Concatene um asterisco para a string para cada $100 do valor do salário. Por exemplo, se o empregado possui um salário de $800, a string deve possuir oito asteriscos.

d. Atualize a coluna STARS para o empregado com a string de asteriscos.

e. Efetue o commit das modificações.

f. Teste o bloco para empregados que não possuem salário e para empregados que possuem um salário.

On Targget Treinamento e Consultoria 20

EMPNO ENAME SAL COMM----- ------ ----- --------- 8000 DOE 0 7499 ALLEN 1600 320 7934 MILLER 1300 195 7369 SMITH 800 80

RESULTS---------------Number is even

Please enter the employee number: 7934PL/SQL procedure successfully completed.Please enter the employee number: 8000PL/SQL procedure successfully completed.

EMPNO SAL STARS----- ------ ---------------- 8000 7934 1300 *************

Page 448: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

21.21. Trabalhando com Tipos deTrabalhando com Tipos de Dados CompostosDados Compostos

On Targget Treinamento e Consultoria

Page 449: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Criar PL/SQL records definidos pelo usuário Criar um PL/SQL record com o atributo %ROWTYPE Criar uma PL/SQL table de registros Descrever a diferença entre PL/SQL records, tables e tables of records

On Targget Treinamento e Consultoria 2

Page 450: Introdução ao Oracle 8i

Funções Básicas

Tipos de Dados Compostos

Tipos de dados compostos (também conhecidos como coleções) são RECORD, TABLE, Nested TABLE (tabela aninhada) e VARRAY. Você utiliza o tipo de dado RECORD para tratar dados relacionados, porém diferentes, como uma unidade lógica. Você usa o tipo de dado TABLE para referenciar e manipular coleções de dados como um único objeto. Não serão discutidos neste curso os tipos de dados Nested TABLE e VARRAY.

Um registro é um grupo de itens de dados relacionados armazenados em campos, cada um com seu próprio nome e tipo de dado. Uma tabela possui uma coluna e uma chave primária para fornecer acesso para as linhas como um array. Uma vez definidos, tabelas e registros podem ser reutilizados.

On Targget Treinamento e Consultoria 3

Page 451: Introdução ao Oracle 8i

Funções Básicas

PL/SQL Records

Um registro é um grupo de itens de dados relacionados armazenados em campos, cada um com seu próprio nome e tipo de dado. Por exemplo, suponha você possui tipos de dados diferentes sobre um empregado como nome, salário, data de admissão e assim por diante. Este dados são diferentes em tipo mas logicamente relacionados. Um registro que contém tais campos como o nome, salário e data de admissão de um empregado permite tratar os dados como uma unidade lógica. Quando você declara um tipo RECORD para estes campos, eles podem ser manipulados como uma unidade.

Cada registro definido pode possuir tantos campos quanto necessário. Podem ser atribuídos valores iniciais e podem ser definidos como NOT NULL. Campos sem valores iniciais são inicializados com NULL. A palavra chave DEFAULT também podem ser utilizada quando definindo campos. Você pode definir tipos RECORD e declarar registros definidos pelo usuário na parte

declarativa de qualquer bloco, subprograma ou package. Você pode declarar e referência registros aninhados. Um registro pode ser o componente

de outro registro.

On Targget Treinamento e Consultoria 4

Page 452: Introdução ao Oracle 8i

Funções Básicas

Criando um PL/SQL Record

Para criar um PL/SQL record, você define um tipo RECORD e então declara registros deste tipo.

Sintaxe:

Onde field_delaration significa:

type_name é o nome do tipo RECORD. Este identificador é utilizado para declarar os registros.

field_name é o nome de um campo dentro do registro.

field_type é o tipo de dado do campo. Representa qualquer tipo de dado PL/SQL exceto REF CURSOR. Você pode utilizar o atributo %TYPE e %ROWTYPE.

expr é o um valor inicial.

A constraint NOT NULL previne a atribuição de nulos para estes campos. Você deve inicializar campos NOT NULL.

Exemplo:

Declare variáveis para armazenar o nome, o cargo e o salário de um novo empregado.

Declarações de campos são como declarações de variáveis. Cada campo possui um nome único e um tipo de dado específico. Não existem tipos de dados pré-definidos para PL/SQL records, como para variáveis escalares. Portanto, você deve criar primeiro o tipo de dado e então declarar um identificador que utilize este tipo de dado.

O exemplo a seguir mostra que você pode utilizar o atributo %TYPE para especificar o tipo de dado de um campo:

Nota: Você pode adicionar a constraint NOT NULL para qualquer declaração de campo e assim prevenir a atribuição de nulos para este campo. Lembre-se que devem ser inicializados os campos declarados como NOT NULL.

On Targget Treinamento e Consultoria 5

TYPE type_name IS RECORD (field_declaration[, field_declaration]…);identifier type_name;

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

... TYPE emp_record_type IS RECORD (ename VARCHAR2(10), job VARCHAR2(9), sal NUMBER(7,2));

emp_record emp_record_type;...

DECLARE TYPE emp_record_type IS RECORD (empno NUMBER(4) NOT NULL := 100, ename emp.ename%TYPE, job emp.job%TYPE);

emp_record emp_record_type;...

Page 453: Introdução ao Oracle 8i

Funções Básicas

Estrutura de um PL/SQL Record

Referenciando e Inicializando Registros

Campos em um registro são acessados pelo nome. Para referenciar e inicializar um determinado campo, utilize a seguinte sintaxe:

Por exemplo, você referência o campo job do registro emp_record como segue:

Você pode atribuir um valor para um campo do registro como segue:

Em uma bloco ou subprograma, registros definidos pelo usuário são inicializados quando você acessa o bloco ou subprograma e deixam de existir quando você encerra o bloco ou subprograma.

Atribuindo Valores para Registros

Você pode atribuir uma lista de valores comuns para um registro utilizando o comando SELECT ou FETCH. Certifique-se que os nomes de colunas estejam na mesma ordem dos campos do registro. Você pode também atribuir um registro para outro se eles possuem o mesmo tipo de dado. Um registro definido pelo usuário e um registro definido com o atributo %ROWTYPE nunca possuem o mesmo tipo de dado.

On Targget Treinamento e Consultoria 6

record_name.field_nameemp_record.job ...emp_record.job := 'CLERK';

Page 454: Introdução ao Oracle 8i

Funções Básicas

Atributo %ROWTYPE

Para declarar um registro baseado em uma coleção de colunas de uma tabela ou visão do bancco de dados, você utiliza o atributo %ROWTYPE. Os campos no registros possuem seus nomes e tipos de dados baseados nas colunas da tabela ou visão. O registro pode também armazenar um linha inteira de dados recuperada a partir de um cursor ou variável de cursor.

No exemplo abaixo um registro é declarado utilizando %ROWTYPE como especificador do tipo de dado.

O registro emp_record consite dos seguintes campos, que refletem todos os campos existentes na tabela EMP.

Vantagens da Utilização de %ROWTYPE

O número e tipos de dados das colunas referenciadas do banco de dados não precisam ser conhecidos.

O número e tipos de dados das colunas referenciadas do banco de dados podem modificar-se em tempo de execução.

Bastante útil quando recupera-se toda uma linha com o comando SELECT.

Exemplos:

Declare uma variável para armazenar a mesma informação de um departamento como ela é armazenada na tabela DEPT.

Declare uma variável para armazenar a mesma informação de um empregado como ela é armazenada na tabela EMP.

A primeira declaração cria um registro com os mesmos nomes de campos e tipos de dados que uma linha da tabela DEPT. Os campos são DEPTNO, DNAME e LOC.

A segunda declaração acima cria um registro com os mesmos nomes de campos e tipos de dados que uma linha da tabela EMP. Os campos são EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM e DEPTNO.

No exemplo seguinte, você seleciona valores de colunas para um registro chamado item_record.

On Targget Treinamento e Consultoria 7

DECLARE emp_record emp%ROWTYPE;(ename VARCHAR2(10), job VARCHAR2(9), sal NUMBER, comm NUMBER)

dept_record dept%ROWTYPE;emp_record emp%ROWTYPE;DECLARE item_record item%ROWTYPE; ...BEGIN SELECT * INTO item_record FROM item WHERE ...

Page 455: Introdução ao Oracle 8i

Funções Básicas

PL/SQL Tables

Objetos do tipo TABLE são chamados PL/SQL tables. Eles são modelados como tabelas do banco de dados. PL/SQL tables utilizam uma chave primária para fornecer um vetor de acesso as linhas.

Uma PL/SQL table:

É semelhante a um array Deve conter dois componentes:

Uma chave primária do tipo de dado BINARY_INTEGER que indexa a PL/SQL table. Uma coluna do tipo de dado escalar ou record, que armazena os elementos da PL/SQL

table. Podem crescer dinamicamente.

On Targget Treinamento e Consultoria 8

Page 456: Introdução ao Oracle 8i

Funções Básicas

Criando uma PL/SQL Table

Exemplo:

Declare uma variável PL/SQL para armazenar um nome.

Existem duas etapas envolvidas na criação de uma PL/SQL table.

1. Declare o tipo de dado da tabela PL/SQL (TABLE type).

2. Declare uma variável com este tipo de dado.

Sintaxe:

type_name é o nome do tipo de dado da tabela (TABLE type). Ele é um especificador de tipo utilizado em declarações subseqüentes de PL/SQL tables.

column_type é qualquer tipo de dado escalar (não composto) como VARCHAR2, DATE ou NUMBER. Você pode utilizar o atributo %TYPE para prover o tipo de dado de uma coluna.

identifier é o nome do identificador que representa uma PL/SQL table.

A constraint NOT NULL previne que nulos sejam atribuídos para a PL/SQL table definida com aquele tipo. Não inicialize a PL/SQL table.

Declare uma variável PL/SQL para armazenar datas.

On Targget Treinamento e Consultoria 9

TYPE type_name IS TABLE OF {column_type | variable%TYPE | table.column%TYPE} [NOT NULL] [INDEX BY BINARY_INTEGER];

identifier type_name;

...TYPE ename_table_type IS TABLE OF emp.ename%TYPE INDEX BY BINARY_INTEGER;

ename_table ename_table_type;...

DECLARE TYPE date_table_type IS TABLE OF DATE INDEX BY BINARY_INTEGER;

date_table date_table_type;

Page 457: Introdução ao Oracle 8i

Funções Básicas

Estrutura de uma PL/SQL Table

Da mesma forma que o tamanho de uma tabela do banco de dados, o tamanho de uma PL/SQL table é indefinido. Ou seja, o número de linhas em uma PL/SQL table pode crescer dinamicamente, à medida que novas linhas forem adicionadas.

PL/SQL tables devem possuir uma coluna e uma chave primária, nenhuma das quais pode ser nomeada. A coluna pode ser de um tipo de dado escalar ou record, mas a chave primária deve ser do tipo BINARY_INTEGER. Você não pode inicializar uma PL/SQL table na sua declaração.

On Targget Treinamento e Consultoria 10

Page 458: Introdução ao Oracle 8i

Funções Básicas

Criando uma PL/SQL Table

Referenciando uma PL/SQL Table

Sintaxe:

Referencie a terceira linha de uma PL/SQL table chamada ename_table.

A faixa de valores de um BINARY_INTEGER é -2147483647...2147483647, de modo que o valor da chave primário pode ser negativo. O indexador não necessita iniciar em 1.

Nota: O comando table.EXISTS(i) retorna TRUE se pelo menos uma linha com o índice i for retornada. Utilize o comando EXITS para prevenir um erro que ocorre na referência para um elemento não existente da tabela.

On Targget Treinamento e Consultoria 11

DECLARE TYPE ename_table_type IS TABLE OF emp.ename%TYPE INDEX BY BINARY_INTEGER; TYPE hiredate_table_type IS TABLE OF DATE INDEX BY BINARY_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;

pl/sql_table_name(primary_key_value)ename_table(3) ...

Page 459: Introdução ao Oracle 8i

Funções Básicas

PL/SQL Table com Registros

Exemplo:

Declare uma variável PL/SQL para armazenar informações de departamentos.

Uma vez que somente uma definição de tabela é necessária para armazenar informações sobre todos os campos de uma tabela do banco de dados, uma tabela com registros aumenta a funcionalidade das PL/SQL tables.

Referenciando uma Tabela com Registros

No exemplo acima, você pode referenciar os campos do registro dept_table porque cada elemento desta tabela é um registro.

Sintaxe:

Exemplo:

LOC representa um campo da tabela DEPT.

Nota: Você pode utilizar o atributo %ROWTYPE para declarar um registro que represente uma linha da tabela do banco de dados.

On Targget Treinamento e Consultoria 12

DECLARE TYPE dept_table_type IS TABLE OF dept%ROWTYPE INDEX BY BINARY_INTEGER;

dept_table dept_table_type; -- Cada elemento de dept_table é um registro

table(index).fielddept_table(15).loc := 'Atlanta';

Page 460: Introdução ao Oracle 8i

Funções Básicas

Utilizando Métodos de PL/SQL Tables

Um método de PL/SQL table é uma procedure ou função do Oracle que opera nas tabelas.

Sintaxe:

Método DescriçãoEXISTS(n) Retorna TRUE se o elemento n existe um uma PL/SQL table.COUNT Retorna o número de elementos que uma PL/SQL table possui.FIRSTLAST

Retorna o primeiro e último (menor e maior) números do índice em uma PL.SQL table. Retorna NULL se a PL/SQL table está vazia.

PRIOR(n) Retorna o número do índice anterior a n.NEXT(n) Retorna o número do índice posterior a n.EXTEND(n, i) Para aumentar o tamanho de uma PL/SQL table.

EXTEND adiciona um elemento nulo.EXTEND(n) adiciona n elementos nulos.EXTEND(n, i) adiciona n cópias do elemento i.

TRIM TRIM remove um elemento do final da PL/SQL table.TRIM(n) remove n elementos do final da PL/SQL table.

DELETE DELETE remove todos os elementos de uma PL/SQL table.DELETE(n) remove o elemento n da PL/SQL table.DELETE(m, n) remove todos os elementos na faixa m...n da PL/SQL table.

On Targget Treinamento e Consultoria 13

table_name.method_name[ (parameters) ]

Page 461: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 20

1. Execute o comando abaixo para criar uma nova tabela para armazenar os empregados e seus salários.

2. Escreva um bloco PL/SQL para recuperar o nome e o salário do empregado fornecido a partir da tabela EMP baseado no número do empregado, utilizando PL/SQL tables.

a. Declare duas PL/SQL tables, ENAME_TABLE e SAL_TABLE, para temporariamente armazenar os nomes e salários.

b. Como cada nome e salário é recuperado dentro do loop, armazene eles nas PL/SQL tables.

c. Fora do loop, transfira os nomes e salários das PL/SQL tables para a tabela TOP_DOGS.

d. Remova as linhas da tabela TOP_DOGS e teste o exercício.

On Targget Treinamento e Consultoria 14

SQL> CREATE TABLE top_dogs 2 (name VARCHAR2(25), 3 salary NUMBER(11,2));

Please enter the employee number: 7934PL/SQL procedure successfully completed.NAME SALARY--------------- ---------MILLER 1300

Please enter the employee number: 7876PL/SQL procedure successfully completed.NAME SALARY--------------- ---------ADAMS 1100

Page 462: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

22.22. Escrevendo CursoresEscrevendo Cursores ExplícitosExplícitos

On Targget Treinamento e Consultoria

Page 463: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Diferenciar cursores implícitos e explícitos Utilizar uma variável PL/SQL record Escrever estruturas Cursor FOR loop

On Targget Treinamento e Consultoria 2

Page 464: Introdução ao Oracle 8i

Funções Básicas

Cursores

O Servidor Oracle utiliza áreas de trabalho chamadas private SQL areas para executar comandos SQL e para armazenar informações de processamento. Você pode utilizar cursores PL/SQL para nomear uma dessas áreas e acessar suas informações armazenadas. O cursor direciona todas as fases de processamento.

Tipo de Cursor Descrição

ImplícitoCursores implícitos são declarados pelo PL/SQL implicitamente para todos os comandos DML e PL/SQL SELECT, incluindo consultas que retornam somente uma linha.

ExplícitoPara consultas que retornam mais de uma linha, um cursor explícito pode ser declarado e nomeado pelo programador e manipulado através de comandos específicos no bloco PL/SQL.

O Servidor Oracle implicitamente abre um cursor para processar cada comando SQL não associado com um cursor declarado explicitamente. O PL/SQL permite referenciar o cursor implícito mais recente como o cursor chamado SQL.

Você não pode utilizar os comandos OPEN, FETCH e CLOSE para controle o cursor SQL, mas você pode utilizar atributos de cursor para obter informações sobre o comando SQL mais recentemente executado.

On Targget Treinamento e Consultoria 3

Page 465: Introdução ao Oracle 8i

Funções Básicas

Cursores Explícitos

Utilize cursores explícitos para individualmente processar cada linha retornada por um comando SELECT multi-row. O conjunto de linhas retornadas por uma consulta multi-row é denominado result set. Seu tamanho é o número de linhas que satisfazem o critério de pesquisa. O diagrama acima apresenta como um cursor explícito “aponta” para a linha corrente no result set. Isto permite ao programa processar as linhas uma de cada vez.

Um programa PL/SQL abre um cursor, processa as linhas retornadas pela consulta e então fecha o cursor. O cursor marca a posição corrente no result set.

Funções do Cursor Explícito

Pode processar além da primeira linha retornada pela consulta, linha por linha Mantém o registro da linha que está sendo processada Permite ao programador manualmente controlá-los no bloco PL/SQL

On Targget Treinamento e Consultoria 4

Page 466: Introdução ao Oracle 8i

Funções Básicas

Controlando Cursores Explícitos

Agora que você possui um entendimento conceitual de cursores, revise os passos para utilizá-los. A sintaxe para cada passo pode ser encontrada nas próximas páginas.

Controlando Cursores Explícitos Utilizando Quatro Comandos

1. Declare o cursor nomeando e definindo a estrutura de consulta a ser executada dentro dele.

2. Abra o cursor. O comando OPEN executa a consulta. As linhas identificadas pela consulta são chamadas de active set (conjunto ativo) e ficam disponíveis para recuperação.

3. Recupere os dados do cursor. O comando FETCH recupera a linha corrente do cursor para variáveis. Cada fetch move o ponteiro do cursor para a próxima linha do active set. Portanto, cada fetch acessa uma linha diferente retornada pela consulta. No diagrama apresentado acima, cada fetch verifica se o cursor ainda possui linhas existentes. Se linhas forem encontradas, ele carrega a linha corrente para variáveis; caso contrário, ele fecha o cursor.

4. Feche o cursor. O comando CLOSE libera o conjunto ativo de linhas. Agora é possível reabrir o cursor para estabelecer um novo active set.

On Targget Treinamento e Consultoria 5

Page 467: Introdução ao Oracle 8i

Funções Básicas

Você utiliza os comandos OPEN, FETCH e CLOSE para controlar um cursor. O comando OPEN executa a consulta associada com o cursor, identifica o result set e posiciona o cursor (ponteiro) antes da primeira linha. O comando FETCH recupera a linha corrente e avança o cursor para a próxima linha. Quando a última linha foi processada, o comando CLOSE fecha o cursor.

On Targget Treinamento e Consultoria 6

Page 468: Introdução ao Oracle 8i

Funções Básicas

Declarando o Cursor

Utilize o comando CURSOR para declarar um cursor explícito. Você pode referenciar variáveis dentro da consulta, mas você deve declará-las antes do comando CURSOR.

Sintaxe:

cursor_name é um identificador PL/SQL.

select_statement é um comando SELECT sem a cláusula INTO.

Nota: Não inclua a cláusula INTO na declaração do cursor porque ela deve ser utilizada depois, no comando FETCH.

Exemplos:

Recupere os empregados um por um.

Nota: Você pode referenciar variáveis na consulta, mas você deve declará-las antes do comando CURSOR.

On Targget Treinamento e Consultoria 7

CURSOR cursor_name IS select_statement;DECLARE CURSOR c1 IS SELECT empno, ename FROM emp;

CURSOR c2 IS SELECT * FROM dept WHERE deptno = 10;BEGIN ...

DECLARE v_empno emp.empno%TYPE; v_ename emp.ename%TYPE;

CURSOR c1 IS SELECT empno, ename FROM emp;BEGIN ...

Page 469: Introdução ao Oracle 8i

Funções Básicas

Abrindo um Cursor

Abra o cursor para executar a consulta e identificar o result set, que consiste de todas as linhas que satisfaçam o critério de pesquisa da consulta. O cursor neste momento aponta para a primeira linha no result set.

Sintaxe:

cursor_name é o nome do cursor previamente declarado.

OPEN é um comando executável que efetua as seguintes operações:

1. Dinamicamente aloca memória para uma context area que eventualmente contém informações importantes de processamento.

2. Executa o parse do comando SELECT.

3. Recebe as variáveis de entrada, ou seja, atribui o valor para as variáveis de entrada obtendo seus endereços de memória.

4. Identifica o result set, ou seja, o conjunto de linhas que satisfaça o critério de pesquisa. Linhas do result set não são recuperadas para variáveis quando o comando OPEN é executado. O comando FETCH é quem recupera as linhas.

5. Posiciona o ponteiro antes da primeira linha no active set.

Nota: Se a consulta não retornar nenhuma linha quando o cursor for aberto, o PL/SQL não dispara nenhuma exceção. Porém, você pode testar o status do cursor após um fetch.

Para cursores declarados utilizando a cláusula FOR UPDATE, o comando OPEN também efetua o lock das linhas.

On Targget Treinamento e Consultoria 8

OPEN cursor_name;

Page 470: Introdução ao Oracle 8i

Funções Básicas

Recuperando Dados do Cursor

O comando FETCH recupera as linhas do result set uma de cada vez. Após cada fetch, o cursor avança para a próxima linha no result set.

Sintaxe:

cursor_name é o nome do cursor previamente declarado.

variable é uma variável para armazenar os resultados.

record_name é o nome do registro no qual os dados recuperados são armazenados. A variável tipo record pode ser declarada utilizando o atributo %ROWTYPE.

Diretrizes

Inclua o mesmo número de variáveis na cláusula INTO do comando FETCH que as colunas do comando SELECT, e garanta que os tipos de dados sejam compatíveis.

Garanta que cada variável corresponda a uma coluna. Alternativamente, defina um registro para o cursor e referencie o registro na cláusula

FETCH INTO. Teste para ver se o cursor possui linhas. Se um fetch não receber valores, não resta

nenhuma linha para processar no active set e nenhum erro é retornado.

Nota: O comando FETCH executa as seguintes operações:

1. Avança o ponteiro para a próxima linha no active set.

2. Lê os dados da linha corrente para variáveis PL/SQL.

5. Encerra o Cursor FOR Loop se o ponteiro estiver posicionado no final do active set.

Exemplos:

Você utiliza o comando FETCH para recuperar os valores da linha corrente para variáveis. Após o fetch, você pode manipular as variáveis através de outros comandos. Para cada valor de coluna retornado pela consulta associada com o cursor, deve existir uma variável correspondente na lista da cláusula INTO. Além disso, seus tipos de dados também devem ser compatíveis.

On Targget Treinamento e Consultoria 9

FETCH cursor_name INTO [variable1, variable2,...] | record_name];FETCH c1 INTO v_empno, v_ename;...OPEN defined_cursor;LOOP FETCH defined_cursor INTO defined_variables EXIT WHEN ...; ... -- Processa os dados recuperados ...END;

Page 471: Introdução ao Oracle 8i

Funções Básicas

Recupere os primeiros dez empregados um por um.

On Targget Treinamento e Consultoria 10

DECLARE v_empno emp.empno%TYPE; v_ename emp.ename%TYPE; i NUMBER := 1; CURSOR c1 IS SELECT empno, ename FROM emp;BEGIN OPEN c1; FOR i IN 1..10 LOOP FETCH c1 INTO v_empno, v_ename; ... END LOOP;END ;

Page 472: Introdução ao Oracle 8i

Funções Básicas

Fechando um Cursor

O comando CLOSE desabilita o cursor e o result set torna-se indefinido. Feche o cursor após completar o processamento do comando SELECT. Este passo permite que o cursor seja reaberto, se neccessário. Portanto, você pode estabelecer um active set várias vezes.

Sintaxe:

cursor_name é o nome do cursor previamente declarado.

Não tente recuperar dados de um cursor uma vez que ele esteja fechado, ou a exceção INVALID_CURSOR será disparada.

Nota: O comando CLOSE libera a context area. Embora seja possível encerrar o bloco PL/SQL sem fechar os cursores, você deve adquirir o hábito de fechar qualquer cursor que tenha declarado explicitamente para liberar os recursos utilizados. Existe um limite máximo para o número de cursores abertos por usuário, que é determinado pelo parâmetro OPEN_CURSORS do banco de dados. Por default, OPEN_CURSORS é igual a 50.

Exemplo:

On Targget Treinamento e Consultoria 11

CLOSE cursor_name;... FOR i IN 1..10 LOOP FETCH c1 INTO v_empno, v_ename; ... END LOOP; CLOSE c1;END;

Page 473: Introdução ao Oracle 8i

Funções Básicas

Atributos de Cursores Explícitos

Como com cursores implícitos, existem quatro atributos para obter informações de status sobre um cursor. Quando adicionado para o cursor ou variável de cursor, estes atributos retornam informações úteis sobre a execução de um comando de manipulação de dados.

Nota: Você não pode referenciar atributos de cursor diretamente em um comando SQL.

On Targget Treinamento e Consultoria 12

Page 474: Introdução ao Oracle 8i

Funções Básicas

Controlando Múltiplos Fetch

Para processar várias linhas de um cursor explícito, você normalmente define um loop para executar um fetch a cada repetição. Eventualmente todas as linha no active set são processadas, e um fetch que não recuperou nenhuma linha atribui TRUE para o atributo %NOTFOUND. Utilize os atributos de cursor explícito para testar o sucesso de cada fetch antes de outras referências serem feitas para o cursor. Se você omitir o critério de exit, o resultado será um loop infinito.

On Targget Treinamento e Consultoria 13

Page 475: Introdução ao Oracle 8i

Funções Básicas

Atributo %ISOPEN

Você pode recuperar linhas somente quando o cursor estiver aberto. Utilize o atributo de cursor %ISOPEN para determinar quando o cursor está aberto, se necessário.

Recupe linhas em um loop. Utilize os atributos de cursor para determinar quando sair do loop.

Utilize o atributo de cursor %ROWCOUNT para recuperar um número exato de linhas.

Nota: %ISOPEN retorna o status do cursor; TRUE se aberto e FALSE caso contrário. Normalmente não é necessário utilizar %ISOPEN.

On Targget Treinamento e Consultoria 14

IF NOT c1%ISOPEN THEN OPEN c1;END IF;LOOP FETCH c1...

Page 476: Introdução ao Oracle 8i

Funções Básicas

Atributos %NOTFOUND e %ROWCOUNT

Exemplo:

Recupere os primeiros dez empregados um por um.

Nota: Antes do primeiro fetch, %NOTFOUND retorna NULL. Assim se um FETCH nunca executar com sucesso, o loop nunca será encerrado. Isto é porque o comando EXIT WHEN executa somente se sua condição WHEN retornar TRUE. Por garantia, você deve utilizar o seguinte comando EXIT:

On Targget Treinamento e Consultoria 15

DECLARE v_empno emp.empno%TYPE; v_ename emp.ename%TYPE;

CURSOR c1 IS SELECT empno, ename FROM emp;BEGIN OPEN c1; LOOP FETCH c1 INTO v_empno, v_ename; EXIT WHEN c1%ROWCOUNT > 10 OR c1%NOTFOUND; ... END LOOP; CLOSE c1;END;

EXIT WHEN c1%NOTFOUND OR c1%NOTFOUND IS NULL;

Page 477: Introdução ao Oracle 8i

Funções Básicas

Cursores e Registros

Além de utilizar registros para definir uma estrutura com as colunas de uma tabela, você também pode definir um registro baseado na lista de colunas selecionadas em um cursor explícito. Isto é conveniente para o processamento das linhas do active set, porque pode simplificar o fetch para um registro. Portanto, os valores da linha são carregados diretamente para campos correspondentes do registro.

On Targget Treinamento e Consultoria 16

... CURSOR c1 IS SELECT empno, ename FROM emp;

emp_record c1%ROWTYPE;BEGIN OPEN c1; . . . FETCH c1 INTO emp_record;

Page 478: Introdução ao Oracle 8i

Funções Básicas

Cursor FOR Loop

Um Cursor FOR Loop é um método conveniente para processar as linhas em um cursor explícito. O cursor é aberto, as linhas são recuperadas uma para cada repetição do loop, e o cursor é fechado automaticamente quando todas as linhas foram processadas. O loop é terminado automaticamente no final da repetição onde a última linha foi recuperada.

Sintaxe:

record_name é o nome do registro implicitamente declarado.

cursor_name é um identificador PL/SQL para o cursor previamente declarado.

Diretrizes

Não declare o registro que controla o loop. Seu escopo é somente no loop. Teste os atributos de cursor durante o loop, se necessário. Forneça parâmetros para um cursor, se necessário, entre parênteses seguinte o nome do

cursor em um comando FOR. Maiores informações sobre parâmetros de cursor serão vistos em um capítulo subseqüente.

Não utilize um Cursor FOR Loop quando as operações do cursor devam ser tratadas manualmente.

Nota: Você pode definir uma consulta no início do próprio loop. A expressão da consulta é chamada de subcomando SELECT, e o cursor fica interno ao FOR loop. Porque o cursor não foi declarado com um nome, você não pode testar seus atributos.

Exemplo:

Recupere os empregados um por um até não restar mais nenhum.

On Targget Treinamento e Consultoria 17

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

DECLARE CURSOR c1 IS SELECT empno, ename FROM emp;BEGIN FOR emp_record IN c1 LOOP -- open implícito e fetch implícito ocorrem IF emp_record.empno = 7839 THEN ... END LOOP; -- close implícito ocorreEND;

Page 479: Introdução ao Oracle 8i

Funções Básicas

Cursor FOR Loop Utilizando Subconsultas

Você não precisa declarar um cursor porque o PL/SQL permite a você substituí-lo por uma subconsulta.

Exemplo:

On Targget Treinamento e Consultoria 18

BEGIN FOR emp_record IN ( SELECT empno, ename FROM emp) LOOP -- open implícito e fetch implícito ocorrem IF emp_record.empno = 7839 THEN ... END LOOP; -- close implícito ocorreEND;

Page 480: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 21

1. Crie um bloco PL/SQL que determine os empregados com os maiores salários.

a. Receba um número n através de um parâmetro de substituição do SQL*Plus.

b. Em um loop, obtenha os nomes e salários dos n empregados com os maiores salários da tabela EMP.

c. Armazena os nomes e salários na tabela TOP_DOGS.

d. Assuma que dois empregados não possuem o mesmo salário.

e. Teste uma variedade de casos especiais, como n = 0 ou n maior que o número de empregados da tabela EMP. Remova as linhas da tabela TOP_DOGS após cada teste.

2. Considere o caso onde vários empregados possuem o mesmo salário. Se uma pessoa é listada, então todas as pessoas que possuem o mesmo salário devem também ser listadas.

a. Por exemplo, se o usuário fornecer o valor 2 para n, então KING, FORD e SCOTT devem ser exibidos.

b. Se o usuário fornecer o valor 3, então KING, FORD, SCOTT e JONES devem ser exibidos.

c. Remova todas as linhas da tabela TOP_DOGS e teste o exercício.

On Targget Treinamento e Consultoria 19

Please enter the number of top money makers: 5NAME SALARY----------- ------KING 5000FORD 3000SCOTT 3000JONES 2975BLAKE 2850

Please enter the number of top money makers: 2NAME SALARY------------ ------KING 5000FORD 3000SCOTT 3000

Page 481: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

23.23. Conceitos Avançados deConceitos Avançados de Cursores ExplícitosCursores Explícitos

On Targget Treinamento e Consultoria

Please enter the number of top money makers: 3NAME SALARY------------ ------KING 5000FORD 3000SCOTT 3000JONES 2975

Page 482: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Escrever um cursor que utilize parâmetros Determinar quando uma cláusula FOR UPDATE em um cursor é necessária Determinar quando utilizar a cláusula WHERE CURRENT OF Escrever um cursor que utilize uma subconsulta

On Targget Treinamento e Consultoria 2

Page 483: Introdução ao Oracle 8i

Funções Básicas

Cursores com Parâmetros

Parâmetros permitem que valores sejam passados para um cursor quando ele for aberto para serem utilizados na subconsulta quando ela executar. Isto significa que você pode abrir e fechar um cursor explícito várias vezes em um bloco, retornando um active set diferente em cada ocasião.

Cada parâmetro na declaração do cursor deve possuir um parâmetro atual correspondente no comando OPEN. Tipos de dados de parâmetros são os mesmo que para variáveis escalares, mas você não deve fornecer o tamanho. Os nomes dos parâmetros servem para referência na consulta do cursor.

Sintaxe:

cursor_name é um identificador PL/SQL para o nome do cursor.

parameter_name é o nome de um parâmetro Parâmetros devem atender à seguinte sintaxe:

datatype é um tipo de dado escalar do parâmetro.

select_statement é um comando SELECT sem a cláusula INTO.

Quando o cusor for aberto, você deve passar valores para cada um dos parâmetros posicionalmente. Você pode passar valores a partir de variáveis PL/SQL ou host como também literais.

Nota: A notação de parâmetro não oferece grande funcionalidade; ele simplesmente permite a você especificar valoes de entrada e forma fácil e clara. Isto é particularmente útil quando o mesmo cursor é referenciado repetidamente.

Exemplo:

Passe o número do departamento e o cargo para a cláusula WHERE.

No exemplo seguinte, duas variáveis e um cursor são declaradas. O cursor é definido com dois parâmetros:

Cada um dos seguintes comandos abre o cursor.

Você pode passar parâmetros para um cursor utilizado em um Cursor FOR Loop:

On Targget Treinamento e Consultoria 3

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

cursor_parameter_name [IN] datatype [{:= | DEFAULT} expr]DECLARE CURSOR c1 (v_deptno NUMBER, v_job VARCHAR2) IS SELECT empno, ename FROM emp WHERE deptno = v_deptno AND job = v_job;BEGIN OPEN c1(10, 'CLERK');...

DECLARE job_emp emp.job%TYPE := 'CLERK'; v_ename emp.ename%TYPE; CURSOR c1 (v_deptno NUMBER, v_job VARCHAR2) is SELECT ...

OPEN c1(10, job_emp);OPEN c1(20, 'ANALYST');DECLARE CURSOR c1 (v_deptno NUMBER, v_job VARCHAR2) is SELECT ...BEGIN FOR emp_record IN c1(10, 'ANALYST') LOOP ...

Page 484: Introdução ao Oracle 8i

Funções Básicas

Cláusula FOR UPDATE

Você pode querer bloquear as linhas antes de atualizá-las ou removê-las. Adicione a cláusula FOR UPDATE na consulta do cursor para efetuar o lock nas linhas afetadas quando o cursor for aberto. Uma vez que o Servidor Oracle libera os locks no final da transação, você não deve executar um commit entre os fetch de um cursor explícito quando FOR UPDATE for utilizado.

Sintaxe:

column_reference é uma coluna de uma tabela onde a consulta é executada. Uma lista de colunas também pode ser utilizada.

NOWAIT retorna um erro do Oracle caso as linhas já estejam bloqueadas por outra sessão.

A cláusula FOR UPDATE deve ser a última cláusula de um comando SELECT, mesmo se um ORDER BY existir. Quando consultar múltiplas tabelas, você pode utilizar a cláusula FOR UPDATE para mantendo o lock de linha apenas para uma tabela específica. Linhas em uma tabela são bloqueadas somente se a cláusula FOR UPDATE referenciar uma coluna desta tabela.

Exemplo:

Nota: Caso o Servidor Oracle não obtenha os locks nas linhas necessárias em um SELECT FOR UPDATE, ele aguarda indefinidamente. Você pode utilizar a cláusula NOWAIT no comando SELECT FOR UPDATE e testar pelo código de erro que retorna caso ocorra uma falha na obtenção dos locks em um loop. Portanto, você pode tentar abrir o cursor n vezes antes de encerrar o bloco PL/SQL. Caso você possua uma tabela muito grande, você pode obter uma melhor performance utilizando o comando LOCK TABLE para bloquear todas as linhas da tabela. Entretanto, quando utilizar LOCK TABLE, você não pode utilizar a cláusula WHERE CURRENT OF e deve utilizar a notação WHERE column = identifier.

On Targget Treinamento e Consultoria 4

SELECT ...FROM ...FOR UPDATE [OF column_reference][NOWAIT]

DECLARE CURSOR c1 IS SELECT empno, ename FROM emp FOR UPDATE NOWAIT;

Page 485: Introdução ao Oracle 8i

Funções Básicas

Cláusula WHERE CURRENT OF

Quando você quiser referenciar a linha atual de um cursor explícito, utilize a cláusula WHERE CURRENT OF. Isto permite a você aplicar atualizações e deleções para a linha atualmente endereçada pelo cursor, sem a necessidade de explicitamente referenciar o ROWID. Você deve incluir a cláusula FOR UPDATE na consulta do cursor para que as linhas sejam bloqueadas na abertura do cursor.

Sintaxe:

cursor é o nome do cursor declarado. O cursor deve ser declarado com a cláusula FOR UPDATE.

Exemplo:

Você pode atualizar linhas baseado no critério de um cursor.

Adicionalmente, você pode escrever o comando DELETE ou UPDATE contendo a cláusula WHERE CURRENT OF cursor_name para referenciar a última linha processada pelo comando FETCH. Quanto você utiliza esta cláusula, o cursor referenciado deve existir e deve conter a cláusula FOR UPDATE na consulta do cursor, caso contrário um erro será retornado.

On Targget Treinamento e Consultoria 5

WHERE CURRENT OF cursorDECLARE CURSOR c1 IS SELECT ... FOR UPDATE NOWAIT;BEGIN ... FOR emp_record IN c1 LOOP UPDATE ... WHERE CURRENT OF c1; ... END LOOP; COMMIT;END;

Page 486: Introdução ao Oracle 8i

Funções Básicas

Cursores com Subconsultas

Exemplo:

Uma subconsulta é uma consulta que aparece dentro de outro comando SQL. Quando analisada, a subconsulta fornece um valor ou conjunto de valores para o comando.

Subconsultas são normalmente utilizadas na cláusula WHERE de um comando SELECT. Elas também podem ser utilizadas na cláusula FROM como no exemplo acima.

On Targget Treinamento e Consultoria 6

DECLARE CURSOR my_cursor IS SELECT t1.deptno, dname, STAFF FROM dept t1, (SELECT deptno,

count(*) STAFF FROM emp GROUP BY deptno) t2 WHERE t1.deptno = t2.deptno AND STAFF >= 5;

Page 487: Introdução ao Oracle 8i

Funções Básicas

Exercícios – 22

1. Escreva uma consulta para recuperar todos os departamentos e empregados em cada departamento. Insira o resultado na tabela MESSAGES. Utilize um cursor para recuperar o número do departamento e passe o número do departamento para um cursor recuperar os empregados deste departamento.

2. Modifique o arquivo e19q5.sql para incorporar as funcionalidades de FOR UPDATE e WHERE CURRENT OF no processamento do cursor.

On Targget Treinamento e Consultoria 7

RESULTS------------------------KING - Department 10CLARK - Department 10MILLER - Department 10JONES - Department 20FORD - Department 20SMITH - Department 20SCOTT - Department 20ADAMS - Department 20BLAKE - Department 30MARTIN - Department 30ALLEN - Department 30TURNER - Department 30JAMES - Department 30WARD - Department 3014 rows selected.

EMPNO SAL STARS----- ------ --------------------- 8000 7900 950 ********** 7844 1500 ***************

Page 488: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

24.24. Tratamento de ExceçõesTratamento de Exceções

On Targget Treinamento e Consultoria

Page 489: Introdução ao Oracle 8i

Funções Básicas

Objetivos

Definir exceções PL/SQL Reconhecer exceções não tratadas Utilizar diferentes tipos de tratamento de exceções PL/SQL Tratar erros inesperados Descrever o efeito da propagação de exceções em blocos aninhados Customizar mensagens de exceções PL/SQL

On Targget Treinamento e Consultoria 2

Page 490: Introdução ao Oracle 8i

Funções Básicas

Tratando Exceções com PL/SQL

Uma exceção é um identificaddor em PL/SQL, disparado durante a execução de um bloco que encerrou seu corpo principal de ações. Um bloco sempre termina quando o PL/SQL dispara uma exceção, mas você pode especificar um tratamento de exceções para executar ações finais.

Métodos de Disparo de Exceções

Um erro Oracle ocorre e a execeção associada é disparada automaticamente. Por exemplo, se o erro ORA-01403 ocorre quando nenhuma linha for recuperada do banco de dados em um comando SELECT, então o PL/SQL dispara a exceção NO_DATA_FOUND.

Você dispara uma exceção explicitamente executando o comando RAISE dentro do bloco. A exceção disparada pode ser uma exceção definida pelo usuário ou pré-definida.

On Targget Treinamento e Consultoria 3

Page 491: Introdução ao Oracle 8i

Funções Básicas

Tratamento de Exceções

Tratando uma Exceção

Se a exceção for disparada na seção executável do bloco, o processamento desvia para o tratamento de exceção correspondente da seção EXCEPTION do bloco. Se o PL/SQL tratar com sucesso a exceção, então ela não propaga para o bloco ou ambiente chamador. O bloco PL/SQL encerra com sucesso.

Propagando uma Exceção

Você pode manipular uma exceção propagando-a para o ambiente chamador. Se a exceção for disparada na seção executável do bloco e não existir um tratamento de exceção correspondente, o bloco PL/SQL encerra com uma falha.

On Targget Treinamento e Consultoria 4

Page 492: Introdução ao Oracle 8i

Funções Básicas

Tipos de Exceções

Existem três tipos de exceções.

Exceção Descrição Diretrizes para Tratamento

Erro pré-definido do Servidor Oracle

Um de aproximadamente 20 erros que ocorrem com maior freqüência no código PL/SQL.

Não declare a exceção, e permita que o Servidor Oracle a dispare implicitamente.

Erro não pré-definido do Servidor Oracle

Qualquer outro erro padrão do Servidor Oracle.

Declare dentro da seção declarativa, e permita que o Servidor Oracle a dispare implicitamente.

Erro definido pelo usuário

Uma condição que o desenvolvedor determina como anormal.

Declare dentro da seção declarativa, e a dispare explicitamente.

Nota: Algumas ferramentas com suporte à PL/SQL, como o Developer/2000 Forms, possuem suas próprias exceções.

On Targget Treinamento e Consultoria 5

Page 493: Introdução ao Oracle 8i

Funções Básicas

Tratando Exceções

Você pode tratar qualquer erro incluindo uma rotina correspondente dentro da seção de tratamento de exceções do bloco PL/SQL. Cada tratamento consiste de uma cláusula WHERE, que especifica uma exceção, seguida pela seqüência de comandos a serem executados quando esta exceção for disparada.

Sintaxe:

exception é o nome padrão de uma exceção pré-definida ou o nome de uma exceção definida pelo usuário declarada dentro da seção declarativa.

statment são um ou mais comandos PL/SQL ou SQL.

OTHERS é uma cláusula de tratamento de exceção opcional que trata exceções não especificadas.

Tratamento de Exceções com WHEN OTHERS

A seção de tratamento de exceções trata somente aquelas exceções especificadas; qualquer outra exceção não é tratada a menos que você utilize o tratamento de exceção OTHERS, que trata qualquer exceção não tratada anteriormente. Por esta razão, OTHERS deve ser o último tratamento de exceção definido.

On Targget Treinamento e Consultoria 6

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

Page 494: Introdução ao Oracle 8i

Funções Básicas

Diretrizes para o Tratamento de Exceções

Inicie a seção de tratamento de exceções do bloco com a palavra chave EXCEPTION. Defina vários tratamentos de exceções para o bloco, cada um com seu próprio conjunto de

ações. Quando uma exceção ocorrer, o PL/SQL processará somente um tratamento antes de

encerrar o bloco. Coloque a cláusula OTHERS após todas as outras cláusulas de tratamento de exceções. Você pode possuir no máximo uma cláusula OTHERS. Exceções não podem aparecer em comandos de atribuição ou comandos SQL.

On Targget Treinamento e Consultoria 7

Page 495: Introdução ao Oracle 8i

Funções Básicas

Tratando Errors Pré-Definidos do Servidor Oracle

Trate um erro pré-definido do Servidor Oracle referenciando seu nome padrão dentro da rotina de tratamento de exceção correspondente.

Exemplos de exceções pré-definidas:

Nome da Exceção Erro Oracle Descrição

ACCESS_INTO_NULL ORA-06530Tentativa de atribuir valores para atributos de um objeto não inicializado.

COLLECTION_IS_NULL ORA-06531Tentativa de aplicar métodos que não o EXISTS para uma PL/SQL table não inicializada.

CURSOR_ALREADY_OPEN ORA-06511 Tentativa de abrir um cursor que já aberto.DUP_VAL_ON_INDEX ORA-00001 Tentativa de inserir um valor duplicado.INVALID_CURSOR ORA-01001 Ocorreu uma operação ilegal em um cursor.

INVALID_NUMBER ORA-01722Falha na conversão de uma string caractere para numérica.

LOGIN_DENIED ORA-01017Conexão ao Oracle com um nome de usuário e/ou senha inválida.

NO_DATA_FOUND ORA-01403 SELECT do tipo single-row não retornou nenhuma linha.

NOT_LOGGED_ON ORA-01012 Programa PL/SQL executou uma chamada ao banco de dados sem estar conectado ao Oracle.

PROGRAM_ERROR ORA-06501 PL/SQL possui um problema interno.

STORAGE_ERROR ORA-06500PL/SQL executou além da memória disponível ou a memória está corrompida.

SUBSCRIPT_BEYOND_COUNT ORA-06533Referência para um elemento de uma PL/SQL table utilizando um número de índice maior que o número de elementos da tabela.

SUBSCRIPT_OUTSIDE_LIMIT ORA-06532Referência para um elemento de uma PL/SQL table utilizando um número de índice que está fora da faixa de valores válidos.

TIMEOUT_ON_RESOURCE ORA-00051Ocorreu um time-out enquanto o Oracle estava aguardando por um recurso.

TOO_MANY_ROWS ORA-01422SELECT do tipo single-row retornou mais que uma linha.

VALUE_ERROR ORA-06502Ocorreu um erro de aritmética, conversão ou truncamento.

ZERO_DIVIDE ORA-01476 Tentativa de divisão por zero.

On Targget Treinamento e Consultoria 8

Page 496: Introdução ao Oracle 8i

Funções Básicas

Exceções Pré-Definidas

No exemplo acima, para cada exceção, uma mensagem pode ser devolvida para o usuário.

Somente uma exceção é disparada e tratada à cada vez.

On Targget Treinamento e Consultoria 9

BEGIN SELECT ... COMMIT;EXCEPTION WHEN NO_DATA_FOUND THEN statement1; statement2; WHEN TOO_MANY_ROWS THEN statement1; WHEN OTHERS THEN statement1; statement2; statement3;END;

Page 497: Introdução ao Oracle 8i

Funções Básicas

Tratando Erros Não Pré-Definidos do Servidor Oracle

...

On Targget Treinamento e Consultoria 10

Page 498: Introdução ao Oracle 8i

Introdução ao Oracle: SQL e PL/SQL

Apêndice A – Soluções dosApêndice A – Soluções dos ExercíciosExercícios

On Targget Treinamento e Consultoria

Page 499: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 2

1. Inicie uma sessão do SQL*Plus utilizando o usuário e senha fornecidos pelo instrutor.

2. Comandos SQL*Plus acessam o banco de dados.

Falso

3. O comando SELECT a seguir executará com sucesso?

Verdadeiro

4. O comando SELECT abaixo executará com sucesso?

Verdadeiro

5. Existem três erros de codificação neste comando. Você pode os identificar?

A tabela EMP não possui uma coluna chamada SALARY. A coluna correta é SAL. O operador de multiplicação é *, e não x, como apresentado na linha 2. O alias ANNUAL SALARY não pode incluir espaços. O alias deveria ser

ANNUAL_SALARY ou ser colocado entre aspas duplas.

6. Mostre a estrutura da tabela DEPT. Selecione todos os dados da tabela DEPT.

7. Mostre a estrutura da tabela EMP. Crie uma consulta para exibir o nome (ename), cargo (job), data de admissão (hiredate) e número do empregado (empno) para cada empregado, mostrando o número do empregado por primeiro. Salve o comando SQL para um arquivo chamado e2q7.sql.

8. Execute a consulta do arquivo e2q7.sql.

9. Crie uma consulta para exibir cada cargo da tabela EMP uma única vez.

Se houver tempo, complete os seguintes exercícios:

10. Carregue e2q7.sql no SQL buffer. Altere os cabeçalhos das colunas para Emp#, Employee, Job e Hire Date, respectivamente. Execute sua consulta novamente.

11. Exiba o nome do empregado concatenado com o cargo, separados por uma vírgula e um espaço, e nomeie o cabeçalho da coluna Employee and Title.

On Targget Treinamento e Consultoria A-2

SQL> SELECT ename, job, sal Salary 2 FROM emp;SQL> SELECT * 2 FROM salgrade;SQL> SELECT empno, ename 2 salary x 12 ANNUAL SALARY 3 FROM emp;

SQL> DESCRIBE deptSQL> SELECT * 2 FROM dept;

SQL> DESCRIBE empSQL> SELECT empno, ename, job, hiredate 2 FROM emp;SQL> SAVE e2q7.sqlWrote file e2q7.sql

SQL> START e2q7.sqlSQL> SELECT DISTINCT job 2 FROM emp;SQL> GET e2q7.sql 1 SELECT empno, ename, job, hiredate 2* FROM empSQL> 1 SELECT empno "Emp #", ename "Employee",SQL> i 2i job "Job", hiredate "Hire Date" 3iSQL> SAVE e2q7.sql REPLACEWrote file e2q7.sqlSQL> START e2q7.sql

Page 500: Introdução ao Oracle 8i

Funções Básicas

Se você quiser um desafio extra, complete os exercícios seguintes:

12. Crie uma consulta para exibir todos os dados da tabela EMP. Separe cada coluna por uma vírgula. Coloque no cabeçalho da coluna resultante a string THE_OUTPUT.

On Targget Treinamento e Consultoria A-3

SQL> SELECT ename||', '||job "Employee and Title" 2 FROM emp;

SQL> SELECT empno || ',' || ename || ','|| job || ',' || 2 mgr || ',' || hiredate || ',' || sal || ',' || 3 comm || ',' || deptno THE_OUTPUT 4 FROM emp;

Page 501: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 3

1. Crie uma consulta para exibir o nome e o salário dos empregados que estão ganhando mais que $2850. Salve o comando SQL para um arquivo chamado e3q1.sql. Execute sua consulta.

2. Crie uma consulta para exibir o nome do empregado e o número do departamento para o empregado número 7566.

3. Altere a consulta em e3q1.sql para exibir o nome e o salário para todos os empregados cujo salário não está na faixa de valores de $1500 à $2850. Salve o novo comando para um arquivo chamado e3q3.sql. Execute a consulta.

4. Mostre o nome do empregado, o cargo e a data de admissão dos empregados contratados entre 20 de Fevereiro de 1981 e 1 de Maio de 1981. Classifique a consulta em ordem ascendente de data de admissão.

5. Mostre o nome do empregado e o número do departamento de todos os empregados que estão no departamento 10 e 30 em ordem alfabética por nome.

6. Altere a consulta em e3q3.sql para listar o nome e o salário dos empregados que ganham mais do que $1500 e estão no departamento 10 ou 30. Coloque o alias para as colunas Employee e Monthly Salary, respectivamente. Salve o novo comando para um arquivo chamado e3q6.sql. Execute a consulta.

7. Mostre o nome e a data de admissão de cada empregado que tenha sido contratado em 1982.

8. Mostre o nome e o cargo de todos os empregados que não possuem gerente.

9. Mostre o nome, o salário e a comissão para todos os empregados que ganham comissões. Ordene os dados em ordem descendente de salário e comissão.

Se houver tempo, complete os seguintes exercícios:

10. Mostre o nome de todos os empregados quando a terceira letra de seu nome for um A.

11. Mostre o nome de todos os empregados que possuem duas letras L em seu nome e estão no departamento 30 ou seu gerente é o empregado 7782.

On Targget Treinamento e Consultoria A-4

SQL> SELECT ename, sal 2 FROM emp 3 WHERE sal > 2850;SQL> SAVE e3q1.sqlCreated file e3q1.sql;

SQL> SELECT ename, deptno 2 FROM emp 3 WHERE empno = 7566;

SQL> EDIT e3q1.sql

SELECT ename, salFROM empWHERE sal NOT BETWEEN 1500 AND 2850/

SQL> START e3q3.sql

SQL> SELECT ename, job, hiredate 2 FROM emp 3 WHERE hiredate BETWEEN '20-Feb-81' AND '01-May-81' 4 ORDER BY hiredate;

SQL> SELECT ename, deptno 2 FROM emp 3 WHERE deptno IN (10, 30) 4 ORDER BY ename;

SQL> EDIT e3q3.sql

SELECT ename "Employee", sal "Monthly Salary"FROM empWHERE sal > 1500 AND deptno IN (10, 30)/

SQL> START e3q6.sql

SQL> SELECT ename, hiredate 2 FROM emp 3 WHERE hiredate LIKE '%82';

SQL> SELECT ename, job 2 FROM emp 3 WHERE mgr IS NULL;

SQL> SELECT ename, sal, comm 2 FROM emp 3 WHERE comm IS NOT NULL 4 ORDER BY sal DESC, comm DESC;

SQL> SELECT ename 2 FROM emp 3 WHERE ename LIKE '__A%';

Page 502: Introdução ao Oracle 8i

Funções Básicas

Se você quiser um desafio extra, complete os exercícios seguintes:

12. Mostre o nome, o cargo e o salário para todos os empregados cujo cargo seja CLERK ou ANALYST e seu salário não seja igual a $1000, $3000 ou $5000.

13. Altere a consulta em e3q6.sql para mostrar o nome, salário e comissão para todos os empregados cujo o valor da comissão seja maior que seu salário incrementado por 10%. Salve o novo comando em um arquivo chamado e3q13.sql. Execute a consulta.

On Targget Treinamento e Consultoria A-5

SQL> SELECT ename 2 FROM emp 3 WHERE ename LIKE '%L%L%' 4 AND deptno = 30 5 OR mgr = 7782;

SQL> SELECT ename, job, sal 2 FROM emp 3 WHERE job IN ('CLERK', 'ANALYST') 4 AND sal NOT IN (1000, 3000, 5000);

SQL> EDIT e3q6.sql

SELECT ename "Employee", sal "Monthly Salary", commFROM empWHERE comm > sal * 1.1/

SQL> START e3q13.sql

Page 503: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 4

1. Escreva uma consulta para exibir a data atual. Coloque o alias de coluna como “Date”.

2. Mostre o número do empregado, o nome, o salário e o salary com um aumento de 15%. Coloque o alias da coluna como “New Salary”. Salve o comando SQL para um arquivo chamado e4q2.sql.

3. Execute a consulta do arquivo e4q2.sql.

4. Altere a consulta em e4q2.sql para adicionar uma nova coluna que subtraia o salário antigo do novo salário. Coloque o alias da coluna como “Increase”. Reexecute a consulta.

5. Mostre o nome do empregado, a data de admissão e data de revisão do salário, que deve ser a primeira segunda-feira após seis meses de trabalho. Coloque o alias da coluna como “REVIEW”. Formate a data para uma padrão semelhante a “Sunday, the Seventh of September, 1981”.

On Targget Treinamento e Consultoria A-6

SQL> SELECT sysdate "Date" 2 FROM dual;SQL> SELECT empno, ename, sal, 2 ROUND(sal * 1.15, 0) "New Salary" 3 FROM emp;

SQL> SAVE e4q2.sqlCreated file e4q2.sql;

SQL> START e4q2.sqlSQL> EDIT e4q2.sql

SELECT empno, ename, sal,ROUND(sal * 1.15, 0) "New Salary",ROUND(sal * 1.15, 0) - sal "Increase"

FROM emp/

SQL> START e4q2.sql

SQL> SELECT ename, hiredate, 2 TO_CHAR(NEXT_DAY(ADD_MONTHS(hiredate, 6), 3 'MONDAY'), 4 'fmDay, "the" Ddspth "of" Month, YYYY') REVIEW 5 FROM emp;

Page 504: Introdução ao Oracle 8i

Funções Básicas

6. Mostre o nome de cada empregado e calcule o número de meses entre a data atual e a data na qual ele foi contratado. Coloque o alias da coluna como “MONTHS_WORKED”. Ordene o resultado pelo número de meses trabalhados. Arredonde o número de meses para o número inteiro mais próximo.

7. Escreva uma consulta que reproduza o seguinte para cada empregado, colocando o alias da coluna como “Dream Salaries”.

Se houver tempo, complete os seguintes exercícios:

8. Crie uma consulta para exibir o nome e o salário para todos os empregados. Formate o salário para 15 caracteres de tamanho, preenchendo os espaços à esquerda com o caractere “$”. Coloque o alias da coluna como “SALARY”.

9. Escreva uma consulta que mostre o nome do empregado com a primeira letra em maiúscula e as demais em minúsculas, juntamente com o tamanho de seu nome, para todos os empregados cujo nome inicie com a letra J, A ou M. Coloque um alias apropriado para cada coluna.

10. Mostre o nome, a data de admissão e o dia da semana no qual o empregado começou a trabalhar. Coloque o alias da coluna como “DAY”. Ordene o resultado pelo dia da semana, começando com “Monday”.

Se você quiser um desafio extra, complete os exercícios seguintes:

11. Crie uma consulta que mostre o nome do empregado e o valor da comissão. Se o empregado não recebe comissão, mostre a string “No Commission”. Coloque o alias de coluna como “COMM”.

On Targget Treinamento e Consultoria A-7

SQL> SELECT ename, ROUND(MONTHS_BETWEEN 2 (SYSDATE, hiredate)) MONTHS_WORKED 3 FROM emp 4 ORDER BY MONTHS_BETWEEN(SYSDATE, hiredate);

SQL> SELECT ename || ' earns ' 2 || TO_CHAR(sal, 'fm$99,999.00') 3 || ' monthly but wants ' 4 || TO_CHAR(sal * 3, 'fm$99,999.00') 5 || '.' "Dream Salaries" 6 FROM emp;

SQL> SELECT ename, 2 LPAD(sal, 15, '$') SALARY 3 FROM emp;

SQL> SELECT INITCAP(ename) "Name", 2 LENGTH(ename) "Length" 3 FROM emp 4 WHERE ename LIKE 'J%' 5 OR ename LIKE 'M%' 6 OR ename LIKE 'A%';

SQL> SELECT ename, hiredate, 2 TO_CHAR(hiredate, 'DAY') DAY 3 FROM emp 4 ORDER BY TO_CHAR(hiredate - 1, 'd');

SQL> SELECT ename, 2 NVL(TO_CHAR(comm), 'No Commission') COMM 3 FROM emp;

Page 505: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 5

1. Escreva uma consulta para exibir o nome, o número do departamento e o nome do departamento para todos os empregados.

2. Crie uma lista única de todos os cargos que estão no departamento 30.

3. Escreva uma consulta para exibir o nome do empregado, o nome do departamento e a localização de todos os empregados que ganham comissão.

4. Mostre o nome do empregado e o nome do departamento para todos os empregados que possuem a letra A no nome. Salve o comando SQL em um arquivo chamado e5q4.sql.

5. Escreva uma consulta para exibir o nome, o cargo, o número do departamento e o nome do departamento para todos os empregados que trabalham em DALLAS.

6. Mostre o nome e o número do empregado juntamento com o nome e o número de seu gerente. Coloque o alias de coluna como “Employee”, “Emp#”, “Manager” e “Mgr#”, respectivamente. Salve o comando SQL para um arquivo chamado e5q6.sql.

7. Modifique a consulta em e5q6.sql para exibir todos os empregados, incluindo o empregado com nome KING, que não possui gerente. Salve a nova consulta para um arquivo chamado e5q7.sql e execute-a.

Se houver tempo, complete os seguintes exercícios:

8. Crie uma consulta que mostre o nome do empregado, o número do departamento e todos os empregados que trabalham no mesmo departamento do empregado. Forneça para cada coluna um alias apropriado.

9. Mostre a estrutura da tabela SALGRADE. Crie uma consulta que mostre o nome, o cargo, o número do departamento, o salário e o nível do salário (grau) para todos os empregados.

Se você quiser um desafio extra, complete os exercícios seguintes:

10. Crie uma consulta para exibir o nome e a data de admissão de qualquer empregado admitido após o empregado BLAKE.

On Targget Treinamento e Consultoria A-8

SQL> SELECT e.ename, e.deptno, d.dname 2 FROM emp e, dept d 3 WHERE e.deptno = d.deptno;

SQL> SELECT DISTINCT e.job, d.loc 2 FROM emp e, dept d 3 WHERE e.deptno = d.deptno 4 AND e.deptno = 30;

SQL> SELECT e.ename, d.dname, d.loc 2 FROM emp e, dept d 3 WHERE e.deptno = d.deptno 4 AND e.comm IS NOT NULL;

SQL> SELECT e.ename, d.dname 2 FROM emp e, dept d 3 WHERE e.deptno = d.deptno 4 AND e.ename LIKE '%A%';

SQL> SELECT e.ename, e.job, e.deptno, d.dname 2 FROM emp e, dept d 3 WHERE e.deptno = d.deptno 4 AND d.loc = 'DALLAS';

SQL> SELECT e.ename "Employee", e.empno "Emp#", 2 m.ename "Manager", m.empno "Mgr#" 3 FROM emp e, emp m 4 WHERE e.mgr = m.empno;SQL> SAVE e5q6.sqlCreated file e54q6.sql

SQL> EDIT e5q6.sql

SELECT e.ename "Employee", e.empno "Emp#",m.ename "Manager", m.empno "Mgr#"

FROM emp e, emp mWHERE e.mgr = m.empno(+)/

SQL> START e5q7.sql

SQL> SELECT e.deptno department, e.ename employee, 2 c.ename colleague 3 FROM emp e, emp c 4 WHERE e.deptno = c.deptno 5 AND e.empno <> c.empno 6 ORDER BY e.deptno, e.ename, c.ename;

SQL> DESCRIBE salgradeSQL> SELECT e.ename, e.job, d.dname, e.sal, s.grade 2 FROM emp e, dept d, salgrade s 3 WHERE e.deptno = d.deptno 4 AND e.sal BETWEEN s.losal AND s.hisal;

Page 506: Introdução ao Oracle 8i

Funções Básicas

11. Mostre os nomes dos empregados e as datas de admissão juntamente com o nome e a data de admissão do gerente para todos os empregados que foram admitidos antes do seu gerente. Coloque o alias das colunas como “Employee”, “Emp Hiredate”, “Manager” e “Mgr Hiredate”, respectivamente.

12. Crie uma consulta que mostre o nome dos empregados e o valor dos salários indicado através de asteriscos. Cada asterisco deve representar cem dólares. Ordene os dados em ordem descendente de salário. Coloque o alias da coluna como “EMPLOYEE_AND_THEIR_SALARIES”.

On Targget Treinamento e Consultoria A-9

SQL> SELECT emp.ename, emp.hiredate 2 FROM emp, emp blake 3 WHERE blake.ename = 'BLAKE' 4 AND blake.hiredate < emp.hiredate;

SQL> SELECT e.ename "Employee", e.hiredate "Emp Hiredate", 2 m.ename "Manager", m.hiredate "Mgr Hiredate" 3 FROM emp e, emp m 4 WHERE e.mgr = m.empno 5 AND e.hiredate < m.hiredate;

SQL> SELECT rpad(ename, 8) ||rpad(' ', sal/100, '*') 2 EMPLOYEE_AND_THEIR_SALARIES 3 FROM emp 4 ORDER BY sal DESC;

Page 507: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 6

Determine a validade das seguintes declarações, circulando a palavra Verdadeiro ou Falso.

1. Funções de grupo atuam sobre muitas linhas para produzir um único resultado.

Verdadeiro

2. Funções de grupo incluem nulos nos cálculos.

Falso

3. A cláusula WHERE restringe as linhas antes de incluí-las em um cálculo de grupo.

Verdadeiro

4. Mostre o maior, o menor, a soma e a média do salário de todos os empregados. Coloque o alias das colunas como "Maximum", "Minimum", "Sum" e "Average", respectivamente. Arredonde os resultados para a posição decimal. Salve o comando SQL em um arquivo chamado e6q4.sql.

5. Modifique a consulta em e6q4.sql para exibir o menor, o maior, a soma e a média do salário para cada tipo de cargo. Salve o novo comando para e6q5.sql. Execute a consulta.

6. Escreva uma consulta para exibir o número de pessoas com o mesmo cargo.

7. Determine o número de gerentes sem listá-los. Coloque o alias da coluna como “Number of Managers”.

8. Escreva uma consulta que mostre a diferença entre o maior e menor salários. Coloque o alias da coluna como “DIFFERENCE”.

Se houver tempo, complete os seguintes exercícios:

9. Mostre o número do gerente e o mais baixo salário dentre os empregados associados para aquele gerente. Exclua qualquer um onde o código do gerente não é conhecido. Exclua qualquer grupo onde o salário mínimo é menor que $1000. Ordene o resultado em ordem descendente de salário.

On Targget Treinamento e Consultoria A-10

SQL> SELECT ROUND(MAX(sal),0) "Maximum", 2 ROUND(MIN(sal),0) "Minimum", 3 ROUND(SUM(sal),0) "Sum", 4 ROUND(AVG(sal),0) "Average" 5 FROM emp;SQL> SAVE e6q4.sqlCreated file e6q4.sql

SQL> EDIT e6q4.sql

SELECT job, ROUND(MAX(sal),0) "Maximum",ROUND(MIN(sal),0) "Minimum",ROUND(SUM(sal),0) "Sum",ROUND(AVG(sal),0) "Average"

FROM empGROUP BY job/

SQL> START e6q5.sql

SQL> SELECT job, COUNT(*) 2 FROM emp 3 GROUP BY job;

SQL> SELECT COUNT(DISTINCT mgr) "Number of Managers" 2 FROM emp;

SQL> SELECT MAX(sal) - MIN(sal) DIFFERENCE 2 FROM emp;

Page 508: Introdução ao Oracle 8i

Funções Básicas

10. Escreva uma consulta para exibir o nome do departamento, o nome da localização, o número de empregados e a média de salário para todos os empregados daquele departamento. Coloque os alias de coluna como “DNAME”, “LOC”, “Number of People” e “Salary”, respectivamente.

Se você quiser um desafio extra, complete os exercícios seguintes:

11. Crie uma consulta que mostre o número total de empregados e o número total de empregados contratados em 1980, 1981, 1982 e 1983. Forneça cabeçalhos de coluna apropriados.

12. Crie uma consulta tipo matriz para exibir o cargo, o salário para aquele cargo baseado no número de departamento e o salário total para aquele cargo para todos os departamentos, fornecendo para cada coluna um cabeçalho apropriado.

On Targget Treinamento e Consultoria A-11

SQL> SELECT mgr, MIN(sal) 2 FROM emp 3 WHERE mgr IS NOT NULL 4 GROUP BY mgr 5 HAVING MIN(sal) > 1000 6 ORDER BY MIN(sal) DESC;

SQL> SELECT d.dname, d.loc, COUNT(*) "Number of People", 2 ROUND(AVG(sal),2) "Salary" 3 FROM emp e, dept d 4 WHERE e.deptno = d.deptno 5 GROUP BY d.dname, d.loc;

SQL> SELECT COUNT(*) total, 2 SUM(DECODE(TO_CHAR(hiredate, 'YYYY'), 3 1980,1,0)) "1980", 4 SUM(DECODE(TO_CHAR(hiredate, 'YYYY'), 5 1981,1,0)) "1981", 6 SUM(DECODE(TO_CHAR(hiredate, 'YYYY'), 7 1982,1,0)) "1982", 8 SUM(DECODE(TO_CHAR(hiredate, 'YYYY'), 9 1983,1,0)) "1983" 10 FROM emp;

SQL> SELECT job "Job", 2 SUM(DECODE(deptno, 10, sal)) "Dept 10", 3 SUM(DECODE(deptno, 20, sal)) "Dept 20", 4 SUM(DECODE(deptno, 30, sal)) "Dept 30", 5 SUM(sal) "Total" 6 FROM emp 7 GROUP BY job;

Page 509: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 7

1. Escreva uma consulta para exibir o nome do empregado e a data de admissão para todos os empregados que estão no mesmo departamento do empregado BLAKE, excluindo-o do resultado.

2. Crie uma consulta para exibir o número do empregado e o nome para todos os empregados que ganham mais que a média de salário. Classifique o resultado em ordem descendente de salário.

3. Escreva uma consulta que mostre o número do empregado e o nome para todos os empregados que trabalham em um departamento com qualquer empregado cujo nome contenha uma letra T. Salve o comando SQL para um arquivo chamado e7q3.sql.

4. Mostre o nome do empregado, o número do departamento e o cargo para todos os empregados cujo o departamento localize-se em DALLAS.

5. Mostre o nome do empregado e o salário de todos os empregados gerenciados por KING.

6. Mostre o número do departamento, o nome e o cargo para todos os empregados que estão em um dos departamentos SALES.

Se houver tempo, complete os seguintes exercícios:

7. Modifique a consulta em e7q3.sql para exibir o número do empregado, o nome e o salário para todos os empregados que ganham mais que a média de salário e que trabalham em um departamento com qualquer empregado com um letra T em seu nome. Salve o novo comando para e7q7.sql e execute.

On Targget Treinamento e Consultoria A-12

SQL> SELECT ename, hiredate 2 FROM emp 3 WHERE deptno IN (SELECT deptno 4 FROM emp 5 WHERE ename = 'BLAKE') 6 AND ename != 'BLAKE';

SQL> SELECT empno, ename 2 FROM emp 3 WHERE sal > (SELECT AVG(sal) 4 FROM emp) 5 ORDER BY sal DESC;

SQL> SELECT empno, ename 2 FROM emp 3 WHERE deptno IN (SELECT deptno 4 FROM emp 5 WHERE ename LIKE '%T%');SQL> SAVE e7q3.sqlCreated file e7q3.sql

SQL> SELECT ename, deptno, job 2 FROM emp 3 WHERE deptno IN (SELECT deptno 4 FROM dept 5 WHERE loc = 'DALLAS');

SQL> SELECT ename, sal 2 FROM emp 3 WHERE mgr IN (SELECT empno 4 FROM emp 5 WHERE ename = 'KING');

SQL> SELECT deptno, ename, job 2 FROM emp 3 WHERE deptno IN (SELECT deptno 4 FROM dept 5 WHERE dname = 'SALES');

SQL> EDIT e7q3.sql

SELECT empno, ename, salFROM empWHERE sal > (SELECT AVG(sal)

FROM emp)AND deptno IN (SELECT deptno

FROM emp WHERE ename LIKE '%T%')

/

SQL> START e7q7.sql

Page 510: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 8

1. Escreva uma consulta para exibir o nome, o número do departamento e o salário de qualquer empregado cujo o número do departamento e o salário correspondam ambos ao número do departamento e ao salário de qualquer empregado que ganha comissão.

2. Mostre o nome, o nome do departamento e o salário de qualquer empregado cujo salário e comissão correspondam ambos ao salário e comissão de qualquer empregado localizado em DALLAS.

3. Crie uma consulta para exibir o nome, a data de admissão e o salário para todos os empregados que possuem o mesmo salário e comissão que SCOTT.

4. Crie uma consulta para exibir os empregados que ganham um salário maior que o salário de qualquer empregado com o cargo CLERK. Classifique o resultado do maior para o menor salário.

On Targget Treinamento e Consultoria A-13

SQL> SELECT ename, deptno, sal 2 FROM emp 3 WHERE (sal, deptno) IN 4 (SELECT sal, deptno 5 FROM emp 6 WHERE comm IS NOT NULL);

SQL> SELECT ename, dname, sal 2 FROM emp e, dept d 3 WHERE e.deptno = d.deptno 4 AND (sal, NVL(comm,0)) IN 5 (SELECT sal, NVL(comm,0) 6 FROM emp e, dept d 7 WHERE e.deptno = d.deptno 8 AND d.loc = 'DALLAS');

SQL> SELECT ename, hiredate, sal 2 FROM emp 3 WHERE (sal, NVL(comm,0)) IN 4 (SELECT sal, NVL(comm,0) 5 FROM emp 6 WHERE ename = 'SCOTT') 7 AND ename != 'SCOTT';

SQL> SELECT ename, job, sal 2 FROM emp 3 WHERE sal > ALL (SELECT sal 4 FROM emp 5 WHERE job = 'CLERK') 6 ORDER BY sal DESC;

Page 511: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 9

Determine se as seguintes declarações são verdadeiras ou falsas:

1. Uma variável de substituição criada com o símbolo (&) é solicitada ao usuário uma única vez.

Verdadeiro

2. O comando ACCEPT é um comando SQL.

Falso

3. Escreva um arquivo de script para mostrar o nome do empregado, o cargo e a data de admissão para todos os empregados que foram admitidos entre um determinado período. Concatene o nome e o cargo, separando-os por uma vírgula e espaço, e coloque o alias da coluna como “Employees”. Solicite ao usuário os dois intervalos do período utilizando o comando ACCEPT. Utilize o formato MM/DD/YY. Salve o script para um arquivo chamado e9q3.sql.

4. Escreva um script para mostrar o nome do empregado, o cargo e o nome do departamento. A condição de pesquisa deve permitir que a procura não faça distinção entre maiúsculas e minúsculas. Salve o script para um arquivo chamado e9q4.sql.

5. Modifique o arquivo e9q4.sql para criar um relatório contendo o nome do departamento, o nome do empregado, a data de admissão, o salário e o salário anual para todos os empregados em uma determinada localização. Solicite ao usuário a localização. Coloque o alias das colunas como “DEPARTMENT NAME”, “EMPLOYEE NAME”, “START DATE”, “SALARY”, “ANNUAL SALARY”, colocando os alias em múltiplas linhas. Save o novo script para um arquivo chamado e9q5.sql.

On Targget Treinamento e Consultoria A-14

SET ECHO OFFSET VERIFY OFFACCEPT low_date DATE FORMAT 'MM/DD/YY' – PROMPT 'Please enter the low date range (''MM/DD/YY''): 'ACCEPT high_date DATE FORMAT 'MM/DD/YY' – PROMPT 'Please enter the high date range (''MM/DD/YY''): 'COLUMN EMPLOYEES FORMAT A25

SELECT ename ||', '|| job EMPLOYEES, hiredateFROM empWHERE hiredate BETWEEN TO_DATE('&low_date', 'MM/DD/YY')

AND TO_DATE('&high_date', 'MM/DD/YY')/UNDEFINE low_dateUNDEFINE high_dateCOLUMN EMPLOYEES CLEARSET VERIFY ONSET ECHO ON

SQL> START e9q3.sql;

SET ECHO OFFSET VERIFY OFFACCEPT p_location PROMPT 'Please enter the location name: 'COLUMN ename HEADING "EMPLOYEE NAME" FORMAT A15COLUMN dname HEADING "DEPARTMENT NAME" FORMAT A15

SELECT e.ename, e.job, d.dnameFROM emp e, dept dWHERE e.deptno = d.deptno AND LOWER(d.loc) LIKE LOWER('%&p_location%')/UNDEFINE p_locationCOLUMN ename CLEARCOLUMN dname CLEARSET VERIFY ONSET ECHO ON

SQL> START e9q4.sql

Page 512: Introdução ao Oracle 8i

Funções Básicas

On Targget Treinamento e Consultoria A-15

SET ECHO OFFSET FEEDBACK OFFSET VERIFY OFFBREAK ON dnameACCEPT p_location PROMPT 'Please enter the location name: 'COLUMN dname HEADING "DEPARTMENT|NAME" FORMAT A15COLUMN ename HEADING "EMPLOYEE|NAME" FORMAT A15COLUMN hiredate HEADING "START|DATE" FORMAT A15COLUMN sal HEADING "SALARY" FORMAT $99,990.00COLUMN asal HEADING "ANNUAL|SALARY" FORMAT $99,990.00

SELECT d.dname, e.ename, e.hiredate,e.sal, e.sal * 12 asal

FROM emp e, dept dWHERE e.deptno = d.deptno AND LOWER(d.loc) LIKE LOWER('%&p_location%')ORDER BY dname/UNDEFINE p_locationCOLUMN dname CLEARCOLUMN ename CLEARCOLUMN hiredate CLEARCOLUMN sal CLEAR COLUMN asal CLEARCLEAR BREAKSET VERIFY ONSET FEEDBACK ONSET ECHO ON

SQL> START e9q5.sql

Page 513: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 10

Insira dados na tabela MY_EMPLOYEE.

1. Execute o script lab10_1.sql para construir a tabela MY_EMPLOYEE que será utilizado nos exercícios.

2. Descreva a estrutura da tabela MY_EMPLOYEE para identificar os nomes das colunas.

3. Adicione a primeira linha de dados na tabela MY_EMPLOYEE a partir do exemplo de dados abaixo. Não liste as colunas na cláusula INSERT.

ID LAST_NAME FIRST_NAME USERID SALARY1 Patel Ralph rpatel 7952 Dancs Betty bdancs 8603 Biri Ben bbiri 11004 Newman Chad cnewman 7505 Ropeburn Audry aropebur 1550

4. Popule a tabela MY_EMPLOYEE com a segunda linha do exemplo de dados acima. Neste momento, liste as colunas explicitamente na cláusula INSERT.

5. Confirme sua inserção para a tabela.

6. Crie um script chamado loademp.sql para inserir linhas na tabela MY_EMPLOYEE interativamente. Solicite ao usuário o primeiro nome do empregado, o último nome e o salário. Concatene a primeira letra do primeiro nome com os primeiros sete caracteres do último nome para produzir o valor para a coluna USERID.

7. Popule a tabela com as próximas duas linhas de exemplo de dados executando o script criado.

On Targget Treinamento e Consultoria A-16

SQL> START lab9_1.sql

SQL> DESCRIBE my_employee

SQL> INSERT INTO my_employee 2 VALUES (1, 'Patel', 'Ralph', 'rpatel', 795);

SQL> INSERT INTO my_employee (id, last_name, first_name, 2 userid, salary) 3 VALUES (2, 'Dancs', 'Betty', 'bdancs', 860);

SQL> SELECT * 2 FROM my_employee;

SET ECHO OFFSET VERIFY OFFACCEPT p_first_name PROMPT 'Please enter the employee's first name: 'ACCEPT p_last_name PROMPT 'Please enter the employee's last name: 'ACCEPT p_id PROMPT 'Please enter the employee number: 'ACCEPT p_salary PROMPT 'Please enter the employee's salary: '

INSERT INTO my_employee VALUES (&p_id, '&p_last_name', '&p_first_name',

substr('&p_first_name', 1, 1) || substr('&p_last_name', 1, 7), &p_salary)

/SET VERIFY ONSET ECHO ON

Page 514: Introdução ao Oracle 8i

Funções Básicas

8. Confirme suas inserções para a tabela.

9. Torne as inserções permanentes.

Atualize e remova dados da tabela MY_EMPLOYEE.

10. Modifique o último nome do empregado 3 para “Drexler”.

11. Modifique o salário para 1000 para todos os empregados com o salário menor que 900.

12. Verifique suas modificações para a tabela.

13. Remova o empregado “Betty Dancs” da tabela MY_EMPLOYEE.

14. Confirme suas modificações para a tabela.

15. Execute o commit de todas as modificações pendentes.

16. Popule a tabela com a última linha do exemplo de dados executando o script criado no exercício 6.

17. Confirme sua inserção para a tabela.

18. Marque um ponto intermediário no processamento da transação.

19. Apague a tabela inteira.

20. Confirme que a tabela está vazia.

21. Descarte a mais recente operação DELETE sem descartar a operação de INSERT anterior.

22. Confirme que a nova linha permanece intacta.

23. Torne a inserção dos dados permanente.

On Targget Treinamento e Consultoria A-17

SQL> START loademp.sqlSQL> START loademp.sqlSQL> SELECT * 2 FROM my_employee;SQL> COMMIT;SQL> UPDATE my_employee 2 SET last_name = 'Drexler' 3 WHERE id = 3;

SQL> UPDATE my_employee 2 SET salary = 1000 3 WHERE salary < 900;

SQL> SELECT last_name, salary 2 FROM my_employee;SQL> DELETE 2 FROM my_employee 3 WHERE last_name = 'Dancs' 4 AND first_name = 'Betty';

SQL> SELECT * 2 FROM my_employee;SQL> COMMIT;SQL> START loademp.sqlSQL> SELECT * 2 FROM my_employee;SQL> SAVEPOINT a;SQL> DELETE 2 FROM my_employee;SQL> SELECT * 2 FROM my_employee;SQL> ROLLBACK TO SAVEPOINT a;SQL> SELECT * 2 FROM my_employee;SQL> COMMIT;

Page 515: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 11

1. Crie a tabela DEPARTMENT baseado no gráfico abaixo. Salve a sintaxe para um arquivo chamado e11q1.sql e então execute-o para criar a tabela. Confirme que a tabela foi criada.

Nome da Coluna ID NAMETipo de ChaveNulos/UniqueTabela (FK)Coluna (FK)Tipo de Dado Number Varchar2Tamanho 7 25

2. Popule a tabela DEPARTMENT com dados a partir da tabela DEPT. Inclua somente as colunas necessárias.

3. Crie a tabela EMPLOYEE baseado no gráfico abaixo. Salve a sintaxe em um arquivo chamado e11q3.sql e execute-o para criar a tabela. Confirme que a tabela foi criada.

Nome da Coluna ID LAST_NAME FIRST_NAME DEPT_IDTipo de ChaveNulos/UniqueTabela (FK)Coluna (FK)Tipo de Dado Number Varchar2 Varchar2 NumberTamanho 7 25 25 7

On Targget Treinamento e Consultoria A-18

SQL> EDIT e11q1.sql

CREATE TABLE department (id NUMBER(7), name VARCHAR2(25))/SQL> START e11q1.sqlSQL> DESCRIBE department

SQL> INSERT INTO department 2 SELECT deptno, dname 3 FROM dept;

CREATE TABLE employee (id NUMBER(7), last_name VARCHAR2(25), first_name VARCHAR2(25), dept_id NUMBER(7))/SQL> START e11q3.sqlSQL> DESCRIBE employee

Page 516: Introdução ao Oracle 8i

Funções Básicas

4. Modifique a coluna LAST_NAME da tabela EMPLOYEE para permitir o uso de nomes de maior tamanho. Confirme sua modificação.

5. Confirme que as tabelas DEPARTMENT e EMPLOYEE estão armazenadas no dicionário de dados (USER_TABLES).

6. Crie a tabela EMPLOYEE2 baseado na estrutura da tabela EMP, incluindo somente as colunas EMPNO, ENAME e DEPTNO. Coloque o nome das colunas na tabela nova como ID, LAST_NAME e DEPT_ID, respectivamente.

7. Remova a tabela EMPLOYEE.

8. Altere o nome da tabela EMPLOYEE2 para EMPLOYEE.

9. Adicione um comentário para a definição das tabelas DEPARTMENT e EMPLOYEE que as descreva. Confirme sua adição no dicionário de dados.

On Targget Treinamento e Consultoria A-19

SQL> ALTER TABLE employee 2 MODIFY (last_name VARCHAR2(50));SQL> DESCRIBE employee

SQL> SELECT table_name 2 FROM user_tables 3 WHERE table_name IN ('DEPARTMENT', 'EMPLOYEE');

SQL> CREATE TABLE employee2 AS 2 SELECT empno id, ename last_name, deptno dept_id 3 FROM emp;

DROP TABLE employee;SQL> RENAME employee2 TO employee;SQL> COMMENT ON TABLE employee IS 'Employee Information';SQL> COMMENT ON TABLE department IS 'Department Information';SQL> COLUMN table_name FORMAT A15SQL> COLUMN table_type FORMAT A10SQL> COLUMN comments FORMAT A40SQL> SELECT * 2 FROM user_tab_comments 3 WHERE table_name = 'DEPARTMENT' 4 OR table_name = 'EMPLOYEE';

Page 517: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 12

1. Adicione a nível de tabela uma constraint PRIMARY KEY para a tabela EMPLOYEE utilizando a coluna ID. A constraint deve ficar habilitada na criação.

2. Crie uma constraint PRIMARY KEY na tabela DEPARTMENT utilizando a coluna ID. A constraint deve ficar habilitada na criação.

3. Adicione uma referência de chave estrangeira para a tabela EMPLOYEE que garanta que o empregado não seja associado para um departamento não existente.

4. Confirme que as constraints foram adicionadas consultando a visão USER_CONSTRAINTS. Observe os tipos e nomes das constraints. Salve o comando em um arquivo chamado e12q4.sql.

5. Modifique a tabela EMPLOYEE. Adicione uma coluna SALARY com o tipo de dado NUMBER(7).

On Targget Treinamento e Consultoria A-20

SQL> ALTER TABLE employee 2 ADD CONSTRAINT employee_id_pk PRIMARY KEY (id);SQL> ALTER TABLE department 2 ADD CONSTRAINT department_id_pk PRIMARY KEY(id);

SQL> ALTER TABLE employee 2 ADD CONSTRAINT employee_dept_id_fk FOREIGN KEY (dept_id) 3 REFERENCES department(id);

SQL> SELECT constraint_name, constraint_type 2 FROM user_constraints 3 WHERE table_name IN ('EMPLOYEE', 'DEPARTMENT');SQL> SAVE e12q4.sql

SQL> ALTER TABLE employee 2 ADD (salary NUMBER(7));

Page 518: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 13

1. Crie uma visão chamada EMP_VU baseada no número do empregado, nome e no número do departamento a partir da tabela EMP. Modifique o cabeçalho para o nome do empregado para “EMPLOYEE”.

2. Mostre o conteúdo da visão EMP_VU.

3. Selecione a coluna VIEW_NAME e TEXT a partir da tabela do dicionário de dados USER_VIEWS.

4. Utilizando a visão EMP_VU, execute uma consulta para exibir todos os nomes de empregados e números de departamentos.

5. Crie uma visão chamada DEPT20 que contenha o número do empregado, o nome e o número do departamento para todos os empregados do departamento 20. Coloque os alias das colunas da visão como “EMPLOYEE_ID”, “EMPLOYEE” e “DEPARTMENT_ID”. Não permita que um empregado seja atribuído a outro departamento pela visão.

On Targget Treinamento e Consultoria A-21

SQL> CREATE VIEW emp_vu AS 2 SELECT empno, ename employee, deptno 3 FROM emp;

SQL> SELECT * 2 FROM emp_vu;SQL> COLUMN view_name FORMAT A30SQL> COLUMN text FORMAT A50SQL> SELECT view_name, text 2 FROM user_views;

SQL> SELECT employee, deptno 2 FROM emp_vu;SQL> CREATE VIEW dept20 AS 2 SELECT empno employee_id, ename employee, 3 deptno department_id 4 FROM emp 5 WHERE deptno = 20 6 WITH CHECK OPTION CONSTRAINT emp_dept_20;

Page 519: Introdução ao Oracle 8i

Funções Básicas

6. Mostre a estrutura e o conteúdo da visão DEPT20.

7. Tente alterar o departamento do empregado SMITH para 30 através da visão.

Se houver tempo, complete os seguintes exercícios:

8. Crie uma visão chamada SALARY_VU baseada no nome do empregado, nome do departamento, salário e nível do salário para todos os empregados. Coloque o alias das colunas como “Employee”, “Department”, “Salary” e “Grade”, respectivamente.

On Targget Treinamento e Consultoria A-22

SQL> DESCRIBE dept20SQL> SELECT * 2 FROM dept20;

SQL> UPDATE dept20 2 SET department_id = 30 3 WHERE employee = 'SMITH';

SQL> CREATE VIEW salary_vu AS 2 SELECT ename employee, dname department, 3 sal salary, grade 4 FROM emp e, dept d, salgrade s 5 WHERE e.deptno = d.deptno 6 AND e.sal between s.losal and s.hisal;

Page 520: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 14

1. Crie uma seqüência para ser utilizada com a coluna da chave primária da tabela DEPARTMENT. A seqüência deve iniciar em 60 e possuir um valor máximo de 200. Forneça para a seqüência um incremento de 10 e o nome como DEPT_ID_SEQ.

2. Crie um arquivo de script para exibir a seguinte informação sobre suas seqüências: o nome da seqüência, o valor máximo, o incremento e o último número fornecido. Coloque o nome do arquivo como e14q2.sql. Execute o script criado.

3. Escreva um script interativo para inserir uma linha na tabela DEPARTMENT. Coloque o nome do arquivo como e14q3.sql. Utilize a seqüência que você criou para a coluna ID. Crie um prompt customizado para solicitar o nome do departamento. Execute o script adicionando dois departamentos chamados “Education” e “Administration”. Confirme as inserções.

4. Crie um índice não único para a coluna definida como FOREIGN KEY na tabela EMPLOYEE.

5. Mostre os índices que existem no dicionário de dados para a tabela EMPLOYEE. Salve o comando para um script chamado e14q5.sql.

On Targget Treinamento e Consultoria A-23

SQL> CREATE SEQUENCE dept_id_seq 2 START WITH 60 3 INCREMENT BY 10 4 MAXVALUE 200;

SQL> EDIT e14q2.sql

SELECT sequence_name, max_value,increment_by, last_number

FROM user_sequences/SQL> START e14q2.sql

SQL> EDIT e14q3.sql

SET ECHO OFFSET VERIFY OFFACCEPT name PROMPT 'Please enter the department name: '

INSERT INTO department (id, name) VALUES (dept_id_seq.NEXTVAL, '&name')/SET VERIFY ONSET ECHO ONSQL> START e14q3.sqlSQL> SELECT * 2 FROM department;

SQL> CREATE INDEX employee_dept_id_idx 2 ON employee (dept_id);SQL> SELECT index_name, table_name, uniqueness 2 FROM user_indexes 3 WHERE table_name = 'EMPLOYEE';SQL> SAVE e14q5.sql

Page 521: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 15

1. Que privilégio um usuário necessita para conectar ao Servidor Oracle? Este privilégio é um privilégio de sistema ou objeto?

CREATE SESSION – Privilégio de sistema

2. Que privilégio é necessário fornecer para um usuário poder criar tabelas?

CREATE TABLE

3. Se você criar uma tabela, quem pode fornecer privilégios para outros usuários sobre esta tabela?

Você ou qualquer um para quem você tenha passado os privilégios com WITH GRANT OPTION.

4. Você é um DBA e está criando vários usuários que necessitam dos mesmos privilégios de sistema. O que você pode utilizar para facilitar seu trabalho?

Crie uma role contendo os privilégios de sistema e passe a role para os usuários.

5. Que comando você utiliza para alterar a sua senha?

ALTER USER

6. Conceda a outro usuário acesso para a sua tabela DEPT. Solicite a este outro usuário que também conceda a você acesso de consulta para a tabela DEPT dele.

7. Consulte todas as linhas da sua tabela DEPT.

8. Adicione uma nova linha para a tabela DEPT. O grupo 1 deve inserir “Education” como o departamento número 50. O grupo 2 deve inserir “Administration” também como o departamento número 50. Torne as modificações permanentes.

9. Crie um sinônimo para a tabela DEPT do outro grupo.

10. Consulte todas as linhas da tabela DEPT do outro grupo utilizando o sinônimo.

11. Consulte a visão do dicionário de dados USER_TABLES para visualizar as tabelas que você possui.

12. Consulte a visão do dicionário de dados ALL_TABLES para visualizar todas as tabelas que você possui acesso. Exclua as tabelas que foram criadas por você.

13. Revogue o privilégio SELECT do outro grupo.

On Targget Treinamento e Consultoria A-24

Grupo 2.SQL> GRANT select 2 ON dept 3 TO <user1>;

Grupo 1.SQL> GRANT select 2 ON dept 3 TO <user2>;

SQL> SELECT * 2 FROM dept;Grupo 1.SQL> INSERT INTO dept (deptno, dname) 2 VALUES (50, 'Education');SQL> COMMIT;

Grupo 2.SQL> INSERT INTO dept (deptno, dname) 2 VALUES (50, 'Administration');SQL> COMMIT;

Grupo 1.SQL> CREATE SYNONYM grupo2 2 FOR <user2>.DEPT;

Grupo 2.SQL> CREATE SYNONYM grupo1 2 FOR <user1>.DEPT;

Grupo 1.SQL> SELECT * 2 FROM grupo2;

Grupo 2.SQL> SELECT * 2 FROM grupo1;

SQL> SELECT table_name 2 FROM user_tables;SQL> SELECT table_name, owner 2 FROM all_tables 3 WHERE owner != <your account>;

Page 522: Introdução ao Oracle 8i

Funções Básicas

On Targget Treinamento e Consultoria A-25

Grupo 1.SQL> REVOKE select 2 ON dept 3 FROM user2;

Grupo 2.SQL> REVOKE select 2 ON dept 3 FROM user1;

Page 523: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 16

1. Analise cada uma das seguintes declarações. Determine qual delas não estão corretas e explique o motivo.

a. Correto

b. Incorreto porque só é permitido um identificador por declaração.

c. Incorreto porque uma variável NOT NULL deve ser inicializada.

d. Incorreto porque 1 não é uma expressão boleana.

e. Correto.

On Targget Treinamento e Consultoria A-26

DECLARE v_id NUMBER(4);DECLARE v_x, v_y, v_z VARCHAR2(10);DECLARE v_birthdate DATE NOT NULL;DECLARE v_in_stock BOOLEAN := 1;DECLARE TYPE name_table_type IS TABLE OF VARCHAR2(20) INDEX BY BINARY_INTEGER; dept_name_table name_table_type;

Page 524: Introdução ao Oracle 8i

Funções Básicas

2. Em cada uma das seguintes atribuições, determine o tipo de dado resultante da expressão.

a. Numérico

b. String caractere

c. Incorreto. PL/SQL não converte símbolos especiais VARCHAR2 para NUMBER

d. Boleano

e. Boleano

f. Qualquer tipo de dado escalar

3. Crie um bloco anônimo para exibir a frase “My PL/SQL Block Works” para a tela.

On Targget Treinamento e Consultoria A-27

v_days_to_go := v_due_date - SYSDATE;

v_sender := USER || ': ' || TO_CHAR(v_dept_no);v_sum := $100,000 + $250,000;

v_flag := TRUE;v_n1 := v_n2 > (2 * v_n3);v_value := NULL;VARIABLE g_message VARCHAR2(30)BEGIN :g_message := 'My PL/SQL Block Works';END;/PRINT g_messageSQL> START e16q3.sql

Page 525: Introdução ao Oracle 8i

Funções Básicas

Se houver tempo, complete os seguintes exercícios:

4. Crie um bloco que declare duas variáveis. Atribua o valor destas variáveis PL/SQL para variáveis host do SQL*Plus e mostre os resultados das variáveis PL/SQL na tela. Execute o bloco PL/SQL. Salve o bloco PL/SQL para um arquivo chamado e16q4.sql.

On Targget Treinamento e Consultoria A-28

VARIABLE g_char VARCHAR2(30)VARIABLE g_num NUMBER

DECLARE v_char VARCHAR2(30); v_num NUMBER(11,2);BEGIN v_char := '42 is the answer'; v_num := TO_NUMBER(SUBSTR(v_char,1,2)); :g_char := v_char; :g_num := v_num;END;/PRINT g_charPRINT g_numSQL> START e16q4.sql

Page 526: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 17

Bloco PL/SQL

1. Avalie o bloco PL/SQL acima e determine cada um dos seguintes valores de acordo com as regras de escopo.

a. O valor de V_WEIGHT no sub-bloco

“2” e o tipo de dado é NUMBER

b. O valor de V_NEW_LOCN no sub-bloco

“Western Europe” e o tipo de dado é VARCHAR2

c. O valor de V_WEIGHT no bloco principal

“601” e o tipo de dado é NUMBER

d. O valor de V_MESSAGE no bloco principal

“Product 10012 is in stock” e o tipo de dado é VARCHAR2

e. O valor de V_NEW_LOCN no bloco principal

Ilegal porque V_NEW_LOCN não é visível fora do sub-bloco

On Targget Treinamento e Consultoria A-29

DECLARE v_weight NUMBER(3) := 600; v_message VARCHAR2(255) := 'Product 10012';BEGIN

SUB-BLOCO 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; END;

v_weight := v_weight + 1; v_message := v_message || ' is in stock'; v_new_locn := 'Western ' || v_new_locn;

END;

Page 527: Introdução ao Oracle 8i

Funções Básicas

Exemplo de Escopo

2. Suponha que você inseriu um sub-bloco dentro de um bloco, como apresentado acima. Você declarou duas variáveis, V_CUSTOMER e V_CREDIT_RATING, no bloco principal. Você também declarou duas variáveis, V_CUSTOMER e V_NAME, no sub-bloco. Determine os valores para cada um dos seguintes casos.

a. O valor de V_CUSTOMER no sub-bloco

“201” e o tipo de dado é NUMBER

b. O valor de V_NAME no sub-bloco

“Unisports” e o tipo de dado é VARCHAR2

c. O valor de V_CREDIT_RATING no sub-bloco

“EXCELLENT” e o tipo de dado é VARCHAR2

d. O valor de V_CUSTOMER no bloco principal

“Womansport” e o tipo de dado é VARCHAR2

e. O valor de V_NAME no bloco principal

V_NAME não é visível no bloco principal.

f. O valor de V_CREDIT_RATING no bloco principal

“EXCELLENT” e o tipo de dado é VARCHAR2

On Targget Treinamento e Consultoria A-30

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_customer v_name v_credit_rating

END;

v_customer v_name v_credit_rating

END;

Page 528: Introdução ao Oracle 8i

Funções Básicas

3. Crie e execute um bloco PL/SQL que receba dois números através de variáveis de substituição do SQL*Plus. O primeiro número deve ser dividido pelo segundo número e então o segundo número deve ser adicionado ao resultado. O resultado deve ser escrito para uma variável PL/SQL e mostrado na tela.

4. Construa um bloco PL/SQL que calcule a gratificação total para um ano. O salário anual e o percentual de bônus anual são passados para o bloco PL/SQL através de variáveis de substituição e o bônus precisa ser convertido de um número inteiro para um número decimal (por exemplo, 15 para .15). Se o salário for nulo, atribua ele para zero antes de calcular a gratificação total. Execute o bloco PL/SQL. Lembre-se: utilize a função NVL para tratar valores nulos.

Nota: Para testar a função NVL escreva NULL no prompt; pressionando [Return] resulta em um erro de expressão.

On Targget Treinamento e Consultoria A-31

SET VERIFY OFFVARIABLE v_result NUMBERACCEPT p_num1 PROMPT 'Please enter the first number: 'ACCEPT p_num2 PROMPT 'Please enter the second number: '

DECLARE v_num1 NUMBER(9,2) := &p_num1; v_num2 NUMBER(9,2) := &p_num2;BEGIN :v_result := (v_num1/v_num2) + v_num2;END;/PRINT v_resultSET VERIFY ONSQL> START e17q3.sql

ACCEPT p_num1 PROMPT 'Please enter the first number: 'ACCEPT p_num2 PROMPT 'Please enter the second number: '

DECLARE v_num1 NUMBER(9,2) := &p_num1; v_num2 NUMBER(9,2) := &p_num2;BEGIN dbms_output.put_line(TO_CHAR(v_num1/v_num2) + v_num2);END;/

SET VERIFY OFFVARIABLE g_total NUMBERACCEPT p_salary PROMPT 'Please enter the salary amount: 'ACCEPT p_bonus PROMPT 'Please enter the bonus percentage: 'DECLARE v_salary NUMBER := &p_salary; v_bonus NUMBER := &p_bonus;BEGIN :g_total := NVL(v_salary, 0) * (1 + NVL(v_bonus, 0) / 100);END;/PRINT g_totalSET VERIFY ONSQL> START e17q4.sql

Page 529: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 18

1. Crie um bloco PL/SQL que seleciona o maior número de departamento na tabela DEPT e armazene ele em uma variável do SQL*Plus. Mostre o resultado na tela. Salve o bloco PL/SQL para um arquivo chamado e18q1.sql.

2. Crie um bloco PL/SQL que insira um novo departamento na tabela DEPT. Salve o bloco PL/SQL para um arquivo chamado e18q2.sql.

a. Utilize o número de departamento recuperado no exercício 1 e adicione 10 para ele como entrada do número do departamento para o novo departamento.

b. Utilize um parâmetro para o nome do departamento.

c. Deixe a localização nula por enquanto.

d. Execute o bloco PL/SQL.

e. Mostre o novo departamento que você criou.

3. Crie um bloco PL/SQL que atualize a localização para um departamento existente. Save o bloco PL/SQL para um arquivo chamado e18q3.sql.

a. Utilize um parâmetro para o número do departamento.

b. Utilize um parâmetro para a localização do departamento.

c. Teste o bloco PL/SQL.

d. Mostre o número, o nome e a localização para o departamento atualizado.

4. Crie um bloco PL/SQL que remova o departamento criado no exercício 2. Salve o bloco PL/SQL para um arquivo chamado e18q4.sql.

a. Utilize um parâmetro para o número do departamento.

b. Mostre na tela o número de linhas afetadas.

c. Teste o bloco PL/SQL.

On Targget Treinamento e Consultoria A-32

VARIABLE g_max_deptno NUMBERDECLARE v_max_deptno NUMBER;BEGIN SELECT MAX(deptno) INTO v_max_deptno FROM dept; :g_max_deptno := v_max_deptno;END;/PRINT g_max_deptnoSQL> START e18q1.sql

SET VERIFY OFFACCEPT p_deptno PROMPT 'Please enter the department number: 'ACCEPT p_dept_name PROMPT 'Please enter the department name: 'BEGIN INSERT INTO dept (deptno, dname, loc) VALUES (&p_deptno, '&p_dept_name', NULL); COMMIT;END;/SET VERIFY ON

SQL> START e18q2.sqlSELECT *FROM deptWHERE deptno = :g_max_deptno + 10;

SET VERIFY OFFACCEPT p_deptno PROMPT 'Please enter the department number: 'ACCEPT p_loc PROMPT 'Please enter the department location: 'BEGIN UPDATE dept SET loc = '&p_loc' WHERE deptno = &p_deptno; COMMIT;END;/SET VERIFY ONSQL> START e18q3.sql

Page 530: Introdução ao Oracle 8i

Funções Básicas

d. O que acontece se você fornecer um número de departamento que não existe?

e. Confirme que o departamento foi removido.

On Targget Treinamento e Consultoria A-33

SET VERIFY OFFVARIABLE g_result VARCHAR2(40)ACCEPT p_deptno PROMPT 'Please enter the department number: '

DECLARE v_result NUMBER(2);BEGIN DELETE FROM dept WHERE deptno = &p_deptno; v_result := SQL%ROWCOUNT; :g_result := (TO_CHAR(v_result) || ' row(s) deleted.'); COMMIT;END;/SET VERIFY ONPRINT g_resultSQL> START e18q4.sql

SQL> SELECT * 2 FROM dept 3 WHERE deptno = &p_deptno;

Page 531: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 19

1. Execute o script lab19_1.sql para criar a tabela MESSAGES. Escreva um bloco PL/SQL para inserir números na tabela MESSAGES.

a. Insira os números de 1 a 10 excluindo o 6 e 8.

b. Execute um COMMIT antes do final do bloco.

c. Selecione os dados da tabela MESSAGES para verificar se o bloco executou corretamente.

2. Crie um bloco PL/SQL que calcule a commissão para o empregado especificado baseado no salário do empregado.

a. Execute o script lab19_2.sql para inserir um novo empregado na tabela EMP.

b. Receba o número do empregado como uma variável de substituição do SQL*Plus.

c. Se o salário do empregado for menor que $1,000, atribua para a comissão do empregado o valor de 10% do seu salário.

d. Se o salário do empregado está entre $1,000 e $1,500, atribua para a comissão do empregado o valor de 15% do seu salário.

e. Se o salário do empregado for maior que $1,500, atribua para a comissão do empregado o valor de 20% do seu salário.

f. Se o salário do empregado for NULL, atribua para a comissão do empregado para 0.

g. Efetue o commit das modificações.

On Targget Treinamento e Consultoria A-34

CREATE TABLE messages (results VARCHAR2 (60))/BEGIN FOR i IN 1..10 LOOP IF i = 6 or i = 8 THEN null; ELSE INSERT INTO messages(results) VALUES (i); END IF; COMMIT; END LOOP;END;/

SQL> SELECT * 2 FROM messages;SQL> START lab19_2.sql

Page 532: Introdução ao Oracle 8i

Funções Básicas

h. Teste o bloco PL/SQL para cada um dos seguintes casos e verifique cada atualização da comissão.

Número do Empregado Salário Comissão Resultante7369 800 807934 1300 1957499 1600 3208000 NULL NULL

Se houver tempo, complete os seguintes exercícios:

3. Modifique o arquivo e16q4.sql para inserir o texto “Number is odd” ou “Numer is even” na tabela MESSAGES dependendo se o valor informado é ímpar ou par. Consulte a tabela MESSAGES para determinar se o bloco PL/SQL executou corretamente.

4. Adicione uma nova coluna para a tabela EMP para armazenar asteriscos (*).

On Targget Treinamento e Consultoria A-35

ACCEPT p_empno PROMPT 'Please enter employee number: 'DECLARE v_empno emp.empno%TYPE := &p_empno; v_sal emp.sal%TYPE; v_comm emp.comm%TYPE;BEGIN SELECT sal INTO v_sal FROM emp WHERE empno = v_empno; IF v_sal < 1000 THEN v_comm := .10; ELSIF v_sal BETWEEN 1000 and 1500 THEN v_comm := .15; ELSIF v_sal > 1500 THEN v_comm := .20; ELSE v_comm := 0; END IF; UPDATE emp SET comm = sal * v_comm WHERE empno = v_empno; COMMIT;END;/

SQL> SELECT empno, sal, comm 2 FROM emp 3 WHERE empno IN (7369, 7934,7499, 8000) 4 ORDER BY comm;

DECLARE v_char VARCHAR2(30); v_num NUMBER(11,2);BEGIN v_char := '42 is the answer'; v_num := TO_NUMBER(SUBSTR(v_char,1,2)); IF mod(v_num, 2) = 0 THEN INSERT INTO messages (results) VALUES ('Number is even'); ELSE INSERT INTO messages (results) VALUES ('Number is odd'); END IF;END;/SQL> SELECT * 2 FROM messages;

SQL> ALTER TABLE emp 2 ADD stars VARCHAR2(100);

Page 533: Introdução ao Oracle 8i

Funções Básicas

5. Crie um bloco PL/SQL que armazene na coluna STARS da tabela EMP um asterisco para cada $100 do salário do empregado. Arredonde o salário para o número inteiro mais próximo. Salve o bloco PL/SQL para um arquivo chamado e19q5.sql.

a. Receba o número do empregado como uma variável de substituição do SQL*Plus.

b. Inicialize a variável que conterá a string de asteriscos.

c. Concatene um asterisco para a string para cada $100 do valor do salário. Por exemplo, se o empregado possui um salário de $800, a string deve possuir oito asteriscos.

d. Atualize a coluna STARS para o empregado com a string de asteriscos.

e. Efetue o commit das modificações.

f. Teste o bloco para empregados que não possuem salário e para empregados que possuem um salário.

On Targget Treinamento e Consultoria A-36

SET VERIFY OFFACCEPT p_empno PROMPT 'Please enter the employee number: 'DECLARE v_empno emp.empno%TYPE := &p_empno; v_asterisk emp.stars%TYPE := NULL; v_sal emp.sal%TYPE;BEGIN SELECT NVL(ROUND(sal/100), 0) INTO v_sal FROM emp WHERE empno = v_empno; FOR i IN 1..v_sal LOOP v_asterisk := v_asterisk ||'*'; END LOOP; UPDATE emp SET stars = v_asterisk WHERE empno = v_empno; COMMIT;END;/SET VERIFY ONSQL> START e19q5.sqlSQL> SELECT empno, sal, stars 2 FROM emp 3 WHERE empno IN (7934, 8000);

Page 534: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 20

1. Execute o comando abaixo para criar uma nova tabela para armazenar os empregados e seus salários.

2. Escreva um bloco PL/SQL para recuperar o nome e o salário do empregado fornecido a partir da tabela EMP baseado no número do empregado, utilizando PL/SQL tables.

a. Declare duas PL/SQL tables, ENAME_TABLE e SAL_TABLE, para temporariamente armazenar os nomes e salários.

b. Como cada nome e salário é recuperado dentro do loop, armazene eles nas PL/SQL tables.

c. Fora do loop, transfira os nomes e salários das PL/SQL tables para a tabela TOP_DOGS.

d. Remova as linhas da tabela TOP_DOGS e teste o exercício.

On Targget Treinamento e Consultoria A-37

SQL> CREATE TABLE top_dogs 2 (name VARCHAR2(25), 3 salary NUMBER(11,2));

SQL> DELETE 2 FROM top_dogs;

Page 535: Introdução ao Oracle 8i

Funções Básicas

On Targget Treinamento e Consultoria A-38

SET VERIFY OFFACCEPT p_empno PROMPT 'Please enter the employee number: 'DECLARE TYPE ename_table_type IS TABLE OF VARCHAR2(10) INDEX BY BINARY_INTEGER; TYPE sal_table_type IS TABLE OF NUMBER(7,2) INDEX BY BINARY_INTEGER; v_empno emp.empno%TYPE := &p_empno; v_ename emp.ename%TYPE; v_sal emp.sal%TYPE; ename_table ename_table_type; sal_table sal_table_type; i BINARY_INTEGER := 0;BEGIN DELETE FROM top_dogs; SELECT ename, sal INTO v_ename, v_sal FROM emp WHERE empno = &p_empno; ename_table(i) := v_ename; sal_table(i) := v_sal; INSERT INTO top_dogs (name, salary) VALUES (ename_table(i), sal_table(i)); COMMIT;END;/SET VERIFY ON

SQL> START e20q2.sqlSQL> SELECT * 2 FROM top_dogs;

Page 536: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 21

1. Crie um bloco PL/SQL que determine os empregados com os maiores salários.

a. Receba um número n através de um parâmetro de substituição do SQL*Plus.

b. Em um loop, obtenha os nomes e salários dos n empregados com os maiores salários da tabela EMP.

c. Armazena os nomes e salários na tabela TOP_DOGS.

d. Assuma que dois empregados não possuem o mesmo salário.

e. Teste uma variedade de casos especiais, como n = 0 ou n maior que o número de empregados da tabela EMP. Remova as linhas da tabela TOP_DOGS após cada teste.

On Targget Treinamento e Consultoria A-39

Page 537: Introdução ao Oracle 8i

Funções Básicas

2. Considere o caso onde vários empregados possuem o mesmo salário. Se uma pessoa é listada, então todas as pessoas que possuem o mesmo salário devem também ser listadas.

a. Por exemplo, se o usuário fornecer o valor 2 para n, então KING, FORD e SCOTT devem ser exibidos.

b. Se o usuário fornecer o valor 3, então KING, FORD, SCOTT e JONES devem ser exibidos.

c. Remova todas as linhas da tabela TOP_DOGS e teste o exercício.

On Targget Treinamento e Consultoria A-40

ACCEPT p_num – PROMPT 'Please enter the number of top money makers: 'DECLARE v_num NUMBER(3) := &p_num; v_ename emp.ename%TYPE; v_sal emp.sal%TYPE;

CURSOR emp_cursor IS SELECT ename, sal FROM emp WHERE sal IS NOT NULL ORDER BY sal DESC;BEGIN OPEN emp_cursor; FETCH emp_cursor INTO v_ename, v_sal; WHILE emp_cursor%ROWCOUNT <= v_num AND emp_cursor%FOUND LOOP INSERT INTO top_dogs (name, salary) VALUES (v_ename, v_sal); FETCH emp_cursor INTO v_ename, v_sal; END LOOP; CLOSE emp_cursor; COMMIT;END;/SQL> DELETE 2 FROM top_dogs;SQL> START e21q1.sqlSQL> SELECT * 2 FROM top_dogs;

ACCEPT p_num - PROMPT 'Please enter the number of top money makers: 'DECLARE v_num NUMBER(3) := &p_num; v_ename emp.ename%TYPE; v_current_sal emp.sal%TYPE; v_last_sal emp.sal%TYPE := -1;

CURSOR emp_cursor IS SELECT ename, sal FROM emp WHERE sal IS NOT NULL ORDER BY sal DESC;BEGIN OPEN emp_cursor; FETCH emp_cursor INTO v_ename, v_current_sal; WHILE (emp_cursor%ROWCOUNT <= v_num OR v_current_sal = v_last_sal) AND emp_cursor%FOUND LOOP INSERT INTO top_dogs (name, salary) VALUES (v_ename, v_current_sal); v_last_sal := v_current_sal; FETCH emp_cursor INTO v_ename, v_current_sal; END LOOP; CLOSE emp_cursor; COMMIT;END;/SQL> DELETE 2 FROM top_dogs;SQL> START e21q2.sqlSQL> SELECT * 2 FROM top_dogs;

Page 538: Introdução ao Oracle 8i

Funções Básicas

Soluções Exercícios – 22

1. Escreva uma consulta para recuperar todos os departamentos e empregados em cada departamento. Insira o resultado na tabela MESSAGES. Utilize um cursor para recuperar o número do departamento e passe o número do departamento para um cursor recuperar os empregados deste departamento.

3. Modifique o arquivo e19q5.sql para incorporar as funcionalidades de FOR UPDATE e WHERE CURRENT OF no processamento do cursor.

On Targget Treinamento e Consultoria A-41

DECLARE v_current_deptno dept.deptno%TYPE; v_emp VARCHAR2(50);

CURSOR dept_cursor IS SELECT deptno FROM dept ORDER BY deptno;

CURSOR emp_cursor(v_deptno NUMBER) IS SELECT ename||' – Department '||TO_CHAR(deptno) FROM emp WHERE deptno = v_deptno;BEGIN OPEN dept_cursor; LOOP FETCH dept_cursor INTO v_current_deptno; EXIT WHEN dept_cursor%NOTFOUND; IF emp_cursor%ISOPEN THEN CLOSE emp_cursor; END IF; OPEN emp_cursor (v_current_deptno); LOOP FETCH emp_cursor INTO v_emp; EXIT WHEN emp_cursor%NOTFOUND; INSERT INTO messages (results) VALUES (v_emp); END LOOP; CLOSE emp_cursor; END LOOP; CLOSE dept_cursor; COMMIT;END;/SQL> START e22q1.sqlSQL> SELECT * 2 FROM messages;

SET VERIFY OFFACCEPT p_empno PROMPT 'Please enter the employee number: 'DECLARE v_empno emp.empno%TYPE := &p_empno; v_asterisk emp.stars%TYPE := NULL;

CURSOR emp_cursor IS SELECT empno, NVL(ROUND(sal/100), 0) sal FROM emp WHERE empno = v_empno FOR UPDATE;BEGIN FOR emp_record IN emp_cursor LOOP FOR i IN 1..emp_record.sal LOOP v_asterisk := v_asterisk ||'*'; END LOOP; UPDATE emp SET stars = v_asterisk WHERE CURRENT OF emp_cursor; v_asterisk := NULL; END LOOP; COMMIT;END;/SET VERIFY ONSQL> START e22q2.sqlSQL> SELECT empno, sal, stars 2 FROM emp 3 WHERE empno IN (7844, 7900, 8000);