【问题标题】:Calling an API from a stored procedure从存储过程调用 API
【发布时间】:2018-01-08 20:03:06
【问题描述】:

我试图从存储过程中的 API 获取结果,但结果为空。我无法代表实际通话,因为它包含敏感信息,但它具有以下逻辑:

EXEC @hResult = sp_OACreate 'MSXML2.XMLHTTP', @Object OUT;
Select @hResult as Create1 --@hResult=0 --> Create OK

EXEC @hResult = sp_OAMethod @Object, 'open', NULL, 'get',@WebAPI,'false'
Select @hResult as Get1 --@hResult=0 --> GET OK

EXEC @hResult = sp_OAMethod @Object, 'send'
Select @hResult as SEND1 --@hResult=0 --> SEND OK

declare @XML table(yourXML XML) INSERT @xml ( yourXML )
EXEC @hResult = sp_OAGetProperty @Object, 'responseXML.xml'
Select @hResult as Response1 --@hResult=0 --> Response OK

Select * from @XML

我在 SQL Server 之外测试了该查询,它工作正常。我从 SQL 服务器调用了一个虚拟 API ('https://www.mocky.io/v2/5185415ba171ea3a00704eed'),结果正常。

由于输出很长,我尝试将结果存储到表或 XML 变量中,但结果仍然为空。

API 将返回 JSON 或 XML。例如,结果集是:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<route code="200" message="OKs">
    <cross_seca>false</cross_seca>
    <total_distance>14417.8587</total_distance>
    <total_seca_distance>0.0</total_seca_distance>
    <section>
        <from_port seca_port="true">CORINTH</from_port>
        <to_port seca_port="false">PUSAN</to_port>
        <distance>14417.8587</distance>
        <distance_seca>0.0</distance_seca>
        <waypoint lat="37.9333000183105" lon="22.9500007629395" name="CORINTH" seca="false"/>
        <waypoint lat="37.9612731933594" lon="22.9347362518311" seca="false"/>
        <waypoint lat="38.0481071472168" lon="22.8005352020264" seca="false"/>
        <waypoint lat="38.2301750183105" lon="22.4502639770508" seca="false"/>
        <waypoint lat="38.3078460693359" lon="22.0923881530762" seca="false"/>
        <waypoint lat="38.3470115661621" lon="21.9775218963623" seca="false"/>
        <waypoint lat="38.3525581359863" lon="21.8507251739502" seca="false"/>
        <waypoint lat="38.3245086669922" lon="21.7836151123047" seca="false"/>
        <waypoint lat="1.5563510656357" lon="108.975273132324" name="KALIMANTAN WEST (RP)" seca="false"/>
        <waypoint lat="3.5768096446991" lon="110.003883361816" seca="false"/>
        <waypoint lat="17.2663631439209" lon="118.031089782715" seca="false"/>
        <waypoint lat="21.8487491607666" lon="121.073471069336" seca="false"/>
        <waypoint lat="22.5359420776367" lon="121.593360900879" name="LAN YU IS. (RP)" seca="false"/>
        <waypoint lat="34.9842147827148" lon="129.087631225586" seca="false"/>
        <waypoint lat="35.0500526428223" lon="129.164993286133" seca="false"/>
        <waypoint lat="35.1067888889" lon="129.0624694444" name="PUSAN" seca="false"/>
    </section>
</route>

为什么我无法通过 SQL 服务器获得结果?

编辑1: API 提供有关它返回结果的次数的信息。当我从 SQL 服务器调用它时,它返回 null 但 API 已发送所有信息。

编辑2:

  • 当我在 Postman 运行 Web API 时,它运行良好。
  • 如果我复制结果并创建一个模拟 API 以提供相同的结果集,并从 SQL 服务器调用模拟 API,它可以正常工作
  • (!) 如果我从服务器调用 API,所有 hResults 报告为 0(成功),但数组上的最终选择返回 null

EDIT3:

从程序调用 https API 时出现一些问题。当我尝试调用 http API 工作正常。

【问题讨论】:

  • 不要从存储过程中调用 Web 方法。有无数的原因使这是一个糟糕的选择。从单独的应用程序调用它。
  • @RemusRusanu 我知道这不是正确的方法,而是因为目前存在架构问题。这是解决它的唯一方法。
  • 我想不出任何理智的 DBA 会禁止使用 CLR 集成但允许使用 OLE 自动化存储过程 - 所以我强烈建议(如果你有 要完成此调用,请参阅 Remus 的评论)它是通过 CLR 存储过程完成的。
  • 如何获取粘贴的xml。可能是身份验证问题
  • 为什么不能调用一个脚本(即p​​owershell)进行网络调用,然后将结果插入表中?

标签: sql sql-server database tsql


【解决方案1】:

由于缺少客户端证书,我可以从该过程中调用任何 HTTP 但不能调用 HTTPS。我从浏览器复制了证书,调用成功。 Postman 和浏览器内置了获取证书的功能。

但是在任何情况下,都应该不鼓励从过程中直接调用 HTTP,因为它在此处的 cmets 中有所提及。

【讨论】:

    猜你喜欢
    • 2014-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-05
    • 1970-01-01
    相关资源
    最近更新 更多