Questão de Banco de Dados — Consultas e Comandos em SQL — CESPE / CEBRASPE 2024
- Código
- ce403620
- Banca
- CESPE / CEBRASPE
- Órgão
- MPO
- Ano
- 2024
- Cargo
- APO ( )
- CCerto
- EErrado
GabaritoC — Certo
Gabarito: Certo. O comando DELETE FROM pedidos WHERE NOT EXISTS (SELECT vendedor FROM vendedores WHERE codigo_vendedor = pedido.codigo_vendedor) apaga, de fato, todos os registros de pedidos cujo codigo_vendedor não encontra correspondência na tabela vendedores — ou seja, os pedidos de vendedores-fantasmas. A lógica está correta: a subconsulta correlacionada verifica, para cada pedido, se existe um vendedor com aquele código; o NOT EXISTS seleciona apenas os pedidos para os quais essa verificação retorna vazio.
O comando DELETE é a instrução da DML (Data Manipulation Language) usada para remover registros de uma tabela. Sua sintaxe básica é DELETE FROM nome_da_tabela WHERE condição;. A cláusula WHERE é opcional, mas, sem ela, todos os registros da tabela seriam apagados. No comando em análise, a condição é definida por uma subconsulta que usa o operador NOT EXISTS.
O operador EXISTS (e sua negação NOT EXISTS) é usado para testar a existência de registros em uma subconsulta. Ele retorna verdadeiro se a subconsulta retornar pelo menos uma linha, e falso caso contrário. Quando a subconsulta é correlacionada, ela faz referência a uma coluna da consulta externa (no caso, pedido.codigo_vendedor), o que significa que a subconsulta é avaliada para cada linha da tabela pedidos. Para cada pedido, o banco executa a subconsulta: se ela retornar alguma linha (ou seja, se existir um vendedor com aquele código), o EXISTS é verdadeiro; se não retornar nenhuma linha (não existe vendedor com aquele código), o EXISTS é falso. O NOT EXISTS inverte esse resultado: a condição do WHERE será verdadeira apenas quando a subconsulta não retornar nenhuma linha.
Vamos aplicar isso ao cenário da questão. A tabela pedidos tem uma coluna codigo_vendedor que referencia o vendedor que realizou o pedido. A tabela vendedores tem uma coluna codigo_vendedor que é a chave primária (ou pelo menos um identificador único). O comando percorre cada pedido e pergunta: "existe um vendedor na tabela vendedores cujo codigo_vendedor seja igual ao codigo_vendedor deste pedido?" Se a resposta for não (não existe), o NOT EXISTS é verdadeiro e o pedido é apagado. Se a resposta for sim (existe), o NOT EXISTS é falso e o pedido é mantido. Portanto, apenas os pedidos de vendedores que não estão cadastrados na tabela vendedores (os "vendedores-fantasmas") são removidos.
Um ponto importante é a sintaxe da subconsulta. No comando apresentado, a subconsulta é SELECT vendedor FROM vendedores WHERE codigo_vendedor = pedido.codigo_vendedor. A coluna vendedor selecionada não é usada diretamente; o que importa é se a subconsulta retorna alguma linha. Por isso, seria mais comum e eficiente usar SELECT 1 ou SELECT *, mas a sintaxe com SELECT vendedor também é válida, desde que a coluna vendedor exista na tabela vendedores. O que não pode haver é um erro de referência: a coluna pedido.codigo_vendedor precisa estar qualificada com o nome da tabela (ou um alias) para evitar ambiguidade, e é exatamente isso que o comando faz.
A pegadinha que a banca poderia explorar seria trocar NOT EXISTS por EXISTS, o que apagaria os pedidos de vendedores que existem na tabela vendedores, ou seja, o oposto do que se deseja. Outra pegadinha seria usar NOT IN com uma subconsulta que retorna valores nulos, o que poderia gerar resultados inesperados. Mas, no comando dado, a lógica está correta e atende exatamente ao objetivo de apagar os pedidos de vendedores-fantasmas.
A banca poderia ter trocado NOT EXISTS por EXISTS, o que inverteria completamente o resultado: em vez de apagar os pedidos de vendedores-fantasmas, apagaria os pedidos de vendedores cadastrados. Fique atento a essa inversão clássica. Outra armadilha seria usar NOT IN (SELECT codigo_vendedor FROM vendedores), que, embora pareça equivalente, pode falhar se a subconsulta retornar valores nulos, pois NULL não é comparável com = e o NOT IN não retornaria nenhuma linha. O NOT EXISTS é mais seguro nesse aspecto.
Critério | NOT EXISTS (comando da questão) | NOT IN (alternativa comum) |
|---|---|---|
Comportamento com valores NULL | Seguro: ignora NULLs corretamente, pois testa apenas a existência de linhas. | Inseguro: se a subconsulta retornar qualquer NULL, o resultado final é vazio (nenhuma linha deletada). |
Resultado esperado | Apaga apenas pedidos de vendedores-fantasmas (sem correspondência). | Pode falhar silenciosamente, não apagando nada, se houver NULL na coluna |
Uso típico recomendado | Preferível para subconsultas correlacionadas e quando a coluna pode conter NULLs. | Evitado quando há possibilidade de NULLs na subconsulta. |
Sintaxe no contexto |
|
|
O comando está correto. A subconsulta correlacionada com NOT EXISTS identifica corretamente os pedidos cujo codigo_vendedor não existe na tabela vendedores, e o DELETE remove exatamente esses registros. A lógica da operação "caça-fantasma" é implementada de forma válida.
Gabarito: Certo.
Link permanente: /questoes/ce403620