有没有办法从SQL存储过程或函数调用Web服务?
答案 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并发回响应。
无论哪个应用程序执行导致Web服务触发的INSERT INTO BLAH
查询都必须等待它完成。除非这只是在背景中发生的事情,就像每日安排的任务一样,你的应用程序的性能将会爆炸
调用Web服务的代码在SQL Server中运行,并耗尽它的资源。由于等待HTTP请求需要很长时间,因此最终会耗尽大量资源,这将再次损害服务器的性能。
答案 2 :(得分:10)
不是在T-SQL代码本身,而是在SQL Server 2005及更高版本中,它们启用了编写CLR存储过程的能力,这些过程本质上是.NET代码中的函数,然后将它们作为存储过程公开以供使用。您可以轻松获得大部分.NET框架,因此我可以通过此方式看到Web服务的消费。
这里详细讨论有点冗长,但这里有关于该主题MSDN article的链接。
答案 3 :(得分:5)
对于繁重的流量或关键任务的东西,我不会这样做,但是,如果你不需要从服务中获得反馈,那么这实际上是一件好事。
这是我所做的一个例子。
不要使用旧的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服务,而没有问题,即使那些流量很大的问题也是如此。所有这些都供内部使用,我的意思是说,只有在工厂内部,无法访问互联网。我建议使用它,但是在设计时要非常小心