Questão de Banco de Dados — PL/SQL e Outras Extensões SQL — FGV 2024
- Código
- fg165185
- Banca
- FGV
- Órgão
- Pref BH
- Ano
- 2024
- Cargo
- ACI ( )
- AO resultado é: 24.
- BO resultado é: 37.
- CO resultado é: 75.
- DO resultado é: 166.
GabaritoD — O resultado é: 166.
Gabarito: letra D — o resultado impresso é 166. A questão testa a execução de dois loops aninhados com comandos EXIT WHEN em PL/SQL do Oracle, exigindo o rastreamento manual das variáveis i, j e s a cada iteração. O ponto central é entender a ordem de execução: o EXIT inner_loop é avaliado antes do EXIT outer_loop, e o EXIT outer_loop só é verificado após o término do loop interno.
O código declara três variáveis do tipo PLS_INTEGER (um tipo inteiro de alto desempenho do Oracle): s (acumulador), i (contador do loop externo) e j (contador do loop interno). O loop externo é rotulado como outer_loop e o interno como inner_loop. A cada iteração do loop externo, i é incrementado e j é reiniciado para 0. No loop interno, j é incrementado, s recebe s + i * j, e então dois EXIT são verificados em sequência.
Vamos rastrear a execução passo a passo. O loop externo começa com i = 0 e j = 0. Na primeira iteração do loop externo, i vira 1 e j é zerado. O loop interno então executa com i = 1:
j = 1, s = 0 + 1*1 = 1. EXIT inner_loop WHEN (j > 5) → falso (1 > 5 é falso). EXIT outer_loop WHEN ((i*j) > 15) → falso (1*1 = 1 > 15 é falso).
j = 2, s = 1 + 1*2 = 3. EXIT inner_loop → falso. EXIT outer_loop → falso (2 > 15).
j = 3, s = 3 + 1*3 = 6. EXIT inner_loop → falso. EXIT outer_loop → falso (3 > 15).
j = 4, s = 6 + 1*4 = 10. EXIT inner_loop → falso. EXIT outer_loop → falso (4 > 15).
j = 5, s = 10 + 1*5 = 15. EXIT inner_loop → falso (5 > 5 é falso). EXIT outer_loop → falso (5 > 15).
j = 6, s = 15 + 1*6 = 21. EXIT inner_loop → verdadeiro (6 > 5). O loop interno termina.
Após o loop interno, o loop externo continua. i vira 2, j é zerado. O loop interno executa com i = 2:
j = 1, s = 21 + 2*1 = 23. EXIT inner_loop → falso. EXIT outer_loop → falso (2*1 = 2 > 15).
j = 2, s = 23 + 2*2 = 27. EXIT inner_loop → falso. EXIT outer_loop → falso (4 > 15).
j = 3, s = 27 + 2*3 = 33. EXIT inner_loop → falso. EXIT outer_loop → falso (6 > 15).
j = 4, s = 33 + 2*4 = 41. EXIT inner_loop → falso. EXIT outer_loop → falso (8 > 15).
j = 5, s = 41 + 2*5 = 51. EXIT inner_loop → falso (5 > 5). EXIT outer_loop → falso (10 > 15).
j = 6, s = 51 + 2*6 = 63. EXIT inner_loop → verdadeiro (6 > 5). Loop interno termina.
O loop externo continua. i vira 3, j é zerado. Loop interno com i = 3:
j = 1, s = 63 + 3*1 = 66. EXIT inner_loop → falso. EXIT outer_loop → falso (3 > 15).
j = 2, s = 66 + 3*2 = 72. EXIT inner_loop → falso. EXIT outer_loop → falso (6 > 15).
j = 3, s = 72 + 3*3 = 81. EXIT inner_loop → falso. EXIT outer_loop → falso (9 > 15).
j = 4, s = 81 + 3*4 = 93. EXIT inner_loop → falso. EXIT outer_loop → falso (12 > 15).
j = 5, s = 93 + 3*5 = 108. EXIT inner_loop → falso (5 > 5). EXIT outer_loop → falso (15 > 15 é falso).
j = 6, s = 108 + 3*6 = 126. EXIT inner_loop → verdadeiro (6 > 5). Loop interno termina.
O loop externo continua. i vira 4, j é zerado. Loop interno com i = 4:
j = 1, s = 126 + 4*1 = 130. EXIT inner_loop → falso. EXIT outer_loop → falso (4 > 15).
j = 2, s = 130 + 4*2 = 138. EXIT inner_loop → falso. EXIT outer_loop → falso (8 > 15).
j = 3, s = 138 + 4*3 = 150. EXIT inner_loop → falso. EXIT outer_loop → falso (12 > 15).
j = 4, s = 150 + 4*4 = 166. EXIT inner_loop → falso. EXIT outer_loop → verdadeiro (16 > 15). O loop externo termina imediatamente.
Portanto, o valor final de s é 166, e o comando DBMS_OUTPUT.PUT_LINE imprime "O resultado é: 166".
A pegadinha central está na ordem de avaliação dos EXIT. O EXIT inner_loop é verificado primeiro; somente se a condição for falsa é que o EXIT outer_loop é avaliado. Além disso, a condição do EXIT outer_loop usa (i * j) > 15, que depende do valor atual de j dentro do loop interno. Muitos candidatos calculam apenas as somas até j = 5 e ignoram a iteração extra que ocorre quando j chega a 6, ou erram ao considerar que o EXIT outer_loop é verificado antes do EXIT inner_loop.
O valor 24 seria obtido se o loop interno executasse apenas uma vez para cada valor de i (por exemplo, se j fosse sempre 1), o que não ocorre. O código executa o loop interno até j ultrapassar 5, acumulando múltiplas somas. O valor 24 não corresponde a nenhuma soma parcial relevante do rastreamento.
O valor 37 seria o resultado se o loop externo terminasse prematuramente, por exemplo, se a condição (i * j) > 15 fosse verificada antes do incremento de j ou se o loop interno executasse apenas até j = 2 para i = 1 e i = 2. No entanto, o código executa o loop interno até j = 6 para cada i, acumulando muito mais. O valor 37 não corresponde a nenhuma soma parcial do rastreamento correto.
O valor 75 seria obtido se o loop externo terminasse quando i = 3 e j = 5, sem executar a iteração extra com j = 6. No rastreamento, ao final de i = 3 e j = 5, s vale 108, não 75. O valor 75 não corresponde a nenhuma soma parcial relevante.
O valor 166 é exatamente o resultado do rastreamento completo. O loop externo executa para i = 1, 2, 3, 4, e o loop interno executa para j = 1 até j = 6 (pois o EXIT inner_loop só sai quando j > 5). A soma acumulada é 166, e o EXIT outer_loop é acionado quando i = 4 e j = 4, pois 4 * 4 = 16 > 15. O comando DBMS_OUTPUT.PUT_LINE imprime "O resultado é: 166".
A banca explora a ordem de avaliação dos EXIT. O EXIT inner_loop é avaliado primeiro; o EXIT outer_loop só é verificado se a condição do primeiro for falsa. Além disso, o loop interno executa até j = 6 (quando j > 5), e não até j = 5. Muitos candidatos param em j = 5 e esquecem a iteração extra, ou invertem a ordem dos EXIT, obtendo valores como 75 ou 37. Com treino, você enxerga essas armadilhas de longe 💪.
Para resolver questões de loops aninhados, monte uma tabela de rastreamento com colunas para i, j, s e as condições dos EXIT. Execute cada iteração na ordem exata do código, verificando as condições após cada incremento. Isso evita erros de contagem e garante o resultado correto.
Gabarito: letra D
Link permanente: /questoes/fg165185