miércoles, 22 de septiembre de 2010

Función días Laborales

Esta función nos es muy útil para calcular los días laborales, funciona desde SQL 2000 hasta SQL 2008 R2

/****** Object: UserDefinedFunction [dbo].[Diaslaborales] Script Date: 09/21/2010 15:09:48 ******/


SET ANSI_NULLS ON

GO



SET QUOTED_IDENTIFIER ON

GO







CREATE FUNCTION [dbo].[Diaslaborales](@StartDate DATETIME,@EndDate DATETIME)

RETURNS integer

AS

Begin

--//Con esta variable calculamos cuantos dias "normales" hay en el rango de fechas



DECLARE @DaysBetween INT



--//Con esta variable acumulamos los dias totales



DECLARE @BusinessDays INT



--//esta variable nos sirve de contador para saber cuando lleguemos al ultimo dia del rango



DECLARE @Cnt INT



/*esta variable es la que comparamos para saber si el dia que esta calculando es sábado o domingo*/



DECLARE @EvalDate DATETIME



/*Esta par de variables sirven para comparar las dos fechas, si son iguales, la funcion nos regresa un 0*/



DECLARE @ini VARCHAR(10)

DECLARE @fin VARCHAR(10)



--//Inicializamos algunas variables



SELECT @DaysBetween = 0

SELECT @BusinessDays = 0

SELECT @Cnt=0



--//Calculamos cuantos dias normales hay en el rango de fechas



SELECT @DaysBetween = DATEDIFF(DAY,@StartDate,@EndDate) + 1



/*Ordenamos el formato de las fechas para que no importando como se proporcionen se comparen igual*/



SELECT @ini = (SELECT CAST((CAST(datepart(dd,@StartDate)AS

VARCHAR(2))+'/'+ CAST(datepart(mm,@StartDate)AS

VARCHAR(2))+'/'+CAST(datepart(yy,@StartDate)AS VARCHAR(4))) as

varchar(10)))

SELECT @fin = (SELECT CAST((CAST(datepart(dd,@EndDate)AS

VARCHAR(2))+'/'+ CAST(datepart(mm,@EndDate)AS VARCHAR(2))+'/'+

CAST(datepart(yy,@EndDate)AS VARCHAR(4)))as varchar(10)))



--//Se comparan las dos fechas



IF @ini <>@fin

BEGIN



/*Si la diferencia de fechas es igual a dos, es porque solo ha transcurrido un dia, asi que solo se valida que no vaya a marcar dias de mas*/



IF @DaysBetween = 2

BEGIN

SELECT @BusinessDays = 1

END

ELSE

BEGIN

WHILE @Cnt < @DaysBetween

BEGIN



/*Se Iguala la fecha a que vamos a calcular para saber si es sabado o domingo en la variable @EvalDate sumandole los dias que marque el contador, el cual no debe ser mayor que el numero total de dias que hay en el rango de fechas*/



SELECT @EvalDate = @StartDate + @Cnt



/*Utilizando la funcion datepart con el parametro dw que calcula que dia de la semana corresponde una fecha determinada, determinados que no sea sabado (7) o domingo (1)*/



IF ((datepart(dw,@EvalDate) <> 1) and

(datepart(dw,@EvalDate) <> 7) )

BEGIN



/*Si no es sabado o domingo, entonces se suma uno al total de dias que queremos desplegar*/



SELECT @BusinessDays = @BusinessDays + 1

END



--//Se suma un dia mas al contador



SELECT @Cnt = @Cnt + 1

END

END

END

ELSE

BEGIN



--//Si fuese cierto que las fechas eran iguales se despliegue cero



SELECT @BusinessDays = 0

END



--//Al finalizar el ciclo, la funcion regresa el numero total de dias



return (@BusinessDays)

END







GO





La utilizas de la siguiente manera
 
 

/*Obtiene los dias laborales*/



update BASEDATOS

set dif_dias=(select dbo.diaslaborales ( fec_inicio , fec_fin))

from BASEDATOS;

go