Saltar al contenido

La conversión de un tipo de datos varchar a un tipo de datos de fecha y hora resultó en un valor fuera de rango

Si encuentras algo que no comprendes puedes comentarlo y te ayudaremos lo mas rápido que podamos.

Solución:

Revisé tu perfil y vi que estás en el Reino Unido. Si su servidor sql está configurado para usar el formato de fecha dmy, eso explica su problema. Sin usar la ‘T’ en lugar del espacio en la fecha y hora stringSql Server no lo reconocerá como formato ISO8601.

Prueba esto:

select count(*) 
  from dbo.profile 
  where [created] between convert(datetime,'2014-11-01T00:00:00.000') 
                      and convert(datetime,'2014-11-30T23:59:59.997');

Consultar usando fechas y/o fechas y horas puede ser complicado, para asegurarse de que está obteniendo lo que está buscando, le recomiendo leer:

  • Los malos hábitos de Aaron Bertrand para patear: mal manejo de consultas de fecha/rango
  • Banco de trabajo de FECHA/HORA del servidor SQL de Robyn Page

editar: para aclarar el valor fuera de rango en su mensaje de error sería interpretar el mes como 30 y el día como 11.

No entiendo por qué los datos se convierten de varchar a fecha y hora cuando ‘Creado’ está configurado en fecha y hora

Los literales que está proporcionando para la comparación con el Created columna son cadenas. Para comparar esos literales con los datetime columna, SQL Server intenta convertir las cadenas a datetime tipos, de acuerdo con las reglas de precedencia de tipos de datos. Sin información explícita sobre el formato de las cadenas, SQL Server sigue sus intrincadas reglas para interpretar cadenas como fechas y horas.

Desde mi punto de vista, la forma más ordenada de evitar este tipo de problemas es ser explícito acerca de los tipos. SQL Server proporciona la CAST and CONVERT funciones para este fin. Al trabajar con cadenas y tipos de fecha/hora, CONVERT es preferible porque proporciona un parámetro de estilo para definir explícitamente el string formato.

La pregunta utiliza cadenas en formato canónico ODBC (con milisegundos) (estilo 121). Ser explícito sobre el tipo de datos y string estilo da como resultado lo siguiente:

SELECT COUNT(*)
FROM dbo.profile 
WHERE [Created] BETWEEN 
    CONVERT(datetime, '2014-11-01 00:00:00.000', 121)
    AND 
    CONVERT(datetime, '2014-11-30 23:59:59.997', 121);

Dicho esto, hay buenas razones (como señala Aaron en su respuesta) para usar un rango semiabierto en lugar de BETWEEN (Utilizo el estilo 120 a continuación solo por variedad):

SELECT COUNT(*)
FROM dbo.profile 
WHERE
    [Created] >= CONVERT(datetime, '2014-11-01 00:00:00', 120)
    AND [Created] < CONVERT(datetime, '2014-12-01 00:00:00', 120);

Ser explícito con los tipos es un muy buen hábito, especialmente cuando se trata de fechas y horas.

Ya que BETWEEN es muy problemático debido al redondeo de diferentes tipos de fecha/hora y otros problemas, y dado que YYYY-MM-DD no es un formato seguro sin la incomodidad Tuna gama abierta que utiliza la norma ISO fechas completas sin separadores es un enfoque mucho mejor:

WHERE Created >= '20141101' AND Created < '20141201';

valoraciones y comentarios

Si tienes algún reparo o forma de aumentar nuestro post eres capaz de ejecutar una reseña y con gusto lo leeremos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *