【问题标题】:Calling an API from SQL Server stored procedure从 SQL Server 存储过程调用 API
【发布时间】:2014-03-30 19:52:12
【问题描述】:

从 ASP.NET Web 窗体调用 API 非常简单。

WebClient wc = new WebClient();
string urlData = wc.DownloadString("http://xxx.xxx.xx.xx/sssss/getResponse.do?ID=testing");

但是我们可以从 SQL Server 存储过程中调用 API。

如果是,那么我们如何从 SQL Server 存储过程调用 API 以及如何获得 API 响应?

【问题讨论】:

标签: sql-server stored-procedures


【解决方案1】:

SQL 查询 select * from openjson ... 仅适用于 SQL 版本 2016 及更高版本。需要SQL兼容模式130。

【讨论】:

    【解决方案2】:

    我认为使用这个 CLR 存储过程SQL-APIConsumer 会更容易:

     exec [dbo].[APICaller_POST]
         @URL = 'http://localhost:5000/api/auth/login'
        ,@BodyJson = '{"Username":"gdiaz","Password":"password"}'
    

    它有多个过程,允许您调用需要参数的 API,甚至传递多个标头和令牌身份验证。

    【讨论】:

      【解决方案3】:

      对着虚无尖叫——只是“不”不要这样做。这是一个愚蠢的想法。

      与外部数据源集成是 SSIS 的目的,或者编写一个 dot net 应用程序/服务来查询框并进行 API 调用。

      编写 CLR 代码以使 SQL 进程能够调用 Web 服务是一种如果做得不好可能会使 SQL 框崩溃的事情 - 想象一下将 CLR 函数放在某个视图中 - 稍后会有其他人出现不知道你做了什么,并在该视图上加入了一百万行表 - 突然你的 SQL 框正在发出一百万个单独的 webapi 调用。

      整个想法很疯狂。

      这种做法是企业 DBA 不信任开发人员的原因。

      CLR是一种巨大的力量,带来了巨大的责任,以上是对它的滥用。

      【讨论】:

      • 我也觉得它没有很好的分离代码库,也让你仍然需要在两个位置设置代码。也许我是老派而且错了,但我认为它应该被分离到 C# Web 服务调用应用程序中,除非这是在最小级别上完成的。
      • “[做] 这类事情是企业 DBA 不信任开发人员的原因” - 作为 DBA 和首席开发人员,我同意这种说法!
      【解决方案4】:

      我建议使用 CLR 用户定义函数,如果你已经知道如何用 C# 编程,那么代码就是;

      using System.Data.SqlTypes;
      using System.Net;
      
      public partial class UserDefinedFunctions
      {
       [Microsoft.SqlServer.Server.SqlFunction]
       public static SqlString http(SqlString url)
       {
        var wc = new WebClient();
        var html = wc.DownloadString(url.Value);
        return new SqlString (html);
       }
      }
      

      这里是安装说明; https://blog.dotnetframework.org/2019/09/17/make-a-http-request-from-sqlserver-using-a-clr-udf/

      【讨论】:

        【解决方案5】:

        我工作了这么多,希望我的努力能帮到你。

        只需将其粘贴到您的 SSMS 中,然后按 F5:

        Declare @Object as Int;
        DECLARE @hr  int
        Declare @json as table(Json_Table nvarchar(max))
        
        Exec @hr=sp_OACreate 'MSXML2.ServerXMLHTTP.6.0', @Object OUT;
        IF @hr <> 0 EXEC sp_OAGetErrorInfo @Object
        Exec @hr=sp_OAMethod @Object, 'open', NULL, 'get',
                         'http://overpass-api.de/api/interpreter?data=[out:json];area[name=%22Auckland%22]-%3E.a;(node(area.a)[amenity=cinema];way(area.a)[amenity=cinema];rel(area.a)[amenity=cinema];);out;', --Your Web Service Url (invoked)
                         'false'
        IF @hr <> 0 EXEC sp_OAGetErrorInfo @Object
        Exec @hr=sp_OAMethod @Object, 'send'
        IF @hr <> 0 EXEC sp_OAGetErrorInfo @Object
        Exec @hr=sp_OAMethod @Object, 'responseText', @json OUTPUT
        IF @hr <> 0 EXEC sp_OAGetErrorInfo @Object
        
        INSERT into @json (Json_Table) exec sp_OAGetProperty @Object, 'responseText'
        -- select the JSON string
        select * from @json
        -- Parse the JSON string
        SELECT * FROM OPENJSON((select * from @json), N'$.elements')
        WITH (   
              [type] nvarchar(max) N'$.type'   ,
              [id]   nvarchar(max) N'$.id',
              [lat]   nvarchar(max) N'$.lat',
              [lon]   nvarchar(max) N'$.lon',
              [amenity]   nvarchar(max) N'$.tags.amenity',
              [name]   nvarchar(max) N'$.tags.name'     
        )
        EXEC sp_OADestroy @Object
        

        此查询将为您提供 3 个结果:

        1。在出现问题时捕获错误(不要惊慌,它总是会显示超过 4000 个字符的错误,因为NVARCHAR(MAX) can only store till 4000 characters

        2。将 JSON 放入一个字符串中(这是我们想要的)

        3。奖励:解析 JSON 并将数据很好地存储到表中(这有多酷?)

        【讨论】:

        • 可以在其中添加遏制身份验证吗?
        • @JoeRod,你想从 Kerberos API 下载数据吗?
        • @FrancescoMantovani 我想使用 kerberos 对 API 端点进行身份验证
        • 我不明白,也许你正在寻找这个? sqlservercentral.com/articles/…
        • 感谢额外的 JSON 解析
        【解决方案6】:

        简单的 SQL 触发 API 调用,无需构建代码项目

        我知道这远非完美或架构纯度,但我有一个客户短期内迫切需要通过不成熟的 API(无 wsdl)与第三方产品集成 当数据库事件发生时,我基本上需要调用 API。 我得到了基本的调用信息——URL、方法、数据元素和令牌,但没有 wsdl 或其他开始导入代码项目。所有建议和解决方案似乎都是从该导入开始的。

        我使用 ARC(高级 Rest 客户端)Chrome 扩展程序和 JaSON 来测试从浏览器与服务的交互并优化调用。 这给了我经过测试的原始调用结构和响应,让我可以快速使用 API。从那里开始,我开始尝试使用在线转换从 json 生成 wsdl 或 xsd,但我认为这需要很长时间才能开始工作,所以我找到了 cURL(云部分,音乐播放)。 cURL 允许我从任何地方将 API 调用发送给本地经理。然后,我打破了一些设计规则,并构建了一个触发器,该触发器将数据库事件和一个 SQL 存储过程和计划任务排队,以将参数传递给 cURL 并进行调用。 我最初有调用 XP_CMDShell 的触发器(我知道,嘘),但不喜欢事务影响或安全问题,所以切换到存储过程方法。

        最后,匹配 API 调用案例的 DB 插入触发将 API 调用的参数写入 Queue 表 存储过程每 5 秒运行一次,运行 Cursor 以拉取每个 Queue table 条目,将 XP_CMDShell 调用发送到带有参数的 bat 文件 Bat 文件包含插入参数的 Curl 调用,将输出发送到日志。 效果很好。

        同样,它并不完美,但时间紧迫,系统使用时间短,可以密切监控以应对连接性和不可预见的问题。

        希望能帮助那些因 API 信息有限而苦苦挣扎的人快速找到解决方案。

        【讨论】:

          【解决方案7】:

          请参阅a link 了解更多详情。

          Declare @Object as Int;
          Declare @ResponseText as Varchar(8000);
          
          Code Snippet
          Exec sp_OACreate 'MSXML2.XMLHTTP', @Object OUT;
          Exec sp_OAMethod @Object, 'open', NULL, 'get',
                           'http://www.webservicex.com/stockquote.asmx/GetQuote?symbol=MSFT', --Your Web Service Url (invoked)
                           'false'
          Exec sp_OAMethod @Object, 'send'
          Exec sp_OAMethod @Object, 'responseText', @ResponseText OUTPUT
          
          Select @ResponseText
          
          Exec sp_OADestroy @Object
          

          【讨论】:

          • 您好,此代码在尝试调用 ASP.NET Web API 端点时不起作用。它接受 JSON。如何更改此代码以使其正常工作?
          • @Bat_Programmer,你遇到了什么问题?
          • 例如我想调用一个需要USERIDAPI KEY(作为密码)的API
          • 身份验证数据可以通过不同的方式传递,例如通过 HTTP 请求标头的正文。这取决于您要调用/使用的 HTTP 服务。要设置 HTTP(授权)标头,您可以尝试在“发送”方法之前添加以下代码:Exec sp_OAMethod @Object, 'setRequestHeader', 'Authorization', 'header value like token'。要设置正文,您可以将内容传递给“发送”方法,如下所示:Exec sp_OAMethod @Object, 'send' , 'body content'
          猜你喜欢
          • 2015-05-08
          • 2021-05-26
          • 2019-12-02
          • 2012-02-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多