Adriano Júnior
← Artigos

SQL Server

Localizando erros de conversão no SQL Server com TRY_CAST

Por que CAST no WHERE falha em tabela inteira antes do filtro — e como usar TRY_CAST para achar só as linhas que não convertem, entendendo a ordem lógica de processamento da query.

Quando lidamos com banco de dados é comum esbarrar na mensagem “Conversion failed when converting…”. Isso aparece em situações em que o valor de origem não pode ser convertido para o tipo de destino.

Conversões válidas (quando o literal bate com o tipo):

SELECT HorarioFormatado = CAST('13:30' AS time);

SELECT DataFormatada = CAST('2024-02-28' AS date);

Essas sentenças são válidas porque os valores respeitam o formato esperado. Já exemplos que quebram:

SELECT HorarioFormatado = CAST('32:00' AS time);

SELECT DataFormatada = CAST('33' AS date);

Elas retornam erro do tipo: “Conversion failed when converting date and/or time from character string.”

Fácil de identificar e de resolver na mão, certo? Nem sempre.

Imagine uma consulta em uma tabela com dez mil registros: você precisa tratar a coluna como time para comparar com um intervalo, por exemplo:

SELECT *
FROM Horarios
WHERE CAST(Horario AS time) BETWEEN CAST('13:40' AS time) AND CAST('15:30' AS time);

Aqui o CAST é necessário porque comparar varchar com BETWEEN em horário não é o mesmo que comparar tipos time de forma confiável — você quer o domínio time.

Só que, se em alguma linha o valor for inválido (ex.: '32:00'), a query inteira pode falhar com o mesmo erro de conversão — mesmo que o seu intervalo de busca seja só entre 13:40 e 15:30. Por quê?

SQL Server: ordem lógica de processamento

Entra em cena a ordem lógica de processamento da query: em linhas gerais, é a ordem em que o motor conceitualmente avalia as cláusulas (FROM, WHERE, GROUP BY, etc.).

No caso acima, o CAST está no WHERE. O ponto importante: a conversão é aplicada no contexto do predicado antes de você “enxergar” só as linhas que passariam no filtro final — ou seja, o motor precisa avaliar a expressão de conversão para as linhas candidatas, e ao encontrar um valor que não converte, a query aborta com erro antes de te entregar um resultado parcial.

Por isso o erro aparece mesmo quando “matematicamente” você só queria o intervalo das 13:40 às 15:30: ainda existe uma linha com lixo na coluna que explode na etapa de avaliação da expressão.

Vale a leitura da documentação oficial do SELECT (Transact-SQL) para aprofundar em logical processing order e no comportamento das cláusulas.

Como achar as linhas problemáticas com TRY_CAST

TRY_CAST tenta converter o valor; se não der, retorna NULL em vez de erro.

Para localizar o que não converte, use isso de propósito no WHERE:

SELECT *
FROM Horarios
WHERE TRY_CAST(Horario AS time) IS NULL
  AND Horario IS NOT NULL;  -- opcional: ignorar NULL “legítimo” da coluna

Assim você lista só os registros em que a conversão para time falharia se fosse um CAST “duro”.

Pense numa tabela Horarios com mistura de valores válidos e inválidos em Horario (varchar):

IdHorario
113:30
232:00
308:15

A consulta com TRY_CAST(...) IS NULL deve trazer a linha do 32:00 (e qualquer outro valor estranho), para você corrigir dado na origem, ajustar ETL ou tratar com regra de negócio — sem derrubar a query que usa CAST no intervalo.

Depois de limpar (ou isolar) os problemáticos, a busca com CAST(Horario AS time) BETWEEN ... volta a ser segura do ponto de vista de conversão.

Considerações

TRY_CAST não serve só para esse diagnóstico: vale estudar os demais cenários na documentação do TRY_CAST.

O objetivo aqui foi ser didático: além de um filtro para achar “lixo”, entender por que o erro aparece mesmo com um WHERE que parece restritivo — e por que a ordem lógica de avaliação importa tanto no dia a dia com SQL Server.