从SQL CLR调用Web服务?
我有一个返回表的SQL Server 2012存储过程。 我必须修改该SP以向返回的表添加其他值。 不幸的是,这种附加值来自对Web服务的调用。 从我的研究中,我收集的主要方法是在SQL中使用OLE自动化程序(sp_OA …),或者使用SQLCLR存储过程。 给定sp_OA …过程运行的安全上下文,单个返回值是VARCHAR(10)注册密钥,并且对服务的调用很少(每小时10到20个),我猜测SQLCLR方法是要走的路。 此外,Web服务托管在我们的Intranet上,外部世界无法访问。
有没有更好的方法来完成我需要的东西? 更好的意思是更高性能,更好的安全性,更容易编码和维护
请不要使用sp_OA*
OLE自动化过程。 它们似乎没有被正式弃用,但SQLCLR取代了OLE自动化程序以及扩展存储过程。
是的,这可以在SQLCLR中轻松完成。 您可以找到有关使用WCF的示例(如@CodeCaster的答案中所示)或使用HttpWebRequest / HttpWebResponse(我在这个答案中有更多信息: 如何从SQL Server存储过程调用webservice )。 此外,请注意,有时您还需要添加序列化程序集: 在CLR集成中使用Webservices和Xml序列化
编码和维护
Web服务提供了一个很好的API,但如果您更改结构,则必须重新编译并重新部署至少部分内容。 假设交换的信息很简单,我倾向于认为将其视为标准Web请求会增加很多灵活性。 您可以创建一个通用的Web请求函数(标量或TVF),它接受参数和URI并构造格式正确的XML请求并将其发送到URI。 然后它获得响应并仅返回XML。 所以你转移了一点责任,因为你现在需要解析XML响应而不是获得一个好的对象。 但是,XML很容易在SQL Server中解析,您可以在任意数量的地方重用此函数。 并且,如果远程服务被更新,更新存储过程以更改传递给Web服务的查询字符串和/或更改XML响应的解析是一个简单的ALTER PROCEDURE,应该易于测试。 无需重新编译/重新部署SQLCLR程序集。
安全
无论你想要一个如何“纯粹”的Web服务调用,最重要的是安全性, 不要懒惰并将TRUSTWORTHY ON
(如@CodeCaster的答案链接页面所示,不幸的是大多数其他示例在这里互联网)。 使此安全的正确方法是执行以下操作:
- 签署你的大会
- 在
[master]
数据库中,从Assembly的DLL中创建一个非对称密钥。 - 此外,在
[master]
,从该非对称密钥创建登录 - 授予您新登录
EXTERNAL ACCESS ASSEMBLY
权限 - 使用
EXTERNAL_ACCESS
的PERMISSION_SET
创建程序集, 而不是UNSAFE
您绝对可以使用SQL CLR调用WCF服务 。
如果您不希望这样,您可以在C#中编写一个Windows服务, 监视或轮询表中的更改 。 根据您实施此服务的方式,对新记录的反应将近乎即时。 另请阅读如何通知DB表更改(sql 2005)的Windows服务(c#)? 。
然后,您可以从C#执行服务调用,执行所需的工作并将结果存储在列中。
当您需要更多信息时,例如在交换期间获得的额外变量,您可以引入一个新表来存储它,以及您感兴趣的实际结果。然后从您问题中的表中加入该表。