Resumo e Exercícios
Resumo
Neste capítulo, expandimos o repertório SQL para além das consultas básicas. Os principais recursos abordados foram:
| Recurso | Finalidade |
|---|---|
NATURAL JOIN |
Une relações pelos atributos de mesmo nome (risco de homônimos não relacionados) |
INNER JOIN ON / JOIN USING |
Junção explícita e segura por predicado ou coluna nomeada |
LEFT / RIGHT / FULL OUTER JOIN |
Preserva tuplas sem correspondência com NULL nos atributos ausentes |
CREATE VIEW |
Define uma relação virtual a partir de uma expressão de consulta |
CREATE MATERIALIZED VIEW |
Visão com resultado fisicamente armazenado; requer REFRESH manual |
REFRESH MATERIALIZED VIEW |
Atualiza o conteúdo de uma visão materializada |
BEGIN / COMMIT / ROLLBACK |
Delimita e controla transações (atomicidade) |
SAVEPOINT |
Permite desfazer apenas parte de uma transação |
NOT NULL |
Impede valores nulos em um atributo |
UNIQUE |
Garante unicidade de valores (admite NULL) |
CHECK (P) |
Valida que toda tupla satisfaz o predicado P |
FOREIGN KEY REFERENCES |
Garante integridade referencial entre tabelas |
ON DELETE CASCADE |
Propaga exclusão em cascata para as tabelas filhas |
ON DELETE SET NULL |
Define como NULL as FKs dos registros filhos ao excluir o pai |
DATE, TIME, TIMESTAMP, INTERVAL |
Tipos temporais do SQL |
BYTEA / TEXT |
Tipos de objetos grandes (binário e texto) no PostgreSQL |
CREATE TYPE |
Define um novo tipo de dado |
CREATE DOMAIN |
Define um tipo com constraints embutidas (reutilizável) |
CREATE INDEX |
Cria estrutura de acesso rápido a valores de um atributo |
GRANT |
Concede privilégios a usuários ou papéis |
REVOKE |
Revoga privilégios concedidos |
CREATE ROLE |
Cria um papel (agrupamento de privilégios) |
WITH GRANT OPTION |
Permite que o destinatário repasse o privilégio a outros |
Exercícios
Os exercícios abaixo usam as tabelas do banco de dados da UnDF: centro, escola, curso, professor, aluno, disciplina, ministra, prereq e matricula_disciplina.
Exercício 1. Liste os nomes de todos os alunos junto com o nome de seu curso e da escola responsável, usando JOIN explícito (não use natural join). Ordene pelo nome da escola, depois pelo nome do curso.
Encadeie três JOIN: aluno → curso → escola. Use USING (id_curso) e USING (id_escola).
Exercício 2. Liste todos os professores e, para cada um, a quantidade de turmas que ministraram (zero se nunca ministraram). Ordene do mais ativo ao menos ativo.
Use LEFT JOIN entre professor e ministra e agrupe com GROUP BY e COUNT(id_disciplina) (que retorna 0 quando não há registros em ministra).
Exercício 3. Crie uma visão chamada v_turmas_completas que mostre o nome da disciplina, o nome do professor, o ano, o semestre e a turma de cada oferta. Use essa visão para listar todas as turmas do ano 2025.
A visão une ministra, disciplina e professor. Depois consulte a visão com WHERE ano = 2025.
Exercício 4. Explique por que o seguinte natural join pode produzir resultados inesperados, e reescreva a consulta de forma correta:
SELECT d.nome_disciplina, m.ano, m.semestre
FROM disciplina d
NATURAL JOIN ministra m;Identifique quais colunas disciplina e ministra têm em comum. Além de id_disciplina, ambas possuem semestre — mas com significados diferentes (semestre curricular vs. semestre de oferta). Use JOIN ... USING (id_disciplina) para corrigir.
Exercício 5. Escreva o comando DDL para adicionar uma restrição CHECK na tabela aluno garantindo que ano_ingresso seja maior ou igual a 2020. Escreva também o comando para remover essa restrição depois.
Use ALTER TABLE aluno ADD CONSTRAINT chk_ano_ingresso CHECK (ano_ingresso >= 2020). Para remover: ALTER TABLE aluno DROP CONSTRAINT chk_ano_ingresso.
Exercício 6. Crie um papel (ROLE) chamado monitor_disciplina com permissão de leitura nas tabelas disciplina, ministra, matricula_disciplina e prereq, e permissão de atualização apenas na coluna nota de matricula_disciplina. Escreva os comandos SQL necessários.
Use CREATE ROLE monitor_disciplina, depois GRANT SELECT ON ... TO monitor_disciplina e GRANT UPDATE (nota) ON matricula_disciplina TO monitor_disciplina.
Exercício 7. Sem executar, explique o que acontece quando uma turma é excluída da tabela ministra, supondo que matricula_disciplina tenha ON DELETE CASCADE na foreign key que referencia ministra. Qual seria o comportamento se a ação fosse ON DELETE SET NULL?
Com CASCADE: todas as matrículas daquela turma são excluídas automaticamente. Com SET NULL: os campos da FK em matricula_disciplina receberiam NULL — mas isso exigiria que as colunas da FK admitissem NULL, o que conflita com a chave primária de matricula_disciplina (onde essas colunas fazem parte da PK e portanto são NOT NULL).