Sql server 2005 Sql 2005 CLR集成-是否支持动态程序集加载?
我有一个静态类,它动态加载.NET程序集(使用Sql server 2005 Sql 2005 CLR集成-是否支持动态程序集加载?,sql-server-2005,sqlclr,Sql Server 2005,Sqlclr,我有一个静态类,它动态加载.NET程序集(使用assembly.LoadFile方法) 我收到以下错误消息: Msg 6522, Level 16, State 2, Line 3 A .NET Framework error occurred during execution of user-defined routine or aggregate "MySQLCLRUDFFunction": System.TypeInitializationException: The type init
assembly.LoadFile
方法)
我收到以下错误消息:
Msg 6522, Level 16, State 2, Line 3
A .NET Framework error occurred during execution of user-defined routine or aggregate "MySQLCLRUDFFunction":
System.TypeInitializationException: The type initializer for 'MyClassName' threw an exception. ---> System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed
当我尝试使用此声明分配CAS安全性时
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
相反,我得到了这个例外
Msg 6522, Level 16, State 2, Line 2
A .NET Framework error occurred during execution of user-defined routine or aggregate "MySQLCLRUDFFunction":
System.TypeInitializationException: The type initializer for 'MyClassName' threw an exception. ---> System.Security.SecurityException: Request failed.
Msg 6522, Level 16, State 2, Line 2
A .NET Framework error occurred during execution of user-defined routine or aggregate "MySQLCLRUDFFunction":
System.TypeInitializationException: The type initializer for 'MyClassName' threw an exception. ---> System.IO.FileLoadException: LoadFrom(), LoadFile(), Load(byte[]) and LoadModule() have been disabled by the host.
注意:我已授予我的SQL Server服务帐户“完全访问”磁盘上的动态资产文件。我使用以下语法复制了动态程序集:
create Assembly TestAssembly
From 'C:\MyTestAssembly.dll';
--Alter Assembly to copy dynamic assembly file
Alter Assembly TestAssembly add file from 'C:\mydynamicassembly.dll';
在打开“可信”并设置“权限”\u SET=UNSAFE后,我现在获得此异常
Msg 6522, Level 16, State 2, Line 2
A .NET Framework error occurred during execution of user-defined routine or aggregate "MySQLCLRUDFFunction":
System.TypeInitializationException: The type initializer for 'MyClassName' threw an exception. ---> System.Security.SecurityException: Request failed.
Msg 6522, Level 16, State 2, Line 2
A .NET Framework error occurred during execution of user-defined routine or aggregate "MySQLCLRUDFFunction":
System.TypeInitializationException: The type initializer for 'MyClassName' threw an exception. ---> System.IO.FileLoadException: LoadFrom(), LoadFile(), Load(byte[]) and LoadModule() have been disabled by the host.
我猜在创建程序集时,您已经将权限设置为SAFE(如果您没有指定它,这将是默认设置)。如果要这样做,您需要将其更改为外部访问或不安全
我是从事SQL-CLR集成的@Microsoft开发人员之一,因此我可能会提供帮助 要实现您的目标,您需要做两件事:
如果可能的话,考虑重新设计应用程序,以便将所有需要的程序集预加载到数据库本身。
[编辑:如果以上任何一项都没有帮助,最好在MSDN论坛上提问]。如错误消息所述,SQL Server完全不允许动态程序集加载-即使在不安全的情况下也是如此。Assembly.Load调用成功的唯一方法是,如果程序集已通过CREATE Assembly加载到数据库中,或加载到GAC和上。上还有一篇关于这个问题的帖子。我知道这是一个非常古老的问题,但我最近找到了一种方法来实现你想要的。当您尝试在SQL CLR托管的程序集中使用
Assembly.Load(…)
时,它将显式失败,这是出于设计考虑,即使在权限设置=不安全的情况下也是如此。这是为了确保数据库服务器的稳定性
加载动态程序集的技术是首先注册它们,然后使用type.GetType(…)
传递完全限定的类型名称(包括程序集版本信息)解析类型
以下是步骤:
1.编译类型,并在磁盘上完成(即,不要创建内存中的程序集)。CompilerResults
类型将具有CompiledAssembly
属性和PathToCompiledAssembly
属性。将后者用作访问CompiledAssembly
属性将尝试使用Assembly.Load
2.使用路径,我从我的代码(使用new-SqlConnection(“Context-Connection=true”)
)调用一个存储过程,我将其传递给程序集的名称(我已经预先确定)和编译的程序集路径:
CREATE PROCEDURE re.CreateAssembly
@name VARCHAR(100),
@path VARCHAR(1000)
AS
BEGIN
DECLARE @sql NVARCHAR(2000)
SET @sql = N'CREATE ASSEMBLY [' + @name + '] AUTHORIZATION [DatabaseUser] FROM ''' + @path + ''' WITH PERMISSION_SET + SAFE';
EXEC sp_executesql @sql;
END
GO
3.使用预先确定的名称,可以使用Type.GetType(…)
,例如:
string typeName = "MyCompiledAssembly.MyClass, MyCompiledAssembly, Version=0.0.0.0, Culture=Neutral, PublicKeyToken=null, ProcessorArchitecture=MSIL";
Type type = Type.GetType(typeName);
当SQLCLR尝试解析该类型时,它应该会找到它,因为在步骤2中,您已经向Sql Server注册了程序集。@Greg Beech和@DenNukem-感谢您的想法。我尝试了权限更改,但仍然得到了最后一个异常-我已编辑了原始问题的详细信息。异常似乎是表示程序集的动态加载已禁用…嗯,这听起来很有说服力;如果SQL Server已显式禁用它,则听起来您将无法动态加载程序集。即使在不安全模式下,我也不知道这是一个限制。有趣的方法。只是出于好奇:您何时需要使用类似的方法?什么情况需要动态加载,并且不知道提前加载什么?@srutzky在撰写本文时,.NET 3.5仍在等待-我已经将我的OOS项目RazorEngine向后移植到.NET 3.5,以便我可以将其安装到Sql Server中,以便在数据库级错误报告机制上使用在SQL中创建一组表(因为DB是每个其他系统之间的公分母),它将触发一封限制错误电子邮件。Razor用于控制电子邮件模板。由于RazorEngine为每个模板生成唯一的DLL,因此必须加载它们才能执行。