Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
APOSTILA
DE SQL
Para Aulas de Laboratório
2
[R1] Comentário: Este índice
ÍNDICE é do tipo Formal. Selecionar
Inserir índice e selecionar Formal.
DICIONÁRIO DE DADOS.......................................................................................................................................40
SEQÜÊNCIAS ...........................................................................................................................................................56
VISÕES ......................................................................................................................................................................59
ÍNDICES ....................................................................................................................................................................64
BIBLIOGRAFIA .......................................................................................................................................................85
3
INTRODUÇÃO AO SQL, SQL*Plus e PL/SQL (Oracle)
Comandos SQL, SQL*Plus e PL/SQL são utilizados para acessar e manipular dados armazenados em
um servidor de Banco de Dados Oracle.
Comandos SQL
Comando Descrição
SELECT Recupera dados do Banco de Dados.
INSERT Insere novas linhas, altera linhas existentes e remove linhas de
UPDATE tabelas do banco de dados, respectivamente. Estes comandos são
DELETE conhecidos como comandos DML (Data Manipulation Language).
CREATE Cria, altera e remove objetos do banco de dados. São conhecidos
ALTER como comandos DDL (Data Definition Language).
DROP
RENAME
TRUNCATE
COMMIT Gerenciam as modificações realizadas pelos comandos DML. As
ROLLBACK modificações efetuadas pelos comandos DML podem ser
SAVEPOINT agrupadas em transações lógicas.
GRANT Atribuem e removem direitos de acesso ao banco de dados e aos
REVOKE objetos a ele pertencentes. São conhecidos como comandos DCL
(Data Control Language).
4
Tipos de Dados Oracle
5
SQL*PLUS
SAVE Nome_do_Arquivo
GET Nome_do_Arquivo
START Nome_do_Arquivo
@ Nome_do_Arquivo
EDIT Nome_do_Arquivo
EXIT
Obs.: Só comandos SQL vão para o buffer do SQL*PLUS, isto é, comandos SQL*PLUS não vão para
o buffer.
Desc Nome_da_Tabela
O comando (SQL*Plus) Describe exibe a estrutura de uma tabela. São exibidos os nomes de colunas,
as colunas NOT NULL e o tipo de cada coluna.
Na janela de logon no servidor de banco de dados digite na caixa de textos “Conta” o string
“AlunoX”, na caixa de textos “password” digite “AlunoX” e no string de conexão digite “ORACLE”.
6
Exemplo de um bloco PL/SQL
BEGIN
COMMIT;
EXCEPTION
END;
7
COMANDO SELECT
SELECT TABLE_NAME
FROM USER_TABLES;
DESC EMPREGADOS
SELECT CARGO
FROM EMPREGADOS;
SELECT *
FROM EMPREGADOS;
8
OU
OU
CLEAR COL
9
Como Ordenar e Limitar as Linhas Selecionadas
OU
OU
10
Exemplo 4: Selecionando apenas o empregado denominado SMITH.
Observações:
Observações:
3. Operadores lógicos:
- AND
- OR
- NOT
11
Exemplo 7: Selecionando linhas com a cláusula IN.
OU
OU
Observações:
12
Exemplo 9: Selecionando linhas com a cláusula IS NULL.
2. Com esta Query recuperamos o único empregado da empresa que não é gerenciado por ninguém,
isto é, o Presidente da empresa.
Observação: O resultado da cláusula Where abaixo é sempre falso pois um valor nulo não pode ser
igual ou diferente de outro valor, mesmo que este outro valor seja nulo. Se valores nulos forem
comparados por operadores que não o “IS NULL” o resultado será sempre falso.
13
Funções Aplicadas a Linhas
- Funções de linhas
- Funções de grupos [R3] Comentário: Por
enquanto vamos ver apenas as
funções de linhas. Funções de
grupo serão vistas mais adiante
quando estivermos estudando
Um função de linha retorna um resultado por linha da tabela acessada. Já uma função de grupo comandos SQL que lidam com
retorna um resultado por grupo de registros. grupos.
14
Exemplo 3: Utilização das funções SUBSTR e LENGTH em uma sentença SQL.
DESC SYS.DUAL
SELECT DUMMY
FROM SYS.DUAL;
Observação: Dual é uma tabela (dummy) do usuário SYS que pode ser utilizada quando se deseja, por
exemplo, buscar a data do sistema.
Formato de Data
As datas no Oracle são armazenadas em um formato numérico interno que representa o século, o
ano, o mês, o dia, a hora, o minuto e os segundos.
O formato de exibição default é DD-MON-YY
SELECT SYSDATE
FROM SYS.DUAL;
15
Para mudar o formato de uma data na sessão corrente
Exemplo 1: Utilização da função TO_CHAR. Como exibir uma data no formato DD/MM/AA.
Observações:
- Por default, a largura de uma coluna que resulta de uma expressão é de 80 posições.
- YYYY ou YYY ou YY ou Y Os últimos 4, 3, 2 ou 1 dígitos do ano.
- MM O mês representado em 2 dígitos.
- MON O nome do mês abreviado em 3 letras.
- DDD ou DD ou D Dia do ano, mês ou semana.
- DAY O nome do dia por extenso, completado com brancos até 9 caracteres.
- MM/AA Apenas o mês e o ano são exibidos.
16
Exemplo 4: Utilização da função TO_CHAR para formatar um valor numérico.
Obs: Através do formato na função TO_CHAR não há como trocar o separador decimal para a
vírgula. Geralmente este tipo de coisa é configurada no próprio software que será utilizado para exibir
os dados. Ex. Delphi.
Observações:
17
Como selecionar dados de mais de uma tabela
Para se exibir dados de mais de uma tabela, através de um comando SQL, é preciso definir
condições de junção. (Joins)
Os joins geralmente ocorrem entre valores de chave primária e de chave estrangeira.
Tipos de Joins:
Equijoin
Non-equijoin
Outer join
Self Join
Set operators
Um produto cartesiano geralmente ocorre quando a condição de junção é omitida ou inválida. [R7] Comentário: Ocorrerá tb
um produto cartesiano quando
Para evitar produtos cartesianos é preciso incluir, na cláusula Where, condições de junção válidas. todas as linhas da primeira tabela
se relacionarem com todas as
linhas da Segunda tabela.
Exemplo 1: Uma junção simples entre a Tabela de Empregados (Emp) e a tabela de Departamentos
(Dept).
OU
18
Exemplo 3: Uma junção entre a tabela de Empregados, a tabela de Departamentos e a tabela de
Dependentes.
15 rows selected.
19
Observações:
- Observe que o empregado Tutti não está lotado em nenhum departamento.
- O sinal de + deve ficar do lado do valor nulo. [R10] Comentário: Na
verdade o valor nulo está na
- O sinal de + não pode ser colocado em ambos os lados da cláusula Where. coluna Numero_dept na tabela de
empregados.
O que aconteceria se o comando fosse escrito conforme vem abaixo?
Supervisor Empregado
---------- ----------
INGO TERESA
INGO CHICO
INGO CELIO
TERESA JOSE
TERESA LUIZA
CHICO ARMANDO
CHICO WALTER
CHICO MARTA
CHICO TUTTI
CHICO JAMES
CELIO JOHN
JOSE SEBASTIAN
LUIZA ABELARDO
LUIZA SILVIO
14 rows selected.
O que precisaria ser feito para que o empregado Ingo (que é o presidente) apareça na coluna de
empregados, porem sem Supervisor? [R12] Comentário:
SELECT E1.NOME
“Supervisor”, E2.NOME
“Empregado”
FROM EMPREGADOS E1,
EMPREGADOS E2
WHERE E1.NUMERO(+) =
E2.NUM_SUPERVISOR;
20
Funções de Grupo
Funções de grupo operam com um conjunto de linhas para dar um resultado por grupo de linhas.
Um conjunto de linhas pode ser uma tabela inteira ou linhas desta tabela divididas em grupos.
Funções de grupo podem aparecer tanto na cláusula Select quanto na cláusula Having.
A cláusula Group By divide as linhas de uma ou mais tabelas em grupos de linhas.
A cláusula Having seleciona os grupos que serão aceitos.
AVG
COUNT
MAX
MIN
STDDEV
SUM
VARIANCE
Observações:
A cláusula Distinct pode ser utilizada para que sejam considerados apenas valores não duplicatas.
Todas as funções de grupo ignoram valores nulos. Para substituir um valor nulo por outro valor
utilize a função NVL.
Exemplo 1: Utilização de funções de grupo, considerando todas as linhas de uma tabela um único
grupo.
OU
21
SELECT COUNT(*)
FROM EMPREGADOS
WHERE NUMERO_DEPT = 10;
Exemplo 4: Utilização da função COUNT para contar o número de empregados que possuem
percentual de comissão diferente de nulo.
SELECT COUNT(PERC_COMISSAO)
FROM EMPREGADOS;
Observações:
22
A cláusula Group By
Observações:
Qualquer coluna incluída na cláusula SELECT, se não estiver em uma função de grupo, deverá
constar da cláusula GROUP BY.
Com a cláusula WHERE é possível excluir determinadas linhas dos grupos.
Por default as linhas são ordenadas ascendentemente conforme a lista de colunas especificada na
cláusula GROUP BY. Para modificar este comportamento é preciso utilizar a cláusula ORDER
BY.
Exemplo 7: Utilização da cláusula Group By, da função COUNT e de um JOIN para se contar
quantos empregados estão lotados em cada departamento.
23
Exemplo 9: A query abaixo está correta? A intenção é listar o número dos departamentos seguido da
média salarial. No entanto, deseja-se listar apenas aqueles departamentos cuja média salarial é superior
a 2000.
A cláusula Having
Exemplo 10: A utilização da cláusula HAVING para listar o número dos departamentos seguido da
média salarial de seus empregados. No entanto, deseja-se listar apenas aqueles departamentos cuja
média salarial é superior a 2000.
Exemplo 11: A utilização da cláusula GROUP BY para listar a quantidade de empregados por
departamento/cargo. Isto é, grupos dentro de grupos. Não deve ser exibido Número de Departamento
NULO.
24
Exemplo 12: A utilização da cláusula GROUP BY para listar a quantidade de empregados por
departamento/cargo. Só devem ser exibidos os grupos de departamentos/cargo com mais de 1
empregado.
25
A recuperação de dados com subconsultas (Subqueries)
Uma subconsulta é um comando SELECT embutido em uma cláusula de outro comando SQL.
Exemplo 1: A utilização de uma subconsulta aninhada para recuperar o nome e salário de todos os
empregados que trabalham no mesmo departamento que o JOSE trabalha.
Exemplo 2: A utilização de uma subconsulta aninhada para recuperar o nome e salário de todos os
empregados que ganham mais do que a média salarial da empresa.
26
Exemplo 3: A utilização de uma subconsulta aninhada para recuperar o nome, número do
departamento e salário de todos os empregados que trabalham no departamento situado no RIO ou no
departamento denominado VENDAS.
Correção da query anterior com a utilização da cláusula IN uma vez que esta subconsulta retorna mais
de uma linha.
Exemplo 6: A utilização de uma subconsulta aninhada para recuperar, por departamento, o nome e o
salário do empregado mais bem pago.
27
A recuperação de dados com subconsultas correlacionadas
O exemplo abaixo difere do anterior (Exemplo 6 da pág. anterior) uma vez que neste caso a
subconsulta é executada uma vez para cada linha da tabela de empregados na consulta mais externa.
Exemplo 2: A utilização de uma subconsulta correlacionada para recuperar o nome dos empregados
que trabalham no projeto numero 2.
SELECT NOME
FROM EMPREGADOS E
WHERE 2 IN ( SELECT NUMERO_PROJ
FROM TRABALHAM
WHERE NUMERO_EMP = E.NUMERO);
SELECT NOME
FROM EMPREGADOS E, TRABALHAM T
WHERE E.NUMERO = T.NUMERO_EMP
AND T.NUMERO_PROJ = 2;
28
Quantificador Existencial
SELECT NOME
FROM EMPREGADOS E
WHERE EXISTS (SELECT *
FROM TRABALHAM
WHERE NUMERO_EMP = E.NUMERO
AND NUMERO_PROJ = 2);
OU
SELECT NOME
FROM EMPREGADOS E, TRABALHAM T
WHERE E.NUMERO = T.NUMERO_EMP
AND T.NUMERO_PROJ = 2;
SELECT NOME
FROM EMPREGADOS E
WHERE NOT EXISTS
(SELECT *
FROM TRABALHAM
WHERE NUMERO_EMP = E.NUMERO
AND NUMERO_PROJ = 2);
OU
29
SELECT NOME
FROM EMPREGADOS
MINUS
SELECT NOME
FROM EMPREGADOS E, TRABALHAM T
WHERE T.NUMERO_EMP = E.NUMERO
AND T.NUMERO_PROJ = 2;
SELECT NOME
FROM EMPREGADOS E
WHERE NOT EXISTS
(SELECT *
FROM PROJETOS P
WHERE NOT EXISTS
(SELECT *
FROM TRABALHAM T
WHERE T.NUMERO_EMP = E.NUMERO
AND T.NUMERO_PROJ = P.NUMERO));
Observações:
- Deve ser selecionado um nome de empregado quando não existir um projeto no qual ele não
trabalhe.
Exemplo 4: Obter o nome dos empregados que trabalham em todos os projetos nos quais o
empregado 7521 trabalha.
SELECT NOME
FROM EMPREGADOS E
WHERE NOT EXISTS
(SELECT *
FROM TRABALHAM T1
WHERE NUMERO_EMP = 7521
AND NOT EXISTS
(SELECT *
FROM TRABALHAM T2
WHERE T2.NUMERO_EMP = E.NUMERO
AND T2.NUMERO_PROJ = T1.NUMERO_PROJ));
30
União (Union e Union All)
Linhas duplicatas são eliminadas do resultado de uma união a não ser que o operador UNION
inclua explicitamente o quantificador ALL. Assim, no exemplo nº 1, o projeto nº 3 é selecionado
em ambos os SELECTS, mas só aparece uma vez no resultado final.
Já o exemplo nº 2 retornará os números de projeto 2, 3 e 3.
Qualquer número de SELECTS pode ser unido pelo UNION.
Quando sabemos que não haverá elementos duplicados no resultado é conveniente utilizarmos
UNION ALL para que o sistema não seja forçado a eliminar duplicidades, desnecessariamente.
Exemplo 1: Obter o número dos projetos que, ou se iniciaram após 31-JUL-97, ou possuem o
empregado 7566 nele trabalhando. União sem repetição.
SELECT NUMERO
FROM PROJETOS
WHERE DT_INICIO > ‘31-JUL-97’
UNION
SELECT NUMERO_PROJ
FROM TRABALHAM
WHERE NUMERO_EMP = 7566;
Exemplo 2: Obter o número dos projetos que, ou se iniciaram após 31-JUL-97, ou possuem o
empregado 7566 nele trabalhando. União com repetição.
SELECT NUMERO
FROM PROJETOS
WHERE DT_INICIO > ‘31-JUL-97’
UNION ALL
SELECT NUMERO_PROJ
FROM TRABALHAM
WHERE NUMERO_EMP = 7566;
31
Exemplo 3: A possibilidade de incluirmos constantes numa cláusula SELECT é frequentemente útil
quando a cláusula UNION é utilizada. Por exemplo, para indicar qual das duas condições WHERE foi
atendida para a inclusão do elemento no resultado final.
Resultado:
NUMERO CONDIÇÃO
------------ ---------------------
2 DT_INICIO > 07-JAN-90
3 DT_INICIO > 07-JAN-90
4 DT_INICIO > 07-JAN-90
3 NUMERO_EMP = 7566
32
SCRIPTS REUTILIZÁVEIS
O objetivo aqui é escrever scripts que, em tempo de execução, indaguem o usuário sobre o valor de
variáveis utilizadas na cláusula WHERE de comandos SQL embutidos no script.
Chame o EDIT e após editar o comando abaixo, salve este arquivo com o nome EXERC01.SQL no
diretório Z:
SQL> @Z:\Exerc01
NOME SALARIO
--------------- -------------
ARMANDO 1600.45
WALTER 1250
MARTA 1250
TUTTI 1100
33
Definindo Variáveis do Usuário
Exemplo 2: Chamar o EDIT e após editar o comando abaixo, salvar este arquivo com o nome
EXERC02.SQL no diretório Z:
START EXERC02
Observações:
- SET ECHO OFF evita que os comandos ecoem na tela do SQL*PLUS. (Assim como ocorre no
DOS).
- SET VERIFY OFF faz desaparecer da tela os valores OLD e NEW da variável de substituição.
- Note que &DATA_ADM na cláusula WHERE acima encontra-se entre plics. Isto evita que o
usuário seja obrigado a digitar os PLICS.
- Sem os plics o usuário teria de digitá-los para tudo que necessitasse ser tratado como caracter
ou data.
- O comando ACCEPT cria a variável (caso ela já não tenha sido criada anteriormente), lê o
valor digitado pelo usuário e o atribui à variável.
- Sintaxe do comando: ACCEPT variável [datatype] [FORMAT] [PROMPT texto] [HIDE]
- O comando UNDEFINE libera a área de memória ocupada pela variável.
- Assim como no DOS, se digito a cláusula WHERE assim: WHERE CARGO = ‘&1’ então
será possível executar este script assim: @Z:\Exerc02.SQL VENDEDOR
- Só comandos SQL vão para o buffer. Todos os demais comandos não vão para o buffer do
SQL*Plus.
34
CRIAÇÃO DE TABELAS
Tabelas
Exemplo:
Observações:
35
Tipos de Dados Oracle
Tipos de Constraints
PRIMARY KEY
FOREIGN KEY
NOT NULL
UNIQUE [R19] Comentário: Automatic
amente será criado um índice
CHECK único para a(a) coluna(s)
especificada(s), se ele já não
existir.
Observações:
[R20] Comentário: Para teste
- É possível criar uma constraint após a criação da tabela. em cima de faixas de valores.
- Uma constraint pode ser definida a nível de coluna ou a nível de tabela.
- Constraints são armazenadas no Dicionário de Dados e podem ser facilmente recuperadas se
possuírem nomes razoáveis.
36
Verificando o Comportamento da Constraint Primary Key da Tabela de Fornecedores
CARGO VARCHAR2(9),
[R23] Comentário: Quando se
NUM_SUPERVISOR NUMBER(4) usa a Constraint Check não quer
CONSTRAINT EMP_EMP_NUM_SUPERVISOR_FK dizer que um valor nulo não possa
ser informado.
REFERENCES EMPREGADOS (NUMERO),
DT_ADMISSAO DATE, [R24] Comentário: Nome da
SALARIO NUMBER(7,2), tabela filho – Nome da tabela pai –
Nome da coluna na tabela filho –
PERC_COMISSAO NUMBER(4,2) Tipo da constraint. A tabela filho
CONSTRAINT EMPREGADOS_PERC_COMISSAO_CK é a de Empregados. A tabela pai é
a de Departamentos.
CHECK (PERC_COMISSAO IN (10, 12.5, 15, 17.5, 20)),
NUMERO_DEPT NUMBER(2) [R25] Comentário: Permite
CONSTRAINT EMPR_DEPARTAMENTOS_NUMERO_DEPT_FK deleção na tabela pai e a deleção
REFERENCES DEPARTAMENTOS (NUMERO) das linhas dependentes na tabela
filho. Pode não haver a cláusula
ON DELETE CASCADE); ON DELETE CASCADE.
37
Exemplo 4:
- A constraint Primary Key é uma combinação das constraints Unique e Not Null.
- Um índice único é automaticamente criado.
- Designa uma coluna ou uma combinação de colunas de tal forma que duas linhas não possam
ter o mesmo valor.
- Valores nulos são aceitos.
- Automaticamente é criado um índice único para a(s) coluna(s) especificada(s).
- A constraint Check define uma condição que cada linha deve satisfazer.
- Não pode fazer referência a CURRVAL, NEXTVAL, LEVEL e ROWNUM ou chamadas às
funções SYSDATE, UID, USER.
- Subconsultas não são permitidas na definição de uma constraint check.
38
Outras Formas de se Validar uma Restrição de Integridade
- Triggers
- Procedimentos ou funções armazenados no servidor de banco de dados
- Através do código na própria aplicação.
Observação:
39
DICIONÁRIO DE DADOS
PREFIXO DESCRIÇÃO
USER_ Contém objetos cujo owner é o próprio usuário. Ex. USER_TABLES
ALL_ Acessa objetos aos quais o usuário recebeu algum direito em adição aos
objetos possuidos pelo usuário.
DBA_ Permite que um usuário com o privilégio de DBA acesse qualquer objeto no
banco de dados.
V$ Apresenta informações de performance do Servidor e informações de lock.
Disponível apenas para o DBA.
Outras Visões: Várias visões do dicionário de dados não usam os prefixos listados acima. Por
exemplo:
40
Exemplo 1: Como saber que visões existem no dicionário de dados e para que servem.
DESC DICTIONARY
Exemplo 2: Para conhecer a descrição das colunas de qualquer tabela ou visão do dicionário de
dados, veja o conteúdo de DICT_COLUMNS. Na cláusula WHERE você deverá informar o nome da
tabela ou visão do dicionário que deseja conhecer.
Que tipos de objetos um usuário pode possuir? Resposta: Tables, Views, Sequences, Indexes e
Clusters.
DESC USER_OBJECTS
SELECT OBJECT_NAME
FROM USER_OBJECTS
WHERE OBJECT_TYPE = ‘TABLE’;
Exemplo 5: Como saber a que tabela e a que coluna uma constraint pertence?
41
Exemplo 6: Como recuperar o nome de todas as constraints da tabela de Empregados acompanhado
do nome das colunas associadas às contraints.
Resultado:
CONSTRAINT_NAME COLUMN_NAME
----------------------------------------------------------- ------------------------------
EMPREGADOS_CPF_UK CPF
EMPREGADOS_NUMERO_PK NUMERO
EMPREGADOS_PERC_COMISSAO_CK PERC_COMISSAO
EMPREG_DEPARTAMENTOS_NUMERO_FK NUMERO_DEPT
EMP_EMP_NUM_SUPERVISOR_FK NUM_SUPERVISOR
42
COMANDOS DE MANIPULAÇÃO DE DADOS
Comandos Descrição
INSERT Adiciona novas linhas a uma tabela.
UPDATE Modifica linhas existentes em uma tabela.
DELETE Remove linhas existentes de uma tabela.
COMMIT Torna permanente todas as modificações pendentes.
SAVEPOINT Permite um Rollback até a marca de savepoint.
ROLLBACK Desfaz todas as manipulações efetuadas.
O Comando INSERT
Exemplo 1: Quando são informados os dados de todas as colunas e na ordem default, não é
necessário informar o nome das colunas.
Exemplo 4: Método explícito de inserção de nulos. Além da palavra-chave NULL, também pode ser
utilizado o string vazio ‘’
43
Exemplo 5: Os nomes das colunas precisaram ser informados uma vez que os dados não estão na
ordem default.
Quando o caracter decimal não é o ponto (.) ou quando o separador de grupos é utilizado, os números
que aparecem em instruções SQL devem aparecer entre plics, pois a vírgula costuma ser utilizada
como separador de itens em instruções SQL.
Exemplo:
44
Exemplo 9: Como copiar linhas de outra tabela.
UPDATE DEPARTAMENTOS
SET LOCAL = ‘ORLANDO’
WHERE NUMERO = 40;
UPDATE DEPARTAMENTOS
SET NOME = ‘MARKETING’, LOCAL = ‘ORLANDO’
WHERE NUMERO = 40;
UPDATE DEPARTAMENTOS
SET LOCAL = ‘FLORIANOPOLIS’
WHERE NUMERO IN (SELECT NUMERO
FROM DEPARTAMENTOS
WHERE LOCAL = ‘PORTO ALEGRE’);
UPDATE DEPARTAMENTOS
SET LOCAL = ‘ORLANDO’;
45
Exemplo 5: Atualização de chave primária.
UPDATE DEPARTAMENTOS
SET NUMERO = 70
WHERE NUMERO = 10;
UPDATE DEPARTAMENTOS
*
ERROR at line 1:
ORA-02292: integrity constraint (CARLOS.EMPR_DEPARTAMENTOS_NUMERO_DEPT_FK) violated -
child record found
Observação:
- Não se pode atualizar a chave primária de uma tabela pai se houver filhos na tabela filho. [R32] Comentário: Como
fazer?
1.Recuperar os empregados
lotados no departamento 10.
2.Armazenar estes numeros de
O Comando DELETE empregados em uma tabela.
3.Alterar para nulo o número do
departamento onde estes
Exemplo 1: Apagar o empregado 7788 da tabela de empregados. empregados estão lotados.
4.Alterar o número do
departamento de 10 para 70.
DELETE FROM EMPREGADOS 5.Alterar para 70 o número do
WHERE NUMERO = 7788; departamentos onde os
empregados (slavos) estão lotados.
ROLLBACK;
46
Exemplo 4: Apagar todos as linhas da tabela TRABALHAM.
ROLLBACK;
47
CONTROLE DE TRANSAÇÕES
Uma transação começa quando o primeiro comando SQL é executado e termina quando ocorre um dos
seguintes eventos:
Quando uma transação termina, o próximo comando SQL inicia automaticamente a próxima
transação.
48
Controlando Transações Através de SavePoints
SAVEPOINT ABC;
UPDATE EMPREGADOS
SET SALARIO = SALARIO * 1.5;
IF (CONDIÇÃO) THEN
ROLLBACK TO ABC;
ELSE
COMMIT
END IF
Obs: Se um único comando DML falha durante a execução de uma transação apenas este comando
sofre ROLLBACK. Quanto às demais modificações caberá ao usuário dar COMMIT ou ROLLBACK
explicitamente.
Antes do commit os dados são vistos por outros usuários como se não tivessem sofrido nenhuma
manipulação.
As linhas afetadas são bloqueadas (locked). Outros usuários não podem modificar os dados
manipulados uma vez que estes dados encontram-se bloqueados.
49
Rollbak a Nível de Comando
Se um único comando DML falha durante sua execução, somente este comando sofre Rollback.
Todas as demais modificações são provisoriamente mantidas até que um comando Commit ou
Rollback seja executado.
50
ALTERANDO TABELAS E CONSTRAINTS
Todos os três comandos acima são comandos DDL. Quando executados causam um COMMIT
automático. Cuidado...
51
Exemplo 1: Adicionando três colunas à tabela de Empregados.
- É possível adicionar e modificar colunas de uma tabela mas não se pode remover uma coluna
de uma tabela. A tabela deve ser criada novamente sem a coluna que se deseja remover.
- Não se pode especificar em que posição da tabela você deseja que a coluna apareça. Ela
aparecerá no final da tabela, isto é, será a última coluna.
- Ao se criar uma nova coluna em uma tabela só se pode especificar a cláusula NOT NULL se a
tabela estiver vazia.
- A largura (precisão) de uma coluna só deve ser diminuída se a coluna só possui valores nulos
ou se a tabela se encontra vazia. [R34] Comentário: Os valores
não serão truncados. Ocorrerá um
- A modificação de um tipo de dado de uma coluna só deve ser efetuada se a coluna só contém erro.
valores nulos.
- Para converter uma coluna CHAR em VARCHAR2 ou de VARCHAR2 para CHAR a coluna
deverá estar vazia ou o tamanho não deverá ser modificado.
52
- A modificação do valor Default de uma coluna só afeta as linhas inseridas posteriormente a
esta modificação.
1. Descobra o nome da constraint que se deseja dropar acessando a USER_CONSTRAINTS. [R35] Comentário: SELECT
CONSTRAINT_NAME,
2. Digamos que após você descobrir os nomes das constraints associadas à tabela Trabalham você CONSTRAINT_TYPE
ainda estivesse na dúvida sobre qual constraint deveria ser dropada. Para você descobrir a que FROM
USER_CONSTRAINTS
coluna da tabela Trabalham cada uma das constraints recuperadas acima se referem seria preciso WHERE TABLE_NAME =
pesquisar a visão do dicionário de dados USER_CONS_COLUMNS 'TRABALHAM';
3. Execute o comando abaixo para dropar a constraint desejada:
[R36] Comentário: SELECT
UC.CONSTRAINT_NAME,
ALTER TABLE TRABALHAM UC.CONSTRAINT_TYPE,
DROP CONSTRAINT NOME_DA_CONSTRAINT; UCC.COLUMN_NAME
FROM
USER_CONSTRAINTS UC,
USER_CONS_COLUMNS UCC
Exemplo 4: Criando uma Constraint. WHERE
UC.CONSTRAINT_NAME =
UCC.CONSTRAINT_NAME
ALTER TABLE TRABALHAM AND UC.TABLE_NAME =
ADD CONSTRAINT NOME_DA_CONSTRAINT 'TRABALHAM';
Exemplo 5: Coma dropar uma constraint de primary key forçando a remoção da respectiva constraint
de foreign key.
OU
53
Exemplo 5: Como habilitar e desabilitar constraints. [R37] Comentário: Não
funcionou. Ao dropar a tabela
Projetos (passo 4) o SGBD
Digamos que você deseja remover a coluna DT_FIM da tabela de Projetos. Como você já sabe não há reclama como se houvesse outra
constraint habilitada.
como fazer isto através do comando ALTER TABLE. É preciso remover a tabela e recriá-la sem esta
coluna. Siga os passos a seguir:
3. Para que possamos apagar a tabela Projetos será preciso desabilitar a constraint que está
provocando este erro, isto é, a constraint TRABALHAM_PROJETOS_NUMERO_FK.
54
5. Recrie a tabela Projetos sem a coluna DT_FIM.
ALTER TABLE
ENABLE CONSTRAINT TRABALHAM_PROJETOS_NUMERO_FK;
Exemplo 7: Como renomear uma tabela, uma visão, uma seqüência ou um sinônimo. [R39] Comentário: É preciso
ter direitos sobre o objeto
renomeado e sobre os demais
RENAME PROJETOS TO PROJ; afetados.
55
SEQÜÊNCIAS
Exemplo 1: Criação de uma seqüência para ser utilizada na geração de valores de chave primária para
a tabela de departamentos.
Exemplo 2: Utilização da seqüência na inserção de uma linha na tabela de departamentos. [R43] Comentário: O default
é CACHE 20. Posso escrever
CACHE 100, por exemplo. Se não
INSERT INTO DEPARTAMENTOS (NUMERO, NOME, LOCAL) quero o cache escrevo
VALUES (S_DEPARTAMENTOS_NUMERO.NEXTVAL, ‘CONTABILIDADE’, NOCACHE.
‘NITEROI’);
[R44] Comentário: O default
é NOCYCLE. A outra opção é
CYCLE.
Observações:
A opção CYCLE não deve ser utilizada se a seqüência será utilizada para gerar valores de chave
primária.
Com a opção CACHE é possível pedir para o Oracle manter na memória uma certa quantidade de
valores da seqüência que, quando solicitados, serão buscados na memória e não no disco. [R45] Comentário: O default
é CACHE 20
Intervalos na seqüência podem ocorrer quando:
Ocorre um Rollback
Ocorre um crash no sistema
A seqüência é utilizada em mais de uma tabela [R46] Comentário: Observe
que uma sequencia não tem qq
Para se saber que valor da seqüência foi utilizado no mais recente Insert em Departamentos deve- víncula com tabela nenhuma.
se utilizar S_DEPARTAMENTOS.CURRVAL.
[R47] Comentário: Digamos
que insiro um departamento na
tabela de departamentos e, em
seguida, desejo inserir os
empregados lotados naquele
departamento. Como saber que
valor informar na chave
estrangeira NUMERO_DEPT em
empregados?
56
Exemplo 3: Utilização de CURRVAL na inserção de um empregado.
FROM DEPARTAMENTOS
UPDATE EMPREGADOS
Onde é possível utilizar NEXTVAL e CURRVAL: SET NUMERO = (SELECT
S_DEPARTAMENTOS_NOME.
NEXTVAL
Em um comando SELECT que não seja parte de uma sub-query. FROM
Em um comando SELECT, sub-query de um INSERT. SYS.DUAL) INVÁLIDO.
Válido sem subquery.
Na cláusula VALUE de um INSERT. WHERE NUMERO = (SELECT
Na cláusula SET de um UPDATE. NUMERO
FROM
EMPREGADOS
Quando não é possível utilizar NEXTVAL e CURRVAL: WHERE
CARGO = ‘FAXINEIRO’)
Sequencia na subquery não é
Em um SELECT de uma VIEW. VÁLIDO.
57
Como modificar uma seqüência
58
VISÕES
Uma visão (VIEW) é uma tabela virtual baseada em tabelas base ou em outras visões.
Exemplo 2: Criação de uma visão sobre a tabela de empregados. [R56] Comentário: Cria a
view mesmo que a tabela base não
exista.
CREATE VIEW V_EMPREGADOS
AS SELECT NUMERO, NOME, SOBRENOME
[R57] Comentário: With
FROM EMPREGADOS check option só permite
WHERE NUMERO_DEPT = 10; atualização se a view continuar a
enxergar o dado após a
atualização. Esta constraint pode
ter um nome.
59
Como utilizar uma visão:
Visões Complexas:
60
Regras relativas à utilização de comandos DML sobre visões:
É possível emitir comandos DML contra visões baseadas em uma única tabela, exceto nos casos
abaixo:
Funções de grupo.
A cláusula Group by.
O comando Distinct.
É possível emitir comandos DML contra visões baseadas em mais de uma tabela quando:
As linhas que se pretende excluir, pertencem à tabela cuja chave primária é preservada na
visão.
As colunas que se pretende alterar ou incluir pertencem à tabela cuja chave primária é
preservada na visão.
61
Exemplo de utilização da clausula WITH CHECK OPTION:
UPDATE V_EMP_DEPT_20
SET NUMERO_DEPT = 30
WHERE NUMERO_DEPT = 20;
UPDATE V_EMP_DEPT_20
ERROR at line 1:
ORA-01402: view WITH CHECK OPTION where-clause violation [R63] Comentário: Uma View
só pode Ter uma constraint WITH
CHECK OPTION daí não ser
importante o nome da constraint.
Exemplos de utilização da clausula WITH READ ONLY:
UPDATE V_EMP_DEPT_20
SET NOME = ‘SILVIO’
WHERE NUMERO = 42;
62
Como consultar visões no dicionário de dados:
Desc USER_VIEWS
SELECT TEXT
FROM USER_VIEWS
WHERE VIEW_NAME = ‘V_EMP_DEPT_20’;
TEXT
--------------------------------------------------------------------------------
SELECT NUMERO, NOME, NUMERO_DEPT
FROM EMPREGADOS
WHERE NUMERO_DEPT = 20
WITH READ ONLY CONSTRAINT V_EMP_DEPT_20_WRO;
63
ÍNDICES
O servidor Oracle 7 utiliza, por default, uma estrutura de árvore balanceada (B*Tree) para índices.
Esta estrutura de índice garante que o acesso a qualquer linha de uma tabela leve aproximadamente o
mesmo tempo independentemente da posição da linha na tabela.
Exemplo:
1 BETO
2 GILBERTO
BETO
3 LAURA
GILBERTO
GILBERTO 4 NAIR
NAIR 5 NELSON
LAURA 6 SERGIO
NAIR 7 UBALDO
ROWID 8 VERA
NEL
...
NELSON
SERGIO
SERGIO
VERA
UBALDO
VERA
Cada linha da base de dados possui um número identificador denominado ROWID que é uma
composição do número do arquivo, do bloco e da linha onde se encontra a linha da tabela desejada.
Exemplo:
(Bloco.Linha.Arquivo)
Tipos de Índices
64
B-Tree
Único
Não Único
Clusterizado
Index Cluster [R67] Comentário: É gerado
um índice do tipo B-Tree para
Hash Cluster indexar a cluster key. Já no tipo
Bitmap Hash é aplicada uma função para
encontrar o endereço do bloco
onde devem estar os dados. Index
Cluster não é muito utilizado.
Quando se deseja uma
Regras Gerais para a Criação de Índices performance muito alta em queries
procurando dados através da
igualdade (e não por faixa de
É adequada a criação de índices quando: valores) se utiliza o hash cluster.
Em um único I/O o bloco do disco
onde estão os dados, com aquele
A coluna é frequentemente utilizada na cláusula Where das queries. cluster index, é lido. Exemplo:
A coluna possui um grande número de valores diferentes. Pedidos com seus itens. Por outro
lado, um índice B-Tree deve ser
A coluna possui muitos valores nulos. utilizado qundo estamos
A tabela é grande e a maioria das queries recuperam em torno de 2 a 4% das linhas. pesquisando dados por faixa de
valores.
Cuidado: Uma maior quantidade de índices nem sempre aumenta o desempenho do banco. Indices do tipo Bitmap são
utilizados em colunas que
possuem poucos valores distintos
(Coluna Estado no cadastro de
Como criar Índices: clientes). São tipicamente
utilizados apenas em sistemas de
suporte a decisão e datawarehouse,
Um índice é criado automaticamente quando se define uma constraint: isto é, em sistemas que manipulam
PRIMARY KEY, ou volumes de dados gigantescos.
65
1. Cria-se o Cluster
2. Cria-se o Índice
SELECT *
FROM EMPREGADOS_AUX;
66
Observações:
Desc USER_INDEXES
Desc USER_IND_COLUMNS
67
Exemplo 1: Para se recuperar detalhes sobre os índices que existem para a tabela de
departamentos.
Resultado:
INDEX_NAME DEPARTAMENTOS_NUMERO_PK
TABLE_NAME DEPARTAMENTOS
TABLE_TYPE TABLE
UNIQUENES UNIQUE
COLUMN_NAME NUMERO
COLUMN_POSITION 1
COLUMN_LENGTH 22
68
CONTROLANDO O ACESSO DOS USUÁRIOS AO BANCO DE DADOS
Schema: É uma coleção de objetos, tais como tabelas, índices, visões, etc. Um schema sempre possui
um Owner (um usuário do banco de dados) e possui o mesmo nome do usuário.
Tipos de Privilégios
Privilégios de Sistema
Privilégios de Objetos
Create Session
Create User
Create Table
Create Index
Drop User
Drop Any Table
Backup Any Table
Uma das tarefas que um DBA deve executar é a criação dos usuários do banco. Não basta apenas criar
os usuários. É preciso, após a criação, atribuir direitos a estes usuários.
REVOKE UNLIMITED
TABLESPACE FROM ALUNO4;
69
Exemplo 2: Como um usuário autorizado pode conceder a JULIO privilégios de objeto sobre a [R73] Comentário: Privilégios
de objeto podem ser sobre:
tabela de DEPARTAMENTOS do usuário CARLOS:
Tabelas
Indices
GRANT SELECT ON CARLOS.DEPARTAMENTOS TO ALUNO; Prcedures e Functions
GRANT ALTER ON CARLOS.DEPARTAMENTOS TO JULIO; Sequences
Views
GRANT INDEX ON CARLOS.DEPARTAMENTOS TO JULIO; Snapshots
GRANT REFERENCES ON CARLOS.DEPARTAMENTOS TO JULIO; Sinonimos
Tabelas
Exemplo 4: Concedendo o privilégio de EXECUTE sobre a Procedure ALTERA_CARGO: Indices
Prcedures e Functions
Sequences
GRANT EXECUTE ON CARLOS.ALTERA_CARGO TO JULIO; Views
Snapshots
Sinonimos
Exemplo 5: Concedendo privilégios para Alterar e Utilizar uma SEQUENCE: [R76] Comentário: Não é
possível atribuir privilégio de
select sobre determinadas colunas.
GRANT ALTER ON CARLOS.S_DEPARTAMENTOS_NOME TO JULIO; Para isto ser feito é preciso definir
views.
GRANT SELECT ON CARLOS.S_DEPARTAMENTOS_NOME TO JULIO;
70
Como consultar, no dicionário de dados, quais os privilégios de sistema e de objetos foram
concedidos a um usuário:
Desc DBA_SYS_PRIVS
Esta visão (DBA_SYS_PRIVS) mostra que usuários e roles receberam privilégios de sistema.
Desc DBA_TAB_PRIVS
Outras Visões
71
Visões de Privilégios de
Objetos Disponíveis para os
Usuários Descrição
USER_TAB_PRIVS Privilégios em objetos dos quais o usuário é Owner,
Grantor ou Grantee.
USER_COL_PRIVS Privilégios em colunas das quais o usuário é Owner,
Grantor ou Grantee.
TABLE_PRIVILEGES Privilégios em objetos dos quais o usuário é Owner,
Grantor, Grantee, ou o grupo PUBLIC é Grantee.
COLUMN_PRIVILEGES Privilégios em colunas das quais o usuário é Owner,
Grantor, Grantee ou o grupo PUBLIC é Grantee.
72
Gerenciando Roles
Para facilitar a gerência de concessão de privilégios deve-se atribuir privilégios a perfis (ROLES) e,
então, designar estes perfis a usuários.
Pode-se criar:
Perfis de Função, e,
Perfis de Aplicação
CREATE SESSION
CREATE TABLE
CREATE CLUSTER
CREATE VIEW
CREATE PROCEDURE
CREATE TRIGGER
Já os usuários finais da aplicação de folha de pagamento poderiam ter a eles associado o perfil
FOLHAPGTO que teria os seguintes privilégios:
CREATE SESSION
EXECUTE sobre as procedures e functions necessárias à aplicação.
Exemplo 1: Como criar e utilizar um role que necessita de password para ser habilitado
73
SQL> CREATE USER NOVO IDENTIFIED BY TIGER;
Agora que nossa ROLE já tem os privilégios definidos, no exemplo abaixo vou passá-la para
algum usuário. No caso o usuário "NOVO" está recebendo os GRANTS da ROLE MANAGER,
que são somente criar tabela e view
Como mudar a senha de um usuário: no caso estamos mudando do user novo que tinha como
senha TIGER ou seja IDENTIFIED igual a TIGER passa a ser LION.
User altered.
74
CREATE SYNONYM
CREATE TABLE
CREATE VIEW
Role RESOURCE
CREATE CLUSTER
CREATE PROCEDURE
CREATE SEQUENCE
CREATE TABLE
CREATE TRIGGER
Role EXP_FULL_DATABASE
BACKUP ANY TABLE
SELECT ANY TABLE
Role IMP_FULL_DATABASE
40 Direitos diferentes
Role DBA
77 Direitos diferentes
SYSOPER
SYSDBA
75
STARTUP
SHUTDOWN
ALTER DATABASE OPEN/MOUNT
ALTER DATABASE
BACKUP CONTROLFILE
ETC.
76
LISTAS DE EXERCÍCIOS
77
LISTA Nº 1
1. É possível emitir um comando Select com a cláusula Order By mencionando uma coluna que não
consta da lista de colunas mencionadas no Select?
3. Escreva uma conulta para recuperar, da tabela de empregados, os seguintes dados: Numero, nome
e departamento de todos os empregados lotados no departamento nº 10. Salve a query no arquivo
Exerc_01.sql.
5. Modifique a query acima para que ela exiba o resultado ordenado descendentemente pelo número
do empregado.
6. Escreva uma query para recuperar o nome, sobrenome e número do departamento dos empregados
lotados nos departamentos 10 e 30. O resultado deverá estar em ordem ascendente de sobrenome.
As colunas nome e sobrenome deverão ser apresentadas como se fossem uma única coluna.
Atribua a esta coluna (resultante da concatenação de nome e sobrenome) o cabeçalho “Nome do
Empregado”.
7. Escreva uma query para exibir o nome, sobrenome e salário de todos os empregados cujo
sobrenome contem um "S".
8. Escreva uma query para listar o número, nome, cargo, data de admissão e número do departamento
de todos os vendedores contratados em fevereiro de 91 e de todos os vendedores que atualmente
não estão lotados em nenhum departamento.
78
LISTA Nº 2
3. Escreva uma query para recuperar o nome e sobrenome dos empregados seguidos do cargo que
ocupam entre parentesis. Devem ser recuperados apenas os empregados que ocupam os seguintes
cargos: PRESIDENTE e GERENTE. Essas informações devem ser listadas conforme vem abaixo:
Nome e Cargo
-------------------------------------------------
INGO HOFFMANN (PRESIDENTE)
TERESA AGUIAR (GERENTE)
CHICO SERRA (GERENTE)
CELIO SILVA (GERENTE)
4. Escreva uma query para recuperar nome e salario e número de semanas desde a data de admissão
(com arredondamento de 2 casas decimais) de todos os empregados contratados a mais de 350
semanas.
5. Escreva uma query para recuperar o nome e o número de meses de trabalho de todos os
empregados da empresa a partir de suas datas de admissão.
6. Recuperar para cada empregado seu nome e data de admissão no formato DD/MM/YY HH:MI:SS.
7. Escreva uma query para recuperar o nome e salário dos empregados no formato abaixo.
8. Escreva uma query para recuperar o nome e o percentual de comissão dos empregados acrescido
de 3%. Aqueles que não possuirem % de comissão (% de comissão nulo) devem aparecer com 3%.
79
LISTA Nº 3
1. Escreva uma query para recuperar o nome dos empregados e o número e nome de seus
departamentos.
2. Escreva uma query para recuperar o nome dos empregados e o nome dos projetos nos quais eles
trabalham.
3. Escreva uma query para recuperar o nome, sobrenome e nome do departamento onde ARMANDO
trabalha.
4. Escreva uma query para recuperar o nome dos produtos utilizados nos diversos projetos
controlados pelos departamentos. Deseja-Se que o resultado seja apresentado conforme vem
abaixo:
DEPTO PRODUTO
-------------- --------------
COMPRAS PROD1
COMPRAS PROD2
COMPRAS PROD4
MARKETING PROD2
MARKETING PROD3
VENDAS PROD1
VENDAS PROD2
VENDAS PROD3
VENDAS PROD4
80
LISTA Nº 4
1. Escreva uma query para recuperar o maior, o menor salário e a diferença entre o maior e o menor
salário existente na tabela de empregados.
2. Escreva uma query para contar o número de gerentes existentes na tabela de empregados.
3. Escreva uma query para recuperar o nome dos empregados seguido do número de dependentes que
possuem.
4. Escreva uma query para recuperar, para cada gerente, o seu numero e o menor salário pago a um
de seus subordinados. Não devem ser considerados os grupos cujos salários sejam inferior a
1000,00 reais. Ordene o resultado por salário.
81
LISTA Nº 5
1. Recupere o nome dos empregados que trabalham nos projetos em que TERESA trabalha.
3. Recupere o número, nome e sobrenome dos empregados que ganham mais do que a média salarial
da empresa e estão subordinados a um gerente que possua a letra T no nome.
4. Recupere o nome e salário de todos os empregados que ganham o salário máximo pago aos
empregados de cada departamento.
82
LISTA Nº 6
1. Adicione uma linha à tabela de PRODUTOS. O número do produto é 1216, seu nome é PROD5 e
sua cor, AMARELO. Antes de emitir o comando INSERT dê um DESCRIBE em PRODUTOS
para tomar conhecimento do tipo de cada coluna.
SELECT *
FROM DEPENDENTES;
9. Ainda na segunda sessão do SQL*PLUS, troque o nome do dependente LUCIO para LUCIO
ALVES. Você conseguiu? Porquê? ____________________________________
_________________________________________________________________________
10. Coloque as duas janelas do SQL*PLUS lado a lado e, em seguida, execute o comando COMMIT
na primeira sessão do SQL*PLUS. Observe o que vai acontecer na outra sessão. Quantas linhas
foram atualizadas? _____________ Ocorreu algum tipo de erro? Porquê?
_________________________________________________________________________
Feche a segunda sessão aberta no SQL*PLUS.
83
LISTA Nº 7
Observação:
PK - Primary Key
FK - Foreign Key
U - Unique
NN - Not Null
CK - Check
Exemplo:
Seguindo a convenção acima a constraint Primary Key da tabela de clientes teria o seguinte nome:
CLIENTES_CODIGO_PK.
84
LISTA Nº 8
NUMERO
NOME
SOBRENOME
3. Crie uma seqüência para ser utilizada na geração de números de chave primária da tabela de
PROJETOS. A seqüência deve começar com o número 5, o incremento deve ser de 1 e o nome da
seqüência deve ser PROJETOS_NUMERO_SEQ. Permita que a seqüência faça um cache de 3
números (o default é de 20).
85
LISTA Nº 9
1. Executar o comando CREATE USER é suficiente para que o usuário criado tenha acesso a um
banco de dados? Porquê? ________________________________________________
_________________________________________________________________________
3. Se você é um DBA e pretende criar muitos usuários com os mesmos privilégios de sistema. O que
você faria para tornar este trabalho mais fácil? ______________________________
_________________________________________________________________________
86
BIBLIOGRAFIA
Livros:
• C. J. Date, An Introduction to Database Systems, Addison-Wesley Publishing Company, 1995.
• C. Batini, S. Ceri, S. Navathe, Conceptual Database Design, The Benjamin Cummings Publishing Company, Inc.,
1992.
• J. D. Ullman, J. Widom, A First Course in Database Systems, Prentice Hall, 1997.
Manuais Oracle:
87