Мы используем сборку с некоторыми пользовательскими функциями в нашей установке 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: An
произошла ошибка в Microsoft .NET
Framework при попытке загрузки
идентификатор сборки 65549. Сервер может быть
не хватает ресурсов, или
сборке нельзя доверять с
PERMISSION_SET = EXTERNAL_ACCESS или
UNSAFE. Запустите запрос еще раз или проверьте
документация, чтобы увидеть, как решить
вопросы доверительного собрания. Для большего
информация об этой ошибке:
System.IO.FileLoadException: не удалось
загрузить файл или сборку 'наши функции,
Версия = 0.0.0.0, Культура = нейтральная,
PublicKeyToken = null 'или один из его
зависимостей. Указанное название сборки
или кодовая база была недействительной. (Исключение
от HRESULT: 0x80131047)
System.IO.FileLoadException: в
System.Reflection.Assembly.nLoad (AssemblyName
fileName, Строка codeBase, Доказательства
СборкаБезопасность, Сборка
locationHint, StackCrawlMark &
stackMark, Boolean
throwOnFileNotFound, Boolean -snip-
Ошибка упоминает наборы разрешений EXTERNAL_ACCESS
И UNSAFE
, тогда как мы используем уровень SAFE
.
Файл .dll создается с целевой платформой 'Любой ЦП', и мы получаем те же результаты, когда пытаемся загрузить dll из файла вместо синтаксиса varbinary. Мы уже попробовали предложения в http://support.microsoft.com/kb/918040
Мы попробовали точно такую же процедуру на 32-битной машине, и все просто сработало. Должно быть разница между x86 и x64. Есть идеи?
РЕШЕНИЕ: Мы наконец нашли решение. Оказывается, наша сборка действительно была 32-битной скомпилированной. В Visual Studio мы использовали цель «Любой процессор», но при проверке базового .csproj я нашел следующий фрагмент:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
...other elements...
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
Итак, наша цель «Любой ЦП» фактически собирала сборку x86! Aaargh. Я проследил эту строку в Subversion, но она уже была там при первой регистрации в 2006 году. Может быть, это была ошибка в каком-то раннем шаблоне проекта базы данных?
В любом случае, спасибо за вашу помощь. Я приму ответ Русса, так как подозреваю, что многим, кто испытывает те же проблемы, больше всего поможет его ответ.