web-dev-qa-db-ja.com

Visual Studio 2017を使用したSQLCLR C#関数の発行エラー

Visual Studio 2017を使用してSQLCLR関数を公開(学習)しようとしています(これは、電子メールを送信する単純な関数です)。

参考として、この記事を CodeProject および MSSQLTips で使用しました。

Visual Studio 2013データベースプロジェクトを使用したSQL CLR関数の作成、実行、デバッグ、および展開

CLRストアドプロシージャを使用してSQL Server Expressから電子メールを送信

プロジェクトのプロパティ-> SQLCLRで設定しました:

Permission level : UNSAFE

そして記事によると、ターゲットデータベースを更新しました:

sp_configure 'clr enabled', 1;  
GO  
RECONFIGURE;  
GO  

エラーが発生した後、MSSQLTipsの記事で次のアドバイスに従いました。

コードをコンパイルしようとしたときにエラーメッセージが表示された場合は、次のコマンドを使用してデータベースを変更し、アセンブリとストアドプロシージャの作成を再試行する必要がある場合があります。

ALTER DATABASE msdb SET trustworthy ON

2つの異なるターゲットデータベースを使用してみました。

  • SQL-Server 2017 LocalDB
  • SQL-Server 2017 Express

エラーなしでプロジェクトをビルドできますが、プロジェクトを公開すると、次のコマンドを実行すると1つのエラーが発生します。

CREATE Assembly [dbSysmac]
    AUTHORIZATION [dbo]
    FROM 0x5F8A900003000000...
    WITH PERMISSION_SET = UNSAFE;

(47,1):SQL72014:.Net SqlClientデータプロバイダー:メッセージ10327、レベル14、状態1、行1アセンブリ 'dbSysmac'のアセンブリは信頼されていないため、アセンブリの作成に失敗しました。アセンブリは、次のいずれかに該当する場合に信頼されます。アセンブリは、UNSAFEアセンブリ権限を持つ対応するログインを持つ証明書または非対称キーで署名されているか、sp_add_trusted_Assemblyを使用して信頼されています。

私は何を間違っていますか?

3
McNets

ターゲットデータベースを更新しました。

_ sp_configure 'clr enabled', 1;
_

明確にするために、「clrが有効」および_sp_configure_は一般にインスタンスレベルであり、データベースレベルの構成ではありません。

MSSQLTipsの記事でこのアドバイスに従いました

うわぁ。さて、MSSQLTipsに関するその記事は、発生しているエラーというよりも問題です。その記事で見たすべてを忘れて、二度とそれを見たことがなければ、それが最善でしょう。それは悪いアドバイスでいっぱいです:

  1. SQLCLRは必要ありません SQL Server Expressでの電子メールの送信 (これをテストしましたが、機能します)。ただし、SQL Server Express LocalDBでは機能しません機能しません:
  2. 入力パラメーターの型(および戻り値の型)には、SqlStringではなくStringを使用する必要があります
  3. msdbに配備していますか?多分それは私だけかもしれませんが、msdbにコードをデプロイすることは決してありません(また、プロシージャをスタートアッププロシージャとしてマークする場合など、物理的に必要な場合にのみコードをmasterに追加しますまたはシステムプロシージャとして)。
  4. UNSAFE権限セット?どうして?メールは?アセンブリは_EXTERNAL_ACCESS_である必要があります。コード(アセンブリ、ログイン、ユーザー、その他)には、必要以上のアクセス許可を与えないでください。
  5. _TRUSTWORTHY ON_をmsdbに設定することは、2つの問題を同時に発生させます:
    1. _TRUSTWORTHY ON_の設定は面倒です。確かに、概念実証/クイックテストを実行することは問題ありませんが、長期的/生産レベルの優れたオプションではありません。これは大きなセキュリティリスクです。代わりに、---(Module Signing を使用する必要があります。これを実現するために私が書いたガイドを以下に示します。これはVisual Studio内で行います。
      SQLCLRとSQL Server 2017、パート2:「CLR厳密なセキュリティ」-ソリューション1
    2. TRUSTWORTHYはすでにONmsdbです。少なくともデフォルトではONです。
  6. _@body_入力パラメーターは、NVARCHAR(MAX)ではなくNVARCHAR(4000)にする必要があります。結局のところ、これはHTMLメールです(つまり、_myMessage.IsBodyHtml = True_)。
  7. いいえ、絶対にしないでください.NETコードにプレーンテキストの電子メールパスワードを保存してください。 DLL /アセンブリは暗号化されていません。 [〜#〜] all [〜#〜]文字列は、EXEの末尾に現状のまま格納されます/ DLL /アセンブリ。アセンブリの内容を表示するのにほとんど労力は必要ありません。このアドバイスに従えば、SMTPサーバー、ログイン、パスワードが誰にでも見られるように保存されます。それらを変数から渡すか、単純なクエリを実行してテーブルから選択します。 Windowsレジストリから取得することもできます。

実際にどのデータベースに公開していますか? msdbではない別のデータベースにパブリッシュしているとすると、少なくとも単純に言えば、この時点で先に進むには、パブリッシュ先のDBに_TRUSTWORTHY ON_を設定する必要があります。ただし、TRUSTWORTHYを有効にすることはテスト用です(次を参照してください: 偽装、TRUSTWORTHY、およびクロスDB所有権の連鎖の使用を中止してください )。

ここで、_ALTER DATABASE..._を手動で実行した後もパブリッシュ時にエラーが発生する場合は、「データベースプロパティのデプロイ」オプションが選択されている可能性があります(Visual Studioの場合:[プロジェクトプロパティ]から[デバッグ]に移動します)タブ|下部にある「展開オプション」領域)。 TRUSTWORTHYは、これらのデータベースプロパティの1つです。したがって、「データベースプロパティのデプロイ」がチェックされている場合、すべてのデプロイメントはプロジェクトで定義されているものと一致するようにオプションを設定します。また、デフォルトでは、Trustworthyは有効になっていません。

オプションは次のとおりです:

  1. データベースプロパティを展開する場合:

    Visual StudioでTrustworthyを有効にするには(デプロイメントの場合):[プロジェクトプロパティ]に移動します。 「プロジェクト設定」タブ| 「データベース設定...」ボタン| 「その他」タブ。 「信頼できる」のチェックボックスをオンにして、「OK」ボタンをクリックします。

  2. データベースプロパティを展開しない場合:

    アセンブリを展開しているデータベースで信頼できるものを有効にします(TRUSTWORTHYmsdbを有効にしても役に立たない)

  3. 開発でこれを正しく機能させたら、本番環境に移行する前にセキュリティを適切に処理します。

    SQLCLRとSQL Server 2017、パート2:「CLR厳密なセキュリティ」-ソリューション1

一般的なSQLCLRの詳細については、次のWebサイトをご覧ください SQLCLR Info 。 SQL Server Centralでこのトピックについて書いているシリーズである「SQLCLRへの階段」リンクを必ずチェックしてください。

2
Solomon Rutzky