Erro ao executar um objeto CLR existente ou criar um assembly

Este artigo ajuda você a resolve dois problemas diferentes que podem ocorrer ao trabalhar com objetos CLR em um banco de dados que foi movido de uma instância diferente de SQL Server.

Versão original do produto: SQL Server
Número original do KB: 918040

Sintomas

Considere o seguinte cenário. Desanexe ou faça backup de um banco de dados que esteja em uma instância de SQL Server. A instância do SQL Server está em execução no Servidor A. Posteriormente, você anexa ou restaura esse banco de dados a uma instância de SQL Server que está em execução no Servidor B. Nesse cenário, você pode experimentar os seguintes sintomas:

  • Quando você tenta executar um objeto CLR (common language runtime) existente que tem o external_access conjunto de permissões ou não seguro do banco de dados que está no Servidor B, você recebe a seguinte mensagem de erro:

    Msg 10314, Nível 16, Estado 11, Linha 2
    Ocorreu um erro no microsoft .NET Framework ao tentar carregar a id do assembly 65536. O servidor pode estar ficando sem recursos ou o assembly pode não ser confiável com PERMISSION_SET = EXTERNAL_ACCESS ou UNSAFE. Execute a consulta novamente ou marcar documentação para ver como resolver os problemas de confiança do assembly. Para obter mais informações sobre esse erro:
    System.IO.FileLoadException: não foi possível carregar arquivo ou assembly 'AssemblyName, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' ou uma de suas dependências. Ocorreu um erro relacionado à segurança. (Exceção de HRESULT: 0x8013150A) System.IO.FileLoadException:
    em System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, AssemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection) em System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) em System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) em System.Reflection.Assembly.Load(String assemblyString)

  • Ao tentar criar um novo assembly que tenha a external_access permissão ou não segura definida no mesmo banco de dados, você receberá a seguinte mensagem de erro:

    Servidor: Msg 10327, Nível 14, Estado 1, Linha 1
    O CREATE ASSEMBLY para assembly 'AssemblyName' falhou porque o assembly 'AssemblyName' não está autorizado para PERMISSION_SET = EXTERNAL_ACCESS. O assembly é autorizado quando um dos seguintes é verdadeiro: o proprietário do banco de dados (DBO) tem permissão ASSEMBLY de ACESSO EXTERNO e o banco de dados tem a propriedade de banco de dados TRUSTWORTHY em; ou o assembly é assinado com um certificado ou uma chave assimétrica que tem um logon correspondente com a permissão ASSEMBLY de ACESSO EXTERNO.

Os problemas ocorrem mesmo se você já tiver definido a propriedade do Trustworthy banco de dados como ON.

Motivo

Esse problema ocorre porque o logon usado para criar o banco de dados no Servidor A não está na instância de SQL Server no Servidor B. Esse logon pode ser o logon do Microsoft Windows ou o logon do SQL Server.

Solução alternativa

Para contornar esse problema, use um dos métodos a seguir.

Observação

Antes de usar os métodos a seguir, certifique-se de habilitar a propriedade de Trustworthy banco de dados.

  • Use o sp_changedbowner procedimento armazenado para alterar o proprietário do banco de dados para sa ou para um logon disponível no Servidor B. Por exemplo, você pode usar a seguinte instrução para alterar o proprietário do banco de dados para sa:

    USE <DatabaseName>
    GO
    
    EXEC sp_changedbowner 'sa'
    

    Observação

    Nesta instrução, <DatabaseName> é um espaço reservado do nome do banco de dados no qual você está trabalhando. O proprietário do banco de dados alterado deve ter as permissões correspondentes para executar uma determinada tarefa. Por exemplo, o proprietário do banco de dados deve ter a permissão CREATE ASSEMBLY para criar um assembly.

  • Adicione o logon na instância de SQL Server no Servidor A que é usado para criar o banco de dados à instância de SQL Server no Servidor B.

Se o logon for uma conta de domínio, você poderá criar o mesmo logon no Servidor B. Em seguida, conceda as permissões necessárias ao logon na instância de SQL Server no Servidor B.

Se o logon for um logon SQL Server, verifique se o SID desse logon corresponde ao novo logon SQL Server que você cria na instância de SQL Server no Servidor B. Para fazer isso, especifique o argumento SID da CREATE LOGIN instrução.

Mais informações

Se você acessar o objeto CLR de um banco de dados diferente e esse banco de dados tiver um SID DBO incompatível, o mesmo problema poderá ocorrer.

Para obter mais informações, visite o seguinte blog: Engenheiros SQL Server do CSS.

Referências