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