SQL Server数据库还原或分离附加后程序集遇到的SQL CLR问题[通俗易懂]

SQL Server数据库还原或分离附加后程序集遇到的SQL CLR问题[通俗易懂]工作中遇到一个案例:备份还原过后或者对数据库分离&附加后(移动数据库文件),发现一些权限为EXTERNAL_ACCESS和UNSAFE程序集对应的CLR函数,在调用的时候会出现一些错误。下面特

SQL Server数据库还原或分离附加后程序集遇到的SQL CLR问题

 

工作中遇到一个案例:备份还原过后或者对数据库分离&附加后(移动数据库文件),发现一些权限为EXTERNAL_ACCESS和UNSAFE程序集对应的CLR函数,在调用的时候会出现一些错误。下面特意用YourSQLDba备份还原到一个测试环境,然后调用CLR函数,就会遇到如下错误:

 

USE YourSQLDba;

代码100分

代码100分GO

SELECT  *

代码100分FROM    [yUtl].[clr_GetFolderList]("C:Program FilesMicrosoft SQL ServerMSSQL12.MSSQLSERVERMSSQLDATA",

                                   "*.mdf");

 

 

Msg 10314, Level 16, State 11, Line 19

在尝试加载程序集 ID 65537 Microsoft .NET Framework 出错。服务器可能资源不足,或者不信任该程序集。请重新运行查询,或检查有关的文档了解如何解决程序集信任问题。有关此错误的详细信息:

System.IO.FileLoadException: Could not load file or assembly “yoursqldba_clrfileop, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null” or one of its dependencies. An error relating to security occurred. (Exception from HRESULT: 0x8013150A)

System.IO.FileLoadException:

   at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)

   at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)

   at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean forIntrospection)

   at System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)

   at System.Reflection.Assembly.Load(String assemblyString)

 

 

检查发现assembly_id=65537的程序集为YourSqlDba_ClrFileOp

 

 

USE YourSQLDba;

GO

SELECT a.name 

      ,a.principal_id

      ,a.assembly_id 

      ,a.clr_name

      ,a.permission_set_desc 

      ,a.is_visible 

      ,a.create_date 

      ,a.modify_date

FROM  sys.assemblies AS a 

 

clip_image001

 

 

 

出现这种错误,一般是EXTERNAL_ACCESS 和UNSAFE的程序集,错误出现的具体原因有两种:

 

 

1: 数据库Owner的SID变化了。无论你是备份还原还是分离附加操作,都要确保数据库所有者SID在数据库属性中显示的内容与源数据库元数据中记录的内容之间匹配。如果使用备份/还原,则数据库所有者SID可能不匹配(取决于你操作时使用的账号),这将阻止CLR代码运行。

 

 

2: 数据库的TRUSTWORTHY属性值变化了。 数据库属性TRUSTWORTHY用于指明SQL Server实例是否信任该数据库以及其中的内容。 默认情况下,此设置为 OFF,但是可以使用ALTER DATABASE语句将其设置为ON.

 

 

此属性可用于减少附加数据库所带来的某些隐患,该数据库包含下列对象之一:

 

·         带有 EXTERNAL_ACCESS UNSAFE 权限设置的有害程序集。 有关详细信息,请参阅 CLR Integration Security

 

·         所定义的、作为高特权用户执行的有害模块。 有关详细信息,请参阅 EXECUTE AS 子句 (Transact-SQL)

 

 

这两种情况均要求具有特定程度的权限,并且在已附加到SQL Server实例的数据库的上下文中使用这两种情况时,应采取相应的机制保护这两种情况。 但是,如果数据库脱机,则对数据库文件具有访问权限的用户可能会将其附加到其选择的SQL Server实例,并将有害内容添加到数据库中。 SQL Server中分离和附加数据库时,将对限制访问数据库文件的数据和日志文件设置某些权限。

 

因为不能立即信任附加到SQL Server实例的数据库,所以不允许数据库访问超出数据库范围的资源,直到数据库已显式标记为可信。 因此,如果备份或分离TRUSTWORTHY选项设置为 ON 的数据库并将该数据库附加或还原到同一个或另一个 SQL Server 实例后,则附加/还原完成后 TRUSTWORTHY 属性将设置为 OFF 此外,旨在访问数据库以外资源的模块和带有 EXTERNAL_ACCESS UNSAFE 权限设置的程序集还需要其他条件才能成功运行。

 

 

 

下面检查数据库的属性TRUSTWORTHYis_trustworth_on), 如下所示

 

 

SELECT  database_id ,

        name ,

        is_trustworthy_on

FROM    sys.databases

WHERE name="YourSQLDba";

 

clip_image002

 

 

但是你对比源数据库的属性TRUSTWORTHY,就会发现数据库还原后,TRUSTWORTHY属性会变化(is_trustworth_on从1变为了0).

 

 

 

clip_image003

 

设置YourSQLDba的属性TRUSTWORTHYON

 

 

USE master;

GO

ALTER DATABASE YourSQLDba SET TRUSTWORTHY ON;

 

 

还原数据库时,由于可能使用不同账号,那么就会出现数据库的owner出现变化的情况。当然,也有可能使用相同的账号操作,不会出现db_owner变化的情况。下面这种情况,就是源数据库的db_owner为sa,但是我使用域账号做了还原操作。数据库的db_owner变成了一个域账号。

 

 

clip_image004

 

 

USE [YourSQLDba];

GO         

EXEC sp_changedbowner "sa";

GO

 

将数据库的db_owner修改为sa,此时问题解决。当然也可以先修改db_owner,然后设置数据库的trustworth属性。分离附加数据库也会导致TRUSTWORTHY属性变化,还有可能导致数据库db_owner变化(这个取决于你操作时使用的账号),另外。这种错误只对权限为EXTERNAL_ACCESS 和UNSAFE的程序集出现,对于SAFE_ACCESS的程序集,不会出现这个问题。

 

 

 

 

 

 

参考资料:

 

https://support.microsoft.com/zh-cn/help/918040/you-may-receive-an-error-message-when-you-try-to-run-an-existing-clr-o

https://docs.microsoft.com/en-us/sql/relational-databases/security/trustworthy-database-property?view=sql-server-ver15

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/7882.html

(0)
上一篇 2023-03-12
下一篇 2023-03-12

相关推荐

  • 如何在PyCharm中打开多个项目

    如何在PyCharm中打开多个项目PyCharm是一个非常流行的Python IDE。对于开发人员而言,有时候需要同时打开多个项目,以便在不同的任务之间轻松切换。在本文中,将向您演示如何在PyCharm中打开多个项目。

    2024-09-15
    26
  • mongotemplate游标查询_游标使用

    mongotemplate游标查询_游标使用一、什么是游标? 游标(Cursor)是处理数据的一种方法,为了查看或者处理结果集中的数据,游标提供了在结果集中一次一行或者多行前进或向后浏览数据的能力。 游标实际上是一种能从包括多条数据记录的结果…

    2023-02-27
    171
  • 数据库-表结构设计性能优化「建议收藏」

    数据库-表结构设计性能优化「建议收藏」在进行数据库表结构设计时,最优性能设计建议如下:1、客户端IP两种存储方式(不考虑ipv6):1)、int2)、char(10)性能上考虑推荐使用int。2、有些表的电话号码改成varchar(12…

    2023-04-03
    165
  • 使用 Python 播放 MP3 文件

    使用 Python 播放 MP3 文件随着数字媒体技术的发展,音频文件已经成为日常生活中不可或缺的一部分。Python 语言中有很多好用的库可以帮助你读写和操作音频文件,比如说 Pygame、PyAudio、AudioSegment 等等。在本文中,我们将介绍如何使用 Python 语言播放 MP3 音频文件。

    2024-09-11
    26
  • 利用 Python Series 快速创建 Dataframe

    利用 Python Series 快速创建 DataframePython是一种广泛用于数据分析和数据科学的高级编程语言。在数据分析中,常常需要将数据结构化,并在表格中存储和分析。这就需要使用Pandas库提供的Dataframe。

    2024-05-11
    85
  • Python字符串拆分函数解析

    Python字符串拆分函数解析Python中的字符串拆分函数是split(),该函数的主要作用是将一个字符串按照指定的分隔符进行拆分,并返回一个由拆分后的字符串组成的列表。

    2024-01-31
    103
  • mysql8.0.19安装教程_mysql安装详解

    mysql8.0.19安装教程_mysql安装详解官网下载安装包:mysql-8.0.19-linux-glibc2.12-x86_64.tar.xz 安装环境:CentOS Linux release 7.5.1804 (Core) 解压安装包:

    2023-01-23
    146
  • MySQL 递归查询实践总结[通俗易懂]

    MySQL 递归查询实践总结[通俗易懂]MySQL复杂查询使用实例 By:授客 QQ:1033553122 表结构设计 SELECT id, `name`, parent_id FROM `tb_testcase_suite` 说明: pa

    2023-02-14
    167

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注