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.
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-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.
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;
}
}
Comentários (0)
Carregando comentários…