Ошибка при запуске существующего объекта CLR или создании сборки

Эта статья поможет устранить две различные проблемы, которые могут возникнуть при работе с объектами CLR в базе данных, перемещенной из другого экземпляра SQL Server.

Оригинальная версия продукта: SQL Server
Оригинальный номер базы знаний: 918040

Симптомы

Рассмотрим следующий сценарий. Отсоедините или создайте резервную копию базы данных, которая находится в экземпляре SQL Server. Экземпляр SQL Server работает на сервере A. Позже вы подключите или восстановите эту базу данных к экземпляру SQL Server, работающему на сервере B. В этом сценарии могут возникнуть следующие симптомы:

  • При попытке запустить существующий объект CLR, имеющий external_access или небезопасный набор разрешений из базы данных на сервере B, появляется следующее сообщение об ошибке:

    Сообщение 10314, уровень 16, состояние 11, строка 2
    При попытке загрузить сборку с идентификатором 65536 в платформа .NET Framework Майкрософт произошла ошибка. На сервере могут заканчиваться ресурсы или сборка может не доверять PERMISSION_SET = EXTERNAL_ACCESS или UNSAFE. Запустите запрос еще раз или проверка документации, чтобы узнать, как устранить проблемы с доверием к сборке. Дополнительные сведения об этой ошибке:
    System.IO.FileLoadException: не удалось загрузить файл или сборку AssemblyName, Version=0.0.0, Culture=neutral, PublicKeyToken=null или одну из его зависимостей. Произошла ошибка, связанная с безопасностью. (Исключение из HRESULT: 0x8013150A) System.IO.FileLoadException:
    в System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection) at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) в System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) в System.Reflection.Assembly.Load(String assemblyString)

  • При попытке создать новую сборку с external_access установленным или небезопасным разрешением в той же базе данных появляется следующее сообщение об ошибке:

    Сервер: msg 10327, уровень 14, состояние 1, строка 1
    Не удалось создать сборку AssemblyName, так как сборка AssemblyName не авторизована для PERMISSION_SET = EXTERNAL_ACCESS. Сборка авторизована, если имеет значение true одно из следующих значений: владелец базы данных (DBO) имеет разрешение EXTERNAL ACCESS ASSEMBLY, а база данных имеет свойство TRUSTWORTHY database в; или сборка подписана сертификатом или асимметричным ключом, который имеет соответствующее имя входа с разрешением EXTERNAL ACCESS ASSEMBLY.

Проблемы возникают, даже если для свойства базы данных уже заданоTrustworthy значение ON.

Причина

Эта проблема возникает из-за того, что имя входа, используемое для создания базы данных на сервере A, отсутствует в экземпляре SQL Server на сервере B. Это может быть имя входа Microsoft Windows или SQL Server.

Обходной путь

Чтобы обойти эту проблему, используйте один из следующих методов.

Примечание.

Прежде чем использовать следующие методы, убедитесь, что вы включили Trustworthy свойство базы данных.

  • Используйте хранимую sp_changedbowner процедуру, чтобы изменить владельца базы данных на sa или на доступную учетную запись на сервере B. Например, для изменения владельца базы данных на sa можно использовать следующую инструкцию:

    USE <DatabaseName>
    GO
    
    EXEC sp_changedbowner 'sa'
    

    Примечание.

    В этой инструкции является заполнителем имени базы данных, <DatabaseName> над которым вы работаете. Измененный владелец базы данных должен иметь соответствующие разрешения для выполнения определенной задачи. Например, владелец базы данных должен иметь разрешение CREATE ASSEMBLY для создания сборки.

  • Добавьте имя входа в экземпляр SQL Server на сервере A, который используется для создания базы данных в экземпляр SQL Server на сервере B.

Если имя входа является учетной записью домена, вы можете создать то же имя входа на сервере B. Затем предоставьте необходимые разрешения для входа в экземпляр SQL Server на сервере B.

Если имя входа является SQL Server, убедитесь, что идентификатор безопасности этого имени входа соответствует новому имени входа SQL Server, создаваемому в экземпляре SQL Server на сервере B. Для этого укажите аргумент SID инструкцииCREATE LOGIN.

Дополнительная информация

Если вы обращаетесь к объекту CLR из другой базы данных и эта база данных имеет несовпадающий идентификатор безопасности DBO, может возникнуть та же проблема.

Дополнительные сведения см. в следующем блоге: Инженеры CSS SQL Server.

Ссылки