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

有帮助吗?

解决方案

是的,你可以这样创建

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

其他提示

相信你 , ,但这是一个糟糕的主意。

由于网络服务调用可能会花费任意时间,并且随机失败,具体取决于当时网络上正在玩的《反恐精英》游戏的数量,因此您无法判断这将花费多长时间。

至少在构建 XML、将 HTTP 请求发送到远程服务器时,您可能需要半秒的时间,然后远程服务器必须解析 XML 并发回响应。

  1. 无论哪个应用程序执行了 INSERT INTO BLAH 导致 Web 服务触发的查询必须等待它完成。除非这只是在后台发生的事情(例如每日计划任务),否则您的应用程序的性能将会崩溃

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

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

这里详细讨论有点长,但这里有一个链接 MSDN 文章 关于这个话题。

对于流量大或关键任务的情况,我不会这样做,但是,如果您不需要从服务接收反馈,那么这实际上是一件很棒的事情。

这是我所做的一个例子。

  1. 触发器在表上插入和更新
  2. 名为 Stored Proc 的触发器将事务的 JSON 数据传递到 Web Api 端点,然后插入到 AWS 中的 MongoDB 中。

不要使用旧的 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

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

这听起来并不是一个像样的架构 - 但有时你必须做一些疯狂的事情。

您可以使用嵌入的 VB 对象来完成此操作。

首先,创建一个“MSXML2.XMLHttp”类型的 VB 对象,然后将这个对象用于所有查询(如果每次都重新创建它,则性能会受到严重影响)。

然后,将该对象和一些参数提供给调用该对象的 sp_OAMethod 的存储过程。

抱歉,这个例子不准确,但是快速的谷歌搜索应该可以揭示 vb-script 方法是如何完成的。

--

但 CLR 版本要简单得多。调用Web服务的问题是它们无法跟上数据库引擎的步伐。当它无法跟上时,你会遇到很多错误。

请记住,网络服务每次都需要新的连接。多样性开始发挥作用。您不想打开 5000 个套接字连接来为表上的函数调用提供服务。真是疯了!

在这种情况下,您必须创建一个自定义聚合函数,并使用它作为参数传递给您的网络服务,这将返回一个结果集......然后您必须对其进行整理。这确实是一种尴尬的获取数据的方式。

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top