Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Belém, maio/1999
Sumário
1 Introdução a SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1. Um Breve Histórico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2. Banco de Dados Relacional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2 Linguagem SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1. Como definir o banco de dados com SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1.1 Create Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1.2 Create Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Exercício 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.1.3 Alter Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.1.4 Drop Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2. Manipulação com tabelas SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.1 Inserção de Tuplas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.2 Alteração de Tuplas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.2.3 Remoção de Tuplas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Exercício 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.3. Consultando Tabelas SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.3.1 Comando Select . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Exercício 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.3.1.1 Comando SELECT - Cláusula DISTINCT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Exercício 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3.1.2 Comando SELECT - Retorno de valores calculados . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Exercício 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3.1.3 Comando SELECT - Funções de Agregação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3.2 Cláusula WHERE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3.2.1 Comparação [NOT] LIKE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3.2.2 Comparação de nulos IS [NOT] NULL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.3.3 Cláusula UNION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.3.4.Cláusula INTERSECT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.3.5 Claúsula MINUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.4 Consultas envolvendo mais de uma tabela do BD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Exercício 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.5. Subconsultas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.5.1 Cláusula [NOT] IN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Exercício 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.5.2 Cláusula ANY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Exercício 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.5.3 Cláusula ALL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Exercício 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.5.4 Cláusula [NOT] EXISTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Exercício 10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.5.5 Cláusula CONTAINS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Exercício 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.6 Ordenando a exibição de tuplas - Cláusula ORDER BY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Exercício 12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.7 Agrupando tuplas - Cláusulas GROUP BY e HAVING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Exercício 13 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.8 Comandos de atualização + comandos de consulta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3. Visões em SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2
3.1 Consultas sobre Visões . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.2 Atualizações . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.3 Vantagens das visões . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.4 Algumas soluções para problemas com visões . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Exercício 14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4. Autorizações de Acesso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.1. Comando Grant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.2. Comando Revoke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
5. Mais Exercícios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
7 Bibliografia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3
1 Introdução a SQL
O objetivo deste curso é introduzir o aluno na tarefa de manipular bancos de dados através da linguagem
SQL. SQL significa Structured Query Language (linguagem estruturada de consulta). Apesar do nome, fazer
consultas a bancos de dados não é a única função de SQL. Ela é utilizada para criar tabelas, inserir, excluir e
alterar dados do banco de dados, além de outras utilizações. A seguir é mostrado um breve histórico da
linguagem seguido de uma rápida visão de bancos de dados relacionais.
4
relacional, o qual foi proposto por E. F. Codd em 1970.
A abordagem relacional está baseada no princípio de que as informações em uma base de dados podem
ser consideradas como relações matemáticas e que estão representadas de maneira uniforme, através do uso de
tabelas bidimensionais. Todos os dados de um BD relacional estão armazenados em relações (ou tabelas).
Cada tabela possui atributos (ou campos), os quais são armazenados em colunas da tabela. As linhas
guardam informações sobre uma entidade (registro). Alguns atributos da tabela são chave primária da mesma.
Isto significa que não existem duas linhas iguais numa tabela. Cada linha pode ser identificada univocamente
pela sua chave primária (por exemplo matrícula de aluno). A seguir é mostrada a tabela de alunos que tem como
atributos Matrícula, Nome, Endereço e Cod_Curso. A chave primária da tabela é o atributo matrícula.
Alunos
A seguir é mostrada a tabela de cursos com os atributos Cod_Curso e Nome. Cod_Curso é a chave
primária.
Cod_Curso Nome
77 Computação
88 Eng. Civil
Note que cada aluno da tabela de alunos possui um valor de Cod_Curso que existe na tabela de cursos.
Isso significa que se quisermos saber o nome do curso de um aluno, basta sabermos o código do curso do aluno
e procurar pelo mesmo código na tabela de cursos. Quando existe essa ligação entre tabelas, o atributo que faz
a ligação (no caso, Cod_Curso) é considerado chave estrangeira ou chave externa. Isto implica em várias regras
de verificação num SGBD, pois um aluno não pode ter um código de curso que não existe na tabela de cursos,
para citar um exemplo.
Existem várias regras definidas por Codd para caracterizar um SGBD relacional. Em resumo, pode-se
dizer que todos os dados do SGBD devem ser armazenados em tabelas e que a manipulação dessas tabelas
através de inclusão, exclusão, alteração e consultas deve gerar novas tabelas
5
2 Linguagem SQL
Atualmente, a linguagem SQL assume um papel muito importante nos sistemas de gerenciamento de
banco de dados (SGBDs), podendo ter muitos enfoques. Através de comandos SQL, os usuários podem montar
consultas poderosas sem a necessidade de criação de um programa, ou ainda utilizar comandos SQL embutidos
em programas de aplicação que acessam os dados armazenados. O DBA, pessoa responsável pela administração
de banco de dados pode realizar suas tarefas através de SQL. Da mesma forma, a linguagem pode ser usada
como linguagem cliente/servidor, linguagem para banco de dados distribuídos e caminho de acesso a outros
bancos de dados ou outras plataformas.
Devido ao fato de possuir várias aplicações, a linguagem SQL provê suporte a várias funções de um
SGBD. Ela consiste de:
C DDL (linguagem de definição de dados), onde os dados a serem armazenados são definidos e
estruturados;
C DML (linguagem de manipulação de dados), que permite a inclusão, remoção, seleção ou atualização de
dados armazenados no banco de dados;
C Controle de acesso, permitindo proteção dos dados de manipulações não autorizadas;
C Restrições de Integridade, que auxiliam no processo de definição da integridade dos dados, protegendo
contra corrupções, inconsistências e falhas do sistema de computação.
Além dessas características principais, ainda podemos citar o suporte a visões, onde são especificadas
as consultas disponíveis através de tabelas virtuais e especificação de transações, para garantia do
compartilhamento dos dados.
6
Formato do comando create table:
Ex: BD bancário:
create table cliente (
cliente_nome char(20) not null,
rua char(30),
cidade char(30,
primary key (cliente_nome))
7
Tipos de dados suportados pelo Personal Oracle 7:
Tipo Comentários
CHAR dados alfanuméricos de até 255 caracteres. Acrescenta espaços
depois do valor para complementar o tamanho da coluna
DATE Inclui século, ano, mês, dia, hora, minuto e segundo
LONG strings alfanuméricas de tamanho variado de até 2 gigabytes
(memo)
LONG RAW Dados binários até 2 gigabytes (BLOB) - gráficos, sons, vídeo,
etc.
NUMBER Números positivos ou negativos com ou sem ponto decimal
RAW Dados binários até 255 bytes
RAWID String hexadecimal representando o endereço único de uma linha
em uma tabela
VARCHAR2 Dados alfanuméricos de tamanho variado. Até 2000 caracteres.
b) Zoológico:
animais (codA, tipo, nome, peso, idade)
jaulas (nro, area)
alocação (nro_jaula, codA, data_entrada)
zeladores (codZ, nomez, tempo_serviço)
manutenção (codZ, nro, horas)
O comando Alter Table permite modificar a estrutura de uma tabela já definida. Pode-se adicionar uma
coluna à tabela ou modificar uma coluna existente. A sintaxe do comando é mostrada a seguir:
8
alter table nome_tabela
[add nome_coluna tipo_dados; |
modify nome_coluna tipo_dados;]
O comando a seguir altera a estrutura da tabela agência para aumentar o tamanho do campo cidade:
9
2.2.2 Alteração de Tuplas
update nome_tabela
set alteração
[where condição]
Exemplos:
Alterar a tabela de depósitos para acrescentar 5% de juros em todos os saldos:
update deposito
set saldo = saldo * 1.05
update cliente
set cidade = “Belém”
where cliente_nome = “João”
update deposito
set saldo = saldo * 1.06
where saldo > 10000
10
Exercício 2: Remover as agências da cidade de Belém
Select seleciona as colunas que deverão compor a tabela resultante. Os nomes dos atributos devem ser
os mesmos definidos no banco de dados. É uma cláusula obrigatória em qualquer consulta.
From indica as tabelas do banco de dados que devem ser consultadas. Também é obrigatória em qualquer
consulta.
Where indica uma condição pela qual os dados serão filtrados. A condição especificada deve retornar
verdadeiro ou falso. Para cada linha da tabela, o interpretador SQL verifica se atende a condição especificada
nesta cláusula e adiciona a linha na resposta caso seja verdadeira a avaliação. É uma cláusula opcional de
consulta.
- Observações:
C Caso a cláusula where seja omitida, o predicado P (condição) é verdadeiro;
C A lista de atributos A1, A2, ..., An pode ser substituida por um asterisco (*) para selecionar todos os
atributos de todas as relações da cláusula from;
C SQL forma o produto cartesiano (relaciona cada linha da primeira tabela com todas as linhas da outra
tabela) das relações chamadas na cláusula from, verifica a condição da cláusula where, e então, projeta
o resultado para os atributos da cláusula select;
C O resultado de uma consulta SQL é uma tabela.
C Operadores lógicos: and, or e not
C Operadores de comparação: >, >=, <, <=, = , != (ou <>)
11
Joana Alm Barroso Belém
O resultado seria:
12
Exercício 4: No BD hospitalar:
a) Buscar todas as especialidades dos médicos;
b) Buscar todas as datas de consultas com horário após as 15hs
c) Buscar todas as idades dos médicos
O comando Select permite retornar expressões aritméticas como resultado da consulta. Cada atributo
especificado na cláusula Select também é uma expressão, e como tal pode ser manipulada. Essa é uma forma
de mostrar resultados que na verdade não estão armazenados no banco de dados. Para atributos numéricos,
podemos utilizar +, -, *, /. E para atributos do tipo string pode-se utilizar concatenação ||. Além desses
operadores, ainda existem outras funções que serão mostradas na seção a seguir.
Obs: Pode-se dar nomes novos as colunas resultantes de tabelas em algumas implementações de sql. Por
exemplo:
As funções de agregação operam sobre um conjunto de linhas e algumas são mostradas a seguir:
13
select count (data) {não conta nulos}
from consultas
where data = “26/05/96"
Na cláusula WHERE são especificadas as condições de busca da tabela. Podem ser usados vários
operadores relacionais, como =, >, <, <=, >=, <> e ainda operadores de comparação de padrões em valores,
como LIKE e comparação de nulos.
14
Obs: algumas implementações de SQL usam % no lugar de *
Buscar o código do médico, paciente e horário para todas as consultas marcadas para o ano de 1996:
select codm, codp, hora {ou *}
from consultas
where data like “*96"
15
where agencia_nome = “Ag1")
union
(select cliente_nome
from empréstimo
where agencia_nome = “Ag1")
obs: a cláusula Union retira as repetições. Em algumas versões de SQL, pode-se utilizar UNION ALL, que
retorna todas as tuplas das tabelas unidas, mesmo havendo repetição.
2.3.4.Cláusula INTERSECT
Permite a interseção de duas tabelas compatíveis (operador 1 da álgebra relacional), retornando apenas
as linhas que pertencem às duas tabelas
Ex: buscar todos os clientes da Ag1 que possuem uma conta e empréstimo:
(select distinct cliente_nome
from depósito
where agencia_nome = “Ag1")
intersect
(select distinct cliente_nome
from empréstimo
where agencia_nome = “Ag1")
Ex: Buscar todos os clientes da Ag1 que possuem conta mas não possuem empréstimo:
(select distinct cliente_nome
from depósito
where agencia_nome = “Ag1")
minus
(select distinct cliente_nome
from empréstimo
where agencia_nome = “Ag1")
16
2.4 Consultas envolvendo mais de uma tabela do BD
Quando a resposta de uma consulta precisa ser buscada em várias tabelas do banco de dados, então é
necessário especificar quais tabelas serão usadas na consulta SQL. Para isso é utilizada a cláusula FROM.
Como SQL é baseada no modelo relacional, a forma de juntar tabelas é através de produto cartesiano das
mesmas. Por exemplo, se quisermos usar duas tabelas, a de médicos e a de consultas, mostradas abaixo, o
resultado é uma tabela que contém relacionamentos entre todos os médicos e todas as consultas. Obviamente
que várias tuplas do resultado não são úteis, portanto temos que especificar quais as tuplas úteis através da
cláusula WHERE.
M1 João 33 traumatologia
M3 Maria 30 obstetrícia
M1 P1 12/12/1997 15
M1 P2 13/12/1997 14
M2 P1 05/10/1997 8
Se a consulta fosse:
select *
from médicos, consultas
O resultado seria:
17
M3 Maria 30 obstetrícia M1 P1 12/12/1997 15
O resultado expressa valores que nem sempre são verdadeiros. Por exemplo, existe uma linha com
médico M1 e ao lado, uma consulta do médico M2. Se quisermos saber os dias de consulta do médico João,
temos que escolher somente as linhas onde o codm em médicos é igual a codm em consultase o nome do médico
seja João. Pode-se perceber que para saber datas de consultas basta olharmos na tabela de consultas, mas esta
somente contém o código dos médicos. Portanto se quisermos avaliar o nome do médico, temos que buscar na
tabela de médicos. Daí a necessidade de juntar as tabelas pelo código do médico. A esta operação damos o
nomes de JOIN, ou seja, junção de valores relacionados. A consulta SQL que obtém tal resposta é:
select data
from médicos, consultas
where médicos.codm = consultas.codm and médicos.nomem = “João"
data
12/12/1997
13/12/1997
Na cláusula FROM, podemos definir quantas tabelas forem necessárias. A única restrição é de que as
chaves estrangeiras devem ser igualadas para que os dados retornados sejam verdadeiros.
Ex: Buscar o nome dos médicos com consulta marcada para o dia 22/05/96:
select medicos.nomem
from medicos, consultas
where consultas.data = “22/05/96" and
medicos.codm = consultas.codm
* Pode-se ter variáveis de tupla associadas a cada tabela declarada na cláusula from
Ex: select M.nomem, P. nomep
from consultas C, medicos M, pacientes P
where C.codm = M.codm and
C.codp = P.codp and
18
C. hora = 15
Exercício 6: Buscar nome e idade dos médicos com consulta marcada com a paciente Ana.
2.5. Subconsultas
Na linguagem SQL ANSI podem ser definidas subconsultas através das cláusulas IN, ANY, ALL,
EXISTS e CONTAINS. Entretanto, somente podem ser definidas subconsultas na cláusula WHERE..
A subconsulta (select codp from consultas) é avaliada primeiro, retornando uma tabela com todos os
códigos de pacientes que possuem consulta marcada. Em seguida a consulta principal é processada selecionando
os nomes dos pacientes cujo código não se encontra no resultado da subconsulta. Pode-se observar que essa
consulta também poderia ser descrita através da cláusula minus, subtraindo os pacientes com consulta do
conjunto de todos os pacientes cadastrados (mostre como!).
Uma outra observação importante é que um item (codp) é comparado a um conjunto (o resultado da
subconsulta). A cláusula IN comporta-se como o operador pertence da matemática, comparando um elemento
a um conjunto de elementos do mesmo tipo. A subconsulta não poderia, por exemplo, retornar código de médico
ao invés de pacientes, ou seja, o elemento comparado tem que ser do mesmo tipo dos elementos do conjunto.
Ex: Buscar nome e problema dos pacientes com idade > 21 e que também são médicos:
select nomep, problema
from pacientes
where idade > 21 and nomep in
(select nomem
from medicos)
19
Exercício 7:
Buscar todos os clientes da Ag1 que possuem conta e empréstimo (com cláusula in):
Buscar todos os clientes da Ag2 que possuem conta mas não possuem empréstimo.
Ex: 1) Buscar o nome dos clientes que tem saldo menor que todos os clientes com depósto na agência
Ag3:
select cliente_nome
20
from deposito
where saldo < all
(select saldo
from deposito
where agencia_nome = “Ag3")
2)Buscar o nome dos médicos com consultas marcadas para horários mais tarde que todas as
consultas da médica Maria
select nomem
from medicos m, consultas c
where m.codm = c.codm and
c.hora > all
(select hora
from consultas c1, medicos m1
where c1.codm = m1.codm and
m1.nomem = “Maria”)
Exercício 9: Buscar os dados dos pacientes com consultas marcadas para horários anteriores a todos os
horários marcados para o dia 22/06/96
Ex: Podemos reescrever a consulta: Encontre os clientes que possuem conta e empréstimo na Ag1.
select cliente_nome
from cliente
where exists (select *
from deposito
where deposito.cliente_nome = cliente.cliente_nome and
agencia_nome = “Ag1")
and exists (select *
from emprestimo
where emprestimo.cliente_nome = cliente.cliente_nome and
agencia_nome = “Ag1")
21
Ex2: Considere novamente a consulta: “Encontre todos os clientes que têm uma conta em todas as
agências localizadas em “StaCruz”. (usando not exists e minus)
select distinct S.cliente_nome
from deposito S
where not exists ((select agencia_nome
from agencia
where agencia_cidade = “StaCruz”)
minus
(select T.agencia_nome
from deposito T
where S.cliente_nome = T.cliente_nome))
Exercício 10 (BD hospitalar): a)Buscar o nome de todos os médicos com consulta marcada.
b)Buscar o nome do médico mais jovem.
Ex: Considere a mesma consulta do Ex2 acima. Para cada cliente, precisamos ver se o conjunto de todas
as agências na qual um cliente possui uma conta contém o conjunto de todas as agências de “StaCruz”.
A consulta pode ser escrita assim:
select distinct S.cliente_nome
from deposito S
where (select T.agencia_nome
from deposito T
where S.cliente_nome = T.cliente_nome)
contains
(select agencia_nome
from agencia
where agencia_cidade = “StaCruz”)
22
Exercício 11: identifique outras possíveis consultas que possam ser reescritas com a cláusula contains.
Esta cláusula permite a ordenação do resultado da consulta. É utilizada após a cláusula Where.
* Sintaxe:
ORDER BY <Lista de atributos> [desc] [asc]
{desc - ordem decrescente, asc - ordem crescente}
Ex: Buscar os nomes dos clientes em ordem alfabética com empréstimo na agência “Ag3":
select distinct cliente_nome
from emprestimo
where agencia_nome = “Ag3"
order by cliente_nome
Ex2: Listar todos os empréstimos na ordem decrescente de quantia e os empréstimos com a mesma quantia
devem ser ordenados pelo número do empréstimo.
select *
from emprestimo
order by quantia desc, emprestimo_numero asc
Exercício 12: Buscar os dados de todas as consultas do paciente Carlos, ordenadas de forma decrescente
pela hora da consulta.
* Group by: agrupa partes do resultado de uma consulta, a partir do qual é possível utilizar funções
de agregação (avg, min, max, count, sum);
* Having: Especifica condições para a formação de um grupo. Só existe associado à cláusula group
by.
* As condições só podem envolver os atributos a serem buscados ou alguma função de agregação.
Exemplos:
23
1) Encontre o saldo médio de conta em cada agência:
select agencia_nome, avg(saldo)
from deposito
group by agencia_nome
3) Buscar as agências nas quais a média dos saldos é maior do que 1200:
select agencia_nome, avg(saldo)
from deposito
group by agencia_nome
having avg(saldo) > 1200
5) Encontre a média dos saldos de todos os depositantes que vivem em “StaCruz” e têm pelo menos 3
contas. (uso de where e having juntos)
select avg(saldo)
from deposito, cliente
where deposito.cliente_nome= cliente.cliente_nome and
cliente.cidade= “StaCruz”
24
group by deposito.cliente_nome
having count(distinct conta_numero) >= 3
obs: O predicado na cláusula where é aplicado antes do predicado de having.
Exercício 13:
1) buscar todas as datas de consultas e o total de consultas para esta data.
2) buscar somente as datas e o total de consultas para horários após as 14 horas
3) buscar somente as datas e o total de consultas para as datas onde haja mais de uma consulta marcada.
4) buscar, para a tabela de médicos, todas as idades e o total de médicos com a mesma idade.
5) buscar o nome dos médicos com mais de uma consulta marcada.
3) Acrescentar 5% de juros sobre contas cujos saldos sejam maiores do que a média:
update deposito
set saldo = saldo * 1.05
where saldo > (select avg (saldo)
from deposito)
25
update consultas
set hora = “19:00"
where codp in (select codp
from pacientes
where nomep = “Ana”)
26
3. Visões em SQL
Um banco de dados é composto de várias tabelas relacionadas. Se quisermos obter qualquer informação,
devemos citar essas tabelas nas consultas. Algumas consultas são bastante utilizadas no dia-a-dia e são
complexas de escrever, devido ao uso de subconsultas. Muitas vezes os usuários não têm conhecimento
adequado para formular tais consultas. Nesse caso, o DBA poderia colocar algumas consultas prontas à
disposição, as quais seriam acessadas com consultas simples.
As visões são tabelas virtuais derivadas das tabelas do banco de dados e são úteis para garantir segurança
de acesso ao BD, disponibilização de tabelas que melhor se adequam às necessidades de uma aplicação e
facilitade de acesso aos dados sem ter que formular consultas complexas.
Exemplos:
a) Um funcionário do hospital não deve ter acesso a todos os dados pessoais de um paciente, somente ao
seu código e nome;
b) Pode ser interessante vincular os dados de um médico aos dados de suas consultas
obs: a visão criada não é executada, e sim, armazenada no catálogo. Porém, para o usuário é como se
tivesse uma visão <nome_visão> armazenada no BD.
obs: a visão especificada é eliminada (a definição é removida) e todas as visões definidas em termos
desta visão também são automaticamente anuladas. Porém os dados continuam existindo, já que a visão
é uma tabela virtual.
Exemplos:
a) A seguir é criada uma visão chamada DadosPac, que, do ponto de vista do usuário comum,
corresponde a uma tabela como outra qualquer. Esta visão retorna somente o código e o nome de todos os
pacientes do hospital. Se um funcionário desse hospital tiver acesso somente a tabela (visão) DadosPac, então
ele não verá o problema do paciente, o qual é um atributo da tabela pacientes.
create view DadosPac as
select codp, nomep
27
from pacientes
b) A visão a seguir, chamada MedCons contém os nomes dos médicos e suas datas e horas de
consulta. Observe que para obter essa informação, precisamos das tabelas de médicos e consultas e da junção
entre os atributos codm das duas tabelas. A visão facilita a consulta já que, após a sua criação, basta pedirmos
para ver todos os dados da tabela MedCons que automaticamente a consulta da visão é processada, sem termos
que defini-la novamente.
create view MedCons as
select nomem, data, hora
from medicos, consultas
where medicos.codm = consultas.codm
Obs: Uma vez definida uma visão, qualquer operação de consulta ou atualização pode ser aplicada sobre
ela.
Operações realizadas sobre uma visão se refletem diretamente sobre as tabelas físicas das quais ela
deriva.
Nas operações de recuperação (select) o processo de conversão das operações em visão para operações
em tabelas básicas é bem direto e funciona bem.
Exemplos:
a) o funcionáro do hospital deseja buscar o nome de todos os pacientes cadastrados que começam com
a letra R:
select nomep
from DadosPac
where nomep like “R*”
b) Buscar o nome dos médicos com consulta marcada para horários após as 18hs no mês de outubro:
select nomem
from MedCons
28
where hora > 18 and data like “*/10/94"
3.2 Atualizações
* Operações de inserção, atualização e remoção de tuplas (insert, update e delete) em uma visão muitas
vezes geram problemas. Nem todas as visões são atualizáveis
Problemas:
- inserção nesta visão viola a regra de integridade de entidade e não se pode inserir no campo count(*);
- Não se pode atualizar um atributo calculado.
- Elas fazem com que o mesmo dado seja visto por diferentes usuários de diferentes formas (ao mesmo
tempo)
- A percepção do usuário é simplificada;
- É óbvio que o mecanismo da visão possibilita aos usuários centrarem-se unicamente nos dados que lhes
29
são importantes e ignorarem o resto. O que talvez não seja tão óbvio é que, pelo menos na recuperação
(select), tal mecanismo também possa simplificar consideravelmente as operações de manipulação de
dados feitas pelo usuário.
- Segurança automática para os dados ocultos
Dados ocultos são aqueles não visíveis através de determinada visão. Ficam claramente protegidos
por meio desta visão específica. Assim, obrigar os usuários a acessar o banco de dados através de
visões é um mecanismo simples, porém eficaz de controle de autorização.
Exercício 14:
Dada o BD de peças e fornecedores:
fornecedores (codf, nomef, cidade)
peças (codp, nomep, peso, cor)
fornecem (codf, codp, qtde)
30
4. Autorizações de Acesso
Muitos SGBDs relacionais podem ser acessados por diversos usuários. Cada usuário tem uma
determinada necessidade em relação aos dados armazenados. De acordo com o projeto do banco de dados,
alguns usuários só podem consultar alguns dados, outros podem atualizar, outros podem inserir, etc. Para que
o dado fique protegido do uso indevido de qualquer usuário, a linguagem SQL permite a definição dos
privilégios que cada um pode ter em relação às tabelas criadas no banco de dados.
Os privilégios garantem a segurança e integridade dos dados, bem como a responsabilidade de cada
usuário sobre seus dados específicos.
<usuário>: nome do usuário que vai receber os privilégios. Deve ser um nome cadastrado dentro do
ambiente.
PUBLIC: concede os privilégios especificados a todos os usuários do ambiente
Exemplos:
- grant select on medicos to Paulo
permite somente consultas do usuário Paulo na tabela de médicos
- grant select, insert, update on consultas to Mary
concede ao usuário Mary os privilégios de seleção, inserção e atualização sobre a tabela consultas
- grant all privileges on DadosPac to public
permite todos os privilégios a todos os usuários sobre a tabela (neste caso, visão) DadosPac.
31
4.2. Comando Revoke
Exemplos:
- revoke select on medicos from Paulo
- revoke all on DadosPac to public - revoga todos os direitos sobre a visão DadosPac
32
5. Mais Exercícios
1) BD formado pelas seguintes tabelas:
medicos (codm, nomem, idade, especialidade)
pacientes (codp, nomep,idade, problema)
consultas (codm, codp, data, hora)
e) fornecer os nomes dos médicos que possuem alguma consulta marcada com o paciente P4
Várias soluções possíveis:
e.1) SELECT nomem
FROM medicos
WHERE codm in (SELECT codm
FROM consultas
WHERE codp= “P4")
e.2) SELECT nomem
FROM medicos
WHERE “P4" in ( SELECT codp
33
FROM consultas
WHERE codm = medicos.codm)
e.3) SELECT nomem
FROM medicos
WHERE EXISTS (SELECT *
FROM consultas
WHERE codm = medicos.codm and
CODP = “P4")
f) mostrar os nomes dos médicos que não têm consulta marcada com a paciente P4
SELECT nomem
FROM medicos
WHERE NOT EXISTS (SELECT *
FROM consultas
WHERE codp = “P4" and codm = medicos.codm)
g) Mostrar os nomes dos médicos que não tem consulta marcada com a paciente Maria
SELECT nomem
FROM medicos
WHERE codm IN
(SELECT codm
FROM consultas
WHERE codp NOT IN ( SELECT codp
FROM pacientes
WHERE nome = “Maria”)
h) Mostrar o código dos pacientes que tem consulta marcada para o dia 23/09/96 ou com médicos pediatras.
(SELECT codp
FROM consultas
WHERE data = “23/09/96")
UNION
(SELECT codp
FROM consultas
34
WHERE codm IN (SELECT codm
FROM medicos
WHERE especialidade = “pediatra”))
obs: poderia ter sido utilizado o OR ao invés de UNION na primeira subconsulta?
i) Mostrar os nomes dos médicos que não fornecem consultas para os pacientes de obstetras.
SELECT nomem
FROM medicos
WHERE codm NOT IN
(SELECT codm
FROM consultas
WHERE codp IN
(SELECT C.codp
FROM medicos M, consultas C, pacientes P
WHERE M.especialidade = “obstetrícia” and
M.codm = C.codm and
C.codp = P.codp))
a) Mostrar os códigos dos empregados que ganham acima da média dos salários
SELECT codemp
FROM empregado
WHERE salario > (SELECT avg(salario) from empregado)
35
FROM empregado)
c) mostrar os departamentos com média salarial inferior a 500 (obs: não cai na prova)
SELECT codd
FROM empregado
GROUP BY codd
HAVING avg(salario) < 500
d) mostrar os departamentos que possuem mais de 10 programadores (obs: não cai na prova)
select codd
from empregado
where funcao = “programador”
group by codd
having count(*) > 10
SELECT nome
FROM time
WHERE codtime IN
(SELECT codtime
FROM joga
WHERE codemp IN
(SELECT codemp
FROM empregado
WHERE salario IN
(SELECT Max(Salario)
FROM empregado)))
g) mostrar a posição e o código dos empregados de maior salário em cada departamento (obs: não cai na prova)
36
select codemp, posicao
from joga
where codemp in
(select codemp
from empregado
where salario in
(select max(salario)
from empregado
group by codd))
37
6 O Futuro do Padrão SQL
Recentemente temos assistido ao aumento da popularidade dos bancos de dados orientados a objetos
(OODBMS -Object Oriented Database Management System). Um banco de dados orientado a objetos é aquele
que incorpora objetos complexos, tipos abstratos de dados (Abstract Data Types - ADTs), encapsulamento e
herança [MULL,1994]. Mantelman define um objeto complexo como aquele que armazena procedimentos além
de dados, e estende a definição de um banco de dados orientado a objetos dizendo que não há restrições a dados
baseados em caracteres e que podem ser acomodados objetos multimídia [MANT,1996].
Os bancos de dados orientados a objetos tratam os dados de modo diferente dos bancos de dados
relacionais. Estes implementam acesso aos dados através de linhas e colunas, enquanto os orientados a objetos
têm uma estrutura mais complexa, que não é suportada pelo padrão SQL92.
Como alguns fornecedores de SGBDs começaram a acrescentar a seus produtos características além do
escopo do padrão SQL92, houve a necessidade de se estudar um novo padrão, de modo a garantir a
portabilidade entre os vários SGBDs. Daí a necessidade do SQL3. Algumas das características implementadas
incluem tipos de dados novos e estendidos, incluindo tipos de dados abstratos, múltiplos tipos de estados nulos,
suporte para objetos e identidade de objetos, encapsulamento, herança e triggers.
O SQL92 tem um conjunto de tipos de dados atômicos. No SQL3, estes tipos de dados são mantidos
como tipos de dados pré-definidos, embora alguns tenham sido modificados ou estendidos. Por exemplo, os
tipos de dados character e bit foram estendidos para incluir o conceito de um "objeto maior"(large object). Estes
"large objects" facilitam o uso de objetos multimídia dentro do banco de dados.
Dois tipos adicionais de dados, antes não suportados, foram incluídos: boolean e enumerated. O tipo
boolean somente pode ter os valores "true", "false" e "unknown". O tipo enumerated permite que se defina
domínios cujos valores são restritos a um pequeno conjunto de valores. Como exemplo, teríamos o comando
CREATE DOMAIN cores (azul, vermelho, amarelo) que define um domínio chamado cores e restringe os
valores inseridos na coluna de tipo enumerated a um dos três valores especificados para o domínio
[MELT,1995].
Ao contrário do SQL92, o SQL3 suporta múltiplos estados nulos. Isto significa que diferentes classes
de null são suportadas, permitindo às aplicações definir os significados de determinado estado nulo. Possíveis
significados incluem "unknown" (como vimos acima, no caso do tipo enumerated), "missing", "not applicable"
ou "pending". Cada definição de nulo tem uma representação diferente que o torna identificável durante uma
consulta ou atualização.
O segundo grupo de objeto de dados suportado pela nova versão, e não suportado pela anterior, é o tipo
abstrato de dados (ADT). O ADT é utilizado pelo SQL3 para possibilitar o uso de objetos na estrutura SQL.
O ADT permite aos usuários criar novos tipos de dados definindo tipos abstratos de dados a partir de tipos de
dados pré-definidos ou a partir de outros ADTs já existentes. Os ADTs suportam os conceitos de
encapsulamento e subtipos da orientação a objetos.
Estendendo o que vimos acima, objetos são itens de dados que combinam complexas estruturas de dados
com processos ou métodos para manipular estes dados. A noção de combinar dados e processos é chamada de
encapsulamento. Enquanto os tipos de dados que conhecemos no SQL92 são identificados através de seus
valores, no SQL3, um dado definido como object será identificado por um identificador único de objeto, gerado
quando o objeto é criado. Os conceitos de subtipo e supertipo são baseados no conceito de herança da orientação
a objetos, que é a capacidade de se criar novos objetos a partir de outros já existentes, herdando suas
características. Atributos e métodos podem ser herdados, o que diminui a redundância de informações. No
SQL3, um ADT pode ser um subtipo de outro ADT. Por exemplo, podemos definir um ADT como um objeto
PESSOA. Um subtipo de PESSOA poderia ser ESTUDANTE, que herdaria as propriedades e comportamento
de PESSOA. Um subtipo do subtipo ESTUDANTE poderia ser GRADUANDO, que herdaria as característica
de PESSOA e ESTUDANTE.
38
Outra importante característica do SQL3 é o suporte a triggers. No padrão SQL92, esta característica
foi deixada de lado porque seu uso foi subestimado. Existe hoje, entretanto, uma grande demanda desta
característica por parte dos usuários, e mais e mais fornecedores estão incluindo suporte a triggers em seus
produtos, como, por exemplo, a Oracle no seu SGBD Oracle7. Um trigger é um objeto do esquema do banco
de dados ou um bloco de código que diz ao banco de dados que outras ações devem ser tomadas depois de
executados certos comandos SQL. Por exemplo, pode-se querer adicionar um registro a uma tabela de log toda
vez que um registro for excluído de uma outra tabela para se manter uma auditoria de quem está realizando as
mudanças. Um trigger seria usado neste caso para iniciar uma sequência de ações (atualizar a tabela de log)
depois que uma função de deleção fosse executada.
O trabalho de revisão de um padrão para a inclusão de novas características é intenso e dinâmico. Os
fornecedores de SGBDs aumentam o poder de seus produtos adicionando mais e mais características, algumas
delas não cobertas pelo padrão atual, o que cria a necessidade de revisão. No caso do SQL3, a inclusão de
características de orientação a objetos é a mais importante.
39
7 Bibliografia
LIMA, CARLA A. G. “Linguagem SQL”. Banco de Dados I - Notas de Aula. Depto. Informática - UFPA.
1997.
MACHADO, F.N; ABREU, M. “Projeto de Banco de Dados: Uma visão prática”. Érica. 1995.
STEPHENS, R.; PLEW, R.; MORGAN, B.; PERKINS, J. “Teach yourself SQL in 21 days”. 2nd Edition.
SAMS Publishing, USA, 1997.
40