CAST, CONVERT, TRY_CAST y TRY_CONVERT: controlar tipos de datos

SQL Server puede convertir algunos valores de forma implícita, es decir, sin que la consulta solicite la conversión de manera expresa. Confiar en ello puede ocultar errores, alterar comparaciones o impedir que un índice —una estructura que organiza valores para facilitar el acceso a filas— se utilice con eficiencia.

Las funciones de conversión hacen explícito el tipo esperado. Sus variantes TRY devuelven NULL cuando un valor compatible en principio no puede convertirse.

La idea

CAST: expresar una conversión con sintaxis estándar

CAST(Expresion AS TipoDeDato)

CONVERT: convertir con sintaxis y estilos de SQL Server

CONVERT(TipoDeDato, Expresion, Estilo)

TRY_CAST: devolver NULL cuando la conversión falla

TRY_CAST(Expresion AS TipoDeDato)

TRY_CONVERT: convertir con estilo sin interrumpir por un valor inválido

TRY_CONVERT(TipoDeDato, Expresion, Estilo)

Ejemplo: controlar un cálculo decimal

SELECT
    pd.IdPedido,
    pd.NumeroPartida,
    CAST(
        pd.Cantidad * pd.PrecioUnitario
        * (1 - pd.Descuento / 100.0)
        AS DECIMAL(12, 2)
    ) AS Importe
FROM dbo.PedidoDetalle AS pd;

La conversión establece la precisión —la cantidad total de dígitos— y la escala —los dígitos posteriores al separador decimal— que esperamos mostrar o almacenar.

Formatear una fecha para intercambio

SELECT
    p.IdPedido,
    CONVERT(CHAR(10), p.FechaPedido, 23) AS FechaISO
FROM dbo.Pedido AS p;

El estilo 23 produce aaaa-mm-dd. Para ordenar, comparar y calcular conviene conservar la columna como fecha; la conversión a texto debería ocurrir solo cuando necesitamos presentar o intercambiar el valor.

Detectar valores que no pueden convertirse

SELECT
    d.ValorOriginal,
    TRY_CONVERT(DECIMAL(12, 2), d.ValorOriginal) AS ValorConvertido
FROM
(
    VALUES
        ('349.00'),
        ('1,250.50'),
        ('sin dato')
) AS d (ValorOriginal);

Los valores que no siguen el formato esperado producen NULL en lugar de detener toda la consulta. Esto nos permite localizarlos antes de modificar una columna:

WHERE TRY_CONVERT(DECIMAL(12, 2), ValorOriginal) IS NULL
  AND ValorOriginal IS NOT NULL;

La cadena con separador de miles puede depender del formato y no debe asumirse válida sin una regla de origen clara.

Conversión fallida y conversión no permitida

Las funciones TRY no convierten cualquier tipo a cualquier otro. Si SQL Server considera que la conversión está explícitamente prohibida, todavía puede devolver un error. Su utilidad principal está en valores de texto con calidad variable.

Qué conviene comprobar

Debemos revisar longitud, precisión, escala y posibilidad de truncamiento. El truncamiento ocurre cuando un destino no puede conservar todo el valor. Convertir un decimal a entero pierde la fracción; convertir texto a una longitud menor puede recortarlo o fallar según la operación.

En filtros y uniones, es preferible convertir el parámetro o el valor externo al tipo de la columna, no aplicar una función a cada fila de la columna. Además de ser más claro, esto puede permitir un mejor acceso mediante índices.

Relacionado con