5

我有一个庞大的 C/C++ 函数库,需要从 SQL Server 2008 调用。我编写了一个 C# 适配器类,它从 Win32 DLL 加载这些函数DllImport并将它们公开给 .Net 代码。这在大多数 .Net 应用程序中运行良好。
现在,我尝试在 SQL Server CLR 中使用相同的技术。我创建了一组调用适配器类的 CLR 函数和存储过程。这不起作用,因为尝试加载非托管 DLL 会导致System.BadImageFormatException.
我可以使用扩展存储过程来做到这一点,但该方法已被弃用,并且可能在任何新版本的 SQL Server 中都不再使用。
从 CLR 存储过程调用非托管函数的正确方法是什么?我猜这应该在进程外完成。


我试图让我的存储过程调用公开这些功能的 Web 服务。这听起来是个好主意,但到目前为止,我在部署进行 Web 服务调用的 SQLCLR 程序集时遇到了问题。我无法加载依赖于程序System.ServiceModel.dll集版本的程序集。version=3.0.0.0System.Web.dll2.0.0.0

加载System.Web程序集给我以下错误:

程序集 'System.Web' 引用程序集 'system.web, version=2.0.0.0,culture=neutral, publickeytoken=b03f5f7f11d50a3a.',当前数据库中不存在。SQL Server 尝试从引用程序集所在的同一位置定位并自动加载引用程序集,但该操作失败(原因:版本、区域性或公钥不匹配)。请将引用的程序集加载到当前数据库中,然后重试您的请求。

我找到了部署System.Web程序集问题的解决方案。与其从 部署它,不如从 部署C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Web.dllC:\Windows\Microsoft.NET\Framework64\v2.0.50727\System.Web.dll。然后所有其他必需的程序集也被部署。

按部署顺序排列的程序集列表:

  • C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\SMdiagnostics.dll
  • C:\Windows\Microsoft.NET\Framework64\v2.0.50727\System.Web.dll
  • C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Messaging.dll
  • C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\System.IdentityModel.dll
  • C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\System.IdentityModel.Selectors.dll
  • C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\Microsoft.Transactions.Bridge.dll
4

1 回答 1

1

这里有有趣的讨论:MSDN-SQL CLR 中的非托管代码。我怀疑这是由于引擎如何加载 DLL。他们提供了一系列选项,包括将代码托管在另一个服务中的 sql server 之外,以及使用 WCF 或 COM 访问代码。最后一个选项可能是将您的代码重新编译为纯托管 C++,但这可能不是遗留代码的选项。

了解 SQL Server 2005 中的 CLR 集成提供了有关该过程如何工作的更多信息。

为了进一步限制允许在 SQL Server 中存在和执行的代码,每个程序集都必须注册一组权限。三个预定义的集合可供使用;SAFE、EXTERNAL_ACCESS 和 UNSAFE ...

您还应该查看CLR 集成安全性,并确定您正在执行的代码所需的信任级别,以及您是否能够访问使用 CLR 进程中的代码。

于 2011-12-15T22:50:39.577 回答