94
Treinamento Oracle www.digidatabrasil.com.br

Apostila Oracle 10g

Embed Size (px)

DESCRIPTION

Apostila de Oracle 10g

Citation preview

Page 1: Apostila Oracle 10g

Treinamento

Oracle

www.digidatabrasil .com.br

Page 2: Apostila Oracle 10g

CONCEITOBanco de DadosProcesso Cliente x Processo ServidorControle de TransaçõesBanco de dados relacionalDefinição Entidades/AtributosDefinição das relações

ARQUITETURA ORACLEInstância OracleComponentes em memóriaShared PoolDatabase Buffer CacheRedo Log BufferProcessosDBWR (DatabaseWriter)LGWR (LogWriter)CKPT (Checkpoint)Sistema de arquivo de uma base de dadosControlfileRedoLogFileDataFileArquivo de LogEstruturas LógicasTablespacesSegmentos

Extensões (EXTENTS) Blocos de Dados (DATABASE BLOCKS)

Privilégios de acessoSelectManipulação de dados (DML)Commit

ESTRUTURA DE LINGUAGEMLinguagem SQLDMLDDLCriar Usuários (Schema)Criar Role (Papel)Estabelecer PermissõesCriar e Administrar TableSpaceCriar TabelasCriar Primary KeysCriar Foreing KeysCriar ChecksCriar ÍndicesCriar SequencesOpções Avançadas da Linguagem SQLInner Joins

Page 3: Apostila Oracle 10g

Outer JoinsLeft Outer JoinsRight Outer JoinsFull Outer JoinsOutros exemplos de Inner JoinLinguagem PL - SQLComponentes da LinguagemIdentificadoresPalavras ReservadasLiteraisComentáriosDeclaraçõesTipos De VariáveisVariáveis SimplesAtributos EspeciaisConstantesConversão de Tipo De VariávelExemplos de DeclaraçõesVariáveis EspeciaisAtributos Para Cursor

ComandosCriar ViewCriar Stored ProceduresCriar Stored Procedures com CursorCriar FunctionsCriar Tabelas TemporáriasCriar TriggerCriar PackagesCriar SinônimosExport e Import de SchemaCriar Backup

Page 4: Apostila Oracle 10g

Apostila de Oracle

Apostila Oracle

CONCEITO

Banco de DadosO primeiro Sistema Gerenciador de Banco de Dados (SGBD) comercial surgiu no final de 1960 com base nos primitivos sistemas de arquivos disponíveis na época, os quais não controlavam o acesso concorrente por vários usuários ou processos. Os SGBDs evoluíram desses sistemas de arquivos de armazenamento em disco, criando novas estruturas de dados com o objetivo de armazenar informações. Com o tempo, os SGBDs passaram a utilizar diferentes formas de representação, ou modelos de dados, para descrever a estrutura das informações contidas em seus bancos de dados. Atualmente, os seguintes modelos de dados são normalmente utilizados pelos SGBDs: modelo hierárquico, modelo em redes, modelo relacional e o modelo orientado a objetos.Em termos simples, um banco de dados é uma coleção de dados, onde os dados são armazenados em tabelas. Alguns gostam de pensar em um banco de dados como um mecanismo organizado que tem a capacidade de armazenar informações, pela qual um usuário pode recuperar as informações armazenadas de uma amaneira eficaz e eficiente.Um banco de dados relacional é um banco de dados dividido em unidades lógicas chamadas tabelas, em que as tabelas são relacionadas entre si dentro do banco de dados. Um banco de dados relacional permite dividir os dados em unidades lógicas menores, mais gerenciáveis, oferecendo melhor e mais fácil manutenção e desempenho ótimo do banco de dados de acordo com o nível de organização.

Processo Cliente X Processo ServidorUm processo é responsável pela manutenção da informação (servidores) e outros responsáveis pela obtenção dos dados (os clientes). Os processos cliente enviam pedidos para o processo servidor, e este por sua vez processa e envia os resultados dos pedidos. O Oracle 10g é um banco de dados relacional, destinado a ser compatível com aplicações que apresentam arquitetura Cliente/Servidor, no qual o banco de dados fica residente em um computador central chamado Servidor e cujas informações são compartilhados por diversos usuários que executam as aplicações em seus computadores locais ou clientes.

BANCOS DE DADOS BASEADOS NA ARQUITETURA CLIENTE/SERVIDOR:Em linhas gerais, esta tecnologia tem como característica principal a divisão de tarefas entreo cliente, a estação de trabalho que ordena através das aplicações o acesso aos bancos de dados, e o servidor, que executa tarefas, tais como: atualizações, exclusões, procura de dados e todas as outras tarefas próprias do gerenciamento de banco de dados, porém, sob as ordens da estação de trabalho (Cliente).A vantagem é evidente: dividindo o processamento em dois sistemas, temos de saída adiminuição do tráfego de dados na rede. Com isto, o desempenho aumenta, pois evitaremosprocessar os dados, fazendo-os transitar pela rede, entre a estação de trabalho e o servidor, pelomenos duas vezes. Ao invés disso, armazenamos os dados variáveis do processo em algunsparâmetros e os enviamos ao servidor. Estes ao chegarem são recepcionados pelo Oracle que osenvia para Stored Procedures, que então inicia o processamento desejado até seu final de dentro do servidor, limitando-se a avisar a estação de trabalho o término do processo, com sucesso ou não.Porém, nem tudo são flores, existem também as desvantagens e a principal delas é o fato dasestações de trabalho (Clientes) se localizarem em pontos geográficos distantes do servidor.Embora este problema possa hoje ser minimizado pela adoção das arquiteturas deprocessamento distribuído, por outro lado não sem um considerável investimento em equipamentos, aplicativos auxiliares e a contratação de especialistas. Este investimento acompanhado de despesas de manutenção constantes embora não signifique propriamente um retorno aos custos de um computador de grande porte, é porém um gasto significativo e que dependendo do tamanho e da complexidade da rede podemos até alcançar os custos de um grande porte.

DigiData Informática 4 - 94

Page 5: Apostila Oracle 10g

Apostila de Oracle

VANTAGENS DA TECNOLOGIA CLIENTE/SERVIDOR:

SEPARAÇÃO DAS TAREFAS DE SOLICITAÇÃO E PROCESSO.A primeira efetuada pela estação de trabalho e a última é feita no servidor, ou seja: as tarefasde tratar e manipular os dados. Como já dissemos o tráfego na Rede diminui sensivelmente, pois só é entregue os dados necessários solicitados pela pesquisa do cliente, e estes depois de tratados são atualizados ao final da transação no servidor. Ao contrário dos Sistemas de Bancos de Dados sem a tecnologia Cliente/Servidor, que disponibiliza todo o banco de dados, indiferente à necessidade quando da solicitação pelo Cliente. A tecnologia Cliente/Servidor é antes de tudo umaincrementadora de performance sem igual.

INDEPENDÊNCIA DA ESTAÇÃO DE TRABALHO.Os usuários não ficam restritos a um tipo de sistema ou plataforma.

PRESERVAÇÃO DA INTEGRIDADE DOS DADOSMesmo quando são efetuados Back-ups em tempo real ou até a encriptação dos dados.Nestes casos o DBMS, utiliza o espelhamento dos dados enquanto eles são acessados, gravandosempre a última fotografia dos dados antes da cópia de segurança.

PROCESSAMENTO DE TRANSAÇÕES.A grande vantagem deste método e guardar durante certo tempo as modificaçõesefetuadas no Banco de Dados. Podendo, recuperá-las em caso de queda de energia ou mesmoquando o usuário do Banco desiste da modificação.

-DESVANTAGENS:1- A maior delas é o aumento do custo administrativo e a contratação de pessoalespecializado para dar suporte e manter o Banco de Dados sempre ativo. Nasce o profissionalAdministrador de Bancos de Dados (DBA).

2- O aumento do custo de hardware, também é significativo, pois parte integrante destatecnologia Cliente/Servidor, exige a distribuição do processamento, quando a rede for grande.

3- Quando da utilização do Processamento Distribuído a complexidade aumenta, o número deequipamentos diversos também aumentam, e nem sempre podemos encontrar profissionais nomercado com um conhecimento tão diversificado

Controle de transações

Uma transação é uma unidade lógica de trabalho que compreende uma ou mais declarações SQL executadas por um único usuário. Segundo o padrão ANSI/ISO SQL com o qual o Oracle é compatível, uma transação se inicia com a primeira declaração SQL executável do usuário e termina quando ela é submetida explicitamente ou rollback pelo usuário.Pense em um Banco de Dados de uma agência bancária. Quando um cliente desse banco transfere dinheiro de uma conta poupança para uma conta-corrente, a transação pode consistir em três operações separadas: a diminuição da conta poupança, o aumento da conta-corrente e o registro da transação no diário de transações.

O Oracle deve garantir que as três declarações SQL sejam executadas para atualizar o saldo das contas. Quando alguma coisa impede que uma declaração da transação seja executada (uma falha de hardware, por exemplo), as outras devem ser desfeitas. Isso é chamado de Rollback. Quando um erro ocorre em uma das atualizações, nenhuma atualização é realizada.

DigiData Informática 5 - 94

Page 6: Apostila Oracle 10g

Apostila de Oracle

Banco de Dados Relacional

O conceito relacional veio da necessidade de se acessar dados em uma estrutura que não apresentasse uma organização em que os dados estivessem postos de forma hierárquica. Tal estrutura tinha o inconveniente de não ter flexibilidade nem desempenho exigido para atender a demanda dos negócios atuais. A lógica do modelo de Banco de Dados Relacional é baseada na teoria de conjuntos, diferenciando das formas tradicionais onde os dados ficam distribuídos de forma anônima e em formato natural. Estruturas de dados como tabelas, são armazenadas mantendo um relacionamento lógico indicado por colunas específicas em cada tabela em particular. Estes relacionamentos estabelecem condições para um rápido acesso, sobretudo, um mecanismo seguro para garantir a total integridade dos dados disponíveis. Podemos dividir as etapas para construção de um Sistema Gerenciado de Banco de Dados Modelo Relacional em:

• Definição das Entidades e Atributos• Definição dos Relacionamentos

Definição das Entidades e Atributos

Define-se por entidade o elemento que pode ser constituído por atributos. Para a construção das entidades é feito levantamento, por meio de análise e entrevista junto aos interessados no negócio. Como exemplo prático, consideremos a construção de um sistema, onde há o objetivo de se registrar as vendas dos clientes. Neste programa, Clientes e Vendas, nome e endereço seriam por exemplo atributos da entidade cliente.

Definição das Relações

Quando finalizado a construção das entidades, a análise é direcionada para a identificação das colunas (atributos) que são possíveis de relacionamento.Baseado no exemplo de Entidades e Atributos do item anterior, podemos afirmar que um Cliente pode conter Pedidos, e de forma inversa, Pedidos são sempre pertencentes a Clientes. As relações podem ocorrer de um para um, de um para vários e de vários para vários. A forma de apresentação deste modelo é denominada ER, ou seja Entidade Relacional.

Arquitetura Oracle

Instância Oracle

DEFINIÇÃODá-se o nome de Instância Oracle ao conjunto, formado por estruturas de memória e processos a esta associados, que o Oracle reserva para seu próprio funcionamento. A função dessas estruturas é a de manter em memória os dados mais recentes copiados dos sistemas de arquivos próprios do Oracle para um acesso mais rápido. Esses dados serão usados pelos vários processos Oracle para manterem atualizados e consistentes os sistemas de arquivos do Oracle, e para realizar diversas tarefas de manutenção e comunicação entre si e entre as próprias estruturas. Para se acessar uma base de dados Oracle é necessário que uma instância esteja estabelecida em memória. Uma dada base de dados estará sempre relacionada a uma única e particular instância (a não ser que se esteja utilizando a opção Parallel Server, quando mais de uma instância pode acessar a mesma base de dados). Portanto, base de dados e instância não são a mesma coisa. A base de dados propriamente dita se compõe de um conjunto de arquivos físicos; instância é o conjunto de processos que controla estes arquivos físicos através de processos próprios e de uma estrutura de memória relacionada (a ligação entre a base de dados e a instância é parametrizada através do arquivo INIT.ORA, que, entre muitas outras funções, dimensiona as estruturas de memória a serem reservadas, e que possibilita, entre outras coisas, montar duas instâncias com comportamentos muito diferentes e apesar disso acessarem a mesma base de dados).

DigiData Informática 6 - 94

Page 7: Apostila Oracle 10g

Apostila de Oracle

A INSTÂNCIA COMO O ÚNICO MEIO DE ABRIR OS ARQUIVOS QUE COMPÕE A BASE DE DADOS

Da mesma forma que duas ou mais instâncias podem coexistir abertas para a mesma base de dados, podemos ter várias instâncias, cada uma com seu banco de dados, e portanto um mesmo servidor disponibilizando vários bancos de dados simultaneamente. Neste cenário o DBA teria que instalar as duas versões independentes uma da outras, gerar cada base de dados na versão apropriada e utilizar uma instância na versão correta para acessar cada base.

Componentes em Memória

Ao se iniciar, utilizar e fechar uma base de dados, então, sempre haverá uma instância a partir do qual isso será feito. Portanto, o sistema operacional deve estar preparado para isso. O processo de inicialização de um banco é feito a partir da leitura do arquivo de inicialização. Há dois tipos de arquivos: o PFILE que é um arquivo texto conhecido pelo INIT.ORA e o SPFILE que é um arquivo de parâmetro do servidor conhecido como spfile.ora. A instância de banco de dados inicialmente procura o SPFILE e se não encontrar busca o PFILE. O arquivo SPFILE é uma versão binária do PFILE. A maior vantagem de utilizar o SPFILE é a otimização da base, pois há diversos parâmetros que são alterados e se tornam persistentes e serão reutilizados na próxima reinicialização da base. É possível verificar se existe o SPFILE com o seguinte comando:

show parameter SPFILE;

O nome completo do arquivo INIT.ORA dependerá do nome da base de dados, da seguinte maneira:

INIT<nome_instância>.ORA

Em função dos parâmetros neste arquivo, as estruturas de memória para esta instância são dimensionadas e reservadas, e iniciados seus processos.Ao conjunto de todas as estruturas de memória assim estabelecidas se dá o nome de SGA (System Global Area). Essa área é compartilhada por todos os usuários da base de dados ao qual esta instância está ligada. Cada usuário, por sua vez, recebe uma estrutura denominada PGA (Program Global Area) através de um processo Server que se liga à sessão deste usuário. A PGA não é compartilhada (é específica de uma sessão).Com relação à SGA, temos as seguintes subestruturas:

• Shared Pool• Database Buffer Cache• Redo Log Buffer

DigiData Informática 7 - 94

Estrutura de memória (SGA)

Processos de Background

Instância

Arquivo que compõem a base de dados.

Page 8: Apostila Oracle 10g

Apostila de Oracle

Shared Pool

Esta área armazena vários objetos que podem ser compartilhados entre usuários. Divide-se por sua vez em Library Cache e Data Dictionary Cache.Na primeira são guardados os planos de execução de comandos SQL e código PL/SQL de procedimentos ou packages que um usuário possa estar utilizando ou venha a reutilizar. Na segunda são mantidos os blocos do dicionário de dados mais recentemente acessados.O tamanho da SGA é dimensionado pelo parâmetro SHARED_POOL_SIZE (em bytes), definido no INIT.ORA.

Database Buffer Cache

Mantém dados obtidos da base de dados para rápido acesso.Quando os arquivos físicos são acessados, os blocos com a informação obtida são trazidos para a memória e colocados nesta área. Ao serem lidos, os blocos novos vindos do disco procuram espaço livre. Caso todo o buffer cache esteja cheio, um algoritmo LRU1 abrirá espaço através da liberação de blocos que permanecem no buffer há mais tempo.Esta área é dimensionada através do parâmetro DB_BLOCK_BUFFERS (em número de blocos) no INIT.ORA.

Redo Log Buffer

O Oracle se utiliza de uma estratégia de Log para, em uma situação de falha, refazer todas as ações pendentes em uma base de dados. A parte em memória deste Log chama-se Redo Log Buffer, que atua como área temporária onde são escritas as ações, e que de tempos em tempos é descarregada em disco, nos logfiles (utilizados de uma maneira circular). Este processo de salvaguarda é muito rápido, e para o usuário da base de dados, totalmente transparente.O parâmetro utilizado para dimensionar o Redo Log Buffer é o LOG_BUFFER_SIZE (em bytes).

ESTRUTURAS DE MEMÓRIA RESERVADAS PELA INSTÂNCIA

1

DigiData Informática 8 - 94

SHERED POOL (Library cache + data dictionary cache)

DATABASE buffer cache

REDO LOG Buffer

Processos de Background

Instância

Arquivo que compõem a base de dados.

Page 9: Apostila Oracle 10g

Apostila de Oracle

Processos

Os principais processos que compõem uma instância (chamados background processes) geralmente realizam dois grupos de funções: gerenciar as estruturas de memória e monitorar a utilização da instância e da base de dados (existem outros tipos, alguns específicos da forma como a instância é configurada, outros que se utilizam com as opções especiais do Oracle). Há ainda os processos que são originados pelas conexões dos usuários (os Server Processes). Em geral se relaciona os seguintes, como parte integrante de uma instância:

• DBWR (Database Writer)• LGWR (Log Writer)• CKPT (Chekpoint process)

DBWR (Database Writer)

Quando um comando se referencia a blocos de dados que não estão em memória, o Server process os retira dos arquivos em disco e os coloca no Database Buffer Cache. Se algum bloco é modificado, é então marcado como “sujo” (dirty). Os blocos dirty devem ser escritos de volta nos arquivos em disco, para salvaguardar as alterações. O DBWR é o encarregado disso.Mas essa gravação não é feita de imediato. Para otimizar ao máximo o I/O (input/output) em disco, o DBWR se utiliza da técnica Delayed Writing (Escrita Retardada), ou Batch Writing (Escrita em Lote) que significa que as alterações nos blocos de dados só são efetuadas em disco se um dos seguintes eventos ocorrer:

1. Um Server process não encontra blocos livres no Database Buffer Cache2. Um Checkpoint3. O número de dirty blocks em memória atingiu um limite determinado

Quando o DBWR escreve de volta para disco os blocos modificados, coloca um bloqueio (lock) em alguns blocos do Database Buffer Cache, e só os libera quando acabar a gravação. Deste modo, alguma contenção pode ocorrer se vários usuários estiverem acessando os mesmos blocos de dados.

LGWR (Log Writer)

Qualquer atividade na base de dados é registrada no Redo Log. Primeiramente elas são feitas no Redo Log Buffer e regularmente vão sendo escritas em disco (nos logfiles) pelo LGWR. Os registro é feito seqüencialmente para evitar contenção. O objetivo é salvaguardar a informação o mais freqüentemente e rapidamente possível nos logfiles, permitindo ao DBWR atrasar as operações de escrita nos arquivos da base de dados propriamente dita. Para o usuário, as operações requisitadas são confirmadas assim que o LGWR informa que a informação está salvaguardada (e não o DBWR), dando assim um tempo de resposta menor.O LGWR “acorda” para gravar do Redo Log Buffer nos logfiles quando ocorre um dos seguintes eventos:

1. O Redo Log Buffer atinge um terço de sua capacidade2. Uma transação qualquer é confirmada (comando COMMIT)3. Num tempo determinado pelo parâmetro LOG_CHECKPOINT_TIMEOUT

DigiData Informática 9 - 94

Page 10: Apostila Oracle 10g

Apostila de Oracle

CKPT (Chekpoint process)

Um checkpoint é o momento em que o conteúdo do Database Buffer Cache é escrito pelo DBWR nos respectivos arquivos em disco. Neste momento, os arquivos físicos que compõem toda a base de dados são sincronizados através da gravação, no header (cabeçalho) de cada um, de um número, chamado SCN (System Change Number). Desta maneira o Oracle “sabe” que a base de dados está consistente.

O evento de checkpoint é de responsabilidade do processo CKPT.Um checkpoint ocorre em resposta a uma das seguintes situações:

1. Quando ocorre um log switch (um grupo de logfiles “enche”)2. De acordo com os parâmetros LOG_CHECKPOINT_INTERVAL ou LOG_CHECKPOINT_TIMEOUT3. Quando é explicitamente comandado pelo DBA4. Quando a instância é fechada (de modo normal)

O LOG_CHECKPOINT_INTERVAL sinaliza um checkpoint sempre que um determinado número de blocos do sistema operacional já tiver sido escritos nos arquivos de log. O outro indica de quantos em quantos segundos deve ocorrem um checkpoint (utilize zero se quiser desativá-lo). Ambos são parâmetros do INIT.ORA.Para forçar manualmente um checkpoint, o DBA, com a instância aberta, pode comandar:

alter system checkpoint;

Sistema de arquivo de uma base de dadosVimos que uma instância Oracle, composta de uma SGA e processos em background, é uma estrutura em memória que possibilitava a conexão e o acesso a uma base de dados. Mas o que é, fisicamente, uma base de dados?Basicamente, uma base de dados Oracle possui os seguintes arquivos em disco:

1. Controlfiles2. Redo Log Files3. Datafiles

Existem outros tipos de arquivos externos à base de dados, com funções distintas (arquivo de inicialização - INIT.ORA, arquivos de backups de Log - Archived Logs e arquivo de password - Password File, dentre os mais importantes, assim como arquivos de rasteio – Trace Files, um arquivo chamado ALERT.LOG, e outros), mas estes não fazem parte da base em si.

Controlfile

O controlfile é um dos arquivos mais importantes de qualquer base de dados Oracle, um dos que mais inspira cuidados. A informação básica de uma determinada base de dados (principalmente, a localização dos dois outros grupos de arquivos, os Redo Log Files e os Datafiles) é guardada no Controlfile. Quando essa informação muda (p.ex., quando se muda a localização de um Log File ou quando se acrescenta mais um Datafile à base de dados), as informações no Controlfile devem refletir esta mudança. Outras informações (p.ex., o estado de um datafile – on-line ou off-line – o SCN – System Change Number, etc.) também são ali guardadas. Outros exemplos: O nome da base de dados, a data da sua criação, valores de parâmetros como MAXLOGFILES, MAXLOGMEMBERS, MAXLOGHISTORY, MAXDATAFILES e MAXINSTANCES, etc.Como o leitor pode constatar é necessária uma extrema cautela com o Controlfile. Tanto que a própria Oracle nos recomenda ter duas ou mais cópias deste arquivo em unidades de armazenamento diferentes (o Controlfile pode ser multiplexado, de modo que a falha em uma cópia é compensada automaticamente pelo uso de outras).

O parâmetro CONTROL_FILES no INIT.ORA determina a localização física dos Controlfiles. O Controlfile pode, portanto, ser visto como um metaarquivo, um local onde o Oracle registra dado sobre si próprio.

DigiData Informática 10 - 94

Page 11: Apostila Oracle 10g

Apostila de Oracle

Redo Log files

Os Redo Logfiles são os arquivos utilizados para atividades de log numa base de dados Oracle. São criados e dimensionados no momento de criação da base de dados e existem em grupos, sendo que há no mínimo dois grupos. Cada grupo é constituído por membros, e todos registram exatamente a mesma informação. O objetivo de ter grupos com mais do que um membro destina-se a aumentar a proteção do sistema contra falhas.O LGWR escreve o conteúdo da memória nos arquivos de log de forma circular: começa por escrever no primeiro grupo (simultaneamente em todos os seus membros); depois deste grupo estar cheio passa para o segundo grupo, e assim por diante até o último grupo, e, ao atingir o seu limite deste, recomeça então com o primeiro grupo novamente. A criação de vários membros para cada grupo de logfiles destina-se a multiplexar a gravação do Redo Log Buffer feita pelo LGWR. A operação de passagem de um grupo para outro é chamada Log Switch e também pode ser forçada pelo DBA com o seguinte comando:

alter system switch logfile;

Caso a base de dados esteja em Modo Archive, os arquivos de log, depois de preenchidos, são copiados para os Archive Logfiles.

Datafiles

Os datafiles são os arquivos onde se registram os dados (sejam dados de aplicação, do dicionário de dados ou qualquer outro tipo de dados de controle). Quando um datafile é criado ele está vazio, mas seu tamanho em termos de espaço em disco é reservado e formatado. As características destes arquivos permitem as seguintes operações:

1. Colocá-los online ou offline2. Parametrizá-los para crescerem de forma dinâmica3. Redimensioná-los, liberando espaço não utilizado

Para o momento, o conceito mais importante a reter é o de que os datafiles são o local onde o Oracle registra todo o tipo de dados, independente do seu nível de abstração. A sua criação será focada na parte reservada à criação de objetos lógicos chamados.

Archived Logs

Se a base de dados estiver em modo Archive, os arquivos de log depois de um log switch (e não necessariamente depois de estarem completamente escritos) são arquivados. O nome destes é archived logs. São estes arquivos que permitem mais tarde a recuperação da base de dados.Os archived logs são guardados pelo processo ARCH no diretório definido pelo parâmetro LOG_ARCHIVE_DEST e o seu formato pode igualmente ser definido pelo DBA. Serão vistos em detalhe na parte de "Backup e Recuperação".

Estruturas Lógicas

As estruturas lógicas permitem ao Oracle Server fazer um mapeamento entre os objetos lógicos e a gerência do seu espaço físico. Cada objeto Oracle (tabelas, índices, etc.) é criado tendo como unidade de armazenamento as estruturas lógicas. Estas estruturas, por sua vez, estão armazenadas nos datafiles de forma completamente transparente ao usuário.

Tablespaces

A tablespace é uma área lógica, composta fisicamente por um ou mais arquivos, os datafiles.Existe em cada base de dados pelo menos um tablespace, chamado SYSTEM, onde está registrada toda a informação sobre a base de dados, e ainda código PL/SQL. Esta tablespace é implicitamente criada no momento da criação da base de dados, cabendo ao DBA a criação dos tablespaces adicionais.

DigiData Informática 11 - 94

Page 12: Apostila Oracle 10g

Apostila de Oracle

Estas estruturas lógicas permitem efetuar uma melhor organização dos dados, agrupar usuários, separar dados de aplicações distintas e gerenciar diferentes necessidades de alocação de espaço. Quando é criado um objeto, como uma tabela ou um índice, este é associado a uma tablespace que por sua vez registra os dados dos seus objetos em um ou mais datafiles. Uma tabela de clientes, p. ex., está atribuída a uma tablespace, e armazenada fisicamente em um ou mais Datafiles.

Segmentos

Os segmentos são a unidade lógica que constitui os tablespaces. Cada tablespace pode ser composta por um numero ilimitado de segmentos, estando o espaço físico limitado apenas pelo tamanho dos datafiles que o compõem, e estes, limitados pelo espaço disponível nos discos do sistema.Existem seis tipos de segmentos numa base de dados Oracle:

Segmentos de DadosSegmentos de ÍndicesSegmentos TemporáriosSegmentos de RollbackSegmentos LOB (só em Oracle8 em diante)Segmento LOB-index (só em Oracle8 em diante)

Os segmentos de dados são criados para armazenar a informação dos objetos do tipo tabela, cluster, tabela particionada (só em Oracle8) ou tabela organizada como um índice (index organized table, também só em Oracle8). Para que o leitor não fique muito confundido, desde já podem associar os segmentos de dados às tão comuns tabelas. A forma como a tabela está organizada deve ser, por hora, ignorada pelo leitor, uma vez que cada tipo de organização será visto em pormenor em seções futuras.De modo a tomar mais rápido o acesso aos dados das tabelas, podem-se criar um outro tipo de objetos, chamados índices. Os índices necessitam de espaço para registrar a sua própria informação, tal como o valor do endereço físico da linha (rowid) e os valores das colunas indexadas. Esta informação é registrada num outro tipo de segmentos, os segmentos de índices.Os segmentos temporários são criados automaticamente pelo Oracle, quando é necessário efetuar operações temporárias, como ordenações, verificação da sintaxe de comandos SQL (parsing) e agrupamentos de dados. Os comandos SELECT que incluam as cláusulas ORDER BY, DISTINCT, GROUP BY, UNION, INTERSECT e MINUS, e ainda o comando CREATE INDEX, são candidatos a originarem a criação pelo Oracle de segmentos temporários.Os segmentos de rollback têm como função principal a de registrar as ações de todas as transações ativas, para o caso de ser necessário desfaze-las. Também são chamadas de undo segments e são dos segmentos que maiores cuidados inspiram por parte do DBA.Por fim temos os segmentos LOB e LOB-index, que são exclusivos da versão 8 do Oracle em diante, e destinados a armazenar, respectivamente, informação de objetos grandes (Large Objects) e dos seus índices.A maior motivação para a criação de tablespaces diferentes reside no fato de se necessitar separar cada um destes tipos de segmentos.Esses tipos de segmentos aqui referidos serão analisados em maior detalhe nas seções posteriores deste livro.

Extensões (EXTENTS) e Blocos de Dados (DATABASE BLOCKS)

Qualquer tipo de segmento é composto por uma série de blocos de dados. O bloco de dados é a menor unidade de armazenamento de informação numa base de dados Oracle (daqui em diante faremos referência ao bloco de dados simplesmente como 'bloco'). Os blocos que compõem um segmento não estão necessariamente contíguos no disco, ainda que façam parte do mesmo datafile. Aos conjuntos de blocos que se encontram contíguos no disco dá-se o nome de extent. O extent é a unidade mínima de alocação de espaço numa base de dados Oracle.Quando um segmento é criado, é reservado um determinado número de extents, que pode ser apenas um ou mais. Uma vez reservados os extents para um segmento, a informação a ser registrada vai utilizando esse espaço. No momento em que o segmento necessitar de mais espaço para crescer, torna-se a reservar um novo extent. Este espaço é procurado dentro dos datafiles que compõem o tablespace onde o segmento está.A definição do tamanho do bloco é feita através do parâmetro DB_BLOCK_SIZE no arquivo de inicialização. Este valor é fixo uma vez que serve para formatar os datafiles que compõem a base de dados. Os valores possíveis

DigiData Informática 12 - 94

Page 13: Apostila Oracle 10g

Apostila de Oracle

para o tamanho do bloco vão desde os 2kbytes até aos 32kbytes, mas nem todos os sistemas operacionais suportam todos os tamanhos possíveis do bloco. A definição deste parâmetro é uma das decisões mais importantes do DBA no momento da criação da base de dados. A parte referente à gerência dos segmentos e a parte de otimização irão trazer mais luz sobre a implicações desta importante decisão.

Como tudo funcionaDepois de descritas as principais peças do database engine Oracle, veremos aqui como elas se encaixam. Quais os processos, estruturas de memória, arquivos e qual a seqüência de passos envolvidos na interação dos usuários com a base de dados. O cerne desta interação é a linguagem SQL e nesta seção serão cobertos cada um dos três tipos de operações que qualquer base de dados tem de oferecer: seleção, manipulação e salvaguarda dos dados. Cada subseção seguinte irá cobrir cada uma destas operações, mostrando os comandos da linguagem SQL dentro do universo Oracle:

. SELECT

. UPDATE

. COMMIT

Na parte da manipulação dos dados (DML) foi escolhida a atualização de dados (comando UPDATE) para exemplificar o funcionamento interno do Oracle.Independente do tipo de operação, cada comando enviado para o servidor da base de dados deve ser previamente validado. Quem envia o comando é o user process e quem o recebe e valida é o server process2. Depois de receber o comando do user process, cabe ao server process fazer a validação do comando (parsing). O parsing do comando inclui:

. Verificação da sintaxe do comando

. Verificação estrutural

Verificação dos privilégios de acesso

A verificação da sintaxe do comando SQL implica uma análise das cláusulas utilizadas de modo a garantir que o comando respeita todas as configurações possíveis. No caso de o comando incluir subqueries, então o processo de verificação da sintaxe começará por aí.A verificação estrutural é a fase em que, depois de verificada a sintaxe do comando, o server process verifica se os objetos a que o comando faz referência existem. No caso de o objeto ser uma tabela, é verificado se esta existe dentro do schema do usuário e se as colunas referenciadas no comando fazem parte dessa tabela.

A verificação dos privilégios de acesso é feita simultaneamente com a verificação estrutural. Caso existam objetos referenciados no comando SQL que pertençam a outro schema/usuário, o server process verifica se o usuário que emitiu o comando possui os necessários privilégios de acesso.

Seleção de Dados (SELECT)

Participam:Processos Envolvidos: Server Process, DBWREstruturas de Memória: Database Buffer Cache, Library Cache (Shared Pool)Arquivos: Datafiles

Como tudo funciona:Depois das necessárias verificações (fase de parsing), o server process procede à leitura dos dados que

o comando referencia, procurando primeiro no Database Buffer Cache em memória. Os dados que não encontrar em memória procura-os no disco (nos datafiles) e coloca-os em memória, no database buffer cache. Ao colocar os blocos trazidos do disco em memória, se o server process não encontrar suficientes blocos livres para

2

DigiData Informática 13 - 94

Page 14: Apostila Oracle 10g

Apostila de Oracle

armazenar os seus dados, sinaliza o processo DBWR para que este liberte espaço em memória. O DBWR percorre então a lista dos blocos marcados como “já modificados” (blocos dirty), escrevendo-os nos respectivos datafiles.

Se os dados necessitarem de algum tipo de ordenação ou agrupamento, este pode ser efetuado em memória ou no disco, em segmentos temporários.

Estas operações de leitura são gerenciadas por um plano de execução construído na fase de parsing. Para cada comando SELECT é construído um plano de execução que é colocado em memória dentro da shared pool, mais precisamente dentro da library cache. De modo a acelerar as pesquisas, evitando verificações e construções de planos de execução repetidos, a library cache é o primeiro acesso de memória do server process. Quando um comando SELECT for repetido, a sua informação de verificação e o seu plano de execução já se encontram resolvidos em memória, tornando o resto do processo mais rápido, uma vez que a fase de parsing, a mais “custosa” em termos de recursos, já não necessita ser feita.

Manipulação de Dados (DML)

Os comandos de manipulação de dados pertencem a um subconjunto de comandos dentro da linguagem SQL, os comandos DML (Data Manipulation Language): UPDATE (atualização), DELETE (exclusão) e INSERT (inserção). Nesta subseção iremos ver como funciona internamente a “máquina” Oracle quando é emitido um comando de UPDATE.

Participantes:Processos Envolvidos: Server Process, DBWREstruturas de Memória: Database Buffer Cache, Data Dictionary Cache (Shared Pool) e Redo Log Buffer.Arquivos: Datafiles

Como tudo funciona:Como qualquer comando SQL, um UPDATE também tem de passar pela fase de parsing. Na fase de

execução é onde começam as diferenças.O server process necessita efetuar os passos que garantam que a operação de atualização dos dados

mantenha a consistência de leitura dos dados.A consistência de leitura destina-se a garantir que os dados retirados da base numa consulta, em

qualquer instante, estão consistentes. A consistência de leitura, numa base de dados Oracle, é garantida através de segmentos específicos (segmentos de rollback) e de mecanismos de bloqueio (locking).

Os segmentos de rollback registram as alterações feitas à base de dados, feitas pelos comandos de DML. No caso de uma alteração de dados (UPDATE), a imagem anterior à alteração é copiada para este tipo de segmentos, garantindo assim que se algum outro usuário desejar consultar informação que está sendo alterada no momento, possa ter acesso a dados consistentes. Os segmentos de rollback necessitam de uma gerência cuidadosa por parte do DBA.

A consistência de leitura deve também garantir que não existe mais do que um usuário atualizando os mesmos dados num mesmo momento. Para tal, existe um mecanismo de bloqueio (lock). Um usuário espera até adquirir o direito de bloqueio sobre determinadas linhas ou sobre uma tabela e quando o obtém bloqueia os dados que vai modificar. Quando o bloqueio for liberado pode depois ser adquirido por outro usuário. Os bloqueios são liberados por um usuário explicitamente, quando a operação de UPDATE é confirmada (COMMIT) ou cancelada (ROLLBACK) ou, implicitamente, quando uma sessão de conexão à base de dados “morre” subitamente (ou é terminada pelo DBA). Nesta altura o processo de background chamado process monitor (PMON) encarrega-se de verificar se a sessão recém terminada deixou pendentes alguns bloqueios que necessitem ser liberados. Caso contrário, os outros usuários que desejassem efetuar operações de UPDATE sobre os mesmos dados teriam de esperar eternamente!

Resumindo: a consistência de leitura deve garantir que nos mesmos dados os processos de leitura não devem esperar pelos processos de escrita e vice-versa.

Os passos dados pelo server process para implementar uma operação de UPDATE são os seguintes:

a) O server process vai aos datafiles buscar os blocos necessários e os coloca no Database Buffer Cache, se estes já não se encontrarem lá. Da mesma forma que o comando SELECT, se não existir espaço livre, o DBWR

DigiData Informática 14 - 94

Page 15: Apostila Oracle 10g

Apostila de Oracle

é sinalizado para o liberar escrevendo blocos dirty para o disco. Os blocos dirty são aqueles cuja imagem em memória é mais atual que o seu correspondente em disco (nos datafiles).b) Uma vez que vai efetuar uma operação de UPDATE, o server process necessita adquirir o lock sobre os dados que vai alterar. Esse lock é registrado no dicionário de dados, mais precisamente na estrutura existente em memória para tal, o Data Dictionary Cache na Shared Pool.c) São registradas no Redo Log Buffer duas entradas, uma referente à alteração a ser feita, outra com a informação antiga.d) Agora que os dados estão bloqueados e o registro feito no log, vão se efetuar as duas operações de escrita que necessitam de ser feitas no Database Buffer Cache: alterar os blocos dos dados que são afetados pelo comando UPDATE e registrar a imagem antiga desses dados em blocos do segmento de rollback. Ambos os tipos de blocos são marcados como dirty.

Mecanismo de Efetivação de Dados (COMMIT)

Participantes:Processos Envolvidos: Server Process, LGWREstruturas de Memória: Database Buffer Cache, Data Dictionary Cache (Shared Pool) e Redo Log Buffer.Arquivos: Redo Log files

Como tudo funciona:Depois de efetuar o comando COMMIT, todos aqueles que estão habituados a trabalhar com uma base

de dados transacional (Oracle ou não) costumam respirar aliviados! De fato, a mensagem que o servidor Oracle envia de volta ao usuário de que os seus dados estão confirmados, gravados, seja lá o que for, quando se executa o comando COMMIT, nos leva a crer que estes estão efetivamente gravados em disco. Vamos ver passo a passo como é executada internamente a salvaguarda dos dados:

a) O COMMIT é registrado como uma entrada no Redo Log Buffer pelo server process.b) O LGWR é sinalizado para escrever em disco, no arquivo de log corrente, o conteúdo do Redo Log Buffer. Desta forma está salvaguardada a intenção do usuário.c) Depois desta escrita nos logfiles, o usuário é informado que o COMMIT foi feito com sucesso.d) Só depois de registrar no log e de informar o usuário é que o server process vai Iiberar eventuais locks que a transação poderia ter obtido, liberando assim os blocos de dados que estavam na Database Buffer Cache reservados a segmentos de rollback.

Então, quando é que os dados são guardados em disco? Para surpresa de muitos que estão habituados a associar a operação de commit ao comum “gravar”, surge aqui a primeira lição sobre Backup e Recuperação: o que importa é o que está no log. Abaixo seguem relacionados três cenários de falha, para mostrar que o dado foi realmente gravado em algum lugar, e a mensagem de Commit bem sucedido é válida:

Cenário de Falha antes do Commit

Se no momento em que se preparava para confirmar uns 100 comandos de INSERT, 50 DELETES e uma mão cheia de UPDATES, naquilo que constituía uma transação pesada, acontece uma falha de energia inultrapassável, então toda a informação que estava em memória se perde. E o que é que estava em memória? Possivelmente até nem estava muito, pois alguns dos blocos dirty que haviam sido afetados pelas operações de manipulação de dados, até já podiam ter sido escritos para disco. Isso mesmo! Dados que ainda ninguém confirmou podem já ter ido parar nos datafiles devido à falta de espaço em memória.

Ao voltar a energia e ao iniciar-se a instância, o processo SMON (system monitor) vai olhar para os arquivos de log e para os datafiles colocando-os de acordo com aquilo que está confirmado nos logs, e desfazendo tudo aquilo que são dados não confirmados. Por este motivo, o registro que “manda” é o que está feito nos logfiles.

DigiData Informática 15 - 94

Page 16: Apostila Oracle 10g

Apostila de Oracle

Cenário de Falha durante o Commit

O cenário de falha que mais gera dúvida é sempre o seguinte: O que é que acontece se a luz falhar exatamente no momento em que o comando de COMMIT é emitido, escrito como entrada em memória no Redo Log Buffer, mas o LGWR não teve tempo de registrá-lo nos arquivos de log?

Se a luz falhou antes do LGWR ter tempo de escrever em disco todas as entradas do Redo Log Buffer incluindo o nosso COMMIT, então significa que ainda não devolveu a mensagem de confirmação (acknowledgement) de volta ao usuário. Se o usuário não recebeu a mensagem, então não deverá ter muitas esperanças de que a sua transação tenha ficado salvaguardada.

De qualquer modo, o importante é colocar a base num estado consistente quando for iniciada e, por isso, o que está registrado no log é a lei. Se o nosso COMMIT não estiver lá, então toda a transação será cancelada (ROLLBACK).

Cenário de Falha depois do Commit

Imagine que a base de dados foi fechada de forma abrupta pelo DBA ou até mesmo que a máquina onde está o Oracle foi desligada de forma abrupta. Novamente o que estava em memória se evaporou, mas o COMMIT já foi registrado nos logfiles em disco, por isso o DBA pode dormir descansado. Isto significa que, mesmo que os dados referentes a esta transação estivessem ainda em memória no momento do crash, eles seriam repostos e confirmados, pois o SMON, no seu processo de recuperação automática da instância, ao ser iniciada a base, iria encarregar-se de aplicar aos datafiles as entradas registradas nos logs.

ESTRUTURA

Linguagem SQL

A linguagem SQL é ferramenta básica para o acesso aos dados de um banco de dados relacional e o primeiro e mais importante passo para se estabelecer nele. Nos últimos anos, a linguagem SQL saiu do mainframe e foi estendida ao desktop. Essa mudança se deve ao fato de que os bancos de dados relacionais também expandiram suas plataformas e hoje possuem versões que executam desde um PC até um mainframe.Por possuir uma estrutura adequada para a arquitetura cliente/servidor, cada vez mais aplicações e páginas que acessam bancos de dados relacionais estão sendo criadas por intermédio da linguagem SQL.

ANSI SQLSignifica American National Standards Institute, uma organização que é responsável por planejar padrões para vários produtos e conceitos. No caso do SQL, isso fornece um esqueleto básico de fundamentos básicos necessários, que como um resultado final, permite consistência entre várias implementações. Com a linguagem SQL podemos nos comunicar com qualquer banco de dados que trabalhe com o sistema (RDBMS), afinal, se tivéssemos uma linguagem para cada banco de dados, ficaria difícil a comunicação e até mesmo a migração desses dados entre bancos de dados.Exemplo, imagine que cada país fosse um banco de dados, logo, cada país tem uma língua nativa, dificultando então a comunicação entre eles, com isso, teríamos que aprender cada língua desses países. Assim como o inglês que é uma língua de comunicação universal, o SQL é a língua universal de comunicação entre banco de dados relacional, tornando mais fácil a comunicação entre os usuários e aplicativos com o banco de dados.

DigiData Informática 16 - 94

Page 17: Apostila Oracle 10g

Apostila de Oracle

Tipos de comandos de SQL

DML (Data Manipulation Language)Linguagem de Manipulação de Dados, é a parte de SQL utilizada para manipular dado dentro de objetos de um banco de dados relacional.Há três comandos básicos de DML:

INSERTUPDATEDELETE

DDL (Data Definition Language) Linguagem de definição de dados, é a parte de SQL que permite criar e reestruturar objetos de banco de dados, como criar e excluir uma tabela.Os principais comandos de DDL incluem os seguintes:

CREATE TABLEALTER TABLEDROP TABLECREATE INDEXALTER INDEXDROP INDEX

DCL (Data Control Language)Linguagem de Controle de Dados, permitem que você controle o acesso a dados dentro do banco de dados, são normalmente utilizados para criar objetos relacionados com acesso de usuário e também para controlar a distribuição de privilégios entre usuários, alguns comandos de controle de dados são:

ALTER PASSWORDGRANTREVOKECREATE SYNONYM

Comandos de Controle TransacionalPermitem ao usuário gerenciar transações dentro de banco de dados.

COMMITROLLBACK

DigiData Informática 17 - 94

Page 18: Apostila Oracle 10g

Apostila de Oracle

Login Padrão/Criar UsuáriosQualquer pessoa que deseja acessar o Oracle precisa ser previamente cadastrada como um usuário desse banco de dados e deve possuir privilégios para realizar suas tarefas.Para ter acesso ao banco de dados, seja qual for a operação desejada, é necessário fazer o login de acesso.Observando abaixo, quando da execução do utilitário, foi fornecido uma interface para entrada de dados de login. Aqui devemos utilizar para Nome do Usuário e Senha, system e 123, respectivamente, pois foram esses os valores utilizados quando da instalação do produto. Na prática, somente a Senha (123) foi opcional na instalação, já que o Nome do Usuário (system) é padrão para todas as instalações.Observando a Figura 02, quando da execução do utilitário, foi fornecido uma interface para entrada de dados de login.

Figura 02

DigiData Informática 18 - 94

Page 19: Apostila Oracle 10g

Apostila de Oracle

Alterando o Login PadrãoComo primeira tarefa, devemos criar um novo login, na verdade, logado como System/123 (usuário padrão), criaremos um novo usuário para com este novo login criar os objetos necessários para nosso projeto, inclusive dar a este novo usuário, poderes de DBA da mesma forma que o usuário System.

Figura 03

Figura 04

DigiData Informática 19 - 94

Page 20: Apostila Oracle 10g

Apostila de Oracle

Observando a Figura 03, clique na opção de menu Criar Usuários, e em seguida oriente-se pela Figura 04 para definir as propriedades e permissões para o novo usuário.Aqui adotamos o nome do usuário como sendo Aluno, com senha de acesso igual a 123. Marque todas as opções conforme a Figura 04. Ao fina termos criado um novo usuário conforme Figura 05.

Figura 05

Criando TablespaceNão encontraremos um único arquivo responsável pela existência do banco de dados, na verdade existe uma coleção de arquivos que compõe uma base Oracle. O estudo minucioso deste aspecto foge ao escopo deste apostila, ficando o foco naquilo que denominamos Tablespace e seus arquivos de dados (Datafile).Um Tablespace é um objeto lógico, que lista um ou mais DataFile (arquivos de dados físicos). O uso de um Tablespace específico para cada projeto, ou até mesmo vários Tablespaces para um mesmo projeto, concorre para os seguintes benefícios:

a) Isolamento dos objetos (Table, View, etc.) de uma projeto de banco de dados de outros permitindo melhor administração.b) Melhor performance, principalmente para projetos onde existe um volume de dados superior a Gigabytes de dados. Assim podemos definir quais objetos residam em que Tablespace.c) No mesmo sentido do item anterior, podemos dividir os DataFiles de um Tablespace em vários diretórios do servidor e ,inclusive, em vários dispositivos de mídia (HDs) do servidor. Isto é especialmente eficiente, sendo a tomada de decisão correta no sentido de otimizar acesso aos dados.

DigiData Informática 20 - 94

Page 21: Apostila Oracle 10g

Apostila de Oracle

Observe a Figura 06 e 07, para iniciar o processo de criação de Tablespace para nosso projeto. Em seguida execute a seguinte instrução no Editor SQL de nosso utilitário:CREATE TABLESPACE TBS_ALUNODATAFILE 'C:\ORACLE10GEXPRESSEDITION\TBS\DF_ALUNO.DBF'SIZE 5MREUSE AUTOEXTEND ONNEXT 5MMAXSIZE 150M;

A Figura 08 exibe o Editor SQL, onde devemos colocar o código acima, e em seguida clicar no botão Executar para proceder à criação da Tablespace. Conforme ainda poderemos observar ao longo deste manual, quase a totalidade das operações de criação de objetos são baseados em interfaces amigáveis com simples opção de escolha e pouca entrada de dados.

Figura 06

DigiData Informática 21 - 94

Page 22: Apostila Oracle 10g

Apostila de Oracle

Figura07

Figura 08

DigiData Informática 22 - 94

Page 23: Apostila Oracle 10g

Apostila de Oracle

Figura09

Tarefas administrativas como criar Tablespace, alterar Tablespace default de usuários, entre outras, exigem o uso do Editor de SQL. Isto não chega a ser problema, até porque, em ambientes de desenvolvimento Oracle, os editores de texto ainda imperam, possivelmente por mera tradição. Somos alheios a isto, e tentaremos obter o máximo de produtividade os recursos RAD de nosso utilitário.

Concluído a etapa exemplificada na Figura 08, podemos ver o resultado do trabalho navegando pelos passos representados pelas Figuras 09 e 10. A figura 10 exibe uma tabela muito útil para acompanharmos a evolução de espaço ocupado por Tablespaces, servindo como termômetro para tomada de decisão quanto à expansão ou criação de novas Tablespaces.

Figura 10

DigiData Informática 23 - 94

Page 24: Apostila Oracle 10g

Apostila de Oracle

Redefinindo Tablespace Padrão do Usuário Quando criamos o usuário para nosso projeto, não tínhamos mais que a Tablespace padrão da instalação do Oracle Database 1og Express Edition. Mas passado os passos da etapa anterior, ou seja a criação da Tablespace TBS_ALUNO, devemos definir esta como Tablespace padrão para o usuário Aluno, objetivando acomodar fisicamente todos os objetos do nosso projeto, já que serão todos de domínio deste usuário.Esta etapa também é classificada como administrativa, e faz parte das tarefas que exigem digitação de código em nosso Editor SQL. Assim sendo, proceda conforme código relacionado abaixo:

ALTER USER ALUNODEFAULT TABLESPACE TBS_ALUNO

Proceda a execução do código acima, observando o resultado no Editor SQL conforme exibida na Figura 11.Agora faça um novo login, como usuário Aluno/123 visando corretamente criar objetos pertencentes a este usuário, acomodados naturalmente na TableSpace TBS_ALUNO.

ROLE (PAPEL)

Criando PapelAs instruções abaixo criam dois papéis (Role) sem nenhum privilégio.

-Create Role Papel_Basico;

-Create Role Papel_Completo;

Concedendo Privilégios a um PapelAs instruções abaixo garantem privilégios a papéis.

-Grant Resource to Papel_Basico;

-Grant Connect to Papel_Basico;

-Grant Resource to Papel_Completo;

-Grant Connect to Papel_Completo;

-Grant Select, Insert on Produtos to Papel_Basico;

-Grant Select, Insert , Update, Delete on Produtos to Papel_Completo;

Criando um novo usuárioNovo usuário, para posterior atribuições de papeis.

-Create User Novo_Usuario identified By A123;

Concedendo Privilégios de Papel a um UsuárioAs instruções abaixo atribuem papéis a usuários.

-Grant Papel_Basico to Novo_Usuario;

Com a instrução acima, qualquer tentativa de inserir e selecionar registros na tabela Produtos, por este novo usuário após o login, será bem sucedida. Porém, se tentar operações como Delete e Update, certamente falhará pois não tem permissão para tanto.

DigiData Informática 24 - 94

Page 25: Apostila Oracle 10g

Apostila de Oracle

A solução seria dar a este usuários privilégios por intermédio do papel Papel_Completo. Veja então a rotina abaixo:

-Grant Papel_Completo to Novo_Usuario;

Figura 11

Sobre Tabelas

Criando Tabelas Uma tabela [table] é um objeto do banco de dados, composto de zero ou mais linhas [rows], contendo os dados, organizados em uma ou mais colunas [columns]. Para criar a tabela você pode usar o Enterprise Manager ou utilizando comandos SQL DDL (Data Definition Language) em um editor SQL . Antes de criar suas tabelas, é importante levar em conta um bom projeto do banco de dados, que determina quais as informações a serem guardadas.

Tipos de DadosCada coluna tem um tipo de dados [data type], que determina que tipo de informações (caracteres, números, datas/horas) podem ser colocadas nas colunas e quais as características desses dados. O tipo de dados é determinado quando a tabela é criada e não pode ser alterado posteriormente. Você pode usar tipo de dados do sistema, predefinidos, ou criar novos tipos de dados, chamados tipo de dados do usuário baseados nos tipos de dados existentes.

Os tipos de dados existentes são:

VARIÁVEIS SIMPLES

• BINARY INTEGER numérico, para armazenamento de valores inteiros de -2**31 a (2**31) - 1

sintaxe: binary_integer

subtipos: natural -de 0 a (2**31) -1positive -de 1 a (2**31) -1

DigiData Informática 25 - 94

Page 26: Apostila Oracle 10g

Apostila de Oracle

• NUMBER numérico, para armazenamento de valores em ponto flutuante com precisão de até 38 dígitos.

sintaxe: number [(<precisão>,<escala>)]

subtipos: dec idem a numberdecimal idem a numberdouble precision idem a numberfloat idem a numberinteger idem a numberint idem a numbernumeric idem a numberreal idem a numbersmallint idem a number

• CHAR alfanumérico de tamanho fixo com até 32767 caracteres.

sintaxe: char [(<comprimento>)]

subtipo: string idem a char

• LONG alfanumérico de tamanho variável com comprimento de até 32760.

sintaxe: long

• VARCHAR2 alfanumérico de tamanho variável com comprimento de até 32767.

sintaxe: varchar2 [(<comprimento>)]

subtipo: varchar idem a varchar2

• RAW para armazenamento de dados binários (tam.máx. até 32767).

sintaxe: raw (<comprimento>)

• LONG RAW para armazenamento de dados binários até o tamanho de 32760.

sintaxe: long raw

• BOOLEAN valores boleanos (true, false, ou null).

• DATE armazenamento de datas.

sintaxe: date

• ROWID valores de “rowid” do Oracle (em hexadecimal).

sintaxe: rowid

formato: BBBBBBBBB.RRRR.FFFFonde:BBBBBBBBB - bloco dentro do arquivo (database file)RRRR - row dentro do bloco (primeira row é 0)FFFF - número do arquivo (database file)

DigiData Informática 26 - 94

Page 27: Apostila Oracle 10g

Apostila de Oracle

CONVERSÃO DE TIPO DE VARIÁVEL

Pode-se converter de um tipo de variável para outro explicitamente, porém, em muitas situações a PL/SQL pode converter o tipo de caractere em outro, implicitamente. Isto ocorre quando usamos variável de um tipo onde era esperado outro. A PL/SQL utiliza uma das seguintes funções para executar esta conversão:

TO_CHAR TO_DATETO_VARCHAR2 TO_NUMBERCHARTOROWID ROWIDTOCHARHEXTORAW RAWTOHEXTO_BINARY_INTEGER

Entidades, Relacionamentos e Atributos

Quanto mais organizadas estiverem as informações no Banco de dados, mais forte será a “Conversa” com o Gerenciador de Banco de Dados. Para Isso criou-se um modelo chamado de Modelo de Entidade e Relacionamentos, do qual fazem parte três elementos:

Entidades: Uma entidade é um objeto de interesse do qual podem ser colecionadas informações. Ex: Tabelas de clientes, Tabela de pedidos de clientes.

Relacionamentos: As entidades podem ser relacionadas entre si pelos relacionamentos.Ex: Entidade de Clientes e Entidade de Pedidos (“clientes fazem pedidos”).

Atributos: São as características das entidades. São representadas pelas colunas das tabelas. Ex: nome, endereço, telefone e etc.

Componentes de uma Tabela

O armazenamento e a manutenção de dados valiosos é a razão para a existência de qualquer banco de dados. Lembre-se de que uma tabela é a forma mais simples de armazenamento de dados em um banco de dados relacional.A seguir os componentes de uma tabela:

Campo: É uma coluna em uma tabela que é projetada para manter informações específicas sobre cada registro na tabela. Ex:

ID_CLIENTE NOME ENDEREÇO TELEFONE

Registro ou Linha de dados: É cada entrada individual que existe em uma tabela. Ex:

ID_CLIENTE NOME ENDEREÇO TELEFONE20003 João da Silva R. Conde Palmeira 3333-323520004 Marcos Pereira R. Paula Frontes 2522-8589

Coluna: É uma entidade vertical em uma tabela que contém todas as informações associadas com um campo específico em uma tabela. Ex:

ID_CLIENTE200032000420005

DigiData Informática 27 - 94

Page 28: Apostila Oracle 10g

Apostila de Oracle

Criando Tabelas Após análise que define a estrutura de dados para um projeto de banco de dados, inicia-se um processo de criação de tabelas desta base, sendo que em nossa ferramenta, poderemos fazer a partir da interface gráfica facilitadora, ou executando instruções em código no Editor SQL da mesma ferramenta.

Figura 12

DigiData Informática 28 - 94

Page 29: Apostila Oracle 10g

Apostila de Oracle

O diagrama abaixo (Figura 13) exibe as tabelas de nosso projeto, bem como o nome de cada campo e o relacionamento entre as mesmas.

Figura 13

O script a seguir, refere-se ao código DDL (Data Definition Language) para cada tabela do projeto. Observe a primeira tabela (CLIENTES) onde é aplicado a maioria dos tipos possíveis considerando análise prévia. Observe ainda a definição de atributos como DEFAULT e NOT NULL.Deve ser ressaltado, o fato de termos criado uma tabela para armazenar a foto (tipo imagem) do cliente, já que não são permitidos dois campos do tipo BLOB em uma mesma tabela. O campo HISTORICO, na tabela CLIENTE é o outro campo desta natureza.

*****************Início do Script *********************

CREATE TABLE CLIENTES (ID_CLIENTE NUMBER (10, 0) NOT NULL,NOME VARCHAR2 (100) NOT NULL,CNPJ CHAR (18) NOT NULL,TIPO CHAR (1) DEFAULT ‘J’ NOT NULL,STATUS NUMBER (1, 0) DEFAULT 1 NOT NULL,DATA DATE NOT NULL,HISTORICO CLOB,CREDITO NUMBER (12, 2),CIDADEID NUMBER (10, 0))

DigiData Informática 29 - 94

Page 30: Apostila Oracle 10g

Apostila de Oracle

CREATE TABLE CLIENTESFOTO (ID_CLIENTE NUMBER (10, 0) NOT NULL,FOTO LONG RAW)

CREATE TABLE CIDADES ( CIDADEID NUMBER (10,0) NOT NULL, CIDADENOME VARCHAR2 (25) NOT NULL,

ESTADO VARCHAR2 (2) NOT NULL)

CREATE TABLE PRODUTOS (ID_PRODUTO NUMBER (10, 0) NOT NULL,DESCRICAO VARCHAR2 (50) NOT NULL,PRECOCOMPRA NUMBER (13, 2),SALDO NUMBER (10, 0))

CREATE TABLE ITENS (ID_PEDIDO NUMBER (10, 0) NOT NULL,ID_PRODUTO NUMBER (10, 0) NOT NULL,QUANTIDADE NUMBER (10, 0) NOT NULL,PRECOVENDA NUMBER (13, 2) NOT NULL)

CREATE TABLE PEDIDOS (ID_PEDIDO NUMBER (10, 0) NOT NULL,ID_CLIENTE NUMBER (10, 0) NOT NULL,DATAPED DATE NOT NULL)

************************* Final do Script **********

Utilizaremos a tabela CLIENTE para demonstrar como é prático e intuitivo o uso da wizard para Criar Tabela de nosso utilitário. Isto será feito em uma sequência lógica, que ajudará compreender cada etapa necessária para: definir os tipos de campos (colunas), definir chave-primária e chave-estrangeira e ainda algumas restrições impostas as colunas.Para as outras tabelas presentes em nosso script, simplesmente executaremos as instruções DDL direto no Editor SQL.

DigiData Informática 30 - 94

Page 31: Apostila Oracle 10g

Apostila de Oracle

Etapa ColunasBasta observar o script para tabela CLIENTE, e com o uso do mouse ir selecionando as opções conforme ilustrado na Figura 14.

Figura 14

Constraints(Restrições)

[Primary Key]

A chave primaria [primary key] de uma tabela é uma coluna ou seqüência de colunas que identificam unicamente uma linha dentro da tabela, ou seja, seu valor não pode ser repetido para outras linhas. Ao definir uma chave primária, automaticamente é criado um índice na tabela. Só pode haver uma chave primária na tabela.Uma chave primária pode ser acrescentada à tabela depois que ela foi criada com o comando ALTER TABLE. Por exemplo, vamos criar chaves primárias às tabelas clientes e produtos:

ALTER TABLE clientes add constraint PK_cliente primary key (id_cliente)

Chave-PrimáriaDa mesma forma que a etapa anterior, observe a imagem da Figura 15, assinalando as opções para definir a chave-primária da tabela CLIENTE. Tornando o campo ID_CLIENTE chave-primária da tabela, estaremos definindo uma restrição (constraint) que impedirá a entrada de valores duplicados nesta coluna, criando uma exceção em tempo de execução caso algum aplicativo ou utilitário tente proceder desta forma.Será criado um índice com este campo, que deverá tornar o campo ID_CLIENTE preferencial em pesquisa, quando possível, devido a performance superior obtida.

DigiData Informática 31 - 94

Page 32: Apostila Oracle 10g

Apostila de Oracle

Figura 15

Visando criar em definitivo a tabela e todas as implementações aplicadas à mesma, basta clicar no botão Finalizar. Também copie e execute os scripts das tabelas restantes no Editor SQL. Ao final do processo, todas as tabelas estarão disponíveis conforme demonstra a Figura 16.

Figura 16

DigiData Informática 32 - 94

Page 33: Apostila Oracle 10g

Apostila de Oracle

Mais Chave-PrimáriaAs tabelas Clientes_Foto, Pedidos, Itens e Produtos ainda não contêm chave-primária, entre outras coisas, necessárias a implantação de restrição tipo chave-estrangeira a ser criada logo adiante.Lembramos que para tabela Clientes, criada a partir do wizard, neste momento foi definida para o campo ID_Cliente.

Figura 17

Conforme imagem observada na Figura 17, clique na opção de menu Criar para obter a janela de ajuda da Figura 18. Atingindo esta etapa defina as opções da caixa de dialogo representada pela Figura 19 e em seguida clique no botão Próximo até chegar à janela representada pela Figura 19.Pronto, basta clicar no botão Finalizar e a chave-primária será criada com sucesso.Para as outras chaves ainda pendentes, ou seja, tabelas Pedidos, Itens e produtos, utilizem as instruções do script abaixo, executando-o na Editor SQL de nosso utilitário:

Alter table ITENS add constraintPK_ITENS primary key (ID_PEDIDO, ID_PRODUTO)

Alter table PEDIDOS add constraintPK_PEDIDOS primary key (ID_PEDIDO)

Alter table PRODUTOS add constraintPK_PRODUTOS primary key (ID_PRODUTO)

Alguns pontos devem ser observados neste momento. O primeiro e evidente, que numa sequência lógica, primeiro criamos as chaves primárias do modelo, e só após, empregamos a criação das chaves estrangeiras, que irão consolidar o modelo relacional. Aliás, os servidores de banco de dados como o Oracle, são comumente denominados Banco de dados relacionais por esta forte característica.

DigiData Informática 33 - 94

Page 34: Apostila Oracle 10g

Apostila de Oracle

Figura 18

Figura 19

DigiData Informática 34 - 94

Page 35: Apostila Oracle 10g

Apostila de Oracle

Chave-Estrangeira [FOREIGN KEY]Chave-estrangeira define os relacionamentos entre tabelas de nosso modelo, implicando em duas restrições: a primeira refere-se a tabela em questão, impedindo que valores sejam assinalados na coluna que compõem a chave-estrangeira caso não existam antes na coluna de referência na tabela de referência. E a outra restrição, diz respeito a tabela de referência, onde os registros que tenham sido referenciados em uma tabela com chave-estrangeira apontando para esta tabela, não poderão ser excluídos. A isso se da o nome de Integridade referencial. Particularmente neste caso em curso, criação da tabela CLIENTE, não terá chave-estrangeira, pois não existe coluna da mesma que referencie (dependa) de coluna em outra tabela. Mas, na sequência após criarmos todas as tabelas, voltaremos a esta análise visando concluir os relacionamentos mapeados no MER (Modelo de Entidade Relacional).

Definindo Chave-EstrangeiraQuando criamos as tabelas, definimos conceitualmente chave-estrangeira, mas não aplicamos na prática. Assim sendo, observe a figura 20 para poder se orientar na edição da tabelas para cumprir esta tarefa. O diagrama exibido na Figura 13 será nossa base para criação de chave-estrangeira em todas as tabelas do modelo.Todos os passos necessários para utilizar o Wizard de criação de chave-estrangeira, estão dispostas entre as Figuras 20 e figura 22 inclusive.A tabela abaixo define nome e referências para as chave-estrangeiras, seguida do script com código para execução no Editor SQL caso seja a opção desejada.

Nome Tabela Coluna Tabela de Ref. Coluna de Ref.FK_ClientesFoto_Clientes ClientesFoto ID_Cliente Clientes ID_ClienteFK_Pedidos_Clientes Pedidos ID_Cliente Clientes ID_ClienteFK_Itens_Pedidos Itens ID_Pedido Pedidos ID_PedidoFK_Itens_Produtos Itens ID_Produto Produtos ID_Produto

ALTER TABLE PEDIDOS ADD CONSTRAINT FK_PEDIDOS_CLIENTES FOREIGN KEY (ID_CLIENTE) REFERENCES CLIENTES (ID_CLIENTE)

ALTER TABLE CLIENTESFOTO ADD CONSTRAINTFK_CLIENTESFOTO_CLIENTES FOREIGN KEY (ID_CLIENTE) REFERENCES

CLIENTES (ID_CLIENTE)

ALTER TABLE ITENS ADD CONSTRAINT FK_ITENS_PEDIDOS FOREIGN KEY (ID_PEDIDO) REFERENCES PEDIDOS (ID_PEDIDO)

ALTER TABLE ITENS ADD CONSTRAINT FK_ITENS_PRODUTOS FOREIGN KEY (ID_PRODUTO) REFERENCES PRODUTOS (ID_PRODUTO)

DigiData Informática 35 - 94

Page 36: Apostila Oracle 10g

Apostila de Oracle

Figura 20

Figura 21

DigiData Informática 36 - 94

Page 37: Apostila Oracle 10g

Apostila de Oracle

Figura 22

CheckNesta última etapa, podemos definir regras de restrição para as colunas da tabela. Uma outra abordagem para implantação de regras, principalmente regras de negócio, será apresentado quando estivermos estudando os objetos Triggers.Observando a Figura 23, vemos uma área de entrada de código, onde podemos criar regras de restrição para as colunas da tabela em curso. Alista abaixo, expõe as regras que iremos aplicar as colunas da tabela CLIENTE, bastando definir a regra e o nome do objeto, clicando em seguida no botão Adicionar.Uma dica importante, é clicar sob o link Constraints de Verificação – Exemplos, na parte de baixo da janela Restrições, visando obter exemplos possíveis aplicáveis.

Figura 23

DigiData Informática 37 - 94

Page 38: Apostila Oracle 10g

Apostila de Oracle

Nome da Restrição RegraAlter table clientes add constraint CLIENTES_ck_Tipo check (TIPO IN ('F', 'J'))Alter table clientes add constraint CLIENTES_ck_Cnpj check (LENGTH (CNPJ) >= 18)

Esse comando mostra informações sobre a tabela, inclusive os nomes de cada restrição. Para excluir, usa-se ALTER TABLE, com a opção DROP (independente do tipo de restrição).

ALTER TABLE clientes DROP CONSTRAINT ‘nome_da_restrição’

Visando criar em definitivo a tabela e todas as implementações aplicadas à mesma, basta clicar no botão Finalizar. Também copie e execute os scripts das tabelas restantes no Editor SQL. Ao final do processo, todas as tabelas estarão disponíveis conforme demonstra a Figura 17.

Unicidade [unique]

Uma restrição unique em uma coluna ou grupo colunas determina que seu valor deva ser único na tabela. Esse tipo de restrição é usado para chaves alternadas, ou seja, valores que se repetem na tabela além da chave primária. Pode haver várias restrições UNIQUE na tabela e as colunas de uma restrição UNIQUE permitem valores nulos. Repare na sintaxe:

ALTER TABLE clientes ADD constraint uk_cnpj UNIQUE (CNPJ)

Índices

Porque Índices?

Índice é um mecanismo que acelera bastante o acesso aos dados. Consiste de uma estrutura de dados que contém ponteiros ordenados para os dados. O Oracle usa [Indexes ou Índices] automaticamente em varias situações para acelerar a pesquisa e atualização de dados. Por exemplo:

• Se uma coluna esta na cláusula WHERE em um comando SELECT, UPDATE ou DELETE, o SQL Server verifica as condições mais rapidamente se houver um índice, caso contrário ele faz uma varredura seqüencial da tabela [table scan].

• Se uma coluna é muito usada para ordenar valores (com ORDER BY), essa ordenação é mais eficiente se ela tiver um índice.

• Se uma coluna é usada para fazer junção de duas tabelas, essas junções podem ser feitas mais eficientes se ela estiver indexada.

No entanto, índices levam tempo para serem criados e ocupam espaço em disco. Cada atualização na tabela também atualiza dinamicamente todos os índices definidos. Portanto se você criar muitos índices inúteis numa tabela, pode estar atrapalhando o desempenho da atualização de dados sem agilizar muito o tempo de resposta nas consultas.Para criar um Índice usamos o comando CREATE INDEX.

DigiData Informática 38 - 94

Page 39: Apostila Oracle 10g

Apostila de Oracle

Alguns Exemplos:

CREATE INDEX IDX_CLIENTES_NOME ON CLIENTES(NOME)

CREATE INDEX IDX_PRODUTOS_DESCRICAO ON PRODUTOS (DESCRICAO)

CREATE INDEX IDX_PEDIDOS_DATAPED ON PEDIDOS (DATAPED)

Sequence

Sequence é um objeto útil para fornecer valores únicos para preenchimento da chave-primária de tabelas.Para criar Sequence acompanhe na sequência a imagem da Figura 24, clicando em seguida no botão Próximo e depois no botão Criar. Abaixo temos o código DDL gerado, bem como um detalhamento de cada propriedade.

Figura 24

Parte do Código DefiniçãoCreate sequence SEQ_CLIENTES Cria objeto Sequence com o nome SEQ_CLIENTESstart with 1 Inicia contagem a partir do número 1increment by 1 Quando invocado o método NextVal, incrementa e valor 1maxvalue 1000000 Número máximo de valores retornadosminvalue 1 Valor mínimo da sequênciacache 5 Quantidade colocada em Cache para otimizar acessonocycle Define como não cíclica, não retornando a contagem ao inícionoorderDefine sem ordem pré estabelecida (Ascendente. ou Descendente)

DigiData Informática 39 - 94

Page 40: Apostila Oracle 10g

Apostila de Oracle

Aproveite e crie outras seqüências úteis ao desenvolvimento de procedimentos no futuro. O script abaixo relaciona código para outras seqüências sugeridas:

create sequence SEQ_PEDIDOSstart with 1 increment by 1 maxvalue 1000000 minvalue 1 cache 5 nocycle noorder

create sequence SEQ_PRODUTOSstart with 1 increment by 1 maxvalue 1000000 minvalue 1 cache 5 nocycle noorder

Linguagem SQL

Inserindo Dados

O comando INSERT insere linhas em uma tabela. A forma mais simples do comando insert somente uma linha de dados. Nesse caso, são informados os valores de todas as colunas da tabela, na ordem em que elas foram definidas na tabela. Mas é possível é possível inserir dados parciais de apenas algumas colunas.

INSERT INTO nome_tabela (colunas) values (valores)

Tabela de Cidades

CIDADEID CIDADENOME ESTADO1 RIO DE JANEIRO RJ

2 SÃO PAULO SP

3 VITORIA ES

4 BELO HORIZONTE MG

Tabela de Clientes

ID_CLIENTE NOME CNPJ TIPO STATUS DATA HISTORICO CREDITO CidadeId

MADEIRAS SAMAN 0002002/0001 J 1 2003/06/25 ENTREGA 1.505 1

SEQ_CLIENTES CAR VEICULOS 10025600/001 J 1 2005/04/12 1.112

1

SEQ_CLIENTES CARLOS PEDREIRA

052116852-85 F 1 2004/04/12 500.00 2

SEQ_CLIENTES FERNADA FERRAZ

011452369-85 F 1 2002/02/11 250.00

1

SEQ_CLIENTES DANIEL SILVA

014548987-20 F 1 2001/03/16 150.00

SEQ_CLIENTES FRAN ADESIVOS 2005006/1000 J 0 2000/04/05 ENTREGA 50.00

SEQ_CLIENTES SAPATOS E CIA. 10060085/100 J 1 2003/05/05 CLIENTE 900.50

SEQ_CLIENTES CALÇADOS VARTA 2002550/0001 J 0 2001/07/12 874.60 2

SEQ_CLIENTES SALE ADVOGADOS 00010003/555 J 1 2004/06/04 20.00

3

SEQ_CLIENTES PAULA MEDEIROS

003254896-84 F 0 2002/06/01 10.00

4

DigiData Informática 40 - 94

Page 41: Apostila Oracle 10g

Apostila de Oracle

Tabela de Pedidos

ID_PEDIDO ID_CLIENTE DATAPEDSEQ_PEDIDOS 1 10/05/2007

SEQ_PEDIDOS 2 10/05/2007

SEQ_PEDIDOS 1 25/05/2007

SEQ_PEDIDOS 3 01/06/2007

SEQ_PEDIDOS 4 04/06/2007

SEQ_PEDIDOS 4 27/06/2007

SEQ_PEDIDOS 5 10/07/2007

SEQ_PEDIDOS 2 13/07/2007

SEQ_PEDIDOS 4 15/07/2007

Tabela de Produtos

ID_PRODUTO DESCRIÇÃO PRECO_CPOMPRA SALDOSEQ_PRODUTOS CANETA 0.19 20

SEQ_PRODUTOS LAPIS 0.10 112

SEQ_PRODUTOS BORRACHA 0.05 42

SEQ_PRODUTOS PAPEL LISO 5.60 23

SEQ_PRODUTOS PAPEL A4 5.80 22

SEQ_PRODUTOS COLA 1.19 3

SEQ_PRODUTOS GRAMPO 1.52 52

SEQ_PRODUTOS COPO PLASTICO 1.06 14

SEQ_PRODUTOS CADERNO 2.26 16

SEQ_PRODUTOS FICHAS 2.42 120

Tabela de Itens

ID_PEDIDO ID_PRODUTO QUANTIDADE PRECO_VENDA01 1 2 2,75

01 2 16 1,50

02 2 10 1,50

03 3 11 0,25

03 4 8 8,95

03 1 45 2,75

04 2 14 1,50

04 4 9 8,95

04 1 10 2,75

05 3 18 0,25

DigiData Informática 41 - 94

Page 42: Apostila Oracle 10g

Apostila de Oracle

Atualizando Dados

Os dados em uma tabela podem ser modificados utilizando o comando UPDATE. O comando update não adiciona novos registros a uma tabela, e nem remove os registros, simplesmente atualiza os dados existentes. A forma mais simples da instrução update é a sua utilização para atualizar uma única coluna em uma tabela. Tanto uma única linha de dados como numerosos registros podem ser atualizados ao atualizar uma única coluna em uma tabela.

UPDATE CLIENTES SET TIPO = 'J'WHERE ID_CLIENTE= 1

Excluindo Dados

O comando delete é utilizado para remover linhas inteiras de dados de uma tabela. O comando delete não é utilizado para remover valores de colunas especificas, um registro completo, incluindo todas as colunas é removido. A instrução delete deve ser usada com cautela, ela funciona muito bem. Para excluir um único registro ou registro selecionados de uma tabela, a instrução delete deve ser utilizada com a seguinte sintaxe:

DELETE FROM CLIENTESWHERE ID_CLIENTE = 5

A Sintaxe SELECT

O comando SELECT recupera dados de uma ou mais tabelas, é a instrução utilizada para construir consultas no banco de dados. A cláusula FROM é a cláusula obrigatória e sempre deve ser utilizada em conjunção com a instrução SELECT.Há quatro cláusulas, que são partes valiosas de uma instrução SELECT, A sintaxe mais simples para recuperar dados dentro de um banco de dados:

SELECT listas_de_colunasFROM listas_de_tabelasWHERE condições

A lista_de_colunas especifica quais colunas serão retornadas como resultado, separadas por vírgula ou um asterisco (*) que indica todas as colunas da tabela.A cláusula FROM, com uma lista_de_tabelas, especifica quais tabelas serão consultadas.A cláusula WHERE especifica condições que devem ser satisfeitas pelas linhas das tabelas.

Comandos Select

SELECT, o camando que representa a Data Query Language (DQL) em que SQL, é a instrução utilizada para construir consultas no banco de dados. A cláusula FROM é a cláusula obrigatória e sempre deve ser utilizada em conjunção com a instrução SELECT.Há quatro cláusulas, que são partes valiosas de uma instrução SELECT:

SELECTFROMWHEREORDER BY

DigiData Informática 42 - 94

Page 43: Apostila Oracle 10g

Apostila de Oracle

Exemplo 01:

SELECT * FROM CLIENTES

Exemplo 02:

SELECT ID_CLIENTE, NOME, CNPJ, STATUS, TIPO, DATA FROM CLIENTES

Agora adicione uma condição à mesma consulta.

SELECT ID_CLIENTE, NOME, CNPJ, STATUS, TIPO, DATAFROM CLIENTESWHERE ID_CLIENTE = 2

Operadores Aritméticos Permitidos

(+) adição(-) subtração(*) multiplicação(/) divisão

Duas Formas Possíveis de Select (com e sem ALIAS)

SELECT Cl.nome, Cl.credito, Pe.DataPed,

Sum(It.Quantidade * It.PrecoVenda) As Total

FROM Clientes Cl, Pedidos Pe, Itens It

WHERE Cl.id_cliente = Pe.id_cliente AND Pe.id_pedido = It.id_pedido

GROUP BY Cl.nome, Cl.credito, Pe.DataPed

ou

SELECT Clientes.nome, Clientes.credito, Pedidos.DataPed,

Sum(Itens.Quantidade * Itens.PrecoVenda) As Total

FROM Clientes, Pedidos, Itens

WHERE Clientes.id_cliente = Pedidos.id_cliente AND Pedidos.id_pedido = Itens.id_pedido GROUP BY Clientes.nome, Clientes.credito, Pedidos.DataPed

DigiData Informática 43 - 94

Page 44: Apostila Oracle 10g

Apostila de Oracle

Funções

COUNTA função COUNT é utilizada para contar linhas ou valores de uma coluna que não tem valor null. A função COUNT quando utilizada com uma consulta retorna valor numérico.

SELECT COUNT(*) FROM CLIENTES

SUMÉ utilizada para retornar um total nos valores de uma coluna para um grupo de linhas.

SELECT SUM(CREDITO) FROM CLIENTES

AVGÉ utilizada para localizar médias para um grupo de linhas.

SELECT AVG (CREDITO) FROM CLIENTES

MAXA função MAX é utilizada para retornar o valor máximo para valores de uma coluna em um grupo de linhas.

SELECT MAX (CREDITO) FROM CLIENTES

MINA função MIN retorna o valor mínimo de uma coluna para um grupo de linhas.

SELECT MIN (CREDITO) FROM CLIENTES

Operadores Lógicos

São aqueles operadores que utilizam palavras-chave de SQL para fazer comparações em vez de símbolos. Os operadores lógicos abordados são:

IS NULLUtilizado para comparar um valor com um valor null. No exemplo, o campo crédito não tem valor.

SELECT * FROM CLIENTES WHERE HISTORICO IS NULL

DigiData Informática 44 - 94

Page 45: Apostila Oracle 10g

Apostila de Oracle

BETWEENÉ utilizado para procurar valores que estão dentro de um conjunto de valores, dado o valor mínimo e o valor máximo. No exemplo, o campo valor deve estar entre 20 e 50.

SELECT * FROM CLIENTES WHERE credito BETWEEN ‘20’ AND ‘2000’

INÉ utilizado para comparar um valor com uma lista de valores literais que foi especificada. No exemplo, o campo crédito deveria ser um dos valores da lista.

SELECT * FROM CLIENTES WHERE crédito IN (20, 30, 50)

LIKEÉ utilizado para comparar um valor com valores semelhantes utilizando operadores curinga.

(%) porcentagem(_) sublinhado

-Exemplo: Localiza quaisquer valores que comecem com PAB

SELECT * FROM CLIENTES WHERE nome LIKE ‘PAB%’ -

-Exemplo: Localiza quaisquer valores que contenham ABL a partir da segunda casa e terminem com quaisquer valores.

SELECT * FROM CLIENTES WHERE nome LIKE ‘_ABL%'

EXISTSÉ utilizado para procurar a presença de uma linha em uma tabela específica que atenda a certos critérios. Veja como pesquisar para ver se id_cliente 982 está na tabela clientes.

SELECT * FROM CLIENTES WHERE EXISTS ( Select id_cliente From clientes Where id_cliente = 982)

NOT EXISTSÉ utilizado para procurar a não ocorrência de uma linha em uma tabela específica que atenda a certos critérios. Veja como pesquisar para ver se existem clientes que não compraram. Logo não ocorrem na tabela de pedidos.

SELECT * FROM CLIENTES WHERE NOT EXISTS ( Select id_cliente From Pedidos)

DigiData Informática 45 - 94

Page 46: Apostila Oracle 10g

Apostila de Oracle

Opções Avançadas da Linguagem SQL

Neste tópico vamos ver como usar JOINs para retornar dados correlacionados de duas ou mais tabelas.

INNER JOINS

Um Inner Join conecta duas ou mais tabelas segundo uma condição de junção. O INNER JOIN retorna os registros que forem encontrados nas tabelas e respeitarem as condições de busca.Por exemplo:

SELECT Clientes.ClienteNome, Cidades.CidadeNome, Cidades.EstadoFROM Clientes INNER JOIN CidadesON Clientes.CidadeID = Cidades.CidadeID;

ClienteNome CidadeNome EstadoCliente1 Rio de Janeiro RJCliente2 São Paulo SPCliente4 Belo Horizonte MG

OUTER JOINS

Como podemos reparar no INNER JOIN, somente as linhas que possuem dados nas duas colunas do relacionamento são retornadas. Caso uma das colunas não possua valor (tenha null), este registro não participará da junção do SELECT.Isto pode não uma determinada pergunta. Você pode estar querendo saber, por exemplo, quais os clientes que você tem cadastrados, e, se houver a informação, o nome da cidade destes.

LEFT OUTER JOINS

Neste caso, você precisa de um OUTER JOIN. Um OUTER JOIN traz todas as linhas de uma determinada tabela, tendo ou não relacionamento completo, e as linhas da segunda tabela que satisfizerem o relacionamento. Vamos construir o exemplo dito antes:

SELECT Clientes.ClienteNome, Cidades.CidadeNome, Cidades.EstadoFROM Clientes LEFT OUTER JOIN Cidades ON Clientes.CidadeID = Cidades.CidadeID;

ClienteNome CidadeNome EstadoCliente1 Rio de Janeiro RJCliente2 São Paulo SPCliente3 NULL NULLCliente4 São Paulo MG

RIGHT OUTER JOINSSe quiséssemos trazer todas as cidades, e os clientes que existirem nelas, faríamos:

SELECT Clientes.ClienteNome, Cidades.CidadeNome, Cidades.EstadoFROM Clientes RIGHT OUTER JOIN CidadesON Clientes.CidadeID = Cidades.CidadeID;

ClienteNome CidadeNome EstadoCliente1 Rio de Janeiro RJCliente2 São Paulo SPCliente4 São Paulo MGNULL Vitória ES

DigiData Informática 46 - 94

Page 47: Apostila Oracle 10g

Apostila de Oracle

Que esteja bem claro que a palavra LEFT ou RIGHT refere-se apenas à ordem escrita das tabelas, vamos ver um outro exemplo de trazer todos os clientes e as cidades destes:

SELECT Clientes.ClienteNome, Cidades.CidadeNome, Cidades.EstadoFROM Cidades RIGHT OUTER JOIN ClientesON Clientes.CidadeID = Cidades.CidadeID;

ClienteNome CidadeNome EstadoCliente1 Rio de Janeiro RJCliente2 São Paulo SPCliente3 NULL NULLCliente4 São Paulo MG

FULL OUTER JOINS

E podemos, ainda, juntar os dois modos: ou seja, fazer um LEFT e RIGHT OUTER JOIN ao mesmo tempo. Isto, na, verdade, se chama FULL OUTER JOIN. E o exemplo está a seguir:SELECT Clientes.ClienteNome, Cidades.CidadeNome, Cidades.EstadoFROM Cidades FULL OUTER JOIN ClientesON Clientes.CidadeID = Cidades.CidadeID;

ClienteNome CidadeNome EstadoCliente1 Rio de Janeiro RJCliente2 São Paulo SPCliente4 São Paulo MGNULL Vitória ESCliente3 NULL NULL

Outros exemplos de INNER JOIN

Vamos gerar uma consulta que liste o nome dos clientes, as datas em realizaram pedidos e o valor total destes pedidos, usando INNER JOIN.

SELECT Clientes.Nome, Clientes.Credito, Pedidos.DataPed, Sum (Itens.Quantidade * Itens.PrecoVenda)as total

FROM Clientes INNER JOIN PedidosON Clientes.Id_Cliente = Pedidos.Id_ClienteINNER JOIN ItensON Pedidos.Id_Pedido = Itens.Id_PedidoGROUP BY Clientes.Nome, Clientes.Credito, Pedidos.DataPed

LINGUAGEM PL/SQL

COMPONENTES DA LINGUAGEM

IDENTIFICADORES

Consiste de uma letra opcionalmente seguida de números, “$”, ”_” ou “#”. As letras podem ser minúsculas ou maiúsculas.

Ex. Legais Ilegaismoney$$$tree teste&testeab### cd_deptonovo_teste_ nmfunc

DigiData Informática 47 - 94

Page 48: Apostila Oracle 10g

Apostila de Oracle

PALAVRAS RESERVADAS

Palavras que possuam um significado especial para a SQL.

Ex. BEGINEND

LITERAIS

É uma representação explícita de um número, caractere, string ou boleano, não representado por um identificador.Ex.:

Numéricos Caracteres Strings Boleanos030 ‘Z’ ‘10-NOV-91’ TRUE6 ‘%’ ‘hello,world’ FALSE-14 ‘7’+32767 ‘.‘12.0 ‘.‘.5 ‘z’‘2E5 ‘(‘-9.5E-3

COMENTÁRIOS:O início do comentário é marcado por dois hífens em qualquer ponto da linha. O restante da linha é considerado comentário. Para comentários que ultrapassem uma linha, pode-se usar a notação /* (inicio) e */(fim).

Ex.:SELECT vl_sal INTO w_salario – obtêm o salário atual

/* calculo da bonificação */IF w_salario > 50000

ATRIBUTOS ESPECIAIS

As variáveis PL/SQL e constantes possuem atributos, que são propriedades que permitem a referência ao tipo e estrutura do objeto sem necessidade de repetição de sua definição. As tabelas e colunas do database possuem atributos similares, que podemos usar para facilitar a manutenção.

• %TYPE este atributo copia os atributos de uma variável, constante ou coluna do database. É particularmente usado quando declaramos variáveis que pertençam as colunas do database.

sintaxe: <variável>/<constante>/<coluna>%TYPE

Ex.:

DECLAREW_CODIGO NUMBER(3);W_CODIGO2 W_CODIGO%TYPE; - variável de tipo idêntico a código

W_COD_DEP DEPTO.CD_DEPTO%TYPE;

DigiData Informática 48 - 94

Page 49: Apostila Oracle 10g

Apostila de Oracle

/* variável de tipo idêntico à variável da base de dados cd_depto */

%ROWTYPE este atributo gera um tipo de registro que representa uma linha da tabela. O registro pode armazenar uma linha de dados selecionados da tabela ou recebidos de um cursor (fetched).

sintaxe: <tabela>/<cursor>%ROWTYPE

Ex.:

DECLAREW_DEP_ROW DEPTO%ROWTYPE; - variável do tipo rowW_MAT NUMBER(3);CURSOR W_C1 Ls - cursor com apenas 2 colunasSELECT CD_DEPTO,NM_DEPTOFROM DEPTO; - colunas da tabelaW_C1_ROW WC1%ROWTYPE; - possui as mesmas colunas de

W_C1

BEGIN

SELECT * INTO W_DEP_ROW - contém todos os dados lidos FROM depto - da linha da tabelaWHERE cd_mat = W_MAT;IF W_DEP_ROW.CD_DEPTO = ‘Á00’ - a referência a cada campo é THEN

- feita com o uso da variável de tipo ROWTYPE

CONSTANTES

A declaração de uma constante é semelhante à declaração de uma variável, exceto que devemos adicionar a palavra chave CONSTANT e, imediatamente, associar um valor inicial. Seu valor não poderá ser alterado durante o programa.

sintaxe: <nome da constante> CONSTANTE<tipo> :=/DEFAULT <valor inicial>;

Ex.:

DECLARE W_TESTE CONSTANT REAL := 3.14159;

W_TESTE1 CONSTANT REAL DEFAULT := 3.14159;

CONVERSÃO DE TIPO DE VARIÁVEL

Pode-se converter de um tipo de variável para outro explicitamente, porém, em muitas situações a PL/SQL pode converter o tipo de caractere em outro, implicitamente. Isto ocorre quando usamos variável de um tipo onde era esperado outro. A PL/SQL utiliza uma das seguintes funções para executar esta conversão:

TO_CHAR TO_DATETO_VARCHAR2 TO_NUMBERCHARTOROWID ROWIDTOCHARHEXTORAW RAWTOHEXTO_BINARY_INTEGER

DigiData Informática 49 - 94

Page 50: Apostila Oracle 10g

Apostila de Oracle

EXEMPLOS DE DECLARAÇÕES

DECLARE W_DATA DATE; - variável de tipo data W_CONTADOR SMALLINT := 0; - variável iniciada com zero W_CODIGO CHAR(O3)NOT NULL := ‘A00’ - variável c/ restrição W_TESTE CONSTANT REAL := 3.14159; - /* constante de tipo real - o valor

inicial é obrigatório */ W_CODIGO2 W_CODIGO%TYPE := ‘B01’ - variável de tipo idêntico a código W_COD_DEP DEPTO.CD_DEPTO%TYPE - variável de tipo idêntico a variável da

da base de dados cd_depto W_DEP_ROW DEPTO%ROWTYPE - variável tipo row

CURSOR W_C1 IS - cursor c/ 2 colunas da tabela SELECT cd_depto, nm_depto FROM DEPTO; W_C1_ROW W_C1%ROWTYPE - possui as mesmas colunas de w_c1

BEGIN SELECT * INTO W_DEP_ROW FROM DEPTO WHERE cd_depto = ‘A00’; IF W_DEP_ROW.cd_DEPTO = ‘A00’ THEN W_CONTADOR := WHERE_CONTADOR + 1; END IF;END

VARIÁVEIS ESPECIAIS

• EXCEPTION - nomeia uma exceção definida pelo usuário.

sintaxe: <nome da exceção> EXCEPTION

Ex.:DECLARE

erro_matrícula EXCEPTION;

• CURSOR - declara um cursor.sintaxe:

CURSOR <nome cursor>[(<parâmetro> <tipo>[,<parâmetro <tipo>...])]RETURN<tipo>/<variável%TYPE/<table.column>%TYPE/<table>%rowtype

IS <comando SELECT >;onde:

4. A cláusula RETURN define o tipo de dado do resultado de um cursor.5. Pode-se usar o atributo %ROWTYPE para representar uma linha em uma tabela da base.6. Pode-se usar %TYPE para representar o tipo de uma variável, constante ou coluna da base.7. Um cursor deve estar associado a um comando SELECT com mesmo número, tipo e ordem de elementos selecionados que os da cláusula RETURN.

Ex.:

DECLARE CURSOR w_c1 IS SELECT cd_mat, vl_sal FROM func;CURSOR w_c2 (dat_ini DATE) IS

DigiData Informática 50 - 94

Page 51: Apostila Oracle 10g

Apostila de Oracle

SELECT cd_mat, nm_func FROM funcWHERE de_nasc > dat_ini;

ATRIBUTOS PARA CURSOR

Existem 2 tipos de cursores em PL/SQL: implícito e explícito. A PL/SQL implicitamente declara um cursor para cada comando SQL que manipule dados, inclusive queries que retornem uma única row.

• %FOUND - indica se o último FETCH retornou uma linha ou não, para cursores explícitos. E se alguma row foi afetada pelo último comando INSERT, UPDATE ou DELETE para cursores implícitos.

sintaxe: <cursor> %FOUNDSQL%FOUND

Ex.:

LOOP FETCH w_c1 INTO w_c1_row;IF w_c1%FOUNDTHEN

• %NOTFOUND - indica se o último FETCH retornou uma row ou não, para cursores explícitos. E se alguma row foi afetada pelo último comando INSERT, UPDATE ou DELETE para cursores implícitos.

sintaxe: <cursor>%NOTFOUNDSQL%NOTFOUND

Ex.:

LOOP FETCH w_c1 INTO w_c1_row;IF w_c1%NOTFOUNDTHEN

EXIT;...

END LOOP;

• %ISOPEN - permite que se verifique se um cursor está aberto ou não. No caso de cursores implícitos o resultado será sempre FALSE, uma vez que o Oracle fecha o cursor após uma operação.

sintaxe: <cursor>%ISOPENSQL%ISOPEN

Ex.:

IF NOT (w_c1%ISOPEN)THEN...

DigiData Informática 51 - 94

Page 52: Apostila Oracle 10g

Apostila de Oracle

• %ROWCOUNT - indica o número de rows lidas para o cursor associado (para cursores explícitos) ou o número de rows afetadas no último comando INSERT, UPDATE, DELETE ou SELECT (para cursores implícitos). Após a abertura do cursor, o valor de ROWCOUNT é zero. O número só será incrementado SE O ÚLTIMO FETCH retornou uma row.

sintaxe: <cursor>%ROWCOUNTSQL %ROWCOUNT

Ex.:

LOOP FETCH w_c1 INTO w_c1_row;IF w_c1% ROWCOUNT THEN

...

FUNÇÕES PRÉ-DEFINIDAS

A PL/SQL permite a utilização de diversas funções pré-definidas para manipulação dos dados. Pode-se usá-las onde expressões do mesmo tipo são permitidas.

CONTROLE DE ERROS

SQLCODEFunção numérica que retorna o código do erro associado à última exceção.

Definição: FUNCTION SQLCODE RETURN NUMBEREx.: <variável> := SQLCODE;

SQLERRMFunção string que retorna a mensagem de erro associado ao último SQLCODE.Definição: FUNCTION SQLERRM [(error_number NUMBER)] RETURN CHAREx.: <variável> := SQLERRM(-1023);

NUMÉRICAS

ABSRetorna o valor absoluto do argumento.

Definição: FUNCTION ABS (<n> NUMBER) RETURN NUMBEREx.: <variável> := ABS (<variável2>);

CEILRetorna o menor inteiro maior ou igual ao argumento.

DigiData Informática 52 - 94

Page 53: Apostila Oracle 10g

Apostila de Oracle

Definição: FUNCTION CEIL(<n> NUMBER) RETURN NUMBEREx.: <variável> := CEIL (<variável2>);

COSRetorna o coseno do argumento, que deve ser expresso em radianos.

Definição: FUNCTION COS (<n> NUMBER) RETURN NUMBEREx.: <variável> := COS (<variável2>);

Obs.: se <n> estiver em graus, basta que seja dividido por 57.29578 para ser convertido para radianos.

COSHRetorna o coseno hiperbólico do argumento.

Definição: FUNCTION COSH (<n> NUMBER) RETURN NUMBEREx.: <variável> := ABS (<variável2>);

EXPRetorna e elevado à n-esima potência, onde e (~2.71828) é a base do logaritmo neperiano.

Definição: FUNCTION EXP (<n> NUMBER) RETURN NUMBEREx.: <variável> := EXP (<variável2>);

FLOORRetorna o maior inteiro menor ou igual ao argumento.

Definição: FUNCTION FLOOR(<n> NUMBER) RETURN NUMBEREx.: <variável> := FLOOR (<variável2>);

LNRetorna o logaritmo natural do argumento, que deve ser maior que zero. Definição: FUNCTION LN (<n> NUMBER) RETURN NUMBEREx.: <variável> := LN (<variável2>);

LOGRetorna o logaritmo de <n> na base <m>, sendo que <m> deve ser maior que 1 e <n> deve ser maior que 1 e <n> deve ser maior que zero.

Definição: FUNCTION LOG (<n> NUMBER) RETURN NUMBEREx.: <variável> := LOG (<variável2>);

MODRetorna o resto da divisão de <m> por <n>. Se <n> for zero, <m> é retornado.

DigiData Informática 53 - 94

Page 54: Apostila Oracle 10g

Apostila de Oracle

Definição: FUNCTION MOD (<n> NUMBER) RETURN NUMBEREx.: <variável> := MOD (<variável2>), (<variável3>);

POWER

Retorna o número <m> elevado à <n>-énesima potência. Se <m> for negativo, <n> deve ser inteiro.

Definição: FUNCTION POWER (<n> NUMBER) RETURN NUMBEREx.: <variável> := POWER (<variável2>);

ROUNDRetorna <m> arredondado para <n> casas decimais. Se <n> for omitido, zero será assumido.

Definição: FUNCTION ROUND (<n> NUMBER) RETURN NUMBEREx.: <variável> := ROUND (<variável2>), (<variável3>);

SIGNRetorna –1 se o argumento for negativo, 0 se igual a zero ou 1 se o argumento for maior que zero.

Definição: FUNCTION SIGN (<n> NUMBER) RETURN NUMBEREx.: <variável> := SIGN (<variável2>);

SINRetorna o seno de <n>, que deve ser expresso em radianos.

Definição: FUNCTION EXP (<n> NUMBER) RETURN NUMBEREx.: <variável> := SIN (<variável2>);

Obs.: Se <n> estiver em graus, basta que seja dividido por 57.29578 para ser convertido para radianos.

SINHRetorna o seno hiperbólico do argumento.

Definição: FUNCTION SINH (<n> NUMBER) RETURN NUMBEREx.: <variável> := SINH (<variável2>);

SQRTRetorna a raiz quadrada do argumento, que não pode ser negativo.

Definição: FUNCTION SQRT (<n> NUMBER) RETURN NUMBEREx.: <variável> := SQRT (<variável2>);

TANRetorna a tangente de <n>, que deve ser expresso em radianos.

DigiData Informática 54 - 94

Page 55: Apostila Oracle 10g

Apostila de Oracle

Definição: FUNCTION TAN (<n> NUMBER) RETURN NUMBEREx.: <variável> := TAN (<variável2>);

TANHRetorna a tangente hiperbólica do argumento.

Definição: FUNCTION TANH (<n> NUMBER) RETURN NUMBEREx.: <variável> := TANH (<variável2>);

TRUNCRetorna o número <m> truncado para <n> casas decimais. Se o <n> for omitido, zero será assumido.

Definição: FUNCTION TRUNC (<n> NUMBER) RETURN NUMBEREx.: <variável> := TRUNC (<variável2>);

CARACTERES

ASCIIRetorna o código ASCII correspondente à string informada no argumento.

Definição: FUNCTION ASCII (<str> VARCHAR2) RETURN NUMBEREx.: <variável> := ASCII (<variável2>);

CHRRetorna a string correspondente à representação numérica informada como argumento. É o contrario da função ASCII.

Definição: FUNCTION CHR (<n> NUMBER) RETURN CHREx.: <variável> := CHR (<variável2>);

CONCATRetorna uma string que é o resultado da concatenação de <str1> (na frente) com <str2>.

Definição: FUNCTION CONCAT (<str1> VARCHAR2,<str2> VARCHAR2) RETURN VARCHAR2Ex.: <variável> := CONCAT (<variável2>,<variável3>);

INITCAPRetorna a primeira letra de cada palavra do argumento em letra maiúscula e as demais em minúsculas.

Definição: FUNCTION INITCAP (<str> VARCHAR2) RETURN VARCHAR2Ex.: <variável> := INITCAP (<variável2>);

DigiData Informática 55 - 94

Page 56: Apostila Oracle 10g

Apostila de Oracle

INSTRRetorna a posição da <n>-énesima ocorrência de <str2> dentro de <str1>, começando na posição <pos>.

Definição: FUNCTION INSTR (<str1> VARCHAR2,<str2> VARCHAR2) [<pos> NUMBER [,<n> NUMBER ]]) RETURN NUMBER

Ex.: <variável> := INSTR (<variável2>, <variavel3>,<pos>,<n>);LENGTHRetorna o número de caracteres da string <str>. Se o argumento é um item definido como CHAR, o comprimento incluirá os brancos. Se <str> for null, o resultado da função será NULL.

Definição: FUNCTION LENGTH (<str> VARCHAR2) RETURN NUMBEREx.: <variável> := LENGTH (<variável2>);

LOWERRetorna o argumento com todas as letras minúsculas.

Definição: FUNCTION LOWER (<str> VARCHAR2) RETURN VARCHAR2Ex.: <variável> := LOWER (<variável2>);

LPADCompleta à esquerda, com os caracteres <pad> para que o tamanho da string resultado seja <len>.

Definição: FUNCTION LPAD (<str> VARCHAR2,<len> NUMBER [,<pad> VARCHAR2]) RETURN VARCHAR2

Ex.: <variável> := LPAD (<variável2>, <comprimento>,’*’);

LTRIMRetira , da esquerda para direita, os caracteres <set> até que seja encontrado um caracter diferente de <set>.

Definição: FUNCTION LTRIM (<str> VARCHAR2 [, <set> VARCHAR2]) RETURN VARCHAR2Ex.: <variável> := LTRIM (<variável2>, <variável3>);

REPLACERetorna <str1> com cada ocorrência de <str2> substituída por <str3>. Se <str3> não for informado, todas as ocorrências se <str2> serão removidas. Se nem <str2> nem <str3> forem informadas a função retornará NULL.

Definição: FUNCTION REPLACE (<str1> VARCHAR2,<str2> VARCHAR2[,<str3> VARCHAR2]) RETURN VARCHAR2

Ex.: <variável> := REPLACE (<variável1>, <variável2>,<variável3);

RPADCompleta, à direita, com os caracteres <pad> para que o tamanho da string resultado seja <len>.

Definição: FUNCTION RPAD (<str> VARCHAR2,<len> NUMBER [,<pad> VARCHAR2])RETURN VARCHAR2

(<n> NUMBER) RETURN NUMBEREx.: <variável> := RPAD (<variável2>, < tamanho>,’*’);

RTRIMRetira , da direita para esquerda, os caracteres <set> até que seja encontrado um caracter diferente de <set>.

Definição: FUNCTION RTRIM (<str> VARCHAR2 [, <set> VARCHAR2]) RETURN VARCHAR2Ex.: <variável> := RTRIM (<variável2>, <variável3>);

DigiData Informática 56 - 94

Page 57: Apostila Oracle 10g

Apostila de Oracle

SOUNDEXRetorna um string que represente o som de <str>.

Definição: FUNCTION SOUNDEX (<str> VARCHAR2) RETURN VARCHAR2Ex.: <variável> := SOUNDEX (<variável2>);

SUBSTRRetorna uma parte da string <str>, a partir da posição <pos> por <len> caracteres. Se l<len> for omitido, retorna o restante da string.

Definição: FUNCTION SUBSTR (<str> VARCHAR2, <pos> NUMBER [,<len> NUMBER]) RETURN VARCHAR2

Ex.: <variável> := SUBSTR (<variável2>, <posição inicial>, <tamanho>);

TRANSLATERetorna <str>, substituindo cada um dos caracteres presentes em <set1> pelo caracter correspondente em <set2>. Se <set1> tiver mais caracteres que <set2>, e esses caracteres estiverem presentes em <str>, serão removidos do resultado.

Definição: FUNCTION TRANSLATE (<str> VARCHAR2, <set1> VARCHAR2,<set3> CHAR) RETURN VARCHAR2

Ex.: <variável> := TRANSLATE (<variável2>, ‘ABCDEF’, GHIJKL’);

UPPERRetorna o argumento com todas as letras maiúsculas.

Definição: FUNCTION UPPER (<str> VARCHAR2) RETURN VARCHAR2Ex.: <variável> := UPPER (‘texto’);

DATAS

ADD_MONTHSRetorna a data <dte> adicionada de <n> meses. <n. deve ser um inteiro e pode ser negativo.

Definição: FUNCTION ADD_MONTHS (<dte> DATE, <n>NUMBER) RETURN DATEEx.: <variável> := ADD_MONTHS (v_dt_nasc,4);

LAST_DAYRetorna a data do último dia do mês de <dte>.

Definição: FUNCTION LAST_DAY (<dte> DATE) RETURN DATEEx.: <variável> := LAST_DAY (<v_dt_adm>);

MONTHS_BETWEENRetorna o número de meses entre <dte1> e <dte2>.Definição: FUNCTION MONTHS_BETWEEN (<dte1> DATE,<dte2> DATE) RETURN DATEEx.: <variável> := MONTHS_BETWEEN (sysdate, v_dt_nasc) /12;

DigiData Informática 57 - 94

Page 58: Apostila Oracle 10g

Apostila de Oracle

NEW_TIMEConverte a data e hora que está no meridiano <zon1>, para a data e hora no meridiano <zon2>.

Definição: FUNCTION NEW_TIME (<dte> DATE,<zon1> VARCHAR2, <zon2> VARCHAR2) RETURN DATE

Ex.: <variável> := NEW_TIME (v_dt_nasc, ‘AST’,’GMT’);

ABREVIATURAS PARA MERIDIANOS

AST,ADT Atlantic Standard ou Daylight TimeGMT GreenwichPST, PDT Pacific Standard ou Daylight Time

NEXT_DAYRetorna a data do primeiro dia da semana nomeado por <day> que seja posterior a <dte>.

Definição: FUNCTION NEXT_DAY (<dte> DATE,<day> VARCHAR2) RETURN DATEEx.: <variável> := NEXT_DAY (sysdate, ‘moday’);

SYSDATERetorna a data e hora correntes.

Definição: FUNCTION SYSDATE RETURN DATEEx.: <variável> := SYSDATE ;

ROUNDRetorna <dte> arredondado para o formato especificado.

Definição: FUNCTION ROUND (<dte> [,<fmt>]) RETURN DATEEx.: <variável> := ROUND (sysdate,’ww’);

TRUNCRetorna uma data no formato especificado por <fmt>, representado <dte> truncada na unidade correspondente.

Definição: FUNCTION TRUNC (<dte> DATE [, <fmt> VARCHAR2 ) RETURN DATEEx.: <variável> := TRUNC (sysdate,’ww’);

FORMATOS PARA ROUND E TRUNC

CC SéculoSYYY, YYYY, YEAR, SYEAR, YYY, YY, Y AnoQ Quarto de anoMONTH, MON, MM MêsWW Início da semana do anoWHERE Início da semana do mêsDDD, DD, J DiaDAY, DY, D Último SábadoHH, HH12, HH24 HoraMI Minuto

DigiData Informática 58 - 94

Page 59: Apostila Oracle 10g

Apostila de Oracle

CONVERSÃO

CHARTOROWIDConverte a string <str> do tipo CHAR ou VARCHAR2 para ROWID.

Definição: FUNCTION CHARTOROWID (<str> CHAR) RETURN ROWIDEx.: <variável> := CHARTOROWID (‘00000000E.000ª0007’);

HEXTORAWConverte uma string hexadecimal do tipo CHAR ou VARCHAR2 para RAW.

Definição: FUNCTION HEXTORAW (<str> CHAR) RETURN RAWEx.: FUNCTION HEXTORAW (<str> VARCHAR2) RETURN RAW

<variável> := HEXTORAW (‘F6’);

RAWTOHEXConverte um valor binário em uma string hexadecimal do tipo VARCHAR2.

Definição: FUNCTION RAWTOHEX (<bin> RAW) RETURN VARCHAR2Ex.: <variável> := RAWTOHEX (<variável do tipo raw);

ROWIDTOCHARConverte o valor binário de <bin> para uma string hexadecimal de 18 bytes.

Definição: FUNCTION ROWIDTOCHAR (<bin> ROWID) RETURN VARCHAR2Ex.: <variável> := ROWIDTOCHAR (<variável do tipo rowid);

TO_CHARConverte um valor numérico ou data para o formato especificado.

Definição: FUNCTION TO_CHAR (<dte> DATE [,<fmt> VARCHAR2 [,<nls1>]])RETURN VARCHAR2FUNCTION TO_CHAR (<n> NUMBER) [,<fmt> VARCHAR2[,<NLS2>]]) RETURN VARCHAR2

Ex.: <variável> := TO_CHAR(5678.32, ‘9.999.99’, ‘nls_numeric_characters =’, ‘.’);

FORMATOS NUMÉRICOS PARA TO CHAR E TO NUMBER

9 9999 A quantidade de 9’s determina o comprimento0 0999 Completa com zeros à esquerda em vez de brancos$ $999 Prefixa o valor com o símbolo $B B999 Substitui o valor 0 por brancoMI 999MI Mostra “-“ após um valor negativoS S999 Coloca um “-“ ou um “+” antes do número.PR 999PR Mostra um valor negativo entre <>D 99D99 Inclui o caracter decimalG 99G99 Inclui o caracter separador de milhar, 99,99 Mostra uma “,” na posição correspondente.. 99.99 Mostra um “.” decimal na posição correspondente.V 999V99 Multiplica o valor por 10<n>, onde <n> corresponde ao número de

9’s após VE 9.99EEEE Notação científicaRN,rn RN Maiúscula ou minúscula para numerais romanos

DigiData Informática 59 - 94

Page 60: Apostila Oracle 10g

Apostila de Oracle

FORMATOS DE NLS

‘NLS_DATE_LANGUAGE = <language>’ ________________para <nls1>‘NLS_NUMERIC_CHARACTERS = ‘ ‘<d> <g>’,NLS_CURRENCY = “<text>”NLS_ISSO_CURRENCY = “<text>” ____________ para <nls2>

Onde:

<d> caracter decimal<g> separador de milhar<text> símbolo monetário

TO_DATEConverte uma string ou um número para o formato data.

Definição: FUNCTION TO_DATE (<str> VARCHAR2[,<fmt> VARCHAR2 [,<nls1>]])RETURN DATE

Ex.: <variável> := TO_DATE (‘12/01/84’, ‘dd/mm/yy’)

FORMATOS DE DATA PARA TO_CHAR E TO_DATE

CC, SCC SéculoSYYY, YYYY, YEAR, SYEAR, YYY, YY, Y AnoQ Quarto de anoMONTH Mês por extensoMON Mês abreviado para três letrasMM Mês (numérico)WW Semana do anoWHERE Semana do mêsWHERE Início da semana do mêsDDD Dia do anoDD Dia do mêsD Dia da semanaDAY Nome do diaDY Dia abreviado p/ 3 letrasJ Dia em data JulianaHH, HH12, HH24 HoraMI MinutoSS Segundo

TO_NUMBERConverte <str> para o valor numérico correspondente.

Definição: FUNCTION TO_NUMBER (<str> VARCHAR2 [, <nls2> ]])RETURN NUMBER

Ex.: <variável> := TO_NUMBER (‘5.678,32’, ‘9.999,99’, ‘nls_numeric_characters = ‘ , ‘.’);

DigiData Informática 60 - 94

Page 61: Apostila Oracle 10g

Apostila de Oracle

COMANDOS

IF THEN ELSEA seqüência de comandos só será executada se a condição for verdadeira.

sintaxe:IF <condição>THEN

<seqüência de comandos>END IF;

ouIF <condição>THEN

<seqüência de comandos>ELSE

<seqüência de comandos>END IF;

ouIF <condição>THEN

<seqüência de comandos>ELSIF <condição>THEN

<seqüência de comandos>ELSE

<seqüência de comandosEND IF;

<condição>[NOT] <expressão boleana> [[AND I OR ] <expressão boleana>]

<expressão boleana>]<literal boleano> I<variável boleana> I<chamada de função boleana> I(<expressão boleana>) I<expressão PLSQL> <operador relacional> <expressão PLSQL> I<expressão PLSQL> IS [NOT] NULL I<expressão PLSQL> [NOT] LIKE <pattern> I<expressão PLSQL> [NOT] BETWEEN

<expressão PLSQL> AND <expressão PLSQL> I<expressão PLSQL> [NOT] IN (<expressão PLSQL>[,

<expressão PLSQL>]) I<expressão PLSQL> { <nome cursor> I SQL}

{%NOTFOUND I %FOUND I%ISOPEN}

DigiData Informática 61 - 94

Page 62: Apostila Oracle 10g

Apostila de Oracle

Ex.:IF val_sal < 300.00THEN

Val_ir := 0;ELSIF val_sal BETWEEN 300.01 AND 1000.00+THEN

val_ir := val_sal * .10;ELSEIF val_sal BETWEEN 1000.01 and 3000.00THEN

val_ir := val_sal * .20;ELSE

val_ir := val_sal * .30;END IF;

EXITEncerra um loop.

sintaxe: EXIT [ <label>] [WHEN <condição>]

Ex.:LOOP

FETCH w_c1 INTO w_c1_row;IF w_c1%FOUNDTHEN

calc_ir........INSERT

ELSEEXIT;

ENDIFEND LOOP;

WHILE LOOP

A seqüência de comandos é executada enquanto a condição for verdadeira. Antes de cada iteração do loop, a condição é avaliada. Se for verdadeira, a seqüência de comandos é executada.

sintaxe:

[<< <label> >>]WHILE <condição> LOOP

<seqüência de comandos>END LOOP;

Ex.:OPEN w_c1;FETCH w_c1 INTO w_c1_row;WHILE w_c1%FOUND LOOP

...INSERT INTO folha

END LOOP;CLOSE w_c1;

DigiData Informática 62 - 94

Page 63: Apostila Oracle 10g

Apostila de Oracle

LOOPA seqüência de comandos é executada num número infinito de vezes ou até que seja encontrado um comando “EXIT” ou a condição de “WHEN” seja satisfeita.

sintaxe:[<< <label> >>]LOOP

<sequencia de comandos>END LOOP

ou LOOP

<sequencia de comandos>IF ....THEN

EXIT; -- encerra o loopEND IF;

END LOOP;

ouLOOP

<sequencia de comandos>EXIT WHEN -- encerra o loop

END LOOP;Ex.:

OPEN w_c1;LOOP

FETCH WHERE_C1 INTO w_c1_row;EXIT WHEN w_c1%NOTFOUND;calc_ir(w_c1_row.vl_sal,w_vl_lim);

...END LOOP;CLOSE w_c1;

FOR LOOP

A seqüência de comandos é executada um número fixo de vezes estabelecido no comando. No início do comando a quantidade de vezes que o mesmo será executado já é conhecida, uma vez que não se pode alterar o valor de <contador> durante a iteração.

sintaxe:[<< <label> >>]FOR <contador> IN [REVERSE] <inferior>..<superior> LOOP

<seqüência da comandos>END LOOP;

Ex.:

FOR i IN 1..3 LOOP <seqüência de comandos><seqüências de comandos> —

executa 3 vezesEND LOOP; — o comando vezes é inválido, pois i só Vezes := i +1 — existe no escopo do comando FOR

DigiData Informática 63 - 94

Page 64: Apostila Oracle 10g

Apostila de Oracle

FOR i IN início..fim LOOP — <seqüência de comandos><seqüência de comandos> — <executada n vezes dependendo

END LOOP; — do valor de início e fim

Fim := 1;FOR i IN 3..fim LOOP — <seqüência de comandos>

<seqüência de comandos> — não será executadaEND LOOP;

FOR IN REVERSE 1..3 LOOP — <seqüência de comandos><seqüência de comandos> — será executado 3 vezes

END LOOP; — i terá o valor inicial de 3

<<início>> — a variável usada em um loopFOR i IN 1..25 LOOP — é automaticamente declarada pela PL/SQL

FOR i IN 1..10 LOOP — no exemplo foram criadasIF início.i > 15 — duas variáveis iTHEN... — a referência ao nível

END LOOP; — externo é feita atravésEND LOOP INÍCIO; — do label

<<início>> — esta forma de interrupçãoFOR i IN 1..25 LOOP — do loop (exit <label> when..)

FOR i IN 1..10 LOOP — encerra os dois níveis ….. — de loopsEXIT início WHEN…

END LOOP;END LOOP início;

GOTO

Desvia incondicionalmente para um “label”, o qual deve ser dentro do scopo e deve preceder um comando ou um bloco da PL/SQL.

sintaxe: GOTO << <label> >>Ex.:

BEGIN…

GOTO inclui; — desvio para o comando INSERT…

<<inclui>>INSERT INTO func…

END;

BEGIN…<<altera>>BEGIN

UPDATE func — o desvio pode ser para traz…

END;GOTO altera;…<<fim>> — este label é porque END

END; — não é um comando executável

DigiData Informática 64 - 94

Page 65: Apostila Oracle 10g

Apostila de Oracle

NULL

Este comando explicitamente indica que não há ação a ser feita. Serve para compor certas situações em que um comando é exigido, mas nenhuma ação é realmente necessária.

sintaxe: NULL;

Ex.:

BEGIN …<<fim>> — o comando “null” resolveNULL; — o problema anterior

END;

Instruções Select mais Complexas - Views

Uma visão (View) é uma forma alternativa de olhar os dados contidos em uma ou mais tabelas. Para definir uma visão, usa-se um comando SELECT que faz uma consulta sobre as tabelas. A visão aparece depois como se fosse uma tabela.Visões têm as seguintes vantagens:

• Uma visão pode restringir quais as colunas da tabela podem ser acessadas (para leitura ou modificação), o que é útil no caso de controle de acesso,

• Uma consulta SELECT que é usado muito frequentemente pode ser criada como visão. Com isso, a cada vez que ela é necessária, basta selecionar dados da visão,

• Visões podem conter valores calculados ou valores de resumo, o que simplifica a operação,

• Uma visão pode usada para exportar dados para outras aplicações.

Objetos desta natureza são úteis em algumas circunstâncias: criar visões padronizadas e otimizadas de tabelas, ocultar informações (campos e registros) limitando visualização de parte de tabelas e até combinação delas.

Criando View Os exercícios abaixo exemplificam algumas Views relacionadas a tabelas de nosso modelo. Utilize o Editor Sql para criar estes objetos.Este exercício também tem como proposta, iniciar o aprendizado sobre a linguagem SQL e também alguma coisa sobre PL/SQL.Observe a sequência entre as Figuras 25 e 30, funcionando como um tutorial para uso da Wizard criador de Views do utilitário.

sintaxe:VIEW view_name[(column[,....n])] AS

Select_statement[WITH CHECK OPTION]

Ex:

VIEW func_sal ASSELECT cd_mat, vl_sal, FROM func WHERE vl_sal >= 1000.00;

DigiData Informática 65 - 94

Page 66: Apostila Oracle 10g

Apostila de Oracle

Create View View_ClientesHistorico As Select Clientes.Nome, Clientes.historicoFrom Clientes Where Clientes.Status = 1

Create View View_Itensdescricao As Select Produtos.Descricao,Itens.Quantidade, Itens.PrecovendaFrom Produtos Inner Join ItensOn Itens.Id_Produto = Produtos.Id_Produto

Create View View_Pedidosdata As Select Clientes.Nome, Pedidos.Dataped, Pedidos.Id_PedidoFrom Clientes Inner Join PedidosOn Clientes.Id_Cliente = Pedidos. Id_Cliente Where Pedidos.Dataped >= Sysdate – 150

Create View View_VendasMes AsSelect To_Char(Pedidos.DataPed, 'Month') As Mes,

Sum (Itens.Quantidade * Itens.PrecoVenda) As TotalFrom Pedidos Inner Join ItensOn Pedidos.Id_Pedido = Itens.Id_pedidoGroup By To_Char(Pedidos.DataPed, 'Month')

Figura 25

DigiData Informática 66 - 94

Page 67: Apostila Oracle 10g

Apostila de Oracle

Figura 26

Importante: Esta janela acessada com um clique no link Query Builder na janela da figura anterior. Serve para construir de forma gráfica a instrução Sql que seleciona com critério ou não dados, funcionando como a lógica da

View.

Figura 27

DigiData Informática 67 - 94

Page 68: Apostila Oracle 10g

Apostila de Oracle

Figura 28

Figura 29

DigiData Informática 68 - 94

Page 69: Apostila Oracle 10g

Apostila de Oracle

Figura 30

Stored Procedure

Um procedimento armazenado [stored procedure] é um conjunto de comandos SQL que são compilados e armazenados no servidor. Ele pode ser chamado a partir de um comando SQL qualquer. A vantagem de usar procedimentos armazenados é que eles podem encapsular rotinas de uso freqüente no próprio servidor, e estarão disponíveis para todas as aplicações. Parte da lógica do sistema pode ser armazenada no próprio banco de dados, em vez de ser codificada várias vezes em cada aplicação. Eles também aumentam o desempenho de várias operações, pois são executados no servidor e pré-compilados, ao contrário de comandos SQL que devem ser interpretados no momento da execução.O Oracle disponibiliza a linguagem PL/SQL com uma vasta coleção de instruções, funções e tipos, voltados a implementação de lógica no lado servidor de um aplicativo. No melhor do modelo Client-Server de desenvolvimento de aplicativos, teremos nesta etapa do treinamento, uma exposição de rotinas na forma de procedures que irão suprir tarefas como: manipular registros de tabelas, processar dados para posterior utilização e manipular cursores de dados.

sintaxe: PROCEDURE <nome da procedure> [(<parâmetro>[,<parâmetro>,…])] ISBEGIN

<comandos>[EXCEPTION

<tratamento das exceções>]END <nome da procedure>];

onde: parâmetro possui a seguinte sintaxe:

<nome da variável> [IN | OUT |IN OUT] <tipo> [{:= | DEFAULT} <valor>]

Quando [IN | OUT …] não for especificado, será assumido IN.

DigiData Informática 69 - 94

Page 70: Apostila Oracle 10g

Apostila de Oracle

Ex:

PROCEDURE calc_ir (val_sal IN NUMBER, val_ir OUT NUMBER) ISBEGIN

IF val_sal < 300.00THEN

val_ir := 0;ELSIF val_sal BETWENN 300.01 AND 1000.00THEN

val_ir := val_sal * .10;ELSIF val_sal BETWEEN 1000.01 AND 3000.00THEN

val_ir := val_sal *.20;ELSE

val_ir := val_sal *.30;END calc_ir;

CREATE PROCEDURE PROCINCCLIENTE ( Parnome Clientes.Nome%Type,Pardata Clientes.Data%Type,Parstatus Clientes.Status%Type,Parcredito Clientes.Credito%Type,Parhistorico Clientes.Historico%Type,Partipo Clientes.Tipo%Type,Parcnpj Clientes.Cnpj%Type) Is

BEGINInsert Into Clientes Values (

Seq_Clientes.Nextval,Parnome,Parcnpj,Partipo,Parstatus,Pardata,Parhistorico,Parcredito

);END;

Comentários:-Todas as definições que ficam entre parênteses após a declaração do nome da procedure referem-se aos parâmetros de entrada do procedimento, e devem ser preenchidos quando invocado o procedimento por uma aplicação cliente.

-A forma Tabela.Campo%Type, facilita a atribuição (definição) de tipo para o parâmetro. Naturalmente, se um parâmetro vai ser utilizado para entrada de valor em uma coluna de tabela, naturalmente seu tipo deve ser igual a referida coluna da tabela. Então a instrução Clientes.Nome%Type define o tipo do parâmetro Parnome como Varchar(2) já que o campo Nome da tabela Clientes assim o é.

-A instrução aqui nesta etapa, não está protegida por nenhum bloco de tratamento de exceções, propositalmente para não haver complexidade excessiva nesta fase do aprendizado. Na sequência teremos entendimento desta prática tão necessária.

-Insert Into Values e o que vem em seguida entre parênteses, são referências aos parâmetros de entrada da Procedure, uma para cada campo da tabela Clientes, e na mesma ordem que estas colunas estão definidas na estrutura da tabela.

- NextVal é uma função embutida do Oracle, que faz retornar uma valor apartir da Sequence Seq_Clientes.

DigiData Informática 70 - 94

Page 71: Apostila Oracle 10g

Apostila de Oracle

Coloque o código da procedure no Editor Sql, clicando em seguida no botão Executar, objetivando criar nossa primeira procedure. Proceda o mesmo para criar as outras procedures definidas e comentadas abaixo.

CREATE PROCEDURE PROCALTCLIENTE (Parcodigo Clientes.Id_Cliente%Type,Parnome Clientes.Nome%Type,Parcnpj Clientes.Cnpj%Type,Partipo Clientes.Tipo%Type,Parstatus Clientes.Status%Type,Pardata Clientes.Data%Type,Parhistorico Clientes.Historico%Type,Parcredito Clientes.Credito%Type) Is

BEGINUpdate Clientes Set

Clientes.Nome = Parnome,Clientes.Data = Pardata,Clientes.Status = Status,Clientes.Credito = Parcredito,Clientes.Historico = Parhistorico,

Clientes.Tipo = Partipo,Clientes.Cnpj = Parcnpj

Where Clientes.Id_Cliente = Parcodigo; END;

Comentários:-Basicamente uma repetição do procedure anterior, exceto que existe um parâmetro a mais, visando termos uma chave de pesquisa para a instrução Update.

-Ao contrário da instrução Insert, não é necessário ter a mesma ordem de colunas da tabela, pois aqui é feito uma atribuição de valor para a coluna, identificando explicitamente qual coluna pelo nome.

Da mesma forma que para o procedimento anterior, copie o código executando-o no Editor Sql de nosso utilitário de desenvolvimento do projeto.

CREATE PROCEDURE PROCEXCCLIENTE (Parcodigo Clientes.Id_Cliente%Type) IS

BEGINDelete Clientes Where Id_Cliente = Parcodigo;

END;

Comentários:-instrução básica DDL para exclusão de registros em uma tabela.-Somente um parâmetro é necessário, pois a pesquisa na clásula Where só testa o campo ID_Cliente.

Para o próximo exemplo, adotaremos ao Wizard implementado pela nossa ferramenta, visando demostra quanto temos de ajuda com a mesma. Observe as Figuras 32, 33, 34, 35, 36 e 37 para tomar conhecimento.

CREATE PROCEDURE PROCMANUTPRODUTOS( ParOpcao VarChar2, ParId_Produto Produtos.Id_Produto%Type, ParDescricao Produtos.Descricao%Type, ParPrecoCompra Produtos.PrecoCompra%Type, ParSaldo Produtos.Saldo%Type) Is

BEGIN IF ParOpcao = 'I' THEN

DigiData Informática 71 - 94

Page 72: Apostila Oracle 10g

Apostila de Oracle

INSERT INTO Produtos Values(Seq_Produtos.NextVal, ParDescricao, ParSaldo, ParPrecoCompra); ELSIF ParOpcao = 'D' THEN DELETE PRODUTOS WHERE Id_Produto = ParId_Produto; ELSE UPDATE PRODUTOS SET Produtos.Descricao = ParDescricao, Produtos.Saldo = ParSaldo, Produtos.PrecoCompra = ParPrecoCompra WHERE Produtos.Id_Produto = ParId_Produto; END IF;END;

Comentários: A única novidade aqui é a instrução IF, exemplificada com sua variação ELSEIF finalizada com a condição ELSE. END IF encerra um bloco condicional IF.

A Figura 31 representa o início do processo de uso do Wizard construtor de Procedures e a Figura 32 onde definimos o nome da Procedure.

Figura 31

DigiData Informática 72 - 94

Page 73: Apostila Oracle 10g

Apostila de Oracle

Figura 32

A imagem representada pela Figura 33 permite definirmos todos os parâmetros da Procedure.

Figura 33

Após passagem pela passo anterior, sempre clicando no botão Próximo temos a área onde devemos entrar com o corpo da Procedure. Aqui é necessário conhecer a linguagem PL/SQL a fim de criar a lógica necessária ao procedimento. Observe a Figura 34 para tanto.

DigiData Informática 73 - 94

Page 74: Apostila Oracle 10g

Apostila de Oracle

Figura 34

Seguindo em frente, quando clicarmos no botão Próximo da tela anterior, seremos apresentado a última interface de criação, onde devemos naturalmente clicar no botão Finalizar. Pronto as Figuras 35 e 36 resumem esta última etapa. Repare na tela da Figura 36, as opções de funcionalidades para manutenção do procedimento recém criado.

Figura 35

DigiData Informática 74 - 94

Page 75: Apostila Oracle 10g

Apostila de Oracle

Figura 36

Criando Procedure com CursorNo oracle temos uma funcionalidade especial, que permite criarmos instruções Sql, basicamente instrução Select da linguagem SQL (DML), armazenando em memória esta coleção de registros selecionados com finalidade de navegar entre esses registros para uso mais diversificado possível.Em nosso exemplo, alcançaremos com a instrução Select alguns registros da tabela Pedidos combinados com a table Itens a fim de armazenar estes registros em uma outra tabela para posterior análise.

OPEN CURSOR

Executa o query associado com uma declaração explícito de cursor.

sintaxe:OPEN <cursor> [(<parâmetro> [, <parâmetro> ...])]

Ex.:

DECLARE CURSOR w_c2 (matrícula NUMBER) IS

SELECT nm_func, cd_matFROM func

WHERE cd_mat <= matrícula;BEGIN

OPEN w_c2 (350);....

END;

DigiData Informática 75 - 94

Page 76: Apostila Oracle 10g

Apostila de Oracle

CURSOR LOOP

Implicitamente declara uma área para receber a row, abre um cursor, lê cada row e fecha o cursor quando todas as rows tiverem sido processadas.

sintaxe: [<< <label> >>]FOR <RECORD> IN <cursor> [(<parâmetro> [,<parâmetro> ...])] LOOP

<seqüência de comandos>END LOOP;

Ex.:DECLARE

CURSOR w_c2 IS SELECT cd_mat, vl_sal, vl_sal * .10 fgts FROM func;

BEGIN DELETE FROM folha;

COMMIT; FOR w_c2_row IN w_c2 LOOP

calc_ir(w_c2_row.vl_sal, w_vl_ir);w_vl_inss := calc_inss(w_c2_row.vl_sal, w_vl_lim);INSERT INTO folha(cd_mat, vl_sal, vl_ir, vl_inss, vl_fgts)VALUES (w_c2_row.cd_mat, w_c2_row.vl_sal, w_vl_ir,

w_vl_inss, w_c2_row.fgts);END LOOP;COMMIT;

END;

ATRIBUTOS PARA CURSOR

Existem 2 tipos de cursores em PL/SQL: implícito e explícito. A PL/SQL implicitamente declara um cursor para cada comando SQL que manipule dados, inclusive queries que retornem uma única row.

%FOUND - indica se o último FETCH retornou uma linha ou não, para cursores explícitos. E se alguma row foi afetada pelo último comando INSERT, UPDATE ou DELETE para cursores implícitos.

sintaxe: <cursor> %FOUNDSQL%FOUND

Ex.:LOOP

FETCH w_c1 INTO w_c1_row;IF w_c1%FOUNDTHEN

%NOTFOUND - indica se o último FETCH retornou uma row ou não, para cursores explícitos. E se alguma row foi afetada pelo último comando INSERT, UPDATE ou DELETE para cursores implícitos.

sintaxe:<cursor>%NOTFOUNDSQL%NOTFOUND

Ex.:LOOP

FETCH w_c1 INTO w_c1_row;IF w_c1%NOTFOUND THENEXIT;

END LOOP;

DigiData Informática 76 - 94

Page 77: Apostila Oracle 10g

Apostila de Oracle

%ISOPEN - permite que se verifique se um cursor está aberto ou não. No caso de cursores implícitos o resultado será sempre FALSE, uma vez que o Oracle fecha o cursor após uma operação.

sintaxe:<cursor>%ISOPENSQL%ISOPEN

Ex.:IF NOT (w_c1%ISOPEN)THEN...

%ROWCOUNT - indica o número de rows lidas para o cursor associado (para cursores explícitos) ou o número de rows afetadas no último comando INSERT, UPDATE, DELETE ou SELECT (para cursores implícitos). Após a abertura do cursor, o valor de ROWCOUNT é zero. O número só será incrementado SE O ÚLTIMO FETCH retornou uma row.

sintaxe:<cursor>%ROWCOUNTSQL %ROWCOUNT

Ex.:LOOP

FETCH w_c1 INTO w_c1_row;IF w_c1% ROWCOUNT THEN

Para concluirmos com sucesso a criação de nossa procedure, devemos antes criar a tabela que receberá os dados alcançados conforme código abaixo:CREATE table VENDASCLI ( NOMECLIENTE VARCHAR2(100), TOTALCOMPRAS NUMBER(18,2))

O código completo da procedure proposta a ser executado no Editor Sql, está na sequência, bem com os comentários para cada instrução que ainda não foi aqui apresentada.

CREATE PROCEDURE ProcVendasCli (Pardata Pedidos.Dataped%Type,Parvalor Itens.PrecoVenda%Type) As

Cursor CursorVendasCli IsSelect Clientes.Nome, Sum(Itens.Quantidade * Itens.PrecoVenda) As TotalFrom Clientes Inner Join Pedidos On Clientes.Id_Cliente = Pedidos.Id_Cliente Inner Join Itens On Pedidos.Id_Pedido = Itens. Id_Pedido Where Pedidos.Dataped >= PardataGroup By Clientes.NomeHaving Sum(Itens.Quantidade * Itens.PrecoVenda) >= ParvalorOrder By Clientes.Nome;

VarNome Clientes.Nome%Type;VarTotal Itens.PrecoVenda%Type;

BEGINDelete VendasCli;Open CursorVendasCli;Fetch CursorVendasCli Into VarNome,VarTotal; If CursorVendasCli %NotFound Then

Raise_Application_Error(-20000, 'Não há vendas neste período.');

DigiData Informática 77 - 94

Page 78: Apostila Oracle 10g

Apostila de Oracle

End If;Insert Into Vendascli Values (Varnome, Vartotal); Loop

Fetch CursorVendasCli Into VarNome,VarTotal; Exit When Cursorvendascli%Notfound; Insert Into Vendascli Values (Varnome, Vartotal);

End Loop;Close Cursorvendascli;

End;

Comentários:-Cursor CursorVendasCli Is: Define um objeto Cursor.

-A instrução que vai de Select a Order By, compõe o código que retorna o total de compras de clientes em um período (Pedidos.Dataped >= Pardata).

-VarNome Clientes.Nome%Type e VarTotal Itens.PrecoVenda%Type, respectivamente definem duas variáveis.

-Delete VendasCli: Exclui possíveis registros nesta tabela.

-Open CursorVendasCli: Abre o cursor, carregando os registros alcançados por sua instrução Select.

-If Sql%NotFound Then: Verifica se existe registros no cursor. A instrução Select teria retornado registros.

-Raise_Application_Error(-20000, 'Não há vendas neste período.'): Levanta uma exceção, fazendo interromper o processo, caso a condição do IF seja verdadeira.

-Loop: Inicia o processo de leitura (giro) incondicional.

-Fetch CursorVendasCli Into VarNome,VarTotal: Faz leitura do registro atual do Cursor, atribuindo valores das colunas deste Cursor as variáveis locais previamente definidas. Também posiciona o Cursor no próximo registro.

-Exit When Cursorvendascli%Notfound: Aborta o Loop caso não exista mais registros no Cursor.

-Insert Into Vendascli Values (Varnome, Vartotal): Instrução (DML) que insere registro na tabela VendasCli.

-End Loop: Encerra um bloco Loop.

-Close Cursorvendascli: Fecha o Cursor liberando recursos.

Objetivando ampliar o conhecimento da linguagem PL/SQL, teremos na sequência algumas rotinas que fazem uso dos principais recursos desta linguagem.

Usando o comando IF... THEN e LOOP... END LOPP Em uma procedure atualize o preço do produto com o valor do parâmetro passado como argumento, para todos os produtos com saldo superior a zero.

1. Create or Replace Procedure CORRIGEPRECOPRODUTO (Percentual IN NUMBER) is2. VarSaldo Number;3. VarId_Produto Number;

4. Cursor ListaProdutos is Select id_produto, saldo From Produtos Where Saldo > 0;

5. Begin6. Open ListaProdutos;7. LOOP8. Fetch ListaProdutos Into VarId_Produto, VarSaldo;

DigiData Informática 78 - 94

Page 79: Apostila Oracle 10g

Apostila de Oracle

9. Exit When ListaProdutos%NotFound; 10. if VarSaldo > 0 then Update Produtos Set PrecoCompra =PrecoCompra * (1 + (Percentual / 100))

Where id_produto = VarId_Produto; 11. end if;12. END LOOP;13. Close ListaProdutos;14. End;

Comentários:

Linha Comentário02 e 03 Define variáveis internas da procedure com o tipo Number04 Declara cursor com o nome ListaProdutos ,e a instrução Select para o cursor06 Abre o cursor, executando a instrução select07 Inicía bloco Loop (executa incondicionalmente)08 Obtem 1º linha do cursor, atribuindo valores das colunas para as variáveis locais09 Caso não exista mais registros no cursor, abandona o Loop10 Comando que avalia condição. No caso, uma variável12 e 13 Executa a instrução Update para atualizar16 Fim do bloco Loop

Usando o comando CASE... END para atribuição de valores.O exercício consiste em varrer os registros da tabela Clientes, identificando quais registros atendam ao critério que traz somente aqueles cujo campo Credito seja maior que 1000. Na sequência, identifica a qual estado pertence o cliente, aplicando por critério decidido pelo comando CASE, um valor de acréscimo a uma variável do tipo numérica naturalmente. Por fim ajusta o valor do campo Credito baseado no valor da variável em questão.

1. Create or Replace Procedure ATUALIZACREDITOCLIENTE is

2. VarId_Cliente Number;3. VarEstado Varchar(2);4. Varpercentual Number;

5. Cursor ListaClientes is Select Clientes.id_cliente, Cidades.estado a. From Clientes Inner Join Cidadesb. On Cidades.CidadeId = Clientes.CidadeIdc. Where Clientes.credito >= 1000;

6. Begin7. Open ListaClientes; 8. LOOP9. Fetch ListaClientes Into VarId_Cliente, VarEstado;10. Exit When ListaClientes%NotFound; 11. Varpercentual:=12. Case VarEstado13. When 'RJ' Then 1.15 14. When 'SP' Then 1.18 15. When 'MG' Then 1.1616. Else 1.10 17. end;

18. Update Clientes Set Credito = Credito * Varpercentual where Clientes.id_cliente = VarId_Cliente;

19. END LOOP;20. Close ListaClientes; 21. End;

DigiData Informática 79 - 94

Page 80: Apostila Oracle 10g

Apostila de Oracle

Comentários:

Linha Comentário12 Atribuição a variável que receberá o valor retornado pelo comando CASE13 Inicia o seletor do CASE14 Condição para verificar o valor do seletor do CASE15 Idem16 Idem17 Condição valida quando nenhuma condição explícita for verdadeira

Obs: Não comentado linhas já abordadas em outras rotinas.

TRATAMENTO DE ERROS

Em PL/SQL uma warning ou error condition é chamada uma exception. Existem algumas exceções já definidas pelo Oracle com minemônicos para referência. Para as demais, podem ser dados nome pelo usuário, como veremos neste capítulo.

Quando um erro ocorre, uma exception é setada, isto é, a seqüência de execução do programa é interrompida e o controle é transferido para a área de tratamento de execução do programa.

As exceções pré-definidas pelo Oracle são setadas quando a condição de erro ocorre. As exceções criadas pelo programa deverão ser setadas explicitamente pelo verbo RAISE.

EXCEÇÕES PRÉ-DEFINIDAS

Nome da Exceção Oracle Error SQLCODE Condição de ErroCURSOR_ALREADY_OPEN ORA-06511 -6511 É setada se for executado um OPEN

para um cursor já aberto.DUP_VAL_ON_INDEX ORA-00001 -1 É setada se for tentada uma inclusão

de uma coluna com valor duplicado em uma tabela que possui um índice unique nesta coluna.

INVALID_CURSOR ORA-01001 -1001 É setada se for feita uma operação ilegal com um cursor. Por exemplo: CLOSE em um cursor não aberto.

INVALID_NUMBER ORA-01722 -1722 É setada se algum comando SQL tentou uma conversão de uma string para número e esta conversão falha porque a string não representa um número.

LOGIN_DENIED ORA-01017 -1017 É setada se for feita uma tentativa de logon com um username/password inválido.

NO_DATA_FOUND ORA-01403 +100 É setada se num SELECT INTO nenhuma row foi retornada ou se foi feita uma referência a uma row não inicializada em uma tabela PL/SQL.

NOT_LOGGED_ON ORA-01012 -1012 É setada se uma programa PL/SQL tenata fazer acesso ao database sem efetuar um logon.

PROGRAM_ERROR ORA-06501 -6501 É setada se ocorrer um problema interno.

STORANGE_ERROR ORA-06500 -6500 É setada se PL/SQL sai da memória ou se a memória estiver corrompida.

TIME_ON_RESOURSE ORA-00051 -51 É setada se ocorrer timeout enquanto o ORACLE estiver aguardando por um recurso.

DigiData Informática 80 - 94

Page 81: Apostila Oracle 10g

Apostila de Oracle

TOO_MARY_ROWS ORA-014222 -1422 É setada se um comando SELECT INTO retormar mais que uma row.

TRANSACTION_BACKED_OUT

ORA-00061 -61 É setada quando a parte remota de uma transação é desmanchada. A transação local deve ser desmanchada também.

VALUE_ERROR ORA-06502 -6502 É setada se uma operação aritmética, conversão, constraint error, truncation ocorrer.

ZERO_DIVIDE ORA-01476 -1476 É setada se houver ocorrido uma divisão por zero.

Ex.:DECLARE

…BEGIN

SELECT …SELECT …SELECT …

EXCEPTIONWHEN NO_DATA_FOUND THEN

…END;

EXCEÇÕES DEFINIDAS PELOS USUÁRIOS

A PL/SQL permite que sejam definidas exceções de um programa. Este tipo de exceção deve ser setada explicitamente pelo verbo RAISE.

RAISE

Seta uma exceção.

sintaxe: RAISE <exceção>

Ex.:DECLARE

erro_soma EXCEPTION;…

BEGINIF …THEN

RAISE erro_soma;END IF;

EXCEPTIONWHEN erro_soma THEN

…WHEN OTHERS THEN

…END;

Obs.: O desvio de execução do programa é transferido para a exceção OTHERS quando o erro ocorrido não foi tratado em outras exceções mais específicas. É uma opção para diminuição da lista de exceptions.

DigiData Informática 81 - 94

Page 82: Apostila Oracle 10g

Apostila de Oracle

PRAGMA EXCEPTION_INIT

Associa um nome de exceção com um número de SQLCODE. Isto permite que se façam testes se erro mais específicos em vez de usar OTHERS.

sintaxe: PRAGMA EXCEPTION_INIT (<nome da exceção>,<número>)

Ex.:

DECLAREsem_privilegio EXCEPTION;PRAGMA EXCEPTION_INIT (sem_privilegio, -1031);— O ORACLE retorna o erro -1031 se, por exemplo, for feita uma tentativa de alterar uma tabela em que o usuário só tem autorização de SELECT.BEGIN

…EXCEPTION

WHEN sem_privilegio THEN…

END;

RAISE_APPLICATION_ERROR

É uma procedure que permite ao usuário enviar mensagens de um subprograma ou database trigger.

sintaxe: RAISE_APPLICATION_ERROR (<número>,<mensagem>);

Ex.:

CREATE TRIGGER checa_salario…DECLARE…BEGIN

…IF (:new.vl_sal <salario_minimo OR :new.vl_sal > salário_maximo)THEN

RAISE_APPLICATION_ERROR (-20225, ‘Salário fora de faixa’);…

END IF;END;

Obs.: <número> deve variar de -20000 a -20999 e a <mensagem> deve possuir até 512 bytes de comprimento.

DigiData Informática 82 - 94

Page 83: Apostila Oracle 10g

Apostila de Oracle

PROPAGAÇÃO DA EXCEÇÃO

Quando uma exceção é setada, se PL/SQL não encontrar um tratamento para ela no bloco correto ou subprograma, a exceção se propaga. Isto é, a exceção se reproduz no bloco externo e assim por diante até que a PL/SQL retorne um erro para o ambiente (abortando o programa).

Ex.:BEGIN

…BEGIN

IF x = 1 THEN RAISE A;ELSIF x = 2 THEN RAISE B;ELSE RAISE C;END IF;…

EXCEPTIONWHEN A THEN…

END;…A’

EXCEPTIONWHEN B THEN…

END;

A exceção A é tratada no bloco mais interno. Após seu tratamento o programa continua no comando A.A exceção B se propaga para o bloco mais externo, é tratada e o programa termina normalmente.A exceção COMANDO SQL: se propaga para o bloco mais externo, não e tratada e o erro passa para o ambiente, isto é, o programa é abortado.

SQLERRM

String procedure para traduzir um SQLCODE.

sintaxe: SQLERRM (<sqlcode>)

Ex.:

DECLAREmsg CHAR(100)

BEGINFOR num IN 1..9999 LOOP

msg := SQLERRM (num * -1);INSERT INTO tab_erro VALUES (msg);

END LOOP;END;

DigiData Informática 83 - 94

Page 84: Apostila Oracle 10g

Apostila de Oracle

3- Este exemplo implementa uma Procedure para incluir registros nas tabelas Produtos e DataProdutos, simultaneamente, controlando o fluxo de código para observar se houve erro. Havendo erro na operação, é levantada uma exceção identificada que é tratada pelo bloco Exception.Importante ressaltar, que não existe até o momento, a tabela DataProdutos, assim, utilize o script abaixo para criar a mesma.

CREATE Table DATAPRODUTOS ( ID_PRODUTO NUMBER (18,0) NOT NULL, DATA DATE NOT NULL, Constraint DATAPRODUTOS_PK primary key (ID_PRODUTO))

1. Create or Replace PROCEDURE IncluiProdutos2. (Descricao IN Varchar2, PrecoCompra Number, Saldo IN NUMBER) is

3. VarIdProduto Number;

4. BEGIN

5. Select SEQ_Produtos.NextVal Into VarIdProduto From Dual;6. Insert Into Produtos(id_produto, descricao, precocompra, saldo)7. Values(VarIdProduto, Descricao, PrecoCompra, Saldo);

8. Insert Into DataProdutos(id_produto, data)9. Values(VarIdProduto, SysDate);10. Commit;

11. EXCEPTION

12. WHEN DUP_VAL_ON_INDEX THEN13. Raise_Application_Error(-20000, 'Valor de Chave duplicado');

14. WHEN OTHERS THEN15. Raise_Application_Error(-20000, 'ERRO NOVO:' || ‘ Nº.:’ || TO_CHAR(SQLCODE) || ‘ MENSAGEM: ‘ || SQLERRM);

16. End;Comentários:

Linha Comentário05 Atribui valor (da sequência) para variável11 Verifica se a última instrução retornou erro, tentando o valor da variável SQLCODE12 Levanta um exceção internamente identificada como VarErro_DataProdutos17 Idem linha 1118 Idem linha 1220 Aplica um Commit explícito, efetivando as inserções nas duas tabelas22 Início do bloco de tratamento de exceções23 Condição que tenta identificar se houve o erro VarErro_Produtos24 Levanta uma exceção para aplicativo cliente, com número padrão e mensagem específica.25 Idem linha 2326 Idem linha 2427 Condição outra de erro não identificada28 Idem linha 24

DigiData Informática 84 - 94

Page 85: Apostila Oracle 10g

Apostila de Oracle

Function

Semelhante a Procedure, mas com a capacidade de retornar um valor, Functions são uma ótima opção para processamento junto a base de dados que devam retornar valores.Normalmente fazemos muita incursão na base de dados, muita vezes varrendo literalmente dezena de milhares de registros, em várias tabelas, a fim de processar tais registros e retornar um valor resultante. Isto traria um impacto siguinificativo sobre a performance de uma aplicativo que viesse acessar o Oracle para obter e processar esta informação, sem falar no atrito de rede que isto provocaria, uma vez que dezena de milhares de registros ou mais, trafegariam pela rede. Dependendo da instrução isto pode provocar o caos.A solução, conforme exemplo abaixo, seria criar uma Function que internamente ao banco de dados obteria os registros e depois processaria tais retornando a aplicação solicitante. Mesmo que isto tenha alguma demanda que provoque alguma espera pela aplicação cliente, ainda assim é melhor de ter este tempo e o atrito de rede de quebra.Então vamos ao código da funçaão que deverá ser executado no Editor Sql de nosso utilitário.

sintaxe: FUNCTION <nome da função> [(<parâmetro>[,<parâmetro>,…])]RETURN <tipo da função> IS[<variáveis locais>]

BEGIN<comando>

[EXCEPTION<tratamento das exceções>]

END <nome da função>];

onde: parâmetros possui a seguinte sintaxe:

<nome da variável> [IN | OUT | IN OUT] <tipo> [{:=| DEFAULT} <valor>]

Quando [IN | OUT …] não for especificado, será assumido IN.

CREATE FUNCTION Func_Totcompracli (Parcodcli In Clientes.Id_Cliente%Type,

Pardata1 In Pedidos.Dataped%Type, Pardata2 In Pedidos.Dataped%Type)

Return Number As Vartotal Number (13,2);

BEGINSelect Sum(Itens.Quantidade * Itens.Precovenda) Into VartotalFrom Pedidos Inner Join ItensOn Pedidos.Id_Pedido = Itens.Id_PedidoWhere Pedidos.Id_Cliente = Parcodcli And

Pedidos.Dataped Between Pardata1 And Pardata2;Return Vartotal;

END;

Comentários:-Três parâmetros de entrada.

-Return Number: Define o tipo de retorno da Function.

- Vartotal Number (13,2): Define uma variável local para receber o valor alcançado pela instrução Select.

-De Select a Where, a instrução Sql que alcançará o valor a ser retornado pela Function.

-Return Vartotal: Efetivamente retorna o valor para a aplicação solicitante.

DigiData Informática 85 - 94

Page 86: Apostila Oracle 10g

Apostila de Oracle

Tabelas temporárias

Como padrão, as tabelas são criadas como permanentes, ou seja, existem até que sejam especificamente excluídas ou modificadas. Por meio do comando CREATE TEMPORARY TABLE, o Oracle permite a criação de uma tabela que existe apenas durante o processamento de uma transação ou sessão.Comandos SQL do tipo DML, que modificam os dados em uma tabela temporária, não geram entradas para os arquivos de redo log, mas geram para os redo logs de rollback. Uma tabela temporária pode ter índices criados para ela com o comando INDEX. Esses índices, assim como as visões e os triggers, também são excluídos quando ela o é também no final da sessão ou transação.

Triggers

Um gatilho [trigger] é um tipo de procedimento armazenado, que é executado automaticamente quando ocorre algum tipo de alteração numa tabela. Gatilhos “disparam” quando ocorre uma operação INSERT, UPDATE e DELETE numa tabela.Geralmente gatilhos são utilizados para reforçar restrições de integridade que não podem ser tratadas pelos recursos mais simples, como regras, restrições, a opção NOT NULL etc.Um gatilho também pode ser usado para calcular e armazenar valores automaticamente em outra tabela.Deste forma, pode-se usar um DATABASE TRIGGER para:

• Logar modificações

• garantir críticas complexas

• Gerar o valor de colunas

• Implementar níveis de segurança mais complexos

• Manter tabelas duplicadas

Pode-se associar até 12 TRIGGERS a cada tabela, um de cada tipo (BEFORE UPDATE <row>, BEFORE DELETE <row>, BEFORE INSERT <row>, BEFORE INSERT <comando>, BEFORE UPDATE <comando>, BEFORE DELETE <comando> e as mesmas sintaxes para AFTER). Um DATABASE TRIGGER é composto de 3 partes:

• evento

• constraint (opcional)

• ação

Vamos cria um gatilho, chamado InclusaoCliente, que será ativado por uma operação INSERT na tabela dbo.clientes.

CREATE TRIGGER TRIG_INCITEM BEFORE INSERT ON ITENS FOR EACH ROW

DECLAREVarsaldo produtos.saldo%type;VarDescricao produtos.descricao%type;

DigiData Informática 86 - 94

Page 87: Apostila Oracle 10g

Apostila de Oracle

BEGINSelect Produtos.Saldo,Produtos.Descricao Into Varsaldo,VardescricaoFrom Produtos Where Produtos.Id_Produto = :New.Id_Produto;

If Varsaldo >= :New.Quantidade ThenUpdate Produtos Set Produtos.Saldo = Produtos.Saldo - :New.QuantidadeWhere Produtos. Id_Produto = :New.Id_Produto;

ElseRaise_Application_Error( -20000, 'Ini O Saldo Do Produto ' ||

Vardescricao || ' É De: ' ||To_Char(Varsaldo) || ' Não Atendendo O Solicitado. Fim' );

End If;END;

Comentários:-CREATE TRIGGER TRIG_INCITEM: Define o nome da Trigger.-BEFORE INSERT ON ITENS: Define o disparo antes da inserção de registros na tabela Itens.-FOR EACH ROW; Garante execução para todas as linhas da tabela.-DECLARE Varsaldo produtos.saldo%type e VarDescricao produtos.descricao%type: Define variáveis local.-:New.Quantidade : Retorna o valor do campo Quantidade para o registro que disparou a Trigger.

CREATE TRIGGER TRIG_ALTITEM BEFORE UPDATE ON ITENS FOR EACH ROW DECLARE

Varsaldo produtos.saldo%type;VarDescricao produtos.descricao%type;

BEGINUpdate Produtos Set Produtos.Saldo = Produtos.Saldo + :Old.QuantidadeWhere Produtos.Id_Produto = :Old.Id_Produto;

Select Produtos.Saldo,Produtos.Descricao Into Varsaldo,VardescricaoFrom Produtos Where Produtos. Id_Produto = :New.Id_Produto;

If Varsaldo >= :New.Quantidade ThenUpdate Produtos SetProdutos.Saldo = Produtos.Saldo - :New.QuantidadeWhere Produtos. Id_Produto = :New.Id_Produto;

ElseRaise_Application_Error(-20000, 'Ini O Saldo Do Produto ' ||

Vardescricao || ' É De: ' ||To_Char(Varsaldo) || ' Não Atendendo O Solicitado. Fim');

End If;END;

CREATE TRIGGER TRIG_EXCITEM BEFORE DELETE ON ITENS FOR EACH ROW BEGIN

Update Produtos Set Produtos.Saldo = Produtos.Saldo + :Old.QuantidadeWhere Produtos.Id_Produto = :Old.Id_Produto;

END;

CREATE TRIGGER TRIG_AJUSTAPRECOVENDA BEFORE INSERT OR UPDATE ON ITENS FOR EACH ROW DECLARE Varprecocompra Produtos.PrecoCompra%Type;

DigiData Informática 87 - 94

Page 88: Apostila Oracle 10g

Apostila de Oracle

BEGINSelect Produtos.PrecoCompra Into VarprecocompraFrom Produtos Where Produtos.Id_Produto = :New.Id_Produto;If :New.Precovenda < (Varprecocompra * 1.17) Then

:New.PrecoVenda := (Varprecocompra * 1.17);End If;

END;

PACKAGES

Um package é um objeto que grupa logicamente subprogramas, objetos e tipos PL/SQL. Packages são compostos de duas partes: A especificação e o corpo do pacote. A especificação é a interface com as aplicações. Nela são declarados os tipos, variáveis, constantes, exceções, cursores e subprogramas. No corpo do pacote é concluída a definição dos cursores e subprogramas e feita a implementação da especificação.

Um package não pode ser chamado, receber parâmetro nem ser aninhado (declarado dentro de outro package).

sintaxe: PACKAGE <nome do pacote> IS — parte da especificação<declarações>

END [<nome do pacote>];

PACKAGE BODY <nome do pacote> IS — corpo do pacote<corpo dos subprogramas>

[BEGIN<comandos de inicialização>]

END [<nome do pacote>];

A parte de especificação são declarações públicas, visíveis pelas aplicações. O corpo implementa detalhes e declarações privadas que são invisíveis pelas aplicações. O corpo seria uma caixa preta.Um pacote pode ser criado internamente no SQL*PLUS ou no SQL*DBA usando-se os comandos CREATE PACKAGE e CREATE PACKAGE BODY.

sintaxe: CREATE [OR REPLACE]PACKAGE <nome do pacote> AS/IS

<declarações>END <nome do pacote>

CREATE [OR REPLACE]PACKAGE BODY <nome do pacote> AS/IS

<corpo dos subprogramas<[BEGIN

<inicializações>]END <nome do pacote>

Deve-se observar que somente a especificação do pacote é visível e acessível pela aplicação. Detalhes da implementação que se localizam do body são invisíveis e inacessíveis. Desta forma pode-se alterar o body sem haver necessidade de se recompilar os programas que usarem os packages

DigiData Informática 88 - 94

Page 89: Apostila Oracle 10g

Apostila de Oracle

VANTAGENS DO USO DE PACKAGES

Packages oferecem várias vantagens:Modularidade Packages permitem que se encapsulem logicamente tipos, objetos e

subprogramas relacionados.Desenho da aplicação quando uma aplicação é desenhada, tudo que á necessário

inicialmente é a informação da especificação do package. Pode se codificar e compilar a especificação sem o corpo do package. Uma vez que armazenado a referência ao pacote pode ser compilada também.

Segurança Com pacotes pode-se especificar que tipos, objetos e subprogramas são públicos ou privados. Os públicos são especificados na parte de especificação dos packages. Já os privados são totalmente especificados do body do package. Eles são usados dentro do próprio pacote e não precisam ficar visíveis a quem usar os pacotes.

Funcionalidade Variáveis públicas e cursores empacotados podem ser compartilhados por todas as procedures que executarem no ambiente.

Performance Quando é feita a primeira chamada de um package subprogram pela primeira vez, todo o pacote é carregado na memória. Assim, subsequentes chamadas a outros subprogramas dentro do pacote não requerem I/O de disco

REFERÊNCIAS A packageS

Para fazer uma referência aos tipos, objetos e subprogramas declaradas dentro da especificação de packages deve-se usar a seguinte notação:

<nome de package>. <tipo><nome de package>. <objeto><nome de package>. <subprograma>

Pode-se fazer referência a pacotes de dentro de database triggers, stored subprograms e blocos PL/SQL dentro de programas e blocos PL/SQL anônimos.

A inicialização da parte executável do package é feita uma única vez, na primeira vez que for feita referência ao package (por sessão).

Criando uma Package

CREATE OR REPLACE PACKAGE Entidade_ProdutoIS

PROCEDURE PROCMANUTPRODUTOS( ParOpcao VarChar2, ParId_Produto Produtos.Id_Produto%Type, ParDescricao Produtos.Descricao%Type, ParPrecoCompra Produtos.PrecoCompra%Type, ParSaldo Produtos.Saldo%Type) ;

FUNCTION Func_Totcompracli (Parcodcli In Clientes.Id_Cliente%Type, Pardata1 In Pedidos.Dataped%Type,Pardata2 In Pedidos.Dataped%Type)return number;

END;CREATE OR REPLACE PACKAGE BODY Entidade_ProdutoIS

DigiData Informática 89 - 94

Page 90: Apostila Oracle 10g

Apostila de Oracle

FUNCTION Func_Totcompracli (Parcodcli In Clientes.Id_Cliente%Type,

Pardata1 In Pedidos.Dataped%Type, Pardata2 In Pedidos.Dataped%Type)

Return Number As Vartotal Number (13, 2);

BEGINSelect Sum(Itens.Quantidade * Itens.Precovenda) Into VartotalFrom Pedidos Inner Join ItensOn Pedidos.Id_Pedido = Itens.Id_PedidoWhere Pedidos.Id_Cliente = Parcodcli And

Pedidos.Dataped Between Pardata1 And Pardata2;Return Vartotal;

END Func_Totcompracli;

PROCEDURE PROCMANUTPRODUTOS( ParOpcao VarChar2, ParId_Produto Produtos.Id_Produto%Type, ParDescricao Produtos.Descricao%Type, ParPrecoCompra Produtos.PrecoCompra%Type, ParSaldo Produtos.Saldo%Type) Is

BEGIN IF ParOpcao = ‘I’ THEN INSERT INTO Produtos Values(Seq_Produtos.NextVal, ParDescricao, ParSaldo, ParPrecoCompra); ELSIF ParOpcao = 'D' THEN DELETE PRODUTOS WHERE Id_Produto = ParId_Produto; ELSE UPDATE PRODUTOS SET Produtos.Descricao = ParDescricao, Produtos.Saldo = ParSaldo, Produtos.PrecoCompra = ParPrecoCompra WHERE Produtos.Id_Produto = ParId_Produto; END IF;

END PROCMANUTPRODUTOS; END Entidade_Produto; Executando um procedimento Público Empacotado SQL> execute Entidade_Produto. Func_Totcompracli(1,’01/01/2000’,’01/01/2001’)

DigiData Informática 90 - 94

Page 91: Apostila Oracle 10g

Apostila de Oracle

Sinônimos

Consiste em uma prática simples para garantir segurança no acesso a dados de uma tabela e objetos em geral. Na prática, sinônimos são nomes alternativos (apelido) dado a objetos de banco de dados.Aspectos como: fornecer um nome não técnico ao objeto de forma abreviada, permitir mudança do nome do objeto sem que isso afete referências a este objeto em rotinas, e ainda segurança, são alguns dos motivos para se criar Sinônimos.Vejamos alguns exemplos:

Create Public Synonym Clientesto Aluno.Clientes;

-Cria um sinônimo público nomeado SIN_Clientes, que representa a tabela Clientes do esquema Aluno.

Naturalmente podemos fazer uso de nosso Editor Sql, ou ainda utilizar o wizard para construir mais facilmente. Caso queira utilizar a interface gráfica para isto, clique na opção Browser de Objetos|Criar|Sinônimo, observe a Figuras 01.

Figura 01

Para encerrar o processo de criação, basta clicar no botão Próximo e em seguida no botão Finalizar.Agora você pode fazer o teste com o comando:

-Select * From SIN_Clientes, tendo como retorno o mesmo caso faça uso direto da tabela Clientes.

DigiData Informática 91 - 94

Page 92: Apostila Oracle 10g

Apostila de Oracle

Exercícios de Revisão

1) Criar as seguintes tabelas:

AssociadosId_Associado Numeric (10,2) Not NullNome Varchar2 (50) Not NullCidade Varchar2 (25) Not NullEstado Varchar2 (2) Not NullData Date

EspecialidadesId_Especialidade Numeric(10,2) Not NullDescricao Varchar2(25) Not Null

Associados_EspecialidadesId_Associado Numeric(10,2) Not NullId_Especialidade Numeric(10,2) Not Null

Nota1:Os itens 1.1 e 1.2 referem-se as tabelas que identificam os agentes do projeto. Já o item 1.3, armazena os relacionamentos possíveis entre associados e especialidades.

Nota2:Quanto a chave primária, para 1.1 e 1.2, somente os campos iniciados com Id compõem a chave; e para a tabela do item 1.3, as duas colunas compõem a chave primária.

Nota3:Finalizando a estrutura, observa-se que as duas colunas da tabela Associados _Especiali dades, são individualmente chave estrangeira, respectivamente com referência as tabelas dos itens 1.1 e 1.2.

Adicionar 4 registros a tabela associados, 4 registros a tabela especialidades e pelo menos 12 registros na última tabela.Criar índices para os campos nome, cidade e estado da tabela associados e índice para o campo descricao da tabela especialidades.Obs.: Usar a seguinte nomenclatura : Idx_campo_tabela

DigiData Informática 92 - 94

Page 93: Apostila Oracle 10g

Apostila de Oracle

2) Criar as seguintes Views:

View que retorne a quantidade de cadastros por mês:

Select To_Char (Associados.Data, ‘Year’) || ‘–‘|| TO_CHAR (Associados.Data, ‘Month’) As AnoMes,Count(Associados.nome) As TotalFrom Associados Group by TO_CHAR (Associados.Data, ‘Year’) || ‘–‘|| TO_CHAR (Associados.Data, ‘Month’)

View que retorne quantas especialidades tem cada associado, que tenha mais de uma especialidade:

Select Associados.Nome,Count (Associados_Especialidades.Id_Associado) As QtdFrom Associados, Associados_EspecialidadesWhere Associados.Id_Associado = Associados_Especialidades.Id_AssociadoGroup by Associados.NomeHaving Count(Associados_Especialidades.Id_Associado) > 1

3) Criar a seguinte Stored Procedure:

- Criar uma procedure para a inclusão de associados, possibilitando alteração e exclusão. Também implementar tratamento de erros (excption) e controle de Transação.

Create or replace procedure Proc_Manut_Associados(PId Associados.Id_Associado%type,Pnome Associados.Nome%type,Pcidade Associados.Cidade%type,Pestado Associados.Estado%type,Pdata Associados.Data%type,Poperacao Varchar2) IsBegin

If Poperacao = ‘I’ ThenInsert into Associados Values(Seq_Associados.nextval, Pnome, Pcidade, Pestado, Pdata);

ElsIf Poperacao = ‘A’ thenUpdate Associados Set

Associados.Nome = Pnome, Associados.Cidade = Pcidade,Associados.Estado = Pestado, Associados.Data = Pdata

Where Associados.Id_Associado = Pid;Else

Delete Associados Where Associados.Id_Associado = Pid;End If;Commit;Exception

When nomeerro ThenRaise_application_error(-20000,’mensagem...’);

When nomeerroWhen Others Then

Raise_application_error(-20000,’mensagem...’);End;

Nota1: Conforme demonstrado no comando Insert, deve ser criado uma seqüência de nome Seq_Associados.

DigiData Informática 93 - 94

Page 94: Apostila Oracle 10g

Apostila de Oracle

4) Criar uma function

- Que retorna a quantidade de associados que tenham especialidades por estado. Esta function deverá prover um parâmetro para escolha do estado.

Create or Replace Function Func_QtdeAssociados_Estado (Pestado varchar2)Return Numeric isVqtde number;

BeginSelect Count(Associados.Id_Associado) As QtdInto VqtdeFrom Associados, Associados_EspecialidadesWhere Associados.Id_Associado = Associados_Especialidades. Id_Associado

And Associados.estado = Pestado;

Return Vqtde;End;

5) Criar Trigger

- Uma triggers que dispare uma exceção, quando da inclusão ou alteração na tabela especialidades, provocar um conteúdo para o campo descrição com menos de três caracteres.

Create or replace trigger Trig_validadescricao Before insert or update on Especialidades for each rowBegin

If Length(:new.descricao) < 3 thenRaise_application_erro(-20000, ‘Minha mensagem..............’);

End If;End;

- Uma Trigger que limite o total de especialistas de uma especialidade(Descricao) em no máximo 4(quatro), por Estado.

Create or replace trigger Trig_Controla_Lim_Espec Before insert or update on Associados_Especialidades for each row

DeclareVtotal Number; Vestado Varchar;

BeginSelect Associados.Estado Into Vestado From AssociadosWhere Associados.Id_Associado = :New.Id_Associado;

Select Count(Associados.Estado) Into VTotalFrom Associados, Associados_Especialidades

Where Associados.Id_Associado = Associados_Especialidades.Id_Associado And Associados_Especialidades. Id_Especialidade = :New.Id_Especialidade

And Associados.Estado = VEstado;If Vtotal > 4 Then

Raise_Application_Error(-20000, ‘Minha Mensagem.....);End If;

End;

DigiData Informática 94 - 94