Questão de Banco de Dados — PL/SQL e Outras Extensões SQL — FCC 2025
Banco de Dados›PL/SQL e Outras Extensões SQL
Código
fc150346
Banca
FCC
Órgão
TRT 1
Ano
2025
Cargo
AJ TRT1
Considere o seguinte trecho de código em PL/SQL: SELECT nome, FLOOR(MONTHS_BETWEEN(SYSDATE, data_admissao) / 12) AS anos_servico, MOD(MONTHS_BETWEEN(SYSDATE, data_admissao), 12) AS meses_servico FROM funcionarios WHERE status = 'Ativo'; Ao ser executado em condições ideais, este comando
Aerra ao calcular o tempo de serviço, pois deveria ter sido usado EXTRACT (YEAR FROM SYSDATE) - EXTRACT (YEAR FROM data_admissao), uma vez que EXTRACT já retorna a diferença correta de anos e meses.
Berra ao calcular o tempo de serviço, pois deveria ter sido usado DATEDIFF(YEAR, data_admissao, SYSDATE), que retorna diretamente os anos completos.
Ccalcula o tempo de serviço dos funcionários ativos somando diretamente os meses obtidos pela função MONTHS_BETWEEN, sem necessidade de divisão ou modulação.
Dcalcula o tempo de serviço dos funcionários ativos, obtendo a diferença total de meses entre a data atual SYSDATE e data_admissao, convertendo os valores em anos e meses utilizando FLOOR e MOD.
Eerra ao calcular o tempo de serviço, pois deveria ter sido utilizado apenas ROUND(MONTHS_BETWEEN(SYSDATE, data_admissao) / 12), pois não há necessidade de calcular separadamente os anos e meses.
Revelar gabarito e comentário▾
GabaritoD — calcula o tempo de serviço dos funcionários ativos, obtendo a diferença total de meses entre a data atual SYSDATE e data_admissao, convertendo os valores em anos e meses utilizando FLOOR e MOD.
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”.
PL/SQL: cálculo de tempo de serviço com MONTHS_BETWEEN, FLOOR e MOD
Gabarito: letra D. O comando calcula corretamente o tempo de serviço dos funcionários ativos: MONTHS_BETWEEN(SYSDATE, data_admissao) retorna a diferença total em meses (com fração), FLOOR(... / 12) extrai os anos completos e MOD(..., 12) extrai os meses restantes — uma decomposição aritmética clássica e correta em PL/SQL (Oracle).
A questão testa o domínio de funções de data do Oracle, especificamente MONTHS_BETWEEN, FLOOR e MOD. Vamos entender cada uma:
MONTHS_BETWEEN(data1, data2): retorna o número de meses entre duas datas, podendo ser um número fracionário (ex.: 25,5 meses). É a função mais precisa para diferenças em meses no Oracle.
FLOOR(n): retorna o maior inteiro menor ou igual a n (arredonda para baixo). Ex.: FLOOR(2,9) = 2.
MOD(a, b): retorna o resto da divisão inteira de a por b. Ex.: MOD(25, 12) = 1.
No comando, a lógica é:
MONTHS_BETWEEN(SYSDATE, data_admissao) → total de meses decorridos (ex.: 25,5).
MOD(total, 12) → meses restantes (ex.: MOD(25,5, 12) = 1,5 — mas como o resultado de MONTHS_BETWEEN pode ter fração, o MOD retorna a fração também; em condições ideais, com datas de admissão em dias inteiros, o resultado é o esperado).
Essa é a forma canônica de decompor uma diferença em meses em anos e meses no Oracle. As alternativas incorretas propõem funções de outros bancos (DATEDIFF é do SQL Server/MySQL) ou abordagens equivocadas (EXTRACT extrai componentes de uma data, não calcula diferenças; ROUND arredondaria, perdendo a precisão de anos completos).
A pegadinha da banca é justamente confundir funções de bancos diferentes: DATEDIFF não existe no Oracle (existe MONTHS_BETWEEN), e EXTRACT não calcula diferença entre datas — extrai um campo (ano, mês, dia) de uma data específica. O candidato que conhece SQL de outros SGBDs pode cair nessas armadilhas.
1MONTHS_BETWEEN → total em meses
2FLOOR(total/12) → anos completos
3MOD(total,12) → meses restantes
LEVEL · soulevel.com.br
Alternativa A — ❌ Incorreta
Afirma que deveria ser usado EXTRACT(YEAR FROM SYSDATE) - EXTRACT(YEAR FROM data_admissao). Isso está errado porque EXTRACT extrai um componente de uma data (ano, mês, dia), mas não calcula diferença entre datas — a subtração de anos extraídos ignora meses e dias, dando resultado impreciso (ex.: de 15/12/2020 a 10/01/2025 daria 5 anos, mas o correto são 4 anos completos). Além disso, o comando original está correto, então não há erro a corrigir.
Alternativa B — ❌ Incorreta
Sugere DATEDIFF(YEAR, data_admissao, SYSDATE). DATEDIFF é função do SQL Server/MySQL, não existe no Oracle (que usa MONTHS_BETWEEN). Mesmo que existisse, DATEDIFF(YEAR, ...) retornaria a diferença de anos sem considerar meses, o que não daria os meses restantes. O comando original não precisa dessa substituição.
Alternativa C — ❌ Incorreta
Diz que o comando soma diretamente os meses de MONTHS_BETWEEN sem divisão ou modulação. Isso é falso: o comando faz a divisão por 12 e o MOD para separar anos e meses. A alternativa descreve um comportamento que não ocorre no código apresentado.
Alternativa D — ✅ Correta ⟵ GABARITO
Descreve exatamente o que o comando faz: MONTHS_BETWEEN calcula a diferença total em meses; FLOOR(.../12) converte em anos completos; MOD(...,12) obtém os meses restantes. É a descrição fiel da lógica do código.
Alternativa E — ❌ Incorreta
Propõe usar apenas ROUND(MONTHS_BETWEEN(...)/12). ROUND arredonda para o inteiro mais próximo, o que perderia os meses restantes (ex.: 25,5 meses → ROUND(2,125) = 2 anos, sem informar os 1,5 meses). Além disso, o comando original já calcula anos e meses separadamente, então não há erro a corrigir.