Você está na página 1de 8

Prova de Fundamentos de Bancos de Dados

2a Prova Prof. Carlos A. Heuser Novembro de 2008 Prova com consulta a livros, apostilas e anotaes

1 Base de dados para as questes


(Esta a mesma base de dados que foi usada na primeira prova) Considere a seguinte base de dados, usada por um banco de dados de informaes sobre genealogia de pessoas. Todas colunas, exceto as chaves primrias so opcionais. /* tabela de localidades */ localidade (codigo_local, nome_local); /* tabela com dados das pessoas codigo_uniao_pais identica a unio que gerou a pessoa */ pessoa (cod_pessoa, sexo, nome, sobrenome, data_de_nascimento, codigo_local_nasc, data_de_falecimento, codigo_local_falec, codigo_uniao_pais); (codigo_uniao_pais) references uniao (codigo_uniao); (codigo_local_nasc) references localidade (codigo_local); (codigo_local_falec) references localidade (codigo_local); /* tabela com as unies entre pessoas */ uniao (codigo_uniao, codigo_local, cod_pessoa_esposa, cod_pessoa_marido, data_uniao); (cod_pessoa_esposa) references pessoa (cod_pessoa); (codigo_local) references localidade (codigo_local); (cod_pessoa_marido) references pessoa (cod_pessoa)

2 Questes
Todas questes tm o mesmo peso. 1. Expresse a consulta abaixo, usando clculo relacional. Obter os nomes das localidades, nas quais ocorreu ao menos uma unio, mas no ocorreu nenhum falecimento. {r | l localidade ( r.nome_local=l.nome_local u uniao ( u.codigo_local=l.codigo_local ) p pessoa ( p.codigo_local_falec=l.cod_local_falec ) ) }

2. Expresse a consulta abaixo em SQL. Para cada pessoa na base de dados, obter seu cdigo e seu nome, seguidos do nome de seu pai. Caso o nome do pai no esteja na base de dados, este deve aparecer vazio. SELECT filho.cod_pessoa, filho.nome, pai.nome FROM ( (pessoa AS filho LEFT JOIN uniao AS uniao_pai ON (filho.cod_uniao_pais= uniao_pai.codigo_uniao) ) LEFT JOIN pessoa AS pai ON (uniao_pai.cod_pessoa_marido= pai.cod_pessoa) )

3. Expresse a consulta abaixo em SQL. Sabe-se que, por um erro de programao, na base de dados, foram includas unies que de fato nunca existiram. A caracterstica comum de cada uma destas unies ter como lhos, todas pessoas nascidas em 1900-01-01. Obter o cdigo de cada unio que tem como lhos todas pessoas nascidas em 190001-01. Soluo: Em clculo relacional, esta consulta seria resolvida com o quanticador universal. Como no temos o mesmo em SQL, a consulta foi resolvida pela negao do quanticador existencial. SELECT codigo_uniao FROM uniao WHERE NOT EXISTS (SELECT * FROM pessoa WHERE data_nasc=1900-01-01 AND codigo_uniao_pais<>codigo_uniao ) Como cada pessoa somente pode ser lha de uma unio, a soluo mais simples obter uma unio qualquer em que a pessoa tenha nascido em 1900-01-01: SELECT codigo_uniao_pais FROM pessoa WHERE data_nasc=1900-01-01

4. Expresse a consulta abaixo em SQL. Obter uma tabela com quatro colunas: a) o cdigo e o nome de cada localidade, b) o cdigo e o nome de cada pessoa, que tenha nascido nesta localidade na data 1932-11-30. Tambm localidades nas quais ningum nasceu devem constar do resultado. Neste caso, o cdigo e o nome da pessoa devem aparecer vazios. SELECT localidade.codigo_local, localidade.nome_local, pessoa.codigo_pess, pessoa.nome FROM localidade LEFT JOIN pessoa ON (localidade.codigo_local =pessoa.codigo_local_nasc AND pessoa.data_nasc=1932-11-30 ) A soluo abaixo est incorreta, j que a clusula WHERE anula o efeito da juno externa. SELECT localidade.codigo_local, localidade.nome_local, pessoa.codigo_pess, pessoa.nome FROM localidade LEFT JOIN pessoa ON (localidade.codigo_local =pessoa.codigo_local_nasc ) WHERE pessoa.data_nasc=1932-11-30

5. Expresse a consulta abaixo em SQL. Para cada localidade na qual nasceram ao menos trs pessoas, obter o cdigo e nome da localidade, seguidos do nmero de pessoas que nela nasceram. SELECT localidade.codigo_local, nome_local, COUNT(*) FROM localidade JOIN pessoa ON localidade.codigo_local =pessoa.codigo_local_nasc GROUP BY localidade.codigo_local, nome_local HAVING COUNT(*)>=3

6. Expresse a consulta abaixo em SQL. Obter o nmero de localidades, nas quais tenha nascido pelo menos uma pessoa. SELECT count (distinct codigo_local_nasc) FROM pessoa

7. Deseja-se que a base de dados garanta a seguinte restrio de integridade: Para cada unio, deve valer que, caso exista uma data da unio informada, esta data deve ser maior que a data de nascimento da pessoa que marido na unio (isto caso o marido seja informado, e caso ele tenha data de nascimento informada). Esta restrio pode ser implementada por um CHECK CONSTRAINT? Caso armativo, mostre o CHECK CONSTRAINT, que implementa esta restrio de integridade. Caso negativo, explique porque no possvel implementar a restrio atravs de um CHECK CONSTRAINT e indique como esta restrio pode ser implementada por triggers. Basta dizer para quais eventos (incluso, excluso, alterao), de que tabelas, devem ser denidos triggers, bem como informar, em Portugus, que erro o trigger deve detectar. No necessrio mostrar o cdigo SQL do trigger. Ao denir os triggers, lembrar que todas colunas, exceto as chaves primrias podem ser vazias. Soluo: A restrio envolve vrias linhas e por isso no pode ser implementada por CHECK CONSTRAINT requerendo implementao de um TRIGGER. Devem ser denidos os seguintes triggers: Incluso e alterao de pessoa: se tiver data de nascimento e for marido de casamento, garantir que a data de nascimento seja menor que a da unio. Incluso e alterao de unio: se a data da unio e o cdigo do marido forem informados e se o marido tiver data de nascimento informada, garantir que que a data de nascimento seja menor que a da unio.