viernes, 23 de septiembre de 2016

[SQL Server] Convertir número Año-mes a fecha de manera simple

Muchas veces tenemos procedimientos almacenador de los que su resultado depende de fechas.

Si la fecha es un día en particular bastaría con declarar un parametro de entrada de esta manera:
declare @fecha date

O si además necesitamos la hora la declaramos así:
declare @fecha datetime

El asunto aparece cuando sólo necesitamos discriminar por un año y mes en particular. Nos puede llegar un valor cómo este:
declare @fecha_codigo int -- 201605, 201504 o 200001

Para convertir este valor intuitivamente podemos pensar en una función como esta:
declare @fecha date
    set @fecha = substring(cast(@fecha_codigo as varchar(6)), 1, 4) + '/' + substring(cast(@fecha_codigo as varchar(6)), 5, 2) + '/01'
El problema de esta función es que dependiendo de la versión de SQL Server nos puede asignarel día y el mes al revés generando fechas erroneas.

Para prevenir cualquier error en la generación de la fecha la genereramos de esta manera, que no tiene ningún problema entre las versiones de SQL Server:

declare @fecha date
set @fecha = convert(date, cast(@fecha_codigo * 100 + 1 as varchar(8)), 112)
Cuando se utiliza la función CONVERT con fecha tiene dos modos de uso:
1) Para generar una fecha con un formato especifico de tipo varchar desde una fecha de tipo date o datetime.

2) Para generar una fecha date o datetime a partir de un varchar con un formato especifico.

El formato especifico al que me refiero es el tercer parametro de la función convert.
Pueden ver la lista completa acá.

Especificamente el 112 es el formato "yyyyMMdd" que nos permite generar la fecha.

Dentro cast varchar(8) está el siguiente código:
@fecha_codigo * 100 + 1

Esto convierte nuestro año-mes (yyyyMM) en formato "yyyyMMdd" concadenando el día 1. Y así haciendolo compatible con el formato 112 de fechas.