SQLCLR:如何将程序集 Npgsql.dll 添加到数据库?

SQLCLR: How to add assembly Npgsql.dll to database?

我想从 SQCLR 过程执行 PostgreSQL 命令。 当我添加 Mono.Security.dll 时收到错误消息:

Msg 6218, Level 16, State 2, Line 33
CREATE ASSEMBLY for assembly 'Mono.Security' failed because assembly 'Mono.Security' failed verification. Check if the referenced assemblies are up-to-date and trusted (for external_access or unsafe) to execute in the database. CLR Verifier error messages if any will follow this message
[ : Mono.Math.BigInteger+Kernel::Multiply][mdToken=0x600005d][offset 0x0000001C][found address of Int32][expected unmanaged pointer] Unexpected type on the stack.
[ : Mono.Math.BigInteger+Kernel::Multiply][mdToken=0x600005d][offset 0x00000039][found address of Int32][expected unmanaged pointer] Unexpected type on the stack.
[ : Mono.Math.BigInteger+Kernel::Multiply][mdToken=0x600005d][offset 0x00000059][found address of Int32][expected unmanaged pointer] Unexpected type on the stack.

是否可以在 SQLCLR 过程中使用 Npgsql?

首先,我将按规定回答问题。但其次,最有可能 far 最好只向 PostgreSQL 添加一个链接服务器,我在处理 SQLCLR 错误后解决了这个问题。


SQLCLR 信息

如果这完全可以通过 SQLCLR 工作,最快/最简单的方法是:

  • ALTER 数据库 TRUSTWORTHY ON
  • 在您的 CREATE ASSEMBLY 查询中包含 WITH PERMISSION_SET = UNSAFE
  • 如果任何引用的程序集在同一文件夹中,它们将自动上传。所以也许尝试从加载 Npgsql.dll?
  • 开始

现在,这项工作要求您加载到 SQL 服务器的所有程序集都是“纯”MSIL 程序集。如果有任何“混合”(包含 MSIL 和本机 C++),则无法加载它们,您将不得不寻找其他解决方案,例如编写可以通过 xp_cmdshell 或其他方式调用的控制台应用程序。

如果以上确实有效,那么不需要将数据库设置为 TRUSTWORTHY ON 的更好方法是从这些程序集中的私钥创建一个非对称密钥(假设它们是强命名的) .


非SQLCLR 信息

所有这些:如果可能的话,创建一个到 PostgreSQL 的链接服务器,然后在常规 T-SQL 和 [= 中进行链接服务器调用88=] 在通过 SQLCLR 提交的查询中(因为 SQLCLR 不执行 SQL,它只是像任何其他客户端软件一样将它传递给 SQL 服务器)。这将避免一些您可能 运行 使用 UNSAFE 程序集的潜在问题。这里有两个处理此设置的资源:


更新:

如果正在使用的 SQL 服务器版本是 2012 或更高版本,那么在执行 CREATE ASSEMBLY 时调用的验证过程中的行为实际上可能会略有变化。查看确切的错误消息,我们可以看到问题的根源在Mono.Math.BigInteger+Kernel::Multiply。由于Mono项目是开源的,我们应该可以看看源码。我在 GitHub 上找到了源文件 Mono.Security/Mono.Math/BigInteger.csKernel class 的 Multiply 方法位于第 2097 行,签名为:

public static unsafe void Multiply (uint [] x, uint xOffset, uint xLen, uint [] y,
                                 uint yOffset, uint yLen, uint [] d, uint dOffset)

是否 SQL 服务器应该抱怨这是以下线程的主题,该线程讨论了与 Oracle 驱动程序相关的非常相似的问题(也出现“堆栈上的意外类型”错误) :

https://social.msdn.microsoft.com/Forums/sqlserver/en-US/4e6a5407-7daa-417d-a7ab-2522dc4ee927/sqlclr-create-assembly-validation-in-sql-2012-vs-2008?forum=sqlnetfx

建议使用官方 PostgreSQL 站点上的 System.Data.OleDB with an appropriate OLEDB provider. I found the following two options from the Software Catalogue - Drivers and interfaces 页面:

  • PGNP: 好像没有免费版,但是有试用版。
  • PgOleDb:免费,但似乎自 2006 年 4 月 17 日以来就没有更新过。

另一种选择可能是通过 System.Data.Odbc 和 ODBC 提供程序使用 ODBC。我从同一个 PostgreSQL.com 页面找到了以下两个选项:

  • psqlODBC:官方 PostgreSQL ODBC 驱动程序。截至 2015-08-16,此驱动程序的最新更新是在 2014-10-26。

  • ODBC Driver for PostgreSQL:好像没有免费版,不过有30天的试用版。

OLEDB 和 ODBC 选项都应该在 SQLCLR 和链接服务器中工作。