你能从SQL代码调用web服务吗?

时间:2008-08-28 21:29:35

标签: sql-server web-services tsql

有没有办法从SQL存储过程或函数调用Web服务?

9 个答案:

答案 0 :(得分:27)

是的,您可以像这样创建

CREATE PROCEDURE CALLWEBSERVICE(@Para1 ,@Para2)
AS
BEGIN
    Declare @Object as Int;
    Declare @ResponseText as Varchar(8000);

    Exec sp_OACreate 'MSXML2.XMLHTTP', @Object OUT;
    Exec sp_OAMethod @Object, 'open', NULL, 'get', 'http://www.webservicex.com/stockquote.asmx/GetQuote?symbol=MSFT','false'
    Exec sp_OAMethod @Object, 'send'
    Exec sp_OAMethod @Object, 'responseText', @ResponseText OUTPUT
    Select @ResponseText
    Exec sp_OADestroy @Object
END

答案 1 :(得分:24)

当然你可以,但这是一个糟糕的主意。

由于网络服务呼叫可能需要花费任意时间,并且随机失败,这取决于当时网络上正在播放的反击游戏数量,您无法确定这需要多长时间。

在构建XML时,您至少可以查看半秒钟,将HTTP请求发送到远程服务器,然后远程服务器必须解析XML并发回响应。

  1. 无论哪个应用程序执行导致Web服务触发的INSERT INTO BLAH查询都必须等待它完成。除非这只是在背景中发生的事情,就像每日安排的任务一样,你的应用程序的性能将会爆炸

  2. 调用Web服务的代码在SQL Server中运行,并耗尽它的资源。由于等待HTTP请求需要很长时间,因此最终会耗尽大量资源,这将再次损害服务器的性能。

答案 2 :(得分:10)

不是在T-SQL代码本身,而是在SQL Server 2005及更高版本中,它们启用了编写CLR存储过程的能力,这些过程本质上是.NET代码中的函数,然后将它们作为存储过程公开以供使用。您可以轻松获得大部分.NET框架,因此我可以通过此方式看到Web服务的消费。

这里详细讨论有点冗长,但这里有关于该主题MSDN article的链接。

答案 3 :(得分:5)

对于繁重的流量或关键任务的东西,我不会这样做,但是,如果你不需要从服务中获得反馈,那么这实际上是一件好事。

这是我所做的一个例子。

  1. 触发表上的插入和更新
  2. 触发器调用Stored Proc,它将事务的JSON数据传递给Web Api端点,然后插入AWS中的MongoDB。
  3. 不要使用旧的XML

    JSON

    EXEC sp_OACreate 'WinHttp.WinHttpRequest.5.1', @Object OUT;
    EXEC sp_OAMethod @Object, 'Open', NULL, 'POST', 'http://server/api/method', 'false'
    EXEC sp_OAMethod @Object, 'setRequestHeader', null, 'Content-Type', 'application/json'
    DECLARE @len INT = len(@requestBody) 
    

    完整示例:

    Alter Procedure yoursprocname
    
     @WavName varchar(50),
     @Dnis char(4) 
    
        AS
    BEGIN
    
        SET NOCOUNT ON;
    
    
    DECLARE @Object INT;
    DECLARE @Status INT;
    
    
    DECLARE @requestBody NVARCHAR(MAX) = '{
    "WavName": "{WavName}",
    "Dnis": "{Dnis}"
    }'
    
    
    SET @requestBody = REPLACE(@requestBody, '{WavName}', @WavName)
    SET @requestBody = REPLACE(@requestBody, '{Dnis}', @Dnis)
    
    
    EXEC sp_OACreate 'WinHttp.WinHttpRequest.5.1', @Object OUT;
    EXEC sp_OAMethod @Object, 'Open', NULL, 'POST',  'http://server/api/method', 'false'
    EXEC sp_OAMethod @Object, 'setRequestHeader', null, 'Content-Type', 'application/json'
    DECLARE @len INT = len(@requestBody) 
    EXEC sp_OAMethod @Object, 'setRequestHeader', null, 'Content-Length', @len
    EXEC sp_OAMethod @Object, 'send', null, @requestBody
    EXEC sp_OAGetProperty @Object, 'Status', @Status OUT
    EXEC sp_OADestroy @Object
    

答案 4 :(得分:3)

在早期版本的Sql中,您可以使用扩展存储过程或xp_cmdshell来外壳并调用Web服务。

并非这些都听起来像一个体面的建筑 - 但有时你必须做疯狂的事情。

答案 5 :(得分:2)

您可以使用嵌入的VB对象执行此操作。

首先,您创建一个类型为“MSXML2.XMLHttp”的VB对象,并将这一个对象用于所有查询(如果每次重新创建它都会产生严重的性能损失)。

然后将该对象(一些参数)提供给在对象上调用sp_OAMethod的存储过程。

对于inprecise示例感到抱歉,但快速谷歌搜索应该揭示vb脚本方法是如何完成的。

-

但CLR版本更多......更容易。 调用Web服务的问题在于它们无法跟上数据库引擎的步伐。你会遇到很多错误,但却无法跟上。

请记住,网络服务每次都需要一个新的连接。多重性发挥作用。您不希望打开5000套接字连接来为表上的函数调用提供服务。多病啊!

在这种情况下,你必须创建一个自定义聚合函数,并使用THAT作为参数传递给你的webservice,这将返回一个结果集......然后你必须整理它。它真的是一种获取数据的尴尬方式。

答案 6 :(得分:1)

如果您使用的是sql 2000兼容级别且无法进行clr集成,请参阅http://www.vishalseth.com/post/2009/12/22/Call-a-webservice-from-TSQL-(Stored-Procedure)-using-MSXML.aspx

答案 7 :(得分:1)

这是一个从Web服务获取一些数据的示例。在这种情况下,将用户代理字符串解析为JSON。

--first configure MSSQL to enable calling out to a webservice (1=true, 0=false)
sp_configure 'show advanced options', 1;  
GO  
RECONFIGURE;  
GO  
sp_configure 'Ole Automation Procedures', 1;  
GO  
RECONFIGURE;  
GO  

CREATE PROCEDURE CallWebAPI_ParseUserAgent @UserAgent VARCHAR(512)
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @Object INT;
    DECLARE @ResponseText AS VARCHAR(8000);
    DECLARE @url VARCHAR(512)

    SET @url = 'http://www.useragentstring.com/?getJSON=all&uas=' + @UserAgent;

    EXEC sp_OACreate 'WinHttp.WinHttpRequest.5.1', @Object OUT;
    EXEC sp_OAMethod @Object, 'Open', NULL, 'GET', @url, 'false'
    EXEC sp_OAMethod @Object, 'setRequestHeader', NULL, 'Content-Type', 'application/json'
    EXEC sp_OAMethod @Object, 'send'
    EXEC sp_OAMethod @Object, 'responseText', @ResponseText OUTPUT
    SELECT @ResponseText
    EXEC sp_OADestroy @Object
END

--example how to call the API
CallWebAPI_ParseUserAgent 'Mozilla/5.0 (Windows NT 6.2; rv:53.0) Gecko/20100101 Firefox/53.0'

答案 8 :(得分:0)

我一直在使用Oracle数据库为世界各地的大型/跨国公司工作。我们一直在通过带有存储过程的DB来使用Web服务,而没有问题,即使那些流量很大的问题也是如此。所有这些都供内部使用,我的意思是说,只有在工厂内部,无法访问互联网。我建议使用它,但是在设计时要非常小心