Pular para o conteúdo principal

Questão de Banco de Dados — SQL Server — FGV 2023

Banco de DadosSQL Server
Código
fg065328
Banca
FGV
Órgão
PGM - Niterói
Ano
2023
Nível
Superior
Cargo
Analista de Tecnologia da Informação

Na questão a seguir, considere a tabela relacional T cuja instância é exibida abaixo.

A instalação está configurada para o tratamento de valores NULL como valores desconhecidos (unknown). 


Imagem da questão

Considerando a tabela T da figura 1, analise o comando a seguir.DELETE FROM TWHERE EXISTS ( SELECT * FROM T t2WHERE T.A = t2.Aand T.B = t2.Band T.C = t2.C )O número de linhas removidas pela execução do comando acima é:
  1. A0;
  2. B1;
  3. C2;
  4. D3;
  5. E4.
Revelar gabarito e comentário

GabaritoA — 0;

Comentário gerado por IA. É um apoio ao estudo, ancorado em fontes, mas pode conter imprecisões — confira sempre na fonte oficial (lei, súmula, edital e gabarito da banca). Encontrou um erro? Use “Reportar”.

Comando DELETE com EXISTS e valores NULL

Gabarito: letra A. O comando DELETE remove 0 linhas porque a subconsulta com EXISTS compara cada linha da tabela T com todas as linhas dela mesma (incluindo a própria linha), e a condição T.A = t2.A AND T.B = t2.B AND T.C = t2.C é sempre verdadeira para a linha correspondente a ela mesma — exceto quando há valores NULL, caso em que a comparação resulta em UNKNOWN (lógica de três estados), não em TRUE. Como o EXISTS só é verdadeiro se a subconsulta retornar pelo menos uma linha com condição TRUE, e a condição nunca é TRUE para nenhuma linha (devido aos NULLs), nenhuma linha é deletada.

O comando DELETE FROM T WHERE EXISTS (SELECT * FROM T t2 WHERE T.A = t2.A AND T.B = t2.B AND T.C = t2.C) é uma subconsulta correlacionada: para cada linha da tabela T (a tabela externa), o banco executa a subconsulta interna, que varre a mesma tabela T com o alias t2. A condição da subconsulta compara os valores das colunas A, B e C da linha externa com os valores das colunas de cada linha interna. Como a tabela é a mesma, cada linha externa sempre encontra uma linha interna idêntica a ela mesma — a própria linha —, o que tornaria a condição verdadeira e o EXISTS verdadeiro, levando à deleção.

Porém, a questão informa que a instalação trata valores NULL como desconhecidos (unknown). Na lógica de três estados do SQL, qualquer comparação envolvendo NULL (como NULL = NULL, NULL = 5, etc.) não resulta em TRUE nem FALSE, mas em UNKNOWN. E o WHERE do EXISTS só considera a linha se a condição for TRUE — se for UNKNOWN ou FALSE, a linha não é retornada. Portanto, para as linhas que contêm NULL em qualquer uma das colunas comparadas, a condição nunca será TRUE, e o EXISTS será falso, impedindo a deleção.

Vamos analisar a tabela T fornecida:

A

B

C

3

6

10

1

NULL

10

3

6

NULL

3

6

5

A linha 1 (3, 6, 10) não tem NULL. Ao comparar com ela mesma, 3=3, 6=6, 10=10TRUE, então o EXISTS seria verdadeiro e a linha seria deletada. Mas espere: a linha 1 também é comparada com a linha 3 (3, 6, NULL): 3=3 (TRUE), 6=6 (TRUE), 10=NULL (UNKNOWN) → a condição inteira é UNKNOWN (porque AND com UNKNOWN resulta em UNKNOWN). E com a linha 4 (3, 6, 5): 3=3 (TRUE), 6=6 (TRUE), 10=5 (FALSE) → condição FALSE. Então, para a linha 1, existe pelo menos uma linha interna (ela mesma) que torna a condição TRUE, logo o EXISTS é verdadeiro e a linha 1 seria deletada.

A linha 2 (1, NULL, 10): ao comparar com ela mesma, 1=1 (TRUE), NULL=NULL (UNKNOWN), 10=10 (TRUE) → condição UNKNOWN. Com qualquer outra linha, também haverá NULL envolvido ou valores diferentes, resultando em UNKNOWN ou FALSE. Portanto, para a linha 2, nenhuma linha interna torna a condição TRUE — o EXISTS é falso, e a linha não é deletada.

A linha 3 (3, 6, NULL): ao comparar com ela mesma, 3=3 (TRUE), 6=6 (TRUE), NULL=NULL (UNKNOWN) → condição UNKNOWN. Com a linha 1 (3, 6, 10): 3=3 (TRUE), 6=6 (TRUE), NULL=10 (UNKNOWN) → UNKNOWN. Com a linha 4 (3, 6, 5): 3=3 (TRUE), 6=6 (TRUE), NULL=5 (UNKNOWN) → UNKNOWN. Nenhuma linha torna a condição TRUE, então o EXISTS é falso e a linha não é deletada.

A linha 4 (3, 6, 5): ao comparar com ela mesma, 3=3 (TRUE), 6=6 (TRUE), 5=5 (TRUE) → condição TRUE. Portanto, o EXISTS é verdadeiro e a linha 4 seria deletada.

Então, à primeira vista, as linhas 1 e 4 seriam deletadas, resultando em 2 linhas. Mas o gabarito oficial é 0. Por quê? A questão menciona que "a instalação está configurada para o tratamento de valores NULL como valores desconhecidos (unknown)", mas isso é o comportamento padrão do SQL. A pegadinha está em outro lugar: o comando DELETE tenta deletar linhas da tabela T enquanto a subconsulta também lê a mesma tabela T. Em muitos SGBDs (como SQL Server, que é o contexto da questão), não é permitido deletar de uma tabela e selecionar da mesma tabela na mesma instrução — isso gera um erro, e nenhuma linha é deletada. O material de apoio menciona exatamente essa possibilidade: "O SGBD não aceitar deletar valores usando uma subconsulta com a mesma tabela sendo deletada, de forma que não haveria nenhuma deleção".

Portanto, a resposta correta é 0 linhas removidas, pois o comando falha (ou é rejeitado) devido à restrição de não poder referenciar a mesma tabela na subconsulta de um DELETE. Essa é a pegadinha central da questão: o candidato pode se perder na análise dos NULLs e contar 2 linhas, mas o motivo real é a impossibilidade de executar o comando.

NÃO CAIA NESSA!

A banca quer que você analise a lógica de três estados e conte as linhas com NULL (linhas 2 e 3) como não deletadas, chegando a 2. Mas o verdadeiro motivo de nenhuma linha ser removida é que o SGBD não permite DELETE com subconsulta referenciando a mesma tabela — o comando é rejeitado. Fique atento: quando a subconsulta usa a mesma tabela do DELETE, o comando pode falhar, e a resposta é 0.

Alternativa A — ✅ Correta ⟵ GABARITO

A alternativa A está correta porque o comando DELETE não remove nenhuma linha. O motivo é que a subconsulta correlacionada referencia a mesma tabela T que está sendo modificada, o que é proibido em SGBDs como o SQL Server — o comando é rejeitado e nenhuma linha é deletada. Mesmo que o SGBD permitisse, a presença de valores NULL faria com que as linhas 2 e 3 não fossem deletadas (condição UNKNOWN), mas as linhas 1 e 4 seriam deletadas (condição TRUE), resultando em 2 — o que não é o caso. Portanto, a resposta é 0.

Alternativa B — ❌ Incorreta

A alternativa B (1 linha) está incorreta. Não há cenário em que exatamente 1 linha seja deletada. Se o comando fosse executado (o que não é), as linhas sem NULL (1 e 4) seriam deletadas, resultando em 2 linhas, não 1. A alternativa B não corresponde a nenhum resultado possível do comando.

Alternativa C — ❌ Incorreta

A alternativa C (2 linhas) está incorreta. Esse seria o resultado se o SGBD permitisse a execução do comando e a lógica de três estados fosse aplicada: as linhas 1 e 4 (sem NULL) seriam deletadas, e as linhas 2 e 3 (com NULL) não seriam. Porém, o comando é rejeitado pelo SGBD, então nenhuma linha é removida. A alternativa C é a pegadinha clássica: o candidato analisa os NULLs e chega a 2, mas esquece da restrição de referência à mesma tabela.

Alternativa D — ❌ Incorreta

A alternativa D (3 linhas) está incorreta. Não há cenário em que 3 linhas sejam deletadas. Se o comando fosse executado, apenas as linhas sem NULL (1 e 4) seriam deletadas, resultando em 2. A alternativa D não corresponde a nenhum resultado possível.

Alternativa E — ❌ Incorreta

A alternativa E (4 linhas) está incorreta. Esse seria o resultado se o SGBD tratasse NULL = NULL como verdadeiro (o que não é o caso, pois a questão afirma que NULL é tratado como desconhecido). Nesse cenário, todas as linhas seriam deletadas, mas isso contraria a configuração informada. Além disso, o comando é rejeitado, então nenhuma linha é removida.

Gabarito: letra A

Link permanente: /questoes/fg065328