NVL vs NVL2 vs COALESCE no Oracle SQL: Qual Usar e Quando?
Você está escrevendo queries SQL e se depara com valores NULL que precisam ser tratados. Aí vem a dúvida: uso NVL, NVL2 ou COALESCE? Se você já se perguntou isso, saiba que não está sozinho.
Neste artigo, vou te mostrar a diferença prática entre essas três funções, quando usar cada uma e como evitar aqueles erros chatos que aparecem quando não tratamos NULL corretamente.
🤔 Por Que Tratar NULL é Importante?
Valores NULL podem causar problemas sérios nas suas consultas:
- Cálculos errados - qualquer operação matemática com NULL resulta em NULL
- Comparações que não funcionam - NULL = NULL retorna FALSE (ou melhor, UNKNOWN)
- Relatórios com dados faltantes - campos em branco que deveriam mostrar algo
- Queries lentas - falta de índices em colunas com muitos NULLs
Tratar NULL corretamente deixa suas queries mais confiáveis, legíveis e profissionais.
📌 Entendendo Cada Função
🔵 NVL (Null Value)
A função mais simples e direta. Se o valor for NULL, substitui por um padrão.
Sintaxe:
NVL(coluna, valor_substituto)Como funciona:
- Se
colunafor NULL → retornavalor_substituto - Se
colunaNÃO for NULL → retorna o valor dacoluna
Exemplo prático:
SELECT
nome,
NVL(telefone, 'Sem telefone') AS contato
FROM clientes;Resultado:
NOME CONTATO
---------- --------------
João Silva (11) 98765-4321
Maria Santos Sem telefone
Pedro Costa (21) 99999-8888Quando usar NVL:
- Substituir NULL por valor padrão simples
- Garantir que um campo sempre tenha valor
- Fazer cálculos sem risco de NULL quebrar a conta
Exemplo em cálculo:
SELECT
produto,
preco,
NVL(desconto, 0) AS desconto,
preco - NVL(desconto, 0) AS preco_final
FROM produtos;Sem o NVL(desconto, 0), se desconto for NULL, o preco_final também seria NULL!
🟢 NVL2 (Null Value 2)
A versão mais poderosa do NVL. Permite definir dois comportamentos diferentes: um se o valor existir, outro se for NULL.
Sintaxe:
NVL2(coluna, valor_se_nao_null, valor_se_null)Como funciona:
- Se
colunaNÃO for NULL → retornavalor_se_nao_null - Se
colunafor NULL → retornavalor_se_null
Exemplo prático:
SELECT
funcionario,
NVL2(email, 'Contato: ' || email, 'Email não cadastrado') AS status
FROM usuarios;Resultado:
FUNCIONARIO STATUS
----------- ---------------------------
Ana Lima Contato: ana@empresa.com
Carlos Souza Email não cadastrado
Julia Mendes Contato: julia@empresa.comQuando usar NVL2:
- Ações diferentes dependendo se o valor existe ou não
- Criar mensagens contextuais
- Fazer cálculos condicionais baseados em NULL
Exemplo em cálculo de comissão:
SELECT
vendedor,
salario,
NVL2(comissao,
salario + comissao, -- Se TEM comissão
salario -- Se NÃO TEM comissão
) AS salario_total
FROM vendedores;🟡 COALESCE
A função mais flexível das três. Retorna o primeiro valor não-NULL de uma lista.
Sintaxe:
COALESCE(valor1, valor2, valor3, valor4, ...)Como funciona:
- Percorre os valores da esquerda para a direita
- Retorna o primeiro que NÃO for NULL
- Se todos forem NULL, retorna NULL
Exemplo prático:
SELECT
nome,
COALESCE(celular, telefone_fixo, telefone_comercial, 'Sem contato') AS contato
FROM clientes;Resultado:
NOME CONTATO
----------- ------------------
João Silva (11) 98765-4321 <- usou celular
Maria Santos (11) 3456-7890 <- usou fixo (celular era NULL)
Pedro Costa (21) 3333-4444 <- usou comercial (celular e fixo NULL)
Ana Oliveira Sem contato <- todos NULLQuando usar COALESCE:
- Procurar o primeiro valor válido entre várias colunas
- Estabelecer hierarquia de prioridade de dados
- Consolidar informações fragmentadas
Exemplo real - preço de produto:
SELECT
produto,
COALESCE(
preco_promocional, -- 1ª opção: preço em promoção
preco_vip, -- 2ª opção: preço para VIP
preco_normal, -- 3ª opção: preço normal
preco_custo * 1.5, -- 4ª opção: custo + margem
0 -- última opção: zero
) AS preco_venda
FROM produtos;📊 Comparação Lado a Lado
| Característica | NVL | NVL2 | COALESCE |
|---|---|---|---|
| Número de parâmetros | 2 | 3 | 2 ou mais |
| Lógica | NULL → substituto | NULL ou não-NULL | Primeiro não-NULL |
| Complexidade | Simples | Média | Flexível |
| Padrão SQL | ❌ Oracle only | ❌ Oracle only | ✅ SQL Standard |
| Melhor para | Valor padrão simples | Ação condicional | Múltiplas opções |
💡 Exemplos Práticos do Dia a Dia
Exemplo 1: Sistema de Contatos
-- NVL: Garantir que sempre mostre algo
SELECT
nome,
NVL(empresa, 'Autônomo') AS empresa
FROM contatos;
-- NVL2: Formatar diferente se tiver empresa ou não
SELECT
nome,
NVL2(empresa, nome || ' - ' || empresa, nome || ' (Pessoa Física)') AS identificacao
FROM contatos;
-- COALESCE: Buscar qualquer contato disponível
SELECT
nome,
COALESCE(whatsapp, telegram, email, 'Sem contato digital') AS contato_digital
FROM contatos;Exemplo 2: E-commerce - Endereço de Entrega
SELECT
pedido_id,
cliente,
-- Tenta endereço de entrega, se NULL usa endereço de cobrança
COALESCE(
endereco_entrega,
endereco_cobranca,
endereco_cadastro,
'Endereço não informado'
) AS endereco_final
FROM pedidos;Exemplo 3: Relatório Financeiro
SELECT
mes,
-- Mostra meta ou "Sem meta" se NULL
NVL(TO_CHAR(meta_vendas, 'L999,999.99'), 'Sem meta') AS meta,
-- Status diferente se bateu a meta
NVL2(meta_batida, 'Meta atingida ✓', 'Abaixo da meta') AS status,
-- Busca o primeiro bônus disponível
COALESCE(bonus_performance, bonus_padrao, 0) AS bonus_final
FROM vendas_mensais;🚀 Dicas Avançadas
Dica 1: NVL com Subqueries
SELECT
departamento,
NVL(
(SELECT AVG(salario) FROM funcionarios f WHERE f.dept_id = d.id),
0
) AS salario_medio
FROM departamentos d;Dica 2: COALESCE com Cálculos
SELECT
produto,
quantidade,
-- Tenta 3 formas diferentes de calcular o peso total
COALESCE(
peso_total, -- Se já tem calculado, usa
peso_unitario * quantidade, -- Senão, calcula
peso_estimado -- Última opção: estimativa
) AS peso_final
FROM estoque;Dica 3: Combinando Funções
SELECT
cliente,
-- Primeiro tenta encontrar telefone, depois formata
NVL2(
COALESCE(celular, telefone_fixo), -- Primeiro acha um telefone
'Tel: ' || COALESCE(celular, telefone_fixo), -- Se achou, formata
'Sem telefone' -- Se não achou nada
) AS contato_formatado
FROM clientes;⚠️ Erros Comuns e Como Evitar
Erro 1: Tipos de Dados Incompatíveis
-- ❌ ERRADO: número com texto
SELECT NVL(idade, 'Não informada') FROM pessoas;
-- ORA-01722: invalid number
-- ✅ CORRETO: converter para o mesmo tipo
SELECT NVL(TO_CHAR(idade), 'Não informada') FROM pessoas;Erro 2: Esquecer de Tratar NULL em Cálculos
-- ❌ ERRADO: Se desconto for NULL, total fica NULL
SELECT
preco - desconto AS total
FROM produtos;
-- ✅ CORRETO
SELECT
preco - NVL(desconto, 0) AS total
FROM produtos;Erro 3: Usar NVL Quando Deveria Usar COALESCE
-- ❌ RUIM: Vários NVL aninhados
SELECT
NVL(celular, NVL(fixo, NVL(comercial, 'Sem telefone')))
FROM clientes;
-- ✅ MELHOR: COALESCE é mais limpo
SELECT
COALESCE(celular, fixo, comercial, 'Sem telefone')
FROM clientes;🎯 Qual Usar? Guia Rápido de Decisão
Use NVL quando:
- Precisa substituir NULL por um valor padrão simples
- Está fazendo cálculos matemáticos
- Quer garantir que um campo sempre tenha valor
Use NVL2 quando:
- Precisa de ações diferentes para NULL vs não-NULL
- Quer criar mensagens contextuais
- Está formatando output baseado na existência do dado
Use COALESCE quando:
- Tem múltiplas colunas que podem ter o valor
- Quer estabelecer prioridade/hierarquia de dados
- Precisa de portabilidade (funciona em outros bancos)
- Tem mais de 2 opções de valores
💼 Quer Dominar SQL Profissionalmente?
Se você quer se tornar expert em SQL e destacar-se no mercado de trabalho, conheça nosso Curso Completo de SQL para Analistas e Desenvolvedores:
- ✅ Desde o básico até queries complexas avançadas
- ✅ Funções SQL que 90% dos profissionais não conhecem
- ✅ Otimização de performance e índices
- ✅ Projetos práticos com bancos reais
- ✅ Certificado reconhecido pelo mercado
- ✅ Suporte vitalício com DBAs experientes
Mais de 4.200 alunos já se capacitaram e conquistaram vagas como Analista de Dados, DBA e Desenvolvedor Backend!
📝 Exercícios Práticos
Teste seu conhecimento! Tente resolver estes exercícios:
Exercício 1:
-- Qual função usar para mostrar "Inativo" se data_fim for NULL e "Ativo" se tiver data?
SELECT
contrato_id,
-- SUA RESPOSTA AQUI
FROM contratos;Exercício 2:
-- Como buscar o primeiro email válido entre email_pessoal, email_trabalho e email_alternativo?
SELECT
nome,
-- SUA RESPOSTA AQUI
FROM usuarios;Exercício 3:
-- Como calcular desconto sendo que desconto_vip pode ser NULL?
SELECT
produto,
preco,
-- SUA RESPOSTA AQUI AS preco_final
FROM produtos;Respostas no final do artigo! 👇
🔚 Conclusão
Agora você sabe a diferença entre NVL, NVL2 e COALESCE e quando usar cada uma. Essas funções parecem simples, mas dominá-las faz toda a diferença na qualidade das suas queries.
Resumindo:
- NVL = substituição simples de NULL
- NVL2 = comportamento condicional baseado em NULL
- COALESCE = primeiro valor válido de uma lista
Lembre-se: sempre trate seus NULLs! Queries sem tratamento de NULL são fonte de bugs silenciosos que aparecem só em produção.
Gostou do conteúdo? Compartilhe com seus colegas desenvolvedores e DBAs! E se ficou com dúvidas sobre alguma função, deixe nos comentários que vou te ajudar. 🚀
Qual dessas funções você mais usa no dia a dia? Tem algum truque com COALESCE que queira compartilhar? Conta aqui embaixo!
📚 Artigos Relacionados
✅ Respostas dos Exercícios
Exercício 1:
SELECT
contrato_id,
NVL2(data_fim, 'Ativo', 'Inativo') AS status
FROM contratos;Exercício 2:
SELECT
nome,
COALESCE(email_pessoal, email_trabalho, email_alternativo, 'Sem email') AS email
FROM usuarios;Exercício 3:
SELECT
produto,
preco,
preco - NVL(desconto_vip, 0) AS preco_final
FROM produtos;