Mostrando entradas con la etiqueta Formato fechas. Mostrar todas las entradas
Mostrando entradas con la etiqueta Formato fechas. Mostrar todas las entradas

Manejando fechas de la manera correcta en SQL Server

Creo que siempre existe un bache en el tema del manejo de fechas en SQL Server, de modo que voy a tratar de clarificar algunos puntos en este artículo.

Existen dos tipos de datos para almacenar fecha en SQL Server, Datetime y SmallDatetime.

La diferencia entre ambas es el espacio que ocupan y la precisión de cada tipo de datos. Datetime es el tipo de datos mas preciso.

El punto es saber como es que SQL Server almacena internamente las fechas. Algunos pensarán en los formatos comunes mm/dd/yyyy o dd/mm/yyyy o formatos similares. Pero no es así.
SQL Server en realidad almacena las fechas como un número entero de 8 bytes, con los primeros 4 bytes almacenados fecha y los otros 4 bytes almacenado la hora. El Smalldatetime por su parte ocupa la mitad de esto, 4 bytes totales, 2 para fecha y 2 para la hora.

Ahora bien, como gente astuta que sois me preguntareis porque motivois (me pintó el hispánico) los selects traen la fecha en un formato dado (americano/español, japonés, coreano, papuense, etc)????
Ese formato me genera un problema al momento de filtrar por fechas, porque 3/1/2008 podría en realidad resultar el 1 de marzo del 2008 y no el 3 de enero del 2008. Me explico hasta aquí??

Como hago entonces para librarme de las configuraciones regionales, seteos, formatos y ser libre de todas estas cosas y despreocuparme por siempre y que mis consultas filtradas por fechas funcionen siempre??

Alguno de ustedes dirá que quizás usando el Standard ANSI y yo le contesto SI ! Esa es la respuesta !. El estandar ansi es así:
YYYYMMDD HH:mm:ss’
Ese es el formato que yo tendría que usar para mis consultas.
Veamos el caso ejemplificado con Northwind la cual viene con SQL Server 2000 o pueden bajarlo directamente desde Microsoft en el peor de los casos.
/* Creo un usuario con idioma predeterminado en Español */ 
sp_addlogin 'usuario','pepenervos','master','Español'
 
/* vamos a darle acceso a Northwind */
use Northwind
GO
sp_grantdbaccess 'usuario' 
GO
Nos logueamos en el Query Analizer como "usuario".
Con la siguiente instruccion confirmamos el idioma español para el usuario "usuario":
Select @@Language
La consulta devuelve:
---------------------------------------------------------
Español
(1 filas afectadas)
Ahora usamos la tabla Orders y hacemos la consulta de fechas de la forma tradicional y la segunda usando el formato ANSI propuesto.
use northwind
go
 
-- la opcion que siempre hemos usado hasta hoy que os he mostrado el camino
select count(*) from orders where orderdate >='01-08-1997'
 
-- La opción que cambiará vuestras vidais.
select count(*) from orders where orderdate >='19970801'
Ambas consultas devuelven 460 registros para pedidos posteriores al 1 de agosto del 97.
Cambiamos el lenguaje al idioma inglés y volvemos a probar a ver que zapa.
use northwind
go
 
SET LANGUAGE us_english
GO
 
-- ya dijimos que esta opción no corre mas.
select count(*) from orders where orderdate >='01-08-1997'
 
-- la opción ANSI que hizo que dejeis de sufrir.
select count(*) from orders where orderdate >='19970801'
 
La primera consulta devolvió 670 registros y la segunda sigue devolviendo la cantidad correcta, 460 registros. Lo que ocurrió es que al cambiar el formato regional la primera consulta en realidad está buscando registros mayores el 8 de enero y eso no tiene nada que ver con el 1 de agosto que nosotros queremos filtrar !

La segunda sentencia sigue siendo correcta, de modo que ya saben, a usar el formato ANSI que se acaba el mundo.
Y si quiero traer solamente los registros de un solo día, teniendo en cuenta que el ansi me toma la hora y eso puede hacer que no devuelva todos los registros de ese dia, podemos escribir algo como lo que sigue:

Select * from orders Where orderdate >='19970805' and orderdate <>

En pocas palabras, le sumo un dia a la fecha que estoy buscando y hago que el filtro funcione por menor a ese dia, de ese modo vienen todos los registros del dia que quiero recuperar.

Y listo el pollo. Una solución sencilla y efectiva al tema de las fechas.


Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...