运行现有 CLR 对象或创建程序集时出现的错误

本文帮助您解决在从 SQL Server 的其他实例中移动的数据库上使用 CLR 对象时可能出现的两个不同的问题。

原始产品版本:   SQL Server
原始 KB 数:   918040

症状

请考虑以下方案。 分离或备份 SQL Server 实例中的数据库。 SQL Server 实例在服务器 A 上运行。稍后,将该数据库附加或还原到运行在服务器 B 上的 SQL Server 实例。在这种情况下,您可能会遇到以下症状:

  • 当您尝试运行现有的公共语言运行时 (CLR) 对象的 external_access 服务器 B 上的数据库中包含或不安全的权限集时,您将收到以下错误消息:

    消息10314,级别16,状态11,第2行
    尝试加载程序集 id 65536 时,Microsoft .NET Framework 出错。 服务器可能资源不足,或者可能无法信任该程序集,PERMISSION_SET = EXTERNAL_ACCESS 或不安全。 再次运行查询,或查看文档以了解如何解决程序集信任问题。 有关此错误的详细信息:
    FileLoadException:无法加载文件或程序集的 AssemblyName、Version = 0.0.0.0、区域性 = 中性、PublicKeyToken = null ' 或其依赖项之一。 发生与安全性相关的错误。 HRESULT 中 (异常: 0x8013150A) FileLoadException:
    在 nLoad (AssemblyName 文件名。字符串基本代码、证据 assemblySecurity、程序集 locationHint、StackCrawlMark& stackMark、Boolean throwOnFileNotFound、Boolean forIntrospection) 在 (AssemblyName InternalLoad、证据 AssemblyRef、AssemblySecurity& StackCrawlMark、boolean stackMark) 在 (& String forIntrospection、InternalLoad assemblyString) (AssemblySecurity StackCrawlMark stackMark forIntrospection assemblyString) string

  • 当您尝试 external_access 在同一数据库中创建具有或不安全权限集的新程序集时,您会收到以下错误消息:

    服务器: Msg 10327,级别14,状态1,第1行
    为程序集 "AssemblyName" 创建程序集失败,因为程序集 "AssemblyName" 未获得 PERMISSION_SET = EXTERNAL_ACCESS 的授权。 如果满足以下任一条件,则会对程序集进行授权:数据库所有者 (DBO) 具有外部访问程序集权限,并且数据库具有受信任的 database 属性。或使用具有 "具有外部访问程序集的对应登录" 权限的证书或非对称密钥对程序集进行签名。

即使您已将 " 可信 数据库" 属性设置为 "开",也会出现问题。

原因

出现此问题的原因是,用于在服务器 A 上创建数据库的登录名不在服务器 B 上的 SQL Server 实例中。此登录可以是 Microsoft Windows 登录名,也可以是 SQL Server 登录名。

解决方法

若要解决此问题,请使用下列方法之一。

备注

在使用以下方法之前,请确保启用了 "可信赖的数据库" 属性。

  • 使用 sp_changedbowner 存储过程将数据库所有者更改为 sa 或服务器 B 上的可用登录名。例如,您可以使用以下语句将数据库所有者更改为 sa

    USE <DatabaseName>
    GO
    
    EXEC sp_changedbowner 'sa'
    

    备注

    在此语句中, <DatabaseName> 是您正在使用的数据库的名称的占位符。 已更改的数据库所有者应具有执行特定任务所需的相应权限。 例如,数据库所有者应具有创建程序集的 "创建程序集" 权限。

  • 将用于创建数据库的服务器 A 上的 SQL Server 实例上的登录名添加到服务器 B 上的 SQL Server 实例中。

如果登录名是域帐户,则可以在服务器 B 上创建相同的登录名。然后为服务器 B 上的 SQL Server 实例上的登录授予所需的权限。

如果登录名是 SQL Server 登录名,请确保此登录的 SID 与您在服务器 B 上的 SQL Server 实例上创建的新 SQL Server 登录名相匹配。若要执行此操作,请指定语句的 SID 参数 CREATE LOGIN

详细信息

如果从其他数据库访问 CLR 对象,并且该数据库具有不一致的 DBO SID,则可能会出现相同的问题。

有关详细信息,请访问以下博客: CSS SQL Server 工程师

参考