Mostrando entradas con la etiqueta SQL SERVER. Mostrar todas las entradas
Mostrando entradas con la etiqueta SQL SERVER. Mostrar todas las entradas

lunes, 28 de diciembre de 2015

Calculo de días festivos para Colombia

El siguiente post tiene como fin, publicar las funciones necesarias para calcular los días festivos en Colombia. Esta desarrollado en T-SQL compatible con Sql Server 2008 o superior.

Está compuesto por 5 funciones de las cuales tres son para acciones auxiliares y las dos restantes permiten listar los festivos de un año determinado o verificar si una fecha es festivo.

Espero sea de utilidad.

1. Función que nos permite crear una fecha a partir del día, mes y año. Para evitar problemas con la configuración regional.

DROP FUNCTION F_CREAR_FECHA
GO
CREATE FUNCTION F_CREAR_FECHA(@ANIO INT, @MES INT, @DIA INT)
RETURNS DATE
AS
BEGIN
 RETURN DATEADD(mm, (@ANIO - 1900) * 12 + @MES - 1 , @DIA - 1)
END
2. Función que a partir de una fecha obtiene el siguiente lunes.


DROP FUNCTION F_OBTENER_SIGUIENTE_LUNES
GO
CREATE FUNCTION F_OBTENER_SIGUIENTE_LUNES(@FECHA DATE)
RETURNS DATE
AS
BEGIN
 DECLARE @LUNES INT = 1
 IF @@DATEFIRST = 7 
 BEGIN 
  SET @LUNES = 2
 END
 IF @@DATEFIRST = 1 
 BEGIN 
  SET @LUNES = 1
 END
 IF @@DATEFIRST = 2 
 BEGIN 
  SET @LUNES = 7
 END
 IF @@DATEFIRST = 3 
 BEGIN 
  SET @LUNES = 6
 END 
 IF @@DATEFIRST = 4 
 BEGIN 
  SET @LUNES = 5
 END   
 IF @@DATEFIRST = 5 
 BEGIN 
  SET @LUNES = 4
 END    
 IF @@DATEFIRST = 6
 BEGIN 
  SET @LUNES = 3
 END     
 DECLARE @FECHA_DEVOLVER  DATE
 IF DATEPART(DW, @FECHA) = @LUNES
 BEGIN
  SET @FECHA_DEVOLVER = @FECHA
 END
 ELSE
 BEGIN
  SET @FECHA_DEVOLVER = DATEADD([day], ((DATEDIFF([day], '19000101', @FECHA) / 7) * 7) + 7, '19000101');          
 END 
 RETURN @FECHA_DEVOLVER
END
3. Función que calcula el domingo de pascua para un año en particular.
DROP FUNCTION F_CALCULA_DOMINGO_PASCUA
GO
CREATE FUNCTION F_CALCULA_DOMINGO_PASCUA(@A_ANO INT)
RETURNS DATE
AS
BEGIN
 DECLARE @M  INT = 25
 DECLARE @N  INT = 5
 DECLARE @A  INT
 DECLARE @B  INT 
 DECLARE @C  INT 
 DECLARE @D  INT 
 DECLARE @E  INT 
 DECLARE @DIA INT
 DECLARE @MES INT
 
 IF  (@A_ANO >= 1583 AND @A_ANO <= 1699)  
 BEGIN
   SET @M = 22
   SET @N = 2
 END 
 ELSE IF (@A_ANO >= 1700 AND @A_ANO <= 1799)  
 BEGIN 
  SET @M = 23
  SET @N = 3 
 END
 ELSE IF (@A_ANO >= 1800 AND @A_ANO <= 1899)  
 BEGIN
  SET @M = 23
  SET @N = 4 
 END
 ELSE IF (@A_ANO >= 1900 AND @A_ANO <= 2099)  
 BEGIN
  SET @M = 24
  SET @N = 5 
 END
 ELSE IF (@A_ANO >= 2100 AND @A_ANO <= 2199)  
 BEGIN 
  SET @M = 24
  SET @N = 6; 
 END 
 ELSE IF (@A_ANO >= 2200 AND @A_ANO <= 2299)  
 BEGIN
  SET @M = 25
  SET @N = 0
 END  
 
 SET @A = @A_ANO % 19
 SET @B = @A_ANO % 4
 SET @C = @A_ANO % 7
 SET @D = (19 * @A + @M) % 30;
 SET @E = (2 * @B + 4 * @C + 6 * @D + @N) % 7; 

 
 IF (@D + @E < 10) 
 BEGIN
  SET @DIA = @D + @E + 22
  SET @MES = 3
 END
 ELSE 
 BEGIN 
  SET @DIA = @D + @E - 9
  SET @MES = 4
 END
 
 
 IF (@DIA = 26 AND @MES = 4)
 BEGIN 
  SET @DIA = 19
 END
 IF (@DIA = 25 AND @MES = 4 AND @D = 28 AND @E = 6 AND @A > 10)
 BEGIN
  SET @DIA = 18
 END
  
 RETURN dbo.F_CREAR_FECHA(@A_ANO, @MES, @DIA);
END

4. Función Recibe un año y retorna el listado de los festivos para ese año.
DROP FUNCTION F_LISTA_FESTIVOS
GO
CREATE FUNCTION F_LISTA_FESTIVOS(@ANIO INT)
 RETURNS @ListaFestivos TABLE(FechaFestivo DATE, Descripcion VARCHAR(50))
AS
BEGIN
 DECLARE @PASCUA DATE = dbo.F_CALCULA_DOMINGO_PASCUA(@ANIO)
 DECLARE @ES_FESTIVO BIT = 0
 
 
 -- Festivos Fecha Fija 
   INSERT INTO @ListaFestivos VALUES(dbo.F_CREAR_FECHA(@ANIO, 1, 1), 'Año Nuevo')
   INSERT INTO @ListaFestivos VALUES(dbo.F_CREAR_FECHA(@ANIO, 5, 1), 'Día del Trabajo')
   INSERT INTO @ListaFestivos VALUES(dbo.F_CREAR_FECHA(@ANIO, 7, 20), 'Grito de la Independencia')
   INSERT INTO @ListaFestivos VALUES(dbo.F_CREAR_FECHA(@ANIO, 8, 7), 'Batalla de Boyacá')   
   INSERT INTO @ListaFestivos VALUES(dbo.F_CREAR_FECHA(@ANIO, 12, 8), 'Inmaculada Concepción')      
   INSERT INTO @ListaFestivos VALUES(dbo.F_CREAR_FECHA(@ANIO, 12, 25), 'Navidad') 
 -- Festivos Siguiente Lunes
   INSERT INTO @ListaFestivos VALUES(dbo.F_OBTENER_SIGUIENTE_LUNES(dbo.F_CREAR_FECHA(@ANIO, 1, 6)), 'Epifanía (Reyes Magos)')
   INSERT INTO @ListaFestivos VALUES(dbo.F_OBTENER_SIGUIENTE_LUNES(dbo.F_CREAR_FECHA(@ANIO, 3, 19)), 'San José esposo de la virgen María')   
   INSERT INTO @ListaFestivos VALUES(dbo.F_OBTENER_SIGUIENTE_LUNES(dbo.F_CREAR_FECHA(@ANIO, 6, 29)), 'San Pedro y San Pablo')      
   INSERT INTO @ListaFestivos VALUES(dbo.F_OBTENER_SIGUIENTE_LUNES(dbo.F_CREAR_FECHA(@ANIO, 8, 15)), 'Asunción de la Virgen')         
   INSERT INTO @ListaFestivos VALUES(dbo.F_OBTENER_SIGUIENTE_LUNES(dbo.F_CREAR_FECHA(@ANIO, 10, 12)), 'Día de la Raza')            
   INSERT INTO @ListaFestivos VALUES(dbo.F_OBTENER_SIGUIENTE_LUNES(dbo.F_CREAR_FECHA(@ANIO, 11, 1)), 'Todos los Santos')               
   INSERT INTO @ListaFestivos VALUES(dbo.F_OBTENER_SIGUIENTE_LUNES(dbo.F_CREAR_FECHA(@ANIO, 11, 11)), 'Independencia de Cartagena')                  
 -- Festivos Dependientes de la pascua
   INSERT INTO @ListaFestivos VALUES(DATEADD(DAY,-7,@PASCUA), 'Domingo De Ramos')                  
   INSERT INTO @ListaFestivos VALUES(DATEADD(DAY,-3,@PASCUA), 'Jueves Santo')                     
   INSERT INTO @ListaFestivos VALUES(DATEADD(DAY,-2,@PASCUA), 'Viernes Santo')                        
   INSERT INTO @ListaFestivos VALUES(@PASCUA, 'Domingo De Pascua')                           
   INSERT INTO @ListaFestivos VALUES(DATEADD(DAY,43,@PASCUA), 'Ascensión de Jesús') 
   INSERT INTO @ListaFestivos VALUES(DATEADD(DAY,64,@PASCUA), 'Corpus Christi')    
   INSERT INTO @ListaFestivos VALUES(DATEADD(DAY,71,@PASCUA), 'Sagrado Corazón de Jesús')       

 RETURN;
END
5.Función Recibe una fecha y retorna un Booleano indicando si es festivo o no
DROP FUNCTION F_CALCULA_ES_FESTIVO
GO
CREATE FUNCTION F_CALCULA_ES_FESTIVO(@FECHA DATE)
RETURNS BIT
AS
BEGIN
 DECLARE @ES_FESTIVO BIT = 0
 IF EXISTS (SELECT * FROM dbo.F_LISTA_FESTIVOS(YEAR(@FECHA)) WHERE FechaFestivo = @FECHA) 
 BEGIN
  SET @ES_FESTIVO = 1
 END
 RETURN (@ES_FESTIVO);
END
Por último la manera de verificar las funciones:


SELECT dbo.F_CALCULA_ES_FESTIVO(CONVERT(DATE, '01/01/2016')) EsFestivo
SELECT * FROM dbo.F_LISTA_FESTIVOS(2016) ORDER BY FechaFestivo

Y el resultado de las consultas seria el siguiente:



jueves, 23 de julio de 2015

Ejecutar un procedimiento al iniciar o reiniciar la instancia en Sql Server 2008

¿Alguna vez has necesitado que se ejecute un procedimiento almacenado apenas se inicie o reinicie la instancia?

Esta solución la necesité cuando tenía algunas tablas en la base de datos tempdb, que como saben se borran cada vez que se reinicia la instancia, por lo cual necesité garantizar que cada vez que se reiniciaba la instancia se crearan las tablas. 

¡Espero sea de utilidad! 

Nota: Debemos tener claro que solo podemos hacer que se ejecute un procedimiento almacenado, el cual no debe recibir parámetros y debe estar creado en la base de datos Master. Sin embargo este procedimiento almacenado puede realizar internamente operaciones sobre otras bases de datos. 

1. Debemos verificar que el parámetro 'scan for startup procs' debe tener el valor '1', ¿Como verificamos el valor de este parámetro?
USE MASTER
GO
SELECT VALUE, VALUE_IN_USE, DESCRIPTION 
FROM SYS.CONFIGURATIONS 
WHERE NAME = 'scan for startup procs'
GO



Si el resultado de la consulta es diferente a '1', no habrá problema, en el paso tres lo solucionaremos.

2. En este paso haremos el procedimiento almacenado que se ejecutará cuando se inicie/reinicie la instancia. Para este ejemplo crearemos un procedimiento que crea una tabla en la base de datos temporal.

USE MASTER
GO
CREATE  PROCEDURE Usp_Create_Dummy as
DECLARE @sql VARCHAR(4000) =  ' '
SET @sql  = @sql +  'USE tempdb  '
SET @sql  = @sql + CHAR(13)
SET @sql =  @sql +  'SET ANSI_NULLS ON  '
SET @sql  = @sql + CHAR(13)
SET @sql =  @sql +  'SET QUOTED_IDENTIFIER ON  '
SET @sql  = @sql + CHAR(13)
SET @sql =  @sql +  'CREATE TABLE [dbo].[TablaDummy]( '
SET @sql =  @sql +  ' [llave] [uniqueidentifier] NOT NULL, '
SET @sql =  @sql +  ' [Valor] [ntext] NULL'
SET @sql =  @sql +  ')'
SET @sql  = @sql + CHAR(13)
EXEC (@sql)

3. Ahora asociaremos el procedimiento para que se ejecute cuando se inicie/reinicie la instancia:
USE MASTER
GO
EXEC sp_procoption @ProcName = 'Usp_Create_Dummy' , @OptionName =  'startup' , @OptionValue = 'on'; 
GO

Al ejecutar el paso tres automáticamente el valor del parámetro 'scan for startup procs' cambiará a '1' solo se debe reiniciar el servicio de Sql Server. 

4. El último punto es, ¿Como verificamos que nuestro procedimiento almacenado está en la lista de ejecución?, es muy sencillo con la siguiente consulta lo verificamos:

SELECT name,create_date,modify_date
FROM sys.procedures
WHERE OBJECTPROPERTY(OBJECT_ID, 'ExecIsStartup') = 1


Espero sea de utilidad.

viernes, 30 de septiembre de 2011

Ejecutar una ETL de integration Services desde C#

El siguiente fragmento de código permite ejecutar una ETL de Integration Services desde C#, se usa la referencia Microsoft.SQLServer.ManagedDTS.
    
            //Creamos una aplicación para realizar la ejecución
            Microsoft.SqlServer.Dts.Runtime.Application app = new Microsoft.SqlServer.Dts.Runtime.Application();
           //Creamos un paquete y le asignamos el que queremos ejecutar
            Package package = app.LoadPackage(@"C:\Users\JI\ETLS\Package.dtsx", null);
           //Ejecutamos el paquete
            DTSExecResult result = package.Execute();  
           //Imprimimos el resultado de la ejecución
            Console.WriteLine("Resultado de la ejecución: {0}", result.ToString());

miércoles, 29 de junio de 2011

Consulta que nos permite listar todas las tablas de una base de datos en SQL SERVER.

Esta consulta es útil cuando necesitamos conocer el listado de las tablas de una base de datos determinada.

  SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE 
  FROM Information_Schema.Tables
  WHERE TABLE_TYPE = 'BASE TABLE'