既存の CLR オブジェクトを実行するか、アセンブリを作成するときにエラーが発生する

この記事では、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(AssemblyName fileName, 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, StackCrawlMark&stackMark, Boolean forIntrospection) at System.Reflection.Assembly.Load(String assemblyString)

  • 同じデータベースにまたは安全でないアクセス許可が設定されている external_access 新しいアセンブリを作成しようとすると、次のエラー メッセージが表示されます。

    サーバー: メッセージ 10327、レベル 14、状態 1、行 1
    アセンブリ 'AssemblyName' の CREATE ASSEMBLY が失敗しました。アセンブリ 'AssemblyName' は、PERMISSION_SET = EXTERNAL_ACCESSに対して承認されていないためです。 データベース所有者 (DBO) に EXTERNAL ACCESS ASSEMBLY 権限があり、データベースに信頼できるデータベース プロパティが設定されている場合、アセンブリは承認されます。または、アセンブリが証明書または EXTERNAL ACCESS ASSEMBLY アクセス許可を持つ対応するログインを持つ非対称キーで署名されています。

この問題は、データベース プロパティを既に ON に Trustworthy 設定している場合でも発生 します

原因

この問題は、サーバー A でデータベースを作成するために使用するログインが、サーバー B のSQL Serverのインスタンスにないために発生します。このログインは、Microsoft Windows ログインまたは SQL Server ログインのいずれかです。

回避策

この問題を回避するには、次のいずれかの方法を使用します。

注:

次のメソッドを使用する前に、データベース プロパティを Trustworthy 有効にしてください。

  • ストアド プロシージャを使用して、 sp_changedbowner データベース所有者を sa または Server B で使用可能なログインに変更します。たとえば、次のステートメントを使用して、データベース所有者を sa に変更できます。

    USE <DatabaseName>
    GO
    
    EXEC sp_changedbowner 'sa'
    

    注:

    このステートメントでは、 は、 <DatabaseName> 作業中のデータベースの名前のプレースホルダーです。 変更されたデータベース所有者には、特定のタスクを実行するための対応するアクセス許可が必要です。 たとえば、データベース所有者は、アセンブリを作成するための CREATE ASSEMBLY アクセス許可を持っている必要があります。

  • サーバー A 上のSQL Serverのインスタンスにログインを追加します。このログインは、サーバー B の SQL Server のインスタンスにデータベースを作成するために使用されます。

ログインがドメイン アカウントの場合は、サーバー B で同じログインを作成できます。次に、サーバー B の SQL Server インスタンスのログインに必要なアクセス許可を付与します。

ログインがSQL Server ログインの場合は、このログインの SID が、サーバー B の SQL Server のインスタンスで作成した新しいSQL Server ログインと一致していることを確認します。これを行うには、 ステートメントの SID 引数をCREATE LOGIN指定します。

詳細

別のデータベースから CLR オブジェクトにアクセスし、そのデータベースに DBO SID が一致しない場合、同じ問題が発生する可能性があります。

詳細については、CSS SQL Server エンジニアに関するブログを参照してください。

関連情報