CLR 程序集不会在 64 位 SQL Server 2005 中加载

发布于 2024-08-20 03:20:23 字数 1935 浏览 7 评论 0原文

我们在安装 SQL Server 2005(32 位)时使用带有一些用户定义函数的程序集。我们使用这样的脚本将其部署到生产中:

CREATE ASSEMBLY [Ourfunctions]
AUTHORIZATION [dbo]
FROM 0x4D5A9000...000
WITH PERMISSION_SET = SAFE
GO
CREATE FUNCTION [dbo].[GLOBAL_FormatString](@input [nvarchar](4000))
RETURNS [nvarchar](4000) WITH EXECUTE AS CALLER
AS 
EXTERNAL NAME [Ourfunctions].[UserDefinedFunctions].[GLOBAL_FormatString]
GO

我们从未遇到过这些函数的任何问题。现在,当我们尝试将其中一台服务器升级到 x64 时,我们在调用任何函数时都会遇到错误。示例堆栈跟踪:

System.Data.SqlClient.SqlException:一个 Microsoft .NET 中发生错误 尝试加载时的框架 程序集 ID 65549。服务器可能是 资源耗尽,或者 程序集可能不被信任 PERMISSION_SET = EXTERNAL_ACCESS 或 不安全。再次运行查询,或检查 文档查看如何解决 大会信任问题。了解更多 有关此错误的信息: System.IO.FileLoadException:无法 加载文件或程序集'ourfunctions, 版本=0.0.0.0,文化=中立, PublicKeyToken=null' 或其之一 依赖关系。给定的程序集名称 或代码库无效。 (例外 来自 HRESULT:0x80131047) System.IO.FileLoadException:位于 System.Reflection.Assembly.nLoad(AssemblyName 文件名、字符串代码库、证据 装配安全、装配 locationHint、StackCrawlMark& 堆栈标记、布尔值 throwOnFileNotFound,布尔值-snip-

该错误提到权限集 EXTERNAL_ACCESSUNSAFE,而我们使用级别 SAFE

.dll 文件是在目标平台设置为“任何 CPU”的情况下构建的,当我们尝试从文件而不是 varbinary 语法加载 dll 时,我们会得到相同的结果。 已经尝试了 http://support.microsoft.com/kb/918040 中的建议

我们 在 32 位机器上尝试了完全相同的过程,一切正常。应该是x86和x64的区别。有什么想法吗?

解决方案:我们终于找到了解决方案。事实证明,我们的程序集确实是一个 32 位编译的程序集。在 Visual Studio 中,我们使用目标“任何 CPU”,但在检查底层 .csproj 时,我发现了以下代码片段:

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    ...other elements...
    <PlatformTarget>x86</PlatformTarget>
  </PropertyGroup>

所以我们的“任何 CPU”目标实际上是在构建 x86 程序集!啊啊。我已经在 subversion 中追踪到了这一行,但它在 2006 年第一次签入时就已经存在了。也许这是数据库项目的某些早期模板中的错误?

不管怎样,谢谢你的帮助。我会接受拉斯的回答,因为我怀疑许多遇到同样问题的人会从他的回答中得到最大的帮助。

We use an assembly with some user defined functions in our installation of SQL Server 2005 (32 bit). We deploy this to production with a script like this:

CREATE ASSEMBLY [Ourfunctions]
AUTHORIZATION [dbo]
FROM 0x4D5A9000...000
WITH PERMISSION_SET = SAFE
GO
CREATE FUNCTION [dbo].[GLOBAL_FormatString](@input [nvarchar](4000))
RETURNS [nvarchar](4000) WITH EXECUTE AS CALLER
AS 
EXTERNAL NAME [Ourfunctions].[UserDefinedFunctions].[GLOBAL_FormatString]
GO

We have never experienced any problems with these functions. Now, when we tried to upgrade one of our servers to x64, we got errors when calling any of the functions. Sample stack trace:

System.Data.SqlClient.SqlException: An
error occurred in the Microsoft .NET
Framework while trying to load
assembly id 65549. The server may be
running out of resources, or the
assembly may not be trusted with
PERMISSION_SET = EXTERNAL_ACCESS or
UNSAFE. Run the query again, or check
documentation to see how to solve the
assembly trust issues. For more
information about this error:
System.IO.FileLoadException: Could not
load file or assembly 'ourfunctions,
Version=0.0.0.0, Culture=neutral,
PublicKeyToken=null' or one of its
dependencies. The given assembly name
or codebase was invalid. (Exception
from HRESULT: 0x80131047)
System.IO.FileLoadException: at
System.Reflection.Assembly.nLoad(AssemblyName
fileName, String codeBase, Evidence
assemblySecurity, Assembly
locationHint, StackCrawlMark&
stackMark, Boolean
throwOnFileNotFound, Boolean -snip-

The error mentions the permission sets EXTERNAL_ACCESS AND UNSAFE whereas we use the level SAFE.

The .dll file is build with target platform set to 'Any CPU' and we get the same results when we try to load the dll from file instead of the varbinary syntax. We already tried the suggestions in http://support.microsoft.com/kb/918040

We have tried the exact same procedure on a 32 bit machine and everything just worked. It must be a difference between x86 and x64. Any ideas?

SOLUTION: We finally found the solution. It turns out that our assembly was indeed a 32 bit compiled one. In Visual Studio, we used the target "Any CPU", but on inspecting the underlying .csproj, I found the following snippet:

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    ...other elements...
    <PlatformTarget>x86</PlatformTarget>
  </PropertyGroup>

So our "Any CPU" target was actually building an x86 assembly! Aaargh. I have traced back this line in subversion, but it was already there at first checkin in 2006. Maybe this was a bug in some early template of the database project?

Anyway, thanks for your help. I will accept Russ's answer, as I suspect that many who experience the same problems will be helped most by his answer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

可可 2024-08-27 03:20:23

它与 64 位无关,您需要更改数据库以允许它。试试这个:

ALTER DATABASE YOURDATABASEHERE
SET TRUSTWORTHY ON;
GO

如果单独这样做不起作用,您也可以尝试这些选项

USE YOURDATABASEHERE
GO
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'Ole Automation Procedures', 1;
GO
RECONFIGURE;
GO 

It doesn't have to do with the fact that it is 64 bit, you need to alter the DB to allow it. Try this:

ALTER DATABASE YOURDATABASEHERE
SET TRUSTWORTHY ON;
GO

if that alone doesn't work, you can try these options as well

USE YOURDATABASEHERE
GO
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'Ole Automation Procedures', 1;
GO
RECONFIGURE;
GO 
挖个坑埋了你 2024-08-27 03:20:23

您可以尝试从文件加载程序集。我不确定是否可以使用编码字符串语法将 32 位版本上编码的程序集部署到 64 位 SQL Server。

You could try to load the assembly from file. I am not sure if it is possible to deploy assembly encoded on 32bit version to 64bit SQL Server using encoded string syntax.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文