2

.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 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.

注: 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';

回転TRUSTWORTHY ONして設定した後PERMISSION_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.IO.FileLoadException: LoadFrom(), LoadFile(), Load(byte[]) and LoadModule() have been disabled by the host.
4

4 に答える 4

2

エラー メッセージに示されているように、SQL Server では動的アセンブリの読み込みが完全に許可されていません。Assembly.Load 呼び出しが成功する唯一の方法は、アセンブリが CREATE ASSEMBLY を介してデータベースに、または GAC と、サポートされている ("祝福された") アセンブリのリストに既に読み込まれている場合です。これに関する別の投稿がsqlclr blogにあります。

于 2010-02-24T03:30:39.367 に答える
1

これは今では非常に古い質問であることは知っていますが、最近、あなたが望むものを達成する方法を見つけました. Assembly.Load(...)SQL CLR でホストされているアセンブリで使用しようとすると、明示的に失敗します。これは設計によるものであり、 PERMISSION_SET = UNSAFE. これは、データベース サーバーの安定性を確保するためです。

動的アセンブリをロードする方法は、最初にアセンブリを登録してからType.GetType(...)、完全修飾型名 (アセンブリのバージョン情報を含む) を渡して型を解決することです。

手順は次のとおりです。

1. 型をコンパイルし、ディスク上でファイナライズします (つまり、インメモリ アセンブリを作成しません)。CompilerResults型にはプロパティCompiledAssemblyPathToCompiledAssemblyプロパティがあります。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 に登録しているためです。

于 2011-09-21T07:13:45.103 に答える
0

CREATE ASSEMBLY を実行したときに、PERMISSION_SET を SAFE に設定したと思います (指定しなかった場合、これがデフォルトになります)。これを行うには、EXTERNAL_ACCESS または UNSAFE に変更する必要があります。

http://msdn.microsoft.com/en-us/library/ms189524.aspx

于 2009-11-12T16:28:25.990 に答える
0

私は Microsoft で SQL-CLR 統合に取り組んだ開発者の 1 人だったので、お役に立てるかもしれません。

目的を達成するには、次の 2 つのことを行う必要があります。

  1. データベースを TRUSTWORTHY としてマークする
  2. アセンブリを UNSAFE としてマークします (データベースは信頼できる必要があります)
  3. SQL Server を実行するアカウントには、ファイル システム上のファイルにアクセスする権限が必要です。多くの場合、ファイルはネットワーク共有上にありますが、SQL Server はネットワークへのアクセス権限を持たないローカル アカウントで実行されているため、これが問題になることがよくあります。デフォルト インストールの SQL Express には、C: に対する権限がありません。

これらすべてを実行すると、いくつかのマイナスの副作用があることに注意してください。

  1. 深刻なセキュリティへの影響 - 安全でないアセンブリのコードにインスタンスの制御を効果的に委譲しているため、生のポインターを使用してエンジン内のあらゆるものにアクセス/変更できるようになりました。
  2. 安定性 - 同じ理由で、安定性の保証も放棄しています。
  3. 移植性と災害復旧 - 負荷分散のためにデータベースを別の場所に移動する必要がある場合、またはマシンの障害後にデータベースをバックアップから復元する場合、新しいマシンには mydynamicassembly.dll がありません。

可能であれば、必要なすべてのアセンブリがデータベース自体に事前に読み込まれるように、アプリを再設計することを検討してください。

[編集: 上記のいずれも役に立たない場合は、MSDN フォーラムで質問するのが最善です]。

于 2009-11-12T16:41:20.627 に答える