SQL CLRを極める3つのコーディング・テクニックSQL Server 2005を使いこなそう(6)(2/3 ページ)

» 2006年07月15日 00時00分 公開
[石橋潤一株式会社システムインテグレータ]

外部データベースへの接続

 SQL CLRを利用する大きなメリットの1つとして、外部データベースへの接続が挙げられます。ストアドプロシージャやユーザー定義関数などから外部データベースへ接続できるため、異種データベース間でのデータ連携などデータベース・プログラミングにおける柔軟性が大きく高まっています。

 外部データベースへの接続に当たって、下記の2点に注意する必要があります。

  1. 権限セットの指定
  2. コンテキスト接続と通常の接続

1.権限セットの指定

 権限セットについては、第4回「SQL CLRの仕組みとメリットを理解しよう」ですでに取り上げました。ネットワークやファイル、外部データベースなど多様なリソースへのアクセスが可能なSQL CLRの動作を制限するための仕組みです。今回は外部データベースへの接続を行うので、この権限セットを変更する必要があります。

 SQL CLRは権限セットのデフォルトで「セーフ」が指定され、外部リソースへのアクセスが不可能な状態となっていますが、外部リソースを利用する場合は、「外部」を指定します。

 「外部」や「アンセーフ」を指定する場合、「セーフ」に比べセキュリティが緩くなったことを踏まえて、作成したアセンブリへのアクセスを制限するなどの対策が必要となります。SQL CLRのセキュリティの詳細は、MSDN2のドキュメント「CLR統合のセキュリティ」を確認してください。

 また、セキュリティ上の懸念から「外部」「アンセーフ」を利用するにはかなり厳しい条件をクリアする必要があります。条件の詳細は同じくMSDN2のドキュメント「アセンブリの作成」を確認してください。マイクロソフトの推奨では、アセンブリファイルから非対称キーを作成し、そのキーにマップするログインを作成する必要があります。権限セットの変更がどれだけのセキュリティ的な脅威をもたらすか、この条件から分かりますね。

1 アセンブリファイルより非対称キーを作成し、キーにひも付けられるログインを作成する。このログインに対し、利用する権限セットに合わせて「EXTERNAL ACCESS ASSEMBLY」または「UNSAFE ASSEMBLY」権限を与える
2 データベース所有者(DBO)が利用する権限セットに合わせて「EXTERNAL ACCESS ASSEMBLY」または「UNSAFE ASSEMBLY」権限を持ち、さらにデータベースの「TRUSTWORTHY」データベース・プロパティがONに設定されている。非推奨
表1 権限セット「外部」「アンセーフ」を利用するための条件

権限セット「外部」「アンセーフ」を利用するためには、上記条件のいずれかを満たす必要がある。

メモ:Visual Studio上では権限セット名が次のように翻訳されています。MSDNでは翻訳前の英語名が使われているので注意してください。翻訳は外部アクセス、とした方が分かりやすいですよね。

英語名 翻訳名
SAFE セーフ
EXTERNAL_ACCESS 外部
UNSAFE アンセーフ


 権限セットを変更するには、プロジェクトのプロパティより行います。「プロジェクト」メニュー内の「<プロジェクト名>のプロパティ」より「データベース」タブを開き、「アクセス許可のレベル」を「外部」に設定します(図1)。

図1 アクセス許可レベルの設定 図1 アクセス許可レベルの設定(画像をクリックすると拡大します)

2.コンテキスト接続と通常の接続

 SQL CLRでは、大きく分けて2種類のデータベースへの接続方法がサポートされています。1つが前回で解説したコンテキスト接続であり、2つ目が一般的なADO.NETなどで見慣れた接続先を指定する通常の接続です。コンテキスト接続は実行時の認証情報を引き継ぎインプロセスで実行されるため、通常の接続に対しパフォーマンスの面で優位性を持っています。

 今回は外部データベースへの接続を行うため、通常の接続によるSQL CLRの実行を確認してみましょう。以下にコンテキスト接続と通常の接続との違いを示します。接続文字列の記述が異なるだけで、コード自体に大きな違いはないことが分かります。

//コンテキスト接続
//using(SqlConnection conn =
            new SqlConnection("context connection=true")) {
//通常の接続
using (SqlConnection conn =
           new SqlConnection(
               "server=MyServer; database=AdventureWorks; " +
               "user id=MyUser; password=Password"))
{
    conn.Open();
    SqlCommand cmd = new SqlCommand(
        "SELECT Name, GroupName FROM HumanResources.Department",
        conn);
    SqlDataReader r = cmd.ExecuteReader();
    while (r.Read())
    {
        SqlContext.Pipe.Send(r);
    }
}
リスト4 コンテキスト接続と通常の接続との違い

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。