Tratamiento de fechas y horas en SQL Server
Introduccin.
El tratamiento de fechas en SQL Server es uno de temas que ms preguntas generan
en los foros y grupos de noticias. SQL Servertiene los tipos de
datos datetime y smalldatetime para almacenar datos de fecha y hora.
No hay tipos de datos diferentes de hora y fecha para almacenar slo horas o slo
fechas. Si slo se especifica una hora cuando se establece un valor datetime o
smalldatetime, el valor predeterminado de la fecha es el 1 de enero de 1900. Si slo se
especifica una fecha, la hora ser, de forma predeterminada, 12:00 a.m.
(medianoche), es decir, las 00:00.
Nota Importante: En SQL Server 2008 s que tenemos como novedad tipos de datos
para almacenar slo la fecha y slo la hora. Por tanto todo lo que contamos a
continuacin se puede solucionar usando los nuevos tipos de datos.
Tipo de datos Datetime.
Datos de fecha y hora comprendidos entre el 1 de enero de 1753 y el 31 de diciembre
de 9999, con una precisin de un trescientosavo de segundo, o 3,33 milisegundos.
SQL Server rechaza todos los valores que no puede reconocer como fechas entre 1753
y 9999.
Tipo de datos Smalldatetime.
Datos de fecha y hora desde el 1 de enero de 1900 al 6 de junio de 2079, con
precisin de minutos. Entonces si se utiliza un valor smalldatetime los segundos y
milisegundos son siempre 0.
Diferencia entre Datetime y Smalldatetime.
SQL Server almacena internamente los valores de tipo de datos datetime como enteros
de 4 bytes y los valores smalldatetime como enteros de 2 bytes.
Funciones de fecha y hora (Transact-SQL)
Estas funciones escalares realizan una operacin sobre un valor de fecha y hora de
entrada, y devuelven un valor de cadena, numrico o de fecha y hora:
DATEADD
DATEDIFF
DATENAME
DATEPART
GETDATE
DAY
MONTH
YEAR
Trabajando con fechas ...
Con algunos pequeos ejemplos trataremos de resolver los mayores problemas para
trabajar con estos tipos de datos. Para ello utilizaremos las funciones CAST y
CONVERT.
Separando Fecha y Hora.
Declare @Fecha datetime
Set @Fecha = Getdate()
Select Convert(Char(10), @Fecha,112) As SoloFecha, Convert(Char(8), @Fecha, 108) As SoloHora
SoloFecha SoloHora
---------- -------20010803 07:35:02
(1 row(s) affected)
Otra forma de conseguir el mismo resultado:
Declare @Fecha datetime
Set @Fecha = Getdate()
SELECT Convert(varchar, @Fecha, 3) AS SoloFecha, Convert(varchar, @Fecha, 8)
Operaciones con Fechas (diferencia entre dos fechas).
Obtener diferencia de meses, dias, minutos, etc. entre dos fechas.
Para realizar operaciones entre dos fechas MSSQL tiene la funcin DATEDIFF. Veamos
algunos ejemplos de cmo utilizarla:
declare @FechaIngreso datetime
declare @FechaEgreso datetime
select @FechaIngreso = '19981231 15:15'
select @FechaEgreso = '20021005 10:10'
Select
DATEDIFF(dd, @FechaIngreso, @FechaEgreso) AS Dias,
DATEDIFF(mm, @FechaIngreso, @FechaEgreso) AS Meses,
DATEDIFF(mi, @FechaIngreso, @FechaEgreso) AS Minutos
Para obtener otras diferencias podemos recurrir a la siguiente tabla:
Parte de la fecha Abreviaturas
ao
aa, aaaa
trimestre
tt, t
mes
mm, m
da del ao
da, a
da
dd, d
semana
sm, ss
hora
hh
minuto
mi, n
segundo
ss, s
milisegundo
Ms
Otro ejemplo de DATEDIFF en donde recuperados los datos de la ultima semana
partiendo de la fecha del da:
SELECT TusDatos
FROM TuTabla
WHERE
DATEDIFF(dd, TuFecha, GetDate()) <= 7
Continuando con las operaciones con las fechas, veamos como podemos hacer para
sumar, restar, das, minutos, meses, a una fecha, para ello utilizamos la funcin
DATEADD:
select convert(varchar(12), DATEADD(month, -1, getdate()), 106)
as 'un mes atrs'
select convert(varchar(12), DATEADD (week, -1, getdate()), 106)
as 'una semana atrs'
select convert(varchar(12), DATEADD (day, -1, getdate()), 106) as 'ayer'
Sugerencia:
Estos ejemplos que mostramos a continuacin devolveran el mismo resultados que las
consultas anteriores, pero, si, siempre hay un pero.... hace un tiempo nuestro
compaero Fernando Guerrero me sugiri no utilizarlo pues este truco no est
soportado oficialmente por SQL Server ni por el estndar ANSI.
select convert(varchar(12), getdate()-7), 106) as 'una semana atrs'
select convert(varchar(12), getdate()-1), 106) as 'Ayer'
Funciona, pero no sabemos hasta cuando.
Ampliar informacin:
Funciones MS SQL con
ejemplos
30 de agosto de 2007
8 comentarios
Aprovecho que estoy en clase de base de datos para publicar algunas funciones
de bases de datos SQL, especficamente para MS SQL Server.
Son los apuntes de lo que va del semestre en Aplicaciones de bases de datos,
pueden venir a mano como referencia, o para aprenderse alguna nueva. La
mayora tienen su respectivo ejemplo aplicado a la bd, aunque se entienden
bastante bien fuera de contexto.
El script de la base de datos lo adjunto como enlace a continuacin:
Base de datos (bd.sql) 5,22 Kb
Maysculas y minsculas:
SELECT UPPER(Nombre), LOWER(Apellido) FROM estudiantes
Eliminar espacios:
SELECT LTRIM('
SELECT RTRIM('Nanuk
Aijuna!')
')
Longitud de un valor en un campo:
SELECT LEN(Nombre) FROM estudiantes
Funcin sub string: args(string, inicio, longitud)
SELECT SUBSTRING('Eoden',1,3)
Funcin buscar ndice de caracter: args(char, string[, a partir de cul])
SELECT CHARINDEX('n','Fernando', 5)
Funcin espacio:
SET @valor = SPACE(9)
Funcin convertir a string:
STR(INT)
Declaracin de variables:
Formato:
DECLARE @NombreVar tipo
SET @NombreVar = Valor
Ejemplo:
DECLARE @Nombre CHAR(8)
DECLARE @Apellido CHAR(6)
DECLARE @valor CHAR(50)
DECLARE @Edad SMALLINT
SET @Edad = 41
SET @valor = 'Fernando Briano'
SET @Nombre = SUBSTRING(@valor, 1, (charindex(' ', @valor) - 1 ))
SET @Apellido = SUBSTRING(@valor, (charindex(' ', @valor) + 1), LEN(@valor))
SELECT @Nombre + ' ' + @Apellido + ' - edad: ' + CONVERT(CHAR(3), @Edad) + ' aos'
CONVERT:
CONVERT(Tipo, Campo o expresin, estilo)
El estilo en las FECHAS:
103 muestra: 23/05/1986
112 muestra: 19660523
114 muestra: hora
FUNCIONES CON FECHAS
DATEADD(partefecha (dd, mm, yy), nmero, fecha)
SELECT CONVERT(CHAR(10), getdate(), 103)
SELECT DATEADD(dd, 3, getdate())
DATEDIFF(partefecha, fecha1, fecha2)
Resta la parte de la fecha = fecha2 fecha1
SELECT DATEDIFF(yy, '19850707', getdate())
SELECT DATEDIFF(yy,FechaNac, getdate()) FROM Estudiantes
DATEPART([dd,mm,y, dw(da de la semana)], fecha)
SELECT DATEPART(yy, getdate())
SELECT DATENAME(mm, getdate())
SELECT DAY(getdate())
SELECT E.Nombre, DATEDIFF(yy, E.FechaNac, getdate()) AS Edad,
C.Descripcion , DATEDIFF(dd, FechaIngreso, getdate()) AS Antiguedad
FROM estudiantes AS E, estudiantes_curso AS EC, cursos AS C
WHERE EC.IdEstudiante = E.Ci
Redondear valores:
SELECT ROUND(479.90, -1)
ISDATE(campo)
Devuelve 1 si el campo contiene una fecha vlida, sino devuelve 0
Valor nulo no es de tipo fecha
ISNUMERIC(campo)
Devuelve 1 si el campo contiene un valor numrico, sino devuelve 0
SELECT ISDATE(FechaIngreso) FROM estudiantes
IDENTIFICADOR UNICO:
DECLARE @Identificador UNIQUEIDENTIFIER
SET @Identificador = NEWID()
SELECT @Identificador
La funcin NEWID solamente funciona para columnas que hayan sido declaradas
como UNIQUEIDENTIFIER
FUNCIONES DEL SISTEMA
Generalmente llevan @@ adelante. Para encontrarlas, en la ayuda se puede
buscar el string @@ que nos va a mostrar la mayora de las que hay.
@@ROWCOUNT
Devuelve el nmero de filas afectadas por la ltima instruccin
Queda en cero cuando hubo error o no se realiz la instruccin.
SELECT * FROM estudiantes
SELECT @@rowcount AS Columnas
UPDATE estudiantes SET FechaEgreso = '07/07/2007' WHERE Nombre='Eustakio'
IF @@ROWCOUNT = 0 PRINT 'Santos Jalapeos enchilados Batman! No ha funcionado'
@@ERROR
Devuelve 0 si no hubo error, o distinto de cero con un cdigo especfico (valo en
el manual) con el error
@@IDENTITY
Muestra el ltimo identity de la tabla. O sea, si por ejemplo hacemos una columna
con valor int que va autoincrementando, y es identidad, al seleccionar ste valor,
nos devuelve el ltimo insertado.
Ver el usuario actual con el que se est logueado:
SELECT CURRENT_USER
ESTRUCTURA IF
IF
BEGIN
-END
ELSE
BEGIN
-END
SENTENCIAs
SENTENCIAS
Ver mensajes del sistema:
Para usar la tabla master:
USE master
agregar la ruta absoluta:
SELECT * FROM master.dbo.sysmessages
En la prxima clase, empiezo a ver vistas. Probablemente vaya publicando ms
apuntes ms adelante.