この記事は、SQL Server の別のインスタンスから移動されたデータベースで CLR オブジェクトを操作するときに発生する可能性がある 2 つの異なる問題を解決するのに役立ちます。
元の製品バージョン: SQL Server
元の KB 番号: 918040
現象
次のシナリオについて考えてみます。 SQL Server のインスタンスにあるデータベースをデタッチまたはバックアップします。 SQL Server のインスタンスがサーバー A で実行されています。その後、そのデータベースを、サーバー B で実行されている SQL Server のインスタンスにアタッチまたは復元します。このシナリオでは、次の現象が発生する可能性があります。
サーバー B 上のデータベースから
external_accessまたは安全でないアクセス許可が設定されている既存の共通言語ランタイム (CLR) オブジェクトを実行しようとすると、次のエラー メッセージが表示されます。メッセージ 10314、レベル 16、状態 11、行 2
アセンブリ ID 65536 の読み込み中に、Microsoft .NET Framework でエラーが発生しました。 サーバーのリソースが不足しているか、PERMISSION_SET が EXTERNAL_ACCESS または UNSAFE に設定されていて、アセンブリが信頼されていない可能性があります。 クエリを再実行するか、アセンブリの信頼関係の問題を解決する方法をマニュアルで確認してください。 このエラーの詳細については、次を参照してください。
System.IO.FileLoadException: ファイルまたはアセンブリ 'AssemblyName, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' またはその依存関係の 1 つを読み込めませんでした。 セキュリティに関連するエラーが発生しました。 (HRESULT からの例外: 0x8013150A)System.IO.FileLoadException:
at System.Reflection.Assembly.nLoad(System.Reflection.Assembly.nLoad(String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection) at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMarkMark&system.Reflection.Assembly.Load(String assemblyString) の stackMark、Boolean forIntrospection)同じデータベースに
external_accessまたは安全でないアクセス許可が設定されている新しいアセンブリを作成しようとすると、次のエラー メッセージが表示されます。サーバー: メッセージ 10327、レベル 14、状態 1、行 1
アセンブリ 'AssemblyName' の CREATE ASSEMBLY が失敗しました。アセンブリ 'AssemblyName' は PERMISSION_SET = EXTERNAL_ACCESSに対して承認されていません。 アセンブリは、次のいずれかに該当する場合に承認されます。データベース所有者 (DBO) に EXTERNAL ACCESS ASSEMBLY 権限があり、データベースに TRUSTWORTHY データベース プロパティがあります。または、アセンブリが、EXTERNAL ACCESS ASSEMBLY 権限を持つ対応するログインを持つ証明書または非対称キーで署名されています。
この問題は、 Trustworthy データベース プロパティを既に ON に設定している場合でも発生します。
原因
この問題は、サーバー A 上のデータベースの作成に使用するログインが、サーバー B 上の SQL Server のインスタンスにないために発生します。このログインは、Microsoft Windows ログインまたは SQL Server ログインのいずれかです。
回避策
この問題を回避するには、次のいずれかの方法を使用します。
Note
次のメソッドを使用する前に、 Trustworthy データベース プロパティを有効にしてください。
sp_changedbownerストアド プロシージャを使用して、データベース所有者を sa またはサーバー B で使用可能なログインに変更します。たとえば、次のステートメントを使用して、データベース所有者を sa に変更できます。USE <DatabaseName> GO EXEC sp_changedbowner 'sa'Note
このステートメントでは、
<DatabaseName>は作業中のデータベースの名前のプレースホルダーです。 変更されたデータベース所有者には、特定のタスクを実行するための対応するアクセス許可が必要です。 たとえば、データベース所有者には、アセンブリを作成するための CREATE ASSEMBLY 権限が必要です。データベースの作成に使用するサーバー A 上の SQL Server のインスタンスに、サーバー B 上の SQL Server のインスタンスへのログインを追加します。
ログインがドメイン アカウントの場合は、サーバー B で同じログインを作成できます。次に、サーバー B の SQL Server インスタンスのログインに必要なアクセス許可を付与します。
ログインが SQL Server ログインの場合は、このログインの SID が、サーバー B 上の SQL Server のインスタンスで作成した新しい SQL Server ログインと一致していることを確認します。これを行うには、 CREATE LOGIN ステートメントの SID 引数を指定します。
詳細
別のデータベースから CLR オブジェクトにアクセスし、そのデータベースに DBO SID が一致しない場合は、同じ問題が発生する可能性があります。
詳細については、次のブログを参照してください: CSS SQL Server エンジニア。