备份还原过后或者对数据库分离&附加后(移动数据库文件),发现一些权限为EXTERNAL_ACCESS和UNSAFE程序集对应的CLR函数,在调用的时候会出现一些错误。下面特意用YourSQLDba备份还原到一个测试环境,然后调用CLR函数,就会遇到如下错误:故障报错:
USE YourSQLDba;GOSELECT *FROM [yUtl].[clr_GetFolderList]('C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\DATA\','*.mdf');
故障分析: 检查发现assembly_id=65537的程序集为YourSqlDba_ClrFileOp 出现这种错误,一般是EXTERNAL_ACCESS 和UNSAFE的程序集,错误出现的具体原因有两种: 1: 数据库Owner的SID变化了。无论你是备份还原还是分离附加操作,都要确保数据库所有者SID在数据库属性中显示的内容与源数据库元数据中记录的内容之间匹配。如果使用备份/还原,则数据库所有者SID可能不匹配(取决于你操作时使用的账号),这将阻止CLR代码运行。 2: 数据库的TRUSTWORTHY属性值变化了。 数据库属性TRUSTWORTHY用于指明SQL Server实例是否信任该数据库以及其中的内容。 默认情况下,此设置为 OFF,但是可以使用ALTER DATABASE语句将其设置为ON. 下面检查数据库的属性TRUSTWORTHY(is_trustworth_on), 如下所示
源数据库的属性TRUSTWORTHY,就会发现数据库还原后,TRUSTWORTHY属性会变化(is_trustworth_on从1变为了0)
处理: 设置YourSQLDba的属性TRUSTWORTHY为ON USE master;GOALTER DATABASE YourSQLDba SET TRUSTWORTHY ON;
还原数据库时,由于可能使用不同账号,那么就会出现数据库的owner出现变化的情况。当然,也有可能使用相同的账号操作,不会出现db_owner变化的情况。下面这种情况,就是源数据库的db_owner为sa,但是我使用域账号做了还原操作。数据库的db_owner变成了一个域账号。 EXEC sp_changedbowner 'sa'; 将数据库的db_owner修改为sa,此时问题解决。当然也可以先修改db_owner,然后设置数据库的trustworth属性。分离附加数据库也会导致TRUSTWORTHY属性变化,还有可能导致数据库db_owner变化(这个取决于你操作时使用的账号),另外。这种错误只对权限为EXTERNAL_ACCESS 和UNSAFE的程序集出现,对于SAFE_ACCESS的程序集,不会出现这个问题。
|