我们在安装 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:尝试加载程序集 id 65549 时,Microsoft .NET Framework 中发生错误。服务器可能资源不足,或者程序集可能不受 PERMISSION_SET = EXTERNAL_ACCESS 或 UNSAFE 的信任。再次运行查询,或查看文档以了解如何解决程序集信任问题。有关此错误的更多信息:System.IO.FileLoadException:无法加载文件或程序集“ourfunctions,Version=0.0.0.0,Culture=neutral,PublicKeyToken=null”或其依赖项之一。给定的程序集名称或代码库无效。(来自 HRESULT 的异常:0x80131047) System.IO.FileLoadException:在 System.Reflection.Assembly.nLoad(AssemblyName 文件名,字符串 codeBase,证据 assemblySecurity,Assembly locationHint,StackCrawlMark&
错误提到了权限集EXTERNAL_ACCESS
ANDUNSAFE
而我们使用的是 level 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>
所以我们的“Any CPU”目标实际上是在构建一个 x86 程序集!啊。我在 subversion 中追溯了这一行,但它在 2006 年第一次签入时已经存在。也许这是数据库项目的一些早期模板中的错误?
无论如何,谢谢你的帮助。我会接受 Russ 的回答,因为我怀疑许多遇到相同问题的人会从他的回答中得到最大的帮助。