特集
SQL Server 2005の新機能「SQL CLR」(前編)

SQL Serverプログラミングを革新するSQL CLRとは?

中 博俊(Microsoft MVP 2005 - Visual C#)
2005/03/09
Page1 Page2 Page3

●ADO.NETのDataAdapterクラスを利用した場合について

 ADO.NETでは、ここまでに紹介した.NETデータ・プロバイダ(SqlCommandクラス)という接続型のクラスによってSQL処理を実行する方法に加えて、非接続型のクラスであるDataAdapterクラスによる方法が存在する。この両者の違いは、.NETデータ・プロバイダがデータベースと直接的にデータのやり取りを行うのに対し、非接続型クラスはDataSetクラスにデータを表形式で保持する仕組みを提供し、それを介してデータのやり取りを行うことである。つまり、非接続型のクラスを利用する場合には、必要なデータをいったんDataSetオブジェクトとして読み取り、それに対する更新を行ってから、最後にまとめてデータベースに反映するという形式になる。

 この非接続型のDataAdapterクラスを利用したADO.NETプログラムは、以下のようなイメージで実行される。

DataAdapterクラスを利用したプログラムの実行イメージ
この実行イメージは、DataAdapterクラスの派生クラスであるSqlDataAdapterクラスを利用した場合のものだ。SqlDataAdapterオブジェクトでは、最初にSELECT、INSERT、UPDATEそしてDELETEなどのSQL命令文を含んだSqlCommandオブジェクトを、それぞれSelectCommand、InsertCommand、UpdateCommand、DeleteCommandというSqlDataAdapterオブジェクトのプロパティに指定するが、ここで指定されたSqlCommandオブジェクトを通じてSQL Serverにアクセスすることになる。例えばデータベースからデータを取得して表示するには、まずSelectCommandプロパティに指定されたSqlCommandオブジェクトを通じてSELECT命令文を発行し、次にそこで得られた結果セットをDataSetオブジェクトに格納する。さらにそのDataSetオブジェクトに対して追加、修正、削除が行われると、それに合わせてInsertCommand、UpdateCommand、DeleteCommandなどのプロパティに指定されたSqlCommandオブジェクトを介してINSERT、UPDATE、DELETEの各SQL命令文を発行する。これらすべての処理をDataAdapterオブジェクトが行ってくれる。

 上図を見ると分かるようにDataAdapterクラスを利用する場合でも(.NETデータ・プロバイダを直接利用する場合と同じように)、すべてのデータ・アクセス処理は.NETプログラム側のプロセス上で処理され、データベースには.NETデータ・プロバイダであるSqlCommandクラスを経由してSQL文が送信される(またはストアド・プロシージャを呼び出す)形になる。

 非接続型のクラスによる処理では、データベース・サーバへのアクセス数を減らすことができるが、データベース・サーバと.NETプログラムとの間で、場合によって大量のデータ転送が必要となることがある。また、このような理由により、大量のデータを読み込んで何らかの処理を施し、そのデータを再びテーブルに書き込むといった、いわゆる「バッチ処理」を非常に苦手としている。

 さらには、ADO.NETはサーバ・カーソル(すべての結果セットをクライアントに持ってくるのではなく、1行ずつもしくは数行のブロックずつ必要なだけのデータを取得するための機能。これにより大量の結果セットに対しても効率的な処理ができる)をサポートしていない。

 そのため、データ処理のパフォーマンスの観点から、すべてのSQL処理を(SQL Server側で実行される)ストアド・プロシージャで行うことが奨励されているのが現状だ。しかし、この状況は次期SQL Server 2005の登場により変化するだろうと筆者は考えている。より効率的なSQL処理が可能なSQL CLRという新機能が追加されるからだ。

 それでは次に、本稿の本題であるそのSQL CLRについて解説していくことにしよう。

2. SQLプログラミングを革新するSQL CLRとは?

 先ほど述べた従来のストアド・プロシージャは、SQL処理を行うには最も適しているとされる。ただしこれは逆にSQL処理以外の分野にはとても弱いということの裏返しでもある。例えば、ストアド・プロシージャのT-SQL言語には、ライブラリ(クラス群を再利用するために、それらをまとめてパッケージ化したもの)といった概念がない。また、SQLに関係しないWebへのアクセスや、XMLの読解、メール送信といった機能は一切持っていない。最近の言語では必ず用意されている配列や、コレクションさえもないのが現状だ。

 よってSQL処理の世界から一歩外に出るためには、他者の力を借りなければいけない。そのための解決策として、拡張ストアド・プロシージャが用意されている。拡張ストアド・プロシージャは前述したようにC/C++言語で記述された単体のDLLファイルなので、これを使うことでWebへのアクセスといったSQL処理以外の処理を実装できるようになる。

 しかし、この拡張ストアド・プロシージャにも問題がある。確かに、SQL Serverのコンテキスト上で動き、SQL Serverのプロセスで動いてはくれるものの、「そのプログラミングは難しい(使い慣れていないC/C++言語を使わなければならない)」「安全性が低い(C/C++言語によるネイティブ・コードは、.NET言語によるマネージ・コードと異なり、メモリ・リークなどのシステム問題を起こしやすく、もし起こしてしまうとサーバをダウンさせてしまう原因となり得る)」「セキュリティが弱い(後述するが、SQL CLRのようなシステム・リソースへのアクセスに対する権限セットが用意されていない)」などの課題が残っている。

●「SQL CLR」という解決策

 そこでその解決策として期待されるのが、次期SQL Server 2005より導入されるのが「SQL CLR」という機能だ。

 SQL CLRでは、従来のT-SQL言語ではなく、C#やVisual Basic .NETのような.NET Framework上でコンパイル可能なプログラム言語を用いて記述するので、.NETプログラマが容易にSQL CLRによるSQLプログラミングを習得できる。作成したSQL CLRのプログラムはSQL Server上で動作し、なおかつ.NET Frameworkのクラス群も使えるため、XMLの読解や配列、コレクションなどの機能にも不自由しない。

●SQL CLRのコーディング

 まずは、先ほど示したサンプル・コードと同じテーブル更新処理を、今度はSQL CLRで実装してみよう。

SqlCommand com = SqlContext.GetCommand();
com.CommandText = "UPDATE [table1] set [value]=@value where [key]=@key";
com.Parameters.Add("@value", SqlDbType.NVarChar, 100);
com.Parameters.Add("@key", SqlDbType.Int);
com.Parameters["@value"].Value = "更新後";
com.Parameters["@key"].Value = 1;
com.ExecuteNonQuery();
SQL CLRを利用したストアド・プロシージャのサンプル・コード(C#)
ここで利用しているSqlCommandクラスはSystem.Data.SqlServer名前空間のものだ。ここまでに出てきたSystem.Data.SqlClient名前空間のSqlCommandクラスと異なるので注意が必要だ。ただし、利用方法はここまでのSqlCommandクラス(System.Data.SqlClient名前空間)と同様だ。
 
Dim com As SqlCommand = SqlContext.GetCommand()
com.CommandText = "UPDATE [table1] set [value]=@value where [key]=@key"
com.Parameters.Add("@value", SqlDbType.NVarChar, 100)
com.Parameters.Add("@key", SqlDbType.Int)
com.Parameters.Item("@value").Value = "更新後"
com.Parameters.Item("@key").Value = 1
com.ExecuteNonQuery()
SQL CLRを利用したストアドプロシージャのサンプル・コード(VB.NET)
ここで利用しているSqlCommandクラスはSystem.Data.SqlServer名前空間のものだ。ここまでに出てきたSystem.Data.SqlClient名前空間のSqlCommandクラスと異なるので注意が必要だ。ただし、利用方法はここまでのSqlCommandクラス(System.Data.SqlClient名前空間)と同様だ。

 上記コードを従来のADO.NETのコードと見比べてほしい。どうだろうか。いままでのADO.NETのコードとほとんど同じということがお分かりいただけただろう。

●.NETアセンブリの登録

 先に述べたようにSQL CLRのプログラムは、SQL Server内で動作し、外部の.NETプログラムから呼び出し可能なプログラムである。しかし上記のように記述したソース・コードをコンパイルしただけでは、単に.NETのDLLファイル(アセンブリ)を作成したにすぎにない。このDLLファイルをSQL Serverから呼び出し可能にするためには、これをSQL Serverに登録する必要がある。

SQL CLRのDLLファイルをSQL Serverに登録するまでの流れ図
SQL CLRのDLLファイルをSQL Serverから呼び出し可能にするためには、そのDLLファイル(アセンブリ)をSQL Serverにあらかじめ登録しておく必要がある。
  通常のDLLファイルを作成するのと同様にコンパイルを行う。
  出来上がったDLLファイルをデータベースに登録する。
  登録したDLLファイルの呼び出し方法などを登録する。

 上図のようにして事前にアセンブリ(SQL CLR用のDLLファイル)をSQL Serverに登録しておくことにより、いつでもそのアセンブリが呼び出し可能な状態になる。Visual Studio 2005で開発する際には、この一連の作業をVisual Studio 2005が自動化してくれる。従って、Visual Studioを使えばこれらの手順を意識することなく開発できるのだ。これについては次回詳しく解説する。

 それではこのようにしてSQL Serverにアセンブリを登録することのメリットは何なのだろうか。次のページでそれについて解説しよう。


 INDEX
  [特集]SQL Server 2005の新機能「SQL CLR」(前編)
  SQL Serverプログラミングを革新するSQL CLRとは?
     1.従来のSQLプログラミングについて
   2.SQLプログラミングを革新するSQL CLRとは?
     3.SQL CLRの特長とストアド・プロシージャとの使い分け
  [特集]SQL Server 2005の新機能「SQL CLR」(後編)
  Visual Studio 2005でSQL CLRを実装してみる
     1.SQL CLRプログラミングの種類
     2.SQL CLRでHello World!を作成してみる
     3.Visual StudioによるSQL CLRの開発
     4.SQL CLRプログラムの実行
 


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間