Prévia do material em texto
Capítulo 13
Views: usando consultas como tabelas virtuais
Views1 são consultas SQL que, em situações diversas, podem ser utilizadas no papel de tabelas
relacionais. Entretanto, diferentemente das tabelas, os registros de uma view não são
armazenados na base de dados. Podemos imaginar uma view como uma tabela que tivesse uma
instância virtual, que é construída cada vez que a mesma é invocada. Quando uma view é
referenciada em expressões SQL, o gerenciador de bancos de dados manipula o resultado da
consulta que define a view como se fosse uma tabela normal.
A similaridade com tabelas estende-se ao ponto de permitir atualizações sobre os virtuais
registros de uma view. Dependendo de certas condições, é possível mapear uma hipotética
operação relacional sobre uma view num conjunto de uma ou mais operações efetivas sobre as
tabelas (ou views) usadas na construção daquela view.
Este capítulo aborda vários aspectos importantes para a compreensão dos mecanismos de
construção e utilização de views no âmbito de bases relacionais.2
13.1 DEFININDO E UTILIZANDO VIEWS
Views constituem um poderoso recurso dos bancos de dados relacionais e sua correta utilização
envolve vários aspectos. Cria-se um view com o comando create view, cuja sintaxe é mostrada a
seguir.
create view <nome> as <comando select>
[ with check option ]
Esses elementos sintáticos são explicados nas seções subsequentes.
DEFININDO VIEWS
Uma view é sempre definida a partir de uma consulta SQL e sua sintaxe de construção é
extremamente simples. O comando
create view v_alunas as
select a.matricula,
a.nome,
a.nascimento,
a.sexo
from aluno a
where a.sexo = 'F'
cria uma view denominada v_alunas, contendo matrículas, nomes e datas de nascimento das
alunas de nossa base de exemplos.
1 Embora o termo visão seja eventualmente empregado neste caso, optamos pela utilização da palavra
view.
2 Views não são implementadas no MySQL. No Access, view podem ser emuladas pela construção de
consultas avulsas.
272 Views
Matrícula Nome Nascimento
1002 Maria Rita Colatti 10/11/1978
1005 Barbara Carlito 29/10/1979
1010 Maria Lucia Silva 10/08/1975
As consultas que definem views podem ser dos mais diversos tipos. Observe a definição abaixo,
que emprega o operador de união.
create view pessoas as
select nome
from aluno
union
select nome
from professor
VIEWS COMO FONTES DE REGISTROS
A view criada acima pode agora ser utilizada como se fosse uma tabela qualquer em outras
consultas SQL. Por exemplo, uma consulta como
select a.matricula,
a.nome,
d.disciplina,
i.nota
from v_alunas a, inscricao i, disciplina d
where a.matricula = i.matricula
and i.coddisciplina = d.coddisciplina
order by a.nome, d.disciplina
produz a lista de alunas com suas respectivas disciplinas e notas.
matricula nome disciplina nota
1005 Barbara Carlito Estatística 4,2
1005 Barbara Carlito Sociologia 3
1010 Maria Lucia Silva Português 5,5
1010 Maria Lucia Silva Sociologia 10
1002 Maria Rita Colatti Compiladores 9,5
No exemplo acima, a view v_alunas foi utilizada como uma fonte de registros na cláusula from,
da mesma forma que uma tabela qualquer da base é usada.
De modo similar, o conteúdo da view pode ser obtido com o comando
select *
from v_alunas
uma vez que todos os atributos, de todos os registros, aparecem no resultado produzido.
VIEWS QUE SIMPLIFICAM OUTRAS CONSULTAS
Na maior parte das vezes, as tabelas relacionais contêm códigos abreviados, tanto para
identificação de registros como para estabelecer suas ligações lógicas. Com isso, a expressão de
consultas SQL adquirem um grau maior de complexidade, uma vez que as conexões devem ser
codificadas corretamente para que os resultados sejam fidedignos. Considere uma consulta que
produz a lista de alunos e suas respectivas matrículas em disciplinas.
select a.matricula,
a.nome,
d.disciplina,
i.nota
from aluno a, inscricao i, disciplina d
where a.matricula = i.matricula
and i.coddisciplina = d.coddisciplina
Error! Style not defined. 273
É possível que uma consulta como essa fosse freqüentemente utilizada numa hipotética
aplicação que manipulasse nossa base de exemplos. Relatórios, extrações de dados e programas
deveriam codificar, sempre que tivessem que relacionar alunos, inscrições e disciplinas, as
tabelas acima e suas ligações lógicas.
Em casos como esse, o emprego de views pode facilitar bastante a obtenção desses dados. A
definição de uma view como
create view alunos_e_inscricoes as
select a.matricula,
a.nome,
d.disciplina,
i.nota
from aluno a, inscricao i, disciplina d
where a.matricula = i.matricula
and i.coddisciplina = d.coddisciplina
disponibiliza uma tabela virtual, cuja expressão está previamente montada, que facilita a
obtenção de dados sobre alunos e inscrições. Uma simples consulta como
select *
from alunos_e_inscricoes
order by nome
é suficiente para obter os referidos dados, sem que seja necessário repetir as expressões. Em
bases de dados com muitas tabelas e numerosos relacionamentos entre elas, a utilização de
views simplificadoras para as consultas mais elaboradas é extremamente eficaz para a redução
de erros de codificação.
ISOLANDO AS TABELAS COM VIEWS
Quando views são empregadas, é possível revelar aos usuários de um banco de dados uma
estrutura diversa daquela que está efetivamente armazenada pelas tabelas. Este efeito é
interessante quando se quer:
• simplificar a estrutura do modelo lógico;
• ocultar dos usuários a verdadeira estrutura dos dados;
• minimizar o impacto de modificações feitas nas tabelas.
Como exemplo do primeiro caso, vamos supor que a estrutura do nosso banco de exemplos seja
exposta através de duas views apenas, referentes a alunos e inscrições, mostradas abaixo.
create view v_aluno as
select a.matricula,
a.nome,
a.sexo,
a.nascimento,
c.curso
from aluno a, curso c
where a.codcurso = c.codcurso
create view v_inscricao as
select i.matricula,
d.disciplina,
i.nota,
p.nome as professor
from inscricao i, disciplina d, professor p
where i.coddisciplina = d.coddisciplina
and d.codprofessor = p.codprofessor
Os resultados dessas views são mostrados a seguir.
matricula nome sexo nascimento curso
1001 Ricardo Biondi M 21/02/80 Direito
1002 Maria Rita Colatti F 10/11/78 Informática
1004 Oscarito Vianna M 14/08/79 Direito
1005 Barbara Carlito F 29/10/79 Jornalismo
274 Views
1007 Carlos Maradona M 30/06/77 Direito
1008 Sacadura Miranda M 12/12/81 Informática
1010 Maria Lucia Silva F 10/08/75 Jornalismo
matricula disciplina nota professor
1001 Dir. Constitucional NULL Zenubio Siqueira
1001 Português 8 Carlos Azambuja
1002 Compiladores 9,5 Lenira Rocha
1005 Sociologia 3 Silvia Ferreira
1005 Estatística 4,2 Pedro Amarante
1007 Dir. Constitucional NULL Zenubio Siqueira
1007 Direito Civil 7 Olivia Straw
1010 Português 5,5 Carlos Azambuja
1010 Sociologia 10 Silvia Ferreira
Embora essa estrutura não seja a ideal quando se pensa em incluir, alterar e excluir registros,
talvez seja adequada para a maior parte das consultas que um aplicativo poderia requerer sobre
uma base de dados desse tipo. Assim, seria razoável revelar para um certo conjunto de usuários
essa estrutura, útil para a extração de relatórios, consultas simples e estatísticas.
Quanto ao segundo efeito mencionado acima, views podem ser úteis quando se deseja permitir
que algunsdados possam ser visualizados e outros não. Por exemplo, suponha que as notas
sejam de acesso restrito, mas não as inscrições. Para isso, bastaria criar uma view sobre a tabela
INSCRIÇÃO que não incluísse o atributo nota. Alguns usuários teriam permissão de acesso à view
mas não à tabela contendo as notas. Esse tipo de recursos é bastante utilizado em sistemas de
cunho financeiro, onde tais informações requerem estrito sigilo. Veja, no capítulo 15, mais
detalhes sobre permissões de acesso.
O terceiro efeito refere-se à possibilidade de empregar views quando se deseja minimizar o
impacto de mudanças na estrutura de um banco de dados. Para exemplificar este conceito,
vamos considerar que nosso banco de dados seja utilizado, além da aplicação principal, por
outros usuários que têm acesso aos dados para os mais diferentes fins. Se algum tipo de
mudança fosse feito sobre a estrutura de dados, o efeito seria refletido para todos esses usuários,
que teriam que mudar seus programas e procedimentos de acesso aos dados. Entretanto, o
emprego de views minimiza este efeito, uma vez que alguns tipos de transformações podem ser
levadas a efeito nas views. Suponha que, em vez de uma nota, agora nosso banco de dados
registrasse três notas para cada aluno, sendo que a nota final de um aluno fosse a média dessas
três. Para os usuários que tivessem acesso ao banco baseados em um nota apenas (para
estatísticas, por exemplo) bastaria confeccionar um view sobre a tabela Inscrição que retornasse
os dados exatamente como eram antes. O impacto, para esses usuários, seria bem menor.
ATRIBUTOS DERIVADOS
A simulação de atributos derivados encaixa-se perfeitamente na concepção de views. Suponha
que quiséssemos trabalhar com dois atributos adicionais aos dados das inscrições: o número de
créditos de um disciplina e um indicador de aprovação do aluno. Somente alunos com notas
não nulas são considerados. Esses dois atributos podem ser deduzidos a partir dos demais, e a
definição da view alunos_status passaria a ser a seguinte.
select a.matricula,
a.nome,
d.disciplina,
iif ( nota>=5.0, 'Aprovado', 'Reprovado' )
as status,
chst + chsp * 0.5 as creditos
from aluno a, inscricao i, disciplina d
where a.matricula = i.matricula
and i.coddisciplina = d.coddisciplina
and nota is not null
Error! Style not defined. 275
create view alunos_status as
select a.matricula,
a.nome,
d.disciplina,
case when nota >= 5.0 then 'Aprovado'
else 'Reprovado'
end as status,
chst + chsp * 0.5 as creditos
from aluno a, inscricao i, disciplina d
where a.matricula = i.matricula
and i.coddisciplina = d.coddisciplina
and nota is not null
Com isso, consultas que usam conceitos ao invés de notas podem ser facilmente construídas. A
própria tabela Inscrição poderia ter uma view que produzisse, além dos seus atributos normais,
um atributo conceito, como mostrado abaixo.
select *,
iif (nota>=9.0, 'A', iif (nota >= 7.0, 'B', iif (nota >= 5.0, 'C', iif (nota >= 0.0, 'D', NULL))))
as conceito
from inscricao
create view inscricao_c as
select *,
case when nota >= 9.0 then 'A'
when nota >= 7.0 then 'B'
when nota >= 5.0 then 'C'
when nota >= 0.0 then 'D'
else NULL
end as conceito
from inscricao
Note que, com esta última definição, poderíamos redefinir a view alunos_e_inscricoes, de modo
a incluir o atributo conceito no seu resultado.
create view alunos_e_inscricoes as
select a.matricula,
a.nome,
d.disciplina,
i.nota,
i.conceito
from aluno a, inscricao_c i, disciplina d
where a.matricula = i.matricula
and i.coddisciplina = d.coddisciplina
Neste último exemplo, a view inscricao_c foi empregada como uma fonte de registros na
cláusula from.
13.2 INCLUINDO, REMOVENDO E ALTERANDO REGISTROS EM VIEWS
Além de serem usadas como fontes de registros em consultas, views podem, em certas
circunstâncias, ser empregadas como alvo em comandos de atualização de dados. Quando um
novo registro é inserido, ou quando um registro existente é alterado ou removido, na verdade o
SQL inclui, altera ou remove registros nas tabelas que compõem a view.
Esse e outros conceitos são melhor compreendidos com exemplos. Considere a view v_alunas,
apresentada no início deste capítulo e sua instância virtual.
create view v_alunas as
select a.matricula,
a.nome,
a.nascimento,
a.sexo
from aluno a
where a.sexo = 'F'
Matrícula Nome Nascimento Sexo
276 Views
1002 Maria Rita Colatti 10/11/1978 F
1005 Barbara Carlito 29/10/1979 F
1010 Maria Lucia Silva 10/08/1975 F
Vamos considerar o efeito das operações de alteração, remoção e inclusão de registro nesta
view.
A operação de alteração é bastante intuitiva neste caso. Um comando como
update v_alunas
set nome = 'Maria Lucia da Silva'
where matricula = 1010
requer que o nome de uma aluna seja modificado. Como a view é construída sobre a tabela
ALUNO, é preciso alterar o registro daquela tabela que dá origem ao registro virtual referenciado
na view. Ora, o problema é mapear exatamente a origem da coluna e da linha que sofrem
alteração na view. Neste caso, isso é bastante fácil, porque a coluna tem somente uma coluna de
origem e a linha sendo atualizada contém a chave primária (matrícula) do registro que a
originou.
Quanto à inserção de um novo registro, um comando como
insert into v_alunas ( matricula, nome, nascimento, sexo )
values ( 1017, 'Natalia Cavezini', #12/01/1980#, 'F' )
insert into v_alunas ( matricula, nome, nascimento, sexo )
values ( 1017, 'Natalia Cavezini', '12/01/1980', 'F' )
não apresenta problemas, porque sabe-se que o registro inserido refere-se à tabela ALUNO, que é a
base da construção da view. Note que nem sempre se pode incluir um aluno com todos seus
atributos preenchidos, pois a view v_alunas possui apenas três dos atributos originais. Para que
este comando fosse processado corretamente, seria preciso que, na definição da tabela ALUNO, o
atributo codcurso admitisse nulos, ou tivesse um valor default.
∴
A operação de remoção é intuitiva. A operação
delete v_alunas
where matricula = 1017
requer a remoção, na tabela de origem, do registro que origina o registro removido. Assim, o
efeito dessa operação sobre a view seria a remoção do registro de matrícula 1017, na tabela
ALUNO.
VIEWS ATUALIZÁVEIS
A capacidade de receber atualizações é uma característica importante para as views de um banco
de dados que depende da formulação da consulta que a define. Esta seção aborda as condições
gerais que definem essa característica.
Vamos considere a view inscricao_c, já apresentada aqui.
select
matricula,
coddisciplina,
iif (nota>=9.0,'A', iif (nota >=7,'B', iif (nota >=5,'C', iif (nota >= 0,'D',NULL)))) as conceito
from inscricao
create view inscricao_conceito as
select matricula,
coddisciplina,
case when nota >= 9.0 then 'A'
when nota >= 7.0 then 'B'
when nota >= 5.0 then 'C'
when nota >= 0.0 then 'D'
else NULL
end as conceito
from inscricao
Error! Style not defined. 277
A instância virtual dessa view corresponde ao conjunto de registros de INSCRIÇÃO, porém agora
com um atributo conceito, alfabético, ao invés da nota numérica.
matricula coddisciplina conceito
1001 112NULL
1001 317 B
1002 210 A
1005 117 D
1005 316 D
1007 112 NULL
1007 114 B
1010 316 A
1010 317 C
Considere agora o comando
update inscricao_conceito
set conceito = 'B'
where matricula = 1007
and coddisciplina = 112
que altera o conceito de determinado registro. Não é possível processar essa transação, pois não
se pode determinar a operação correspondente a ser realizada nos registros originais. Seria
preciso identificar o valor do atributo nota a ser gravado no registro atualizado da tabela
INSCRIÇÃO. Por outro lado, a operação
delete inscricao_conceito
where matricula = 1007
and coddisciplina = 112
poderia ser realizada, porque não há problemas em identificar o registro de INSCRIÇÃO que deve,
de fato, ser removido.
Pode-se dizer que há duas categorias de critérios sobre a possibilidade de atualizar uma view ou
não. A primeira categoria refere-se aos critérios construtivos que, independentemente da
instância de cada tabela, determinam se uma view pode ser atualizável. Ou seja, a partir da
análise da consulta é possível deduzir as operações que são permitidas. A segunda categoria
envolve aspectos do esquema relacional, tais como a definição dos identificadores, e envolve o
conceito de fontes de registros de chave preservada. As duas seções seguintes detalham este
tópico.
CRITÉRIOS CONSTRUTIVOS DE VIEWS ATUALIZÁVEIS
Cada implementação tem critérios ligeiramente diferentes para decidir se uma view pode ou não
ser atualizada. Como norma geral, entretanto, as seguintes restrições devem ser observadas na
construção de uma view para que a mesma seja atualizável:
Uma coluna atualizável não pode ser resultante de:
• funções de agregação, tais como sum, avg, etc.;
• funções escalares, tais como sin, trim, etc.;
• expressões aritméticas;
• expressões condicionais, tais como case, iif, etc.;
• literais;
• subconsultas.
Uma view atualizável deve conter
• pelo menos uma fonte de registros atualizável referenciada na cláusula from.
Uma view atualizável não pode conter:
• operadores algébricos, tais como union;
278 Views
• a cláusula group by;
• a cláusula distinct.
As restrições acima formam um conjunto genérico de características das views atualizáveis.
Essas regras, entretanto, devem ser analisadas à luz das operações pretendidas. Por exemplo,
uma view que tenha algumas colunas baseadas em expressões aritméticas talvez não possa ser
objeto de um comando update nesses atributos, mas pode permitir a remoção de registros. Por
este e outros motivos, a lida de cada implementação com essa questão varia bastante, e cada
caso merece uma análise cuidadosa.
FONTES DE REGISTROS DE CHAVE PRESERVADA
Um conceito importante na atualização de views é o de fonte de registro de chave preservada.
Suponha que F é uma fonte de registros numa view V, e que K seja o conjunto de atributos de F
que constituem algum identificador de F. Diz-se que F é uma fonte de registros de chave
preservada em V se os atributos componentes de K são também identificadores na instância
virtual de V. Em termos mais simples, cada registro corresponde a, no máximo, uma linha no
resultado da consulta que define a view. F tem que, necessariamente, ser uma tabela da base de
dados, com algum identificador único, ou uma view de chave preservada.
A definição, à primeira vista, parece mais complicada do que realmente é, e um exemplo mostra
isso. Suponha uma view como
create view v_alunos_e_cursos as
select a.matricula,
a.nome,
a.nascimento,
a.codcurso as a_codcurso,
c.codcurso as c_codcurso,
c.curso
from aluno a, curso c
where a.codcurso = c.codcurso
cuja instância virtual é
matricula nome nascimento sexo a_codcurso c_codcurso curso
1001 Ricardo Biondi 21/02/80 M DIR DIR Direito
1002 Maria Rita Colatti 10/11/78 F INF INF Informática
1004 Oscarito Vianna 14/08/79 M DIR DIR Direito
1005 Barbara Carlito 29/10/79 F JOR JOR Jornalismo
1007 Carlos Maradona 30/06/77 M DIR DIR Direito
1008 Sacadura Miranda 12/12/81 M INF INF Informática
1010 Maria Lucia Silva 10/08/75 F JOR JOR Jornalismo
Considere a definição acima, sendo ALUNO a fonte de registros F. Neste caso, essa tabela tem a
chave preservada na view v_alunos_e_cursos (V) porque sua chave primária (K), formada pelo
atributo matrícula aparece na view e não há dois registros na instância virtual de V que possuam
o mesmo valor para matrícula. Ou seja, matrícula é um identificador na view
v_alunos_e_cursos. Por outro lado, a tabela CURSO, que também é referenciada como uma fonte
de registros na view, não tem sua chave preservada, uma vez que a chave primária codcurso
repete-se em várias linhas.
∴
Fontes de chaves não preservadas são definidas por exclusão. Diz-se que F é uma fonte de
registros de chave não preservada em V se seus atributos identificadores não são únicos na
instância virtual de V. A mesma view v_alunos_e_cursos serve de exemplo, uma vez que a
fonte de registros CURSO, neste caso, tem registros que participam de mais de uma linha do
Error! Style not defined. 279
resultado da view e, portanto, o atributo original da coluna c_codcurso, que é um identificador
de CURSO, não pode ser considerado um identificador para a view.
∴
Em outro exemplo, temos duas fontes de registros com chaves preservadas na mesma view.
create view v_disciplinas_e_professores as
select coddisciplina,
disciplina,
d.codprofessor as d_codprofessor,
chst,
chsp,
p.codprofessor as p_codprofessor,
nome
from disciplina d, professor p
where d.codprofessor = p.codprofessor
coddisciplina disciplina d_codprofessor chst chsp p_codprofessor nome
114 Direito Civil 2 4 2 2 Olivia Straw
317 Português 3 4 0 3 Carlos Azambuja
211 Bancos de Dados 10 4 2 10 Marina Azambuja
117 Estatística 12 2 2 12 Pedro Amarante
112 Dir. Constitucional 15 4 0 15 Zenubio Siqueira
210 Compiladores 17 2 4 17 Lenira Rocha
316 Sociologia 18 3 1 18 Silvia Ferreira
As tabelas DISCIPLINA e PROFESSOR constituem fontes de chave preservada, porque não há dois
registros na instância virtual da view que tenham os mesmos valores para coddisciplina ou
codprofessor. Essa é uma ocorrência rara, porque normalmente envolve tabelas que tenham,
entre si, um relacionamento 1:1, cuja ocorrência não é comum nos bancos de dados.
∴
Se a expressão de uma view contém apenas uma fonte de registros (de chave preservada), então
essa fonte é sempre de chave preservada, como a view a seguir.
create view v_aniversarios as
select matricula,
nome,
nascimento
from aluno
∴
Um quarto exemplo pode ser extraído da view a seguir.
create view v_alunos_e_notas as
select a.matricula,
a.nome,
a.sexo,
a.codcurso,
a.nascimento,
i.nota
from aluno a, inscricao i
where a.matricula = i.matricula
matricula nome sexo codcurso nascimento nota
1001 Ricardo Biondi M DIR 21/02/80 NULL
1001 Ricardo Biondi M DIR 21/02/80 8
1002 Maria Rita Colatti F INF 10/11/78 9,5
1005 Barbara Carlito F JOR 29/10/79 4,2
1005 Barbara Carlito F JOR 29/10/79 3
1007 Carlos Maradona M DIR 30/06/77 NULL
1007 Carlos Maradona M DIR 30/06/77 7
1010 Maria Lucia Silva F JOR 10/08/75 10
280 Views
1010 Maria Lucia Silva F JOR 10/08/75 5,5
Note que cada registro do resultado da view á formado a partir de um registro diferente de
INSCRIÇÃO, e não há um registro de INSCRIÇÃO que participe da formação de mais de um registro da
instância virtual desta view. Ou seja, embora a chave não esteja presente entre as colunas da
view, para cada registro damesma corresponde um único, e distinto, registro da tabela INSCRIÇÃO.
Isso fica mais claro se imaginarmos que os atributos matrícula e coddisciplina, que formam a
chave primária de INSCRIÇÃO, constituiriam um identificador na instância virtual de
v_alunos_e_notas.
create view v_alunos_e_notas as
select a.matricula,
a.nome,
a.sexo,
a.codcurso,
a.nascimento,
i.nota,
i.matricula as i_matricula,
i.coddisciplina
from aluno a, inscricao i
where a.matricula = i.matricula
ALTERAÇÕES INCOMPATÍVEIS COM A DEFINIÇÃO DE UMA VIEW
Observe um caso paradoxal, que pode ocorrer quando da atualização de views, como no
comando a seguir.
insert into v_alunas ( matricula, nome, nascimento, sexo )
values ( 1016, 'Mario Fornari', #12/07/1979#, 'M' )
insert into v_alunas ( matricula, nome, nascimento, sexo )
values ( 1016, 'Mario Fornari', '12/07/1979', 'M' )
O aluno Mário Fornari é do sexo masculino e não deveria pertencer à instância virtual da view.
Mesmo que o atributo sexo não tivesse sido explicitado na inclusão, seu valor seria nulo (ou o
valor default), persistindo o problema, pois o critério de filtragem é estabelecido pela expressão
sexo = “F”.
O comando é paradoxal porque um comando imediatamente subsequente, para remoção do
mesmo registro, falharia, uma vez que tal registro não seria encontrado na instância virtual da
view, embora estivesse presente na base de dados. Ou seja, o comando
delete from v_alunas
where nome = 'Mario Fornari'
tem efeito nulo.
A opção with check option, na criação de um view impede que alterações não
compatíveis com sua definição sejam realizadas. Supondo que a view v_alunas
tenha sido definida como no comando
create view v_alunas as
select a.matricula,
a.nome,
a.nascimento,
a.sexo
from aluno a
where a.sexo = 'F'
with check option
o comando de inclusão para o aluno Mario Fornari teria falhado. Teria falhado também um
comando update como
update v_alunas
set sexo = 'M'
where matricula = 1010
Error! Style not defined. 281
pelos mesmos motivos. Note que mesmo que o atributo sexo aceite nulos, um comando como
update v_alunas
set sexo = NULL
where matricula = 1010
geraria erro, pois persistiria a incompatibilidade com a definição da view.
13.3 OPERAÇÕES SOBRE FONTES DE REGISTROS DE CHAVE PRESERVADA
INCLUSÃO DE REGISTROS
É sempre possível inserir registros numa fonte de registros de chave preservada, desde que
todos os atributos obrigatórios da tabela base estejam entre as colunas da view. O comando
insert into v_aniversarios ( matricula, nome )
values ( 1018, 'Breno Giordani' )
provoca a inserção de um novo registro na tabela ALUNOS, que é uma fonte de registros de chave
preservada na view v_aniversarios.
Se houver duas ou mais fontes de registros de chave preservada numa view, é possível inserir
registros em qualquer delas, dependendo das colunas escolhidas no comando de inserção.
Vamos considerar a view v_disciplinas_e_professores definida pela consulta mostrada abaixo,
juntamente com suas colunas componentes.
create view v_disciplinas_e_professores as
select d.coddisciplina,
d.disciplina,
d.codprofessor as d_codprofessor,
p.codprofessor as p_codprofessor,
p.nome
from disciplina d, professor p
where d.codprofessor = p.codprofessor
coddisciplina disciplina d_codprofessor p_codprofessor nome
Os comandos
insert into v_disciplinas_e_professores ( p_codprofessor, nome )
values ( 21, 'Sergio Duarte' )
insert into v_disciplinas_e_professores ( coddisciplina, disciplina, d_codprofessor )
values ( 401, 'Astronomia', 21 )
incluem registros nas tabelas PROFESSOR e DISCIPLINA, respectivamente, porque somente colunas
desta fonte de registros foram preenchidas. Os registros sendo inseridos devem ser diferentes
dos que já existem na tabela, ou ocorre um erro de violação de chave.
Algumas implementações aceitam inclusão de registros em mais de uma fonte num
mesmo comando insert. Um comando como
insert into v_disciplinas_e_professores ( coddisciplina, disciplina, d_codprofessor, p_codprofessor, nome )
values ( 401, 'Astronomia', 21, 21, 'Sergio Duarte' )
teria este efeito. Veja nas características de cada implementação, mais adiante neste capítulo,
como isso e tratado.
∴
Note que um comando como
insert into v_alunos_e_notas ( nota )
values ( 10 )
X
282 Views
poderia ser aceito se todos os atributos de preenchimento obrigatório pudessem ser
referenciados. No caso, o não preenchimento dos atributos matrícula e coddisciplina causaria
violação das restrições de integridade da base de exemplos.
REMOÇÃO DE REGISTROS
Comandos de remoção de registros são permitidos sobre fontes de chave preservada, desde que
haja esta única fonte de registros na consulta base da view. O comando
delete from v_aniversarios
where matricula = 1018
ocasiona a remoção do registro de matrícula 1018 da tabela ALUNO e é permitido porque esta é
uma fonte de chave preservada na view v_aniversarios, além de ser a única.
Views que possuam mais de uma fonte de registros, mesmo que sejam todas de chave
preservada, não podem ser alvo do comando delete. Assim, o comando
delete v_disciplinas_e_professores
where coddisciplina = 401
é rejeitado, porque a view v_disciplinas_e_professores têm duas fontes de registros, ambas de
chave preservada.
ALTERAÇÃO DE REGISTROS
É possível alterar colunas atualizáveis que sejam oriundas de apenas uma fonte de registros de
chave preservada. Os comandos
update v_disciplinas_e_professores
set nome = 'Sergio Duarte da Silva'
where coddisciplina = 401
update v_disciplinas_e_professores
set disciplina = 'Astronomia I'
where coddisciplina = 401
são aceitos porque alteram, cada um, colunas de uma mesma fonte de registros: a coluna nome
refere-se à tabela ALUNO e a coluna disciplina, à tabela DISCIPLINA. Note que qualquer outra coluna
da view pode ser referenciada no comando update.
Assim como no comando insert, algumas implementações permitem que registros de
diferentes tabelas de chave preservada sejam atualizados num mesmo comando update.
O comando
update v_disciplinas_e_professores
set nome = 'Sergio Duarte da Silva', disciplina = 'Astronomia I'
where coddisciplina=401
altera atributos de duas tabelas e é aceito em algumas implementações. Vide detalhes de cada
uma delas mais adiante neste capítulo.
∴
É importante observar que mais de um registro, da mesma fonte, pode ser atualizado num
mesmo comando. Considere a instância virtual da view v_alunos_e_notas, apresentada
anteriormente neste capítulo. O comando
update v_alunos_e_notas
set nota = 8.5
where matricula = 1002
é aceito e faz com que a nota 9,5, da aluna Maria Rita Collati, seja alterada para 8,5. Somente
uma nota é alterada, porque apenas um registro atende aos critérios da cláusula where.
Entretanto, se o comando fosse emitido como
update v_alunos_e_notas
set nota = 8.5
X
Error! Style not defined. 283
where matricula = 1002
haveria dois registros da tabela de origem sendo alterados, pois o aluno referido têm duas
inscrições (uma com nota 8 e outra com nota nula).
13.4 OPERAÇÕES SOBRE FONTES DE REGISTROS DE CHAVE NÃO PRESERVADA
Na view v_alunos_e_cursos a fonte de registros CURSO não preserva a chave, pois pode haver
duas ou mais linhas, na instância virtual da view, que contêm os mesmos valores para o atributo
codcurso.
create view v_alunos_e_cursos as
select a.matricula,
a.nome,
a.nascimento,
a.codcurso as a_codcurso,c.codcurso as c_codcurso,
c.curso
from aluno a, curso c
where a.codcurso = c.codcurso
INSERÇÃO
A possibilidade de inserir registros em fontes de registros de chave não preservada não está
disponível uniformemente nas implementações SQL. Algumas aceitam e outras não. Um
comando como
insert into v_alunos_e_cursos ( c_codcurso, curso )
values ( 'XXX', 'Curso XXX' )
teria o efeito de inserir um novo registro de curso. Veja mais detalhes nas seções específicas de
cada implementação, neste capítulo. Em qualquer implementação, entretanto, persiste a
restrição de que somente podem ser inseridos registros numa única fonte como conseqüência da
inserção sobre a view.
ALTERAÇÃO
Valem para o comando update as mesmas observações tecidas na seção anterior. A aceitação de
comandos como
update v_alunos_e_cursos
set nome='João' where matricula=8888
depende de cada implementação.
REMOÇÃO
A remoção de registros em views com fontes de chave não preservada é aceita em algumas
implementações SQL. Usualmente, somente views com uma única fonte de registros podem ser
objeto do comando delete. Uma fonte de registros única, entretanto, é tratada como se fosse de
chave preservada, mesmo que a tabela base não possua identificador algum.
FONTES DE REGISTROS ÚNICAS SOBRE TABELAS SEM IDENTIFICADORES
O exemplo a seguir mostra como se comportam os comandos de atualização quando uma view
possui uma única fonte de registros, construída sobre uma tabela sem identificadores. Suponha
que a seguinte seqüência de comandos seja executada.
create table teste ( a int, b int )
create view v_teste as
284 Views
select * from teste
insert into teste values ( 1, 1 )
insert into teste values ( 1, 2 )
insert into teste values ( 2, 1 )
insert into v_teste values ( 2, 2 )
update v_teste
set b= b + 1
where a=1
delete from v_teste
where a=2
Finalmente, o comando select mostra a instância da tabela TESTE após as atualizações.
select * from teste
Note que todos os comandos foram corretamente processados, mesmo que a tabela de base não possua
identificadores.
a b
1 2
1 3
13.5 IMPLEMENTAÇÃO DE VIEWS
As seções apresentam as peculiaridades mais importantes na implementação de views para os
gerenciadores tratados neste livro.
IMPLEMENTAÇÃO DE VIEWS NO ACCESS
Access não aceita a construção create view explicitamente. Entretanto, o mesmo efeito pode ser
obtido através das consultas nomeadas. Uma consulta (ou query), ao ser gravada (salva), recebe
um nome que, para todos os efeitos, pode ser utilizada exatamente como se referenciasse uma
view. Por exemplo, se a consulta
select *,
iif (nota>=9.0, 'A', iif (nota >= 7.0, 'B', iif (nota >= 5.0, 'C', iif (nota >= 0.0, 'D', NULL))))
as conceito
from inscricao
tivesse sido salva com o nome query23, seria possível fazer referência à mesma, como fonte de
registros, em outras consultas e comandos SQL.
select *
from query23
order by conceito, matricula
∴
Não há distinção entre fontes de registros de chave preservada ou não. Todas as operações
aceitas no primeiro tipo são também aceitas no segundo.
∴
Views atualizáveis devem ser expressas na sintaxe de junção explícita. Por exemplo, a consulta
select d.coddisciplina,
d.disciplina,
d.codprofessor as d_codprofessor,
p.codprofessor as p_codprofessor,
p.nome
from disciplina d, professor p
where d.codprofessor = p.codprofessor
não é atualizável. Porém, uma construção equivalente, com junções explícitas, como
select d.coddisciplina,
d.disciplina,
d.codprofessor as d_codprofessor,
Error! Style not defined. 285
p.codprofessor as p_codprofessor,
p.nome
from disciplina d inner join professor p on d.codprofessor=p.codprofessor
é atualizável.
∴
Access permite que comandos insert e update gerem inclusões e atualizações em registros de
mais de uma fonte de dados. Assim, os comandos
insert into v_disciplinas_e_professores ( coddisciplina, disciplina, d_codprofessor, p_codprofessor, nome )
values ( 401, 'Astronomia', 21, 21, 'Sergio Duarte' )
update v_disciplinas_e_professores
set nome = 'Sergio Duarte da Silva', disciplina = 'Astronomia I'
where coddisciplina = 401
que haviam sido comentados anteriormente, são aceitos. O primeiro, inclui um registro na
tabela DISCIPLINA e outro na tabela PROFESSOR. Para o comando delete permanece a restrição de que
haja apenas uma fonte de registros na view.
∴
Access – Quadro resumo para atualização de views
Operações
Propriedades
Inserção Remoção Alteração
Chave preservada � Permite inserção de
registros em mais de uma
fonte num mesmo comando
insert
� Somente quando há
apenas uma fonte de
registros
� Permite alteração de
colunas em mais de uma
fonte num mesmo comando
update
Chave não preservada idem idem idem
IMPLEMENTAÇÃO DE VIEWS NO ORACLE
NÃO dexiar de falr sobre
A coluna search_condition aplica-se comente a constraints do tipo check. OS tipos de
constraints seguem a seguinte convenção: C – check constraints; P – primary key; U –
unique; R – chave estrangeira; V – opção with check, para views; O – opção read only,
para views.3
Mencionadas no capítulo 11.
A sintaxe básica para a criação de views no Oracle segue o padrão mostrado abaixo.
<comando create view> :=
create [ or replace ] [ [ no ] force] view [ <esquema> .] <nome>
[ ( { <nome de coluna> [ <constraint de atributo>... ]
|
<constraint geral>
},... )
] as <comando select> [ <cláusula de restrição> ]
<cláusula de restrição> :=
{ with read only
|
check option [ constraint <nome da constraint> ]
3 Veja mais detalhes no capítulo 13.
286 Views
}
∴
A opção or replace permite que uma view seja criada com o mesmo nome de uma view anterior,
sem que seja preciso removê-la. Isso é útil porque não é preciso reeditar os comandos que
estabelecem permissões sobre a view (veja capítulo 15).
No Oracle, uma view pode ser criada com erros, através da opção force, embora não possa ser
utilizada assim. Isto é útil quando é necessário codificar elementos que referencia objetos ainda
não completamente especificados. Tabelas ou colunas inexistentes são exemplos de erros que
são sobrepujados dessa maneira. Embora seja o default, no force pode ser especificado
explicitamente.
∴
Falar sobre materialized views.
∴
Falar sobre object views.
∴
Algumas restrições aplicam-se ao comando select que define uma view no Oracle, a saber:
• A cláusula sample não pode ser utilizada (vide capítulo 4);
• Se a lista alvo contém * (asterisco), as colunas existentes nas fontes de registros
correspondentes são expandidas no momento da criação da view, e assim permanecem.
Eventuais mudanças na lista de atributos dessas fontes de registros não são incorporadas à
view, a menos que a mesma seja recriada;
• Pseudocolunas devem ser utilizadas com critério na lista alvo do comando select: curval e
nextval não podem aparecer, e rowdim, rownum e level, se utilizadas, devem
obrigatoriamente ser renomeadas.
∴
A opção with check option, na criação de uma view, tem o efeito de:
• impedir inserção de registros;
• impedir a atualização de valores em colunas utilizadas nas junções das fontes de registros;
• impedir, para tabelas que se repetem numa view, tanto a remoção de registros, mesmo
quando a fonte de registros é de chave preservada, quanto a atualização de suas colunas.
Num exemplo concreto dos dois primeiros itens acima, a view v_disciplinas_e_professores,definida como
create view v_disciplinas_e_professores as
select d.coddisciplina,
d.disciplina,
d.codprofessor as d_codprofessor,
p.codprofessor as p_codprofessor,
p.nome
from disciplina d, professor p
where d.codprofessor = p.codprofessor
with read only
não permitiria comandos como
insert into v_disciplinas_e_professores ( p_codprofessor, nome )
values ( 21, 'Sergio Duarte' )
e
update v_disciplinas_e_professores
set d_codprofessor = 21
where disciplina = 'Direito Civil'
Para um exemplo sobre o terceiro item, considere a seguinte definição de view
create view v_alunos_e_alunos as
select a1.matricula as m1, a1.nome as nome1, a2.matricula as m2, a2.nome as nome2
from aluno a1, aluno a2
where a1.matricula = a2.matricula
with check option
Error! Style not defined. 287
Embora as duas fontes de registros preservem suas chaves, o fato de haver uma tabela repetida
entre elas faz com que alterações, em qualquer coluna, não sejam permitidas.
∴
A opção with read only impede qualquer tipo de alteração através da view, mesmo que todos os
critérios para isso sejam atendidos. Por exemplo, a view v_disciplinas_e_professores, definida
como
create view v_disciplinas_e_professores as
select d.coddisciplina,
d.disciplina,
d.codprofessor as d_codprofessor,
p.codprofessor as p_codprofessor,
p.nome
from disciplina d, professor p
where d.codprofessor=p.codprofessor
with read only
não permite os comandos insert e update.
∴
Oracle – Quadro resumo para atualização de views
Operações
Propriedades
Inserção Remoção Alteração
Chave preservada � Permite inserção de
registros em qualquer fonte
de registros de chave
preservada, porém cada
comando insere numa
única tabela
� Somente quando há
apenas uma fonte de
registros
� Permite alteração de
registros em qualquer fonte
de registros de chave
preservada, porém cada
comando altera uma única
tabela
Chave não preservada � Não aceita inserção de
registros
� Não aceita remoção de
registros
� Não aceita alteração de
registros
IMPLEMENTAÇÃO DE VIEWS NO SQL SERVER
A sintaxe
create view <nome> [ ( <nome de coluna>,... ) ]
[ with encryption ]
as <comando select> [ with check option ]
permite estabelecer nomes alternativos para as colunas da view, determinar a codificação do
texto que contém a descrição da view e da cláusula with check option, que estabelece que todas
as alterações de dados devem estar em conformidade com a definição da view. Ou seja,
registros que não apareceriam na instância virtual da view não podem ser inseridos através dela
com esta opção.
∴
SQL Server não permite as cláusulas top e order by na consulta que define uma view.
∴
Fontes de registro de chave preservada podem ser atualizadas pelos comandos insert e update.
Quanto ao comando delete, persiste a restrição de não haver mais de uma fonte de registros.
∴
A stored procedure sp_depends é bastante útil quando se pretende conhecer todas as views que
dependem de uma determinada tabela. Por exemplo, o comando
exec sp_depends ( 'aluno' )
288 Views
produz a lista de objetos que referenciam a tabela Aluno. No nosso caso, pelo menos as views aqui
definidas seriam listadas.
∴
SQL Server – Quadro resumo para atualização de views
Operações
Propriedades
Inserção Remoção Alteração
Chave preservada � Permite inserção de
registros em qualquer fonte
de registros de chave
preservada, porém cada
comando insere numa
única tabela
� Somente quando há
apenas uma fonte de
registros
� Permite alteração de
colunas em mais de uma
fonte num mesmo comando
update
Chave não preservada � Permite inserção de
registros em qualquer fonte
de registros de chave
preservada, porém cada
comando insere numa
única tabela
� Somente quando há
apenas uma fonte de
registros
� Permite alteração de
colunas em mais de uma
fonte num mesmo comando
update
REVER ESTA TABELA!!!!!!???
EXERCÍCIOS
13.1 Qual o efeito do comando
delete inscricao.*
from ( aluno a inner join curso c on a.codcurso = c.codcurso )
left join inscricao on a.matricula = inscricao.matricula
where nota is null
and c.curso = 'Direito'
13.2 Remover a pior nota de um aluno...
13.3 Considere que a tabela
Turma (Matrícula, CodDisciplina, CodTurma)
passe a fazer parte da base de exemplos, com a seguinte instância.
matricula coddisciplina turma
1001 112 A
1001 317 B
1002 210 C
1005 117 D
1005 316 E
1007 112 A
1007 114 F
1010 317 B
1010 316 E
Indique ...
select a.*, i.nota, t.turma
from ( aluno a inner join inscricao i on a.matricula = i.matricula )
inner join turma t on t.matricula = i.matricula and t.coddisciplina = i.coddisciplina
matricula nome sexo codcurso nascimento nota turma
1001 Ricardo Biondi M DIR 21/02/80 NULL A
1001 Ricardo Biondi M DIR 21/02/80 8 B
1002 Maria Rita Colatti F INF 10/11/78 9,5 C
1005 Barbara Carlito F JOR 29/10/79 4,2 D
Error! Style not defined. 289
1005 Barbara Carlito F JOR 29/10/79 3 E
1007 Carlos Maradona M DIR 30/06/77 NULL A
1007 Carlos Maradona M DIR 30/06/77 7 F
1010 Maria Lucia Silva F JOR 10/08/75 5,5 B
1010 Maria Lucia Silva F JOR 10/08/75 10 E