Hola, chicos,
¡Buenas tardes!

En esta publicación, seguiré el consejo de un lector y utilizaré la excelente API gratuita del sitio. Calendario.com.br para devolver la lista de feriados nacionales, estatales, municipales y opcionales en Brasil, permitiéndole filtrar por año, estado y/o ciudad. Ya había comentado este tema en el post. Cómo crear una tabla con días festivos (nacionales, estatales y móviles) en SQL Server, pero creo que esta publicación proporcionará otra forma de realizar esta tarea.

Creo que la solución de este post es más completa que la de mi post anterior sobre festivos, ya que incluye incluso festivos municipales y facultativos. Sin embargo, cada consulta genera una solicitud HTTP, que aplicada a una gran lista de ciudades/años, podría tardar varios segundos, mientras que la solución del otro post ya calcula y almacena todos los datos en una tabla, lo que no impide que esto también se pueda hacer con la solución vía API.

Para obtener más información sobre la función Automatización OLE, haga clic en este enlace.

Usando la automatización OLE

La forma más rápida de implementar esto es utilizar el objeto de automatización OLE MSXML2.ServerXMLHTTP, que le permite realizar solicitudes XML a través del protocolo HTTP.

Como ya mencioné en otras publicaciones, por razones de seguridad y estabilidad ambiental, NO recomiendo activar y usar la función OLE Automation, pero quería demostrar aquí una solución sobre cómo usar esta poderosa pero peligrosa función de base de datos.

Ver código fuente
CREATE PROCEDURE dbo.stpConsulta_Feriado (
    @Ds_Token VARCHAR(100),
    @Nr_Ano INT,
    @Ds_Cidade VARCHAR(50),
    @Sg_UF VARCHAR(2) = 'ES'
)
AS BEGIN


    DECLARE 
        @obj INT,
        @Url VARCHAR(8000),
        @xml XML,
        @resposta VARCHAR(MAX)
        
 
    IF (OBJECT_ID('tempdb..#xml') IS NOT NULL) DROP TABLE #xml
    CREATE TABLE #xml ( 
        Ds_Dados VARCHAR(MAX)
    )
    
 
    SET @Url = 'http://www.calendario.com.br/api/api_feriados.php?token=' + @Ds_Token + '&ano=' + CAST(@Nr_Ano AS VARCHAR(4))
 
    IF (NULLIF(LTRIM(RTRIM(@Sg_UF)), '') IS NOT NULL)
        SET @Url += '&estado=' + @Sg_UF


    IF (NULLIF(LTRIM(RTRIM(@Ds_Cidade)), '') IS NOT NULL)
        SET @Url += '&cidade=' + @Ds_Cidade

    
    EXEC sys.sp_OACreate @progid = 'MSXML2.ServerXMLHTTP', @objecttoken = @obj OUT, @context = 1
    EXEC sys.sp_OAMethod @obj, 'open', NULL, 'GET', @Url, false
    EXEC sys.sp_OAMethod @obj, 'setRequestHeader', NULL, 'Content-Type', 'application/x-www-form-urlencoded'
    EXEC sys.sp_OAMethod @obj, 'send'
 
 
    INSERT INTO #xml(Ds_Dados)
    EXEC sys.sp_OAGetProperty @obj, 'responseText' --, @resposta OUT
    
    
    EXEC sys.sp_OADestroy @obj
 
 
    SELECT TOP 1 @resposta = Ds_Dados FROM #xml
    SET @xml = @resposta COLLATE SQL_Latin1_General_CP1251_CS_AS

    SELECT
        eventos.linha.value('date[1]','varchar(100)') AS [Data],
        eventos.linha.value('name[1]','varchar(100)') AS Nome,
        eventos.linha.value('type[1]','varchar(30)') AS Tipo,
        eventos.linha.value('type_code[1]','int') AS Codigo_Tipo,
        eventos.linha.value('link[1]','varchar(100)') AS Link
    FROM   
        @xml.nodes('//events/event') eventos(linha)
    

END

Ejemplo de uso:

sql-server-como-gerar-uma-tabela-de-feriados-nacionais-municipais-estaduais-com-api-ole-automation
sql-server-cómo-generar-una-tabla-de-vacaciones-nacionales-de-ciudad-estado-con-api-ole-automation

Usando SQL CLR (C#)

Ya conocido aquí por publicaciones de blog, el CLR permite utilizar código C# o VB.NET de .NET Framework dentro de la base de datos SQL Server, y así obtener nuevas funciones y ampliar la capacidad de la base de datos.

Si no conoces el CLR, o no sabes cómo funciona y qué es, accede a este enlace.

Ver código fuente
using System.Collections;
using System.Data.SqlTypes;
using System.IO;
using System.Net;
using System.Text;
using System.Xml;
using Bibliotecas.Model;
using System;

public partial class UserDefinedFunctions
{

    private class ConsultaFeriado
    {

        public SqlDateTime Date;
        public SqlString Name;
        public SqlString Type;
        public SqlInt32 Type_Code;
        public SqlString Link;

        public ConsultaFeriado(SqlDateTime date, SqlString name, SqlString type, SqlInt32 typeCode, SqlString link)
        {

            Date = date;
            Name = name;
            Type = type;
            Type_Code = typeCode;
            Link = link;

        }

    }
    
    [Microsoft.SqlServer.Server.SqlFunction(
        FillRowMethodName = "FillRow_ConsultaFeriado",
        TableDefinition = "Dt_Feriado DATETIME, Ds_Nome NVARCHAR(100), Ds_Tipo NVARCHAR(50), Nr_Tipo INT, Ds_Link NVARCHAR(500)"
    )]
    public static IEnumerable fncFeriados(int Ano, string Sg_UF, string Ds_Cidade)
    {

        var consultaFeriadoCollection = new ArrayList();

        if (Ano < 1900 || Ano > 2099)
            return consultaFeriadoCollection;


        // Gere o seu token no endereço: http://www.calendario.com.br/api_feriados_municipais_estaduais_nacionais.php
        var token = "";
        var parametros = "?token=" + token + "&ano=" + Ano;

        if (!string.IsNullOrEmpty(Sg_UF))
            parametros += "&estado=" + Sg_UF;

        if (!string.IsNullOrEmpty(Ds_Cidade))
            parametros += "&cidade=" + Ds_Cidade;


        var request = (HttpWebRequest)WebRequest.Create("http://www.calendario.com.br/api/api_feriados.php" + parametros);
        //request.Proxy = new WebProxy(Servidor.Ds_Proxy_Url, Servidor.Ds_Proxy_Porta) { Credentials = new NetworkCredential(Servidor.Ds_Proxy_Usuario, Servidor.Ds_Proxy_Senha, Servidor.Ds_Proxy_Dominio) };

        request.Method = "GET";
        request.UserAgent = "curl/7.45.0";
        request.ContentType = "application/x-www-form-urlencoded";


        using (var response = (HttpWebResponse)request.GetResponse())
        {
            using (var stream = response.GetResponseStream())
            {

                if (stream == null) return consultaFeriadoCollection;

                using (var streamReader = new StreamReader(stream, Encoding.GetEncoding("UTF-8")))
                {

                    var resposta = streamReader.ReadToEnd();

                    var xml = new XmlDocument();
                    xml.LoadXml(resposta);

                    var root = xml.DocumentElement;
                    var nodes = root?.SelectNodes("/events/event");

                    if (nodes == null) return consultaFeriadoCollection;

                    foreach (XmlNode node in nodes)
                    {

                        if (node != null)
                        {

                            consultaFeriadoCollection.Add(new ConsultaFeriado(
                                (string.IsNullOrEmpty(node["date"]?.InnerText)) ? SqlDateTime.Null : Convert.ToDateTime(node["date"].InnerText),
                                node["name"]?.InnerText,
                                node["type"]?.InnerText,
                                int.Parse(node["type_code"]?.InnerText),
                                node["link"]?.InnerText
                            ));

                        }
                        
                    }
                }
            }
        }


        return consultaFeriadoCollection;

    }

    protected static void FillRow_ConsultaFeriado(object objConsultaFeriado, out SqlDateTime date, out SqlString name, out SqlString type, out SqlInt32 typeCode, out SqlString link)
    {

        var consultaFeriado = (ConsultaFeriado)objConsultaFeriado;

        date = consultaFeriado.Date;
        name = consultaFeriado.Name;
        type = consultaFeriado.Type;
        typeCode = consultaFeriado.Type_Code;
        link = consultaFeriado.Link;

    }

}

sql-server-como-listar-os-feriados-nacionais-estaduais-e-municipais-no-clr
sql-server-cómo-listar-vacaciones-nacionales-estatales-y-municipales-en-clr

¡Eso es todo, amigos!
Gracias por visitarnos, espero que os haya gustado y nos vemos en el próximo post.