¡Hola, chicos!
¡Buenas tardes!

En esta publicación, demostraré una vez más el uso de Automatización OLE en SQL Server para consumir datos de un servicio web. Esta vez consumiré el servicio Correios para calcular tiempos y costos de envío (muy utilizado para comercio electrónico).

Conociendo el WebService Correios

Antes de comenzar a crear el procedimiento almacenado que consultará los datos, primero debemos comprender los parámetros y indicadores del servicio Correios.

Correios WebService - Parámetros de entrada

CampoTipoObligatorioDescripción
nCdCompañíaCadenaNo. El parámetro debe pasarse incluso cuando esté vacío.Tu código administrativo con la ECT. El código está disponible en el cuerpo del contrato firmado con Correios.
sDsContraseñaCadenaNo. El parámetro debe pasarse incluso cuando esté vacío.Contraseña de acceso al servicio asociada a su clave administrativa. La contraseña inicial corresponde a los primeros 8 dígitos del CNPJ informado en el contrato.
nCdServicoCadenaCódigo de servicio
sCepOrigenCadenaCódigo postal de origen sin guión. Ejemplo: 05311900
sCepDestinoCadenaCódigo postal de destino sin guión
nVlPesoDecimalPeso del pedido incluido su embalaje. El peso debe declararse en kilogramos.
nCdFormatointernacionalFormato de pedido (incluido embalaje). 1 – Formato caja/paquete / 2 – Formato rollo/prisma
nVlLongitudDecimalLongitud del pedido (incluido el embalaje) en centímetros.
nVlAlturaDecimalAlto del pedido (incluido el embalaje) en centímetros.
nVlAnchoDecimalAncho del pedido (incluido el embalaje) en centímetros.
nVlDiámetroDecimalDiámetro del pedido (incluido el embalaje) en centímetros.
sCdMaoPropriaCadenaIndica si el pedido se entregará con el servicio adicional en mano. Valores posibles: Y o N (Y – Sí / N – No)
nVlValorDeclaradoDecimalIndica si el pedido será entregado con el valor del servicio adicional declarado. En este campo se debe presentar el valor declarado deseado en Reales.
sCdAvisoReciboCadenaIndica si el pedido será entregado con el acuse de recibo del servicio adicional. Valores posibles: Y o N (Y – Sí / N – No)
strReturnCadenaIndica cómo se devuelve la consulta. XML = Resultado en XML / Popup = Resultado en una ventana emergente / = Resultado mediante publicación en la página de un solicitante

Correios WebService - Parámetros de devolución

Parámetro de salidaDescripción
CódigoCódigo de servicio de entrega.
Valor declaradoValorPrecio del servicio adicional Valor Declarado.
ValorPrecio total del pedido en reales incluyendo los precios de los servicios opcionales.
ValorMaoPropriaPrecio del servicio adicional Mão Própria.
ValorAvisoReciboPrecio del servicio adicional Acuse de Recibo.
Plazo de entregaPlazo estimado en días para la entrega del producto. Si el valor devuelto es 0 (cero), indica que la fecha límite no se devolvió correctamente.
Entrega a domicilioInforma si el local proporcionado ofrece servicio a domicilio. Si la fecha límite no se devuelve correctamente, este parámetro estará vacío.
EntregasábadoInforma si el local brindado cuenta con entrega a domicilio los días sábados. Si la fecha límite no se devuelve correctamente, este parámetro estará vacío.
ErrorLo mismo que los Servicios Web.
mensajeErrorDevuelve la descripción del error generado.

Correios WebService - Códigos de Servicio

Códigos de servicio
41106PAC sin contrato
40010SEDEX sin contrato
40045SEDEX se cobrará sin contrato
40126SEDEX se cargará con el contrato
40215SEDEX 10 sin contrato
40290SEDEX Hoy sin contrato
40096SEDEX con contrato
40436SEDEX con contrato
40444SEDEX con contrato
81019e-SEDEX con contrato
41068PAC con contrato
40568SEDEX con contrato
40606SEDEX con contrato
81868(Grupo 1) e-SEDEX con contrato
81833(Grupo 2) e-SEDEX con contrato
81850(Grupo 3) e-SEDEX con contrato

Creando el procedimiento almacenado para consultar los datos

Con el fragmento de código a continuación, crearemos el procedimiento almacenado que usaremos para consultar el valor de envío y los datos del tiempo de entrega mediante procedimientos. Automatización OLE para realizar la solicitud GET y devolver el XML web, que leeremos usando XQuery.

CREATE PROCEDURE dbo.stpConsulta_Frete_Correios (
    @sCepOrigem VARCHAR(12),
    @sCepDestino VARCHAR(12),
    @nCdServico INT,
    @nVlPeso FLOAT = 0.1,
    @nCdFormato SMALLINT = 1,
    @nVlComprimento INT = 20,
    @nVlAltura INT = 5,
    @nVlLargura INT = 15,
    @nVlDiametro INT = 0,
    @CdMaoPropria CHAR(1) = 'n',
    @nVlValorDeclarado FLOAT = 0,
    @CdAvisoRecebimento CHAR(1) = 'n'
)
AS BEGIN
 
 
    DECLARE 
        @obj INT,
        @Url VARCHAR(500),
        @resposta VARCHAR(8000),
        @xml XML
        
        
        
    -- Recupera apenas os números do CEP de Origem
    DECLARE @startingIndex INT = 0
    
    WHILE (1=1)
    BEGIN
      
        SET @startingIndex = PATINDEX('%[^0-9]%', @sCepOrigem)  
        
        IF (@startingIndex <> 0)
            SET @sCepOrigem = REPLACE(@sCepOrigem, SUBSTRING(@sCepOrigem, @startingIndex, 1), '')  
        ELSE    
            BREAK
            
    END
    
    
    
    -- Recupera apenas os números do CEP de Destino
    SET @startingIndex = 0
    
    WHILE (1=1)
    BEGIN
      
        SET @startingIndex = PATINDEX('%[^0-9]%', @sCepDestino)  
        
        IF (@startingIndex <> 0)
            SET @sCepDestino = REPLACE(@sCepDestino, SUBSTRING(@sCepDestino, @startingIndex, 1), '')  
        ELSE    
            BREAK
            
    END
        
 
 
    SET @Url = 'http://ws.correios.com.br/calculador/CalcPrecoPrazo.aspx?' + 
    'sCepOrigem=' + @sCepOrigem + 
    '&sCepDestino=' + @sCepDestino + 
    '&nVlPeso=' + CAST(@nVlPeso AS VARCHAR(20)) + 
    '&nCdFormato=' + CAST(@nCdFormato AS VARCHAR(20)) + 
    '&nVlComprimento=' + CAST(@nVlComprimento AS VARCHAR(20)) + 
    '&nVlAltura=' + CAST(@nVlAltura AS VARCHAR(20)) + 
    '&nVlLargura=' + CAST(@nVlLargura AS VARCHAR(20)) + 
    '&sCdMaoPropria=' + @CdMaoPropria + 
    '&nVlValorDeclarado=' + CAST(@nVlValorDeclarado AS VARCHAR(20)) + 
    '&sCdAvisoRecebimento=' + @CdAvisoRecebimento + 
    '&nCdServico=' + CAST(@nCdServico AS VARCHAR(20)) + 
    '&nVlDiametro=' + CAST(@nVlDiametro AS VARCHAR(20)) + '&StrRetorno=xml'
 
    EXEC sys.sp_OACreate 'MSXML2.ServerXMLHTTP', @obj OUT
    EXEC sys.sp_OAMethod @obj, 'open', NULL, 'GET', @Url, FALSE
    EXEC sys.sp_OAMethod @obj, 'send'
    EXEC sys.sp_OAGetProperty @obj, 'responseText', @resposta OUT
    EXEC sys.sp_OADestroy @obj
    
    SET @xml = @resposta COLLATE SQL_Latin1_General_CP1251_CS_AS
    
    
    SELECT
        @xml.value('(/Servicos/cServico/Codigo)[1]', 'bigint') AS Codigo_Servico,
        @xml.value('(/Servicos/cServico/Valor)[1]', 'varchar(20)') AS Valor_Frete,
        @xml.value('(/Servicos/cServico/PrazoEntrega)[1]', 'int') AS Prazo_Entrega,
        @xml.value('(/Servicos/cServico/ValorSemAdicionais)[1]', 'varchar(20)') AS Valor_Sem_Adicionais,
        @xml.value('(/Servicos/cServico/ValorMaoPropria)[1]', 'varchar(20)') AS Valor_Entrega_Em_Maos,
        @xml.value('(/Servicos/cServico/ValorAvisoRecebimento)[1]', 'varchar(20)') AS Valor_Aviso_Recebimento,
        @xml.value('(/Servicos/cServico/EntregaDomiciliar)[1]', 'varchar(20)') AS Entrega_Domiciliar,
        @xml.value('(/Servicos/cServico/EntregaDomiciliar)[1]', 'varchar(1)') AS Entrega_Domiciliar,
        @xml.value('(/Servicos/cServico/EntregaSabado)[1]', 'varchar(1)') AS Entrega_Sabado,
        @xml.value('(/Servicos/cServico/Erro)[1]', 'int') AS Codigo_Erro,
        @xml.value('(/Servicos/cServico/MsgErro)[1]', 'varchar(500)') AS Mensagem_Erro
        
 
END

Ejemplos de uso

Realización de una prueba sencilla, rellenando sólo los parámetros obligatorios

WebService Correios - Teste simples
WebService Correios - Prueba sencilla

Realización de una prueba más completa, completando todos los parámetros del SP.

WebService Correios - Teste completo
WebService Correios - Prueba completa

Llamando al SP, pero reportando un código postal no válido

WebService Correios - CEP inválido
WebService Correios - Código postal no válido

¡Eso es todo, amigos!
¡Hasta el próximo post!