更新日: 2006 年 2 月 1 日

このコンテンツのポイント

  • Multiple Active Result Sets の利用方法を理解する。

今回紹介するコード

<Program.cs>

C#
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;

namespace MARSSample
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SqlConnection cnn = new SqlConnection(
                "Data Source=.\\SQLEXPRESS;Initial Catalog=AdventureWorks;" +
                "Integrated Security=true;MultipleActiveResultSets=true"))
            {
                cnn.Open();
                SqlCommand cmd1 = new SqlCommand(
                    "SELECT * FROM Production.ProductCategory", cnn);

                // 1つ目の結果セットをアクティブ化
                SqlDataReader rdr1 = cmd1.ExecuteReader();
                while (rdr1.Read())
                {
                    SqlCommand cmd2 = new SqlCommand(
                        "SELECT * FROM Production.ProductSubcategory" +
                        " WHERE ProductCategoryID=@ID", cnn);
                    cmd2.Parameters.AddWithValue("@ID", rdr1["ProductCategoryID"]);

                    // 2つ目の結果セットをアクティブ化
                    SqlDataReader rdr2 = cmd2.ExecuteReader();
                    while (rdr2.Read())
                    {
                        Console.WriteLine("{0} / {1}", rdr1["Name"], rdr2["Name"]);
                    }
                }
            }
        }
    }
}
 

目次

はじめに
作成するアプリケーションの概要
コンソール アプリケーションの作成
MARS を利用するコードの実装
動作と解説
おわりに

Visual Basic の内容はこちらに掲載しています。
10 行でズバリ !! Multiple Active Result Sets の利用 (VB)

はじめに

SQL Server 2005 では、Multiple Active Result Sets (MARS) という、アクティブな結果セットを複数保持する機能が追加されています。

ADO.NET 2.0 では、この MARS を利用することで、より柔軟なデータ アクセスを行うことが出来ます。

今回の 10 行シリーズでは、MARS を使用する方法について、簡単なサンプル アプリケーションを通じて解説します。

作成するアプリケーションの概要

今回は、MARS を使用し複数の結果セットを取得するコンソール アプリケーションを作成します。

複数のデータに対して、DataReader でのネストしたループ処理を実施し、複数の結果セットよりデータの取得を行います。

なお、データベースとしては SQL Server 2005 に付属の 「AdventureWorks」 サンプル データベースを使用します。 (SQL Server 2005 Express Edition を使用している場合は、ダウンロードセンタ / SQL Server 2005 Express Edition ドキュメントとサンプル より別途入手します。)

コンソール アプリケーションの作成

Visual Studio 2005 を起動して、新規にプロジェクトを作成します。

ここでは、 [Visual C#] - [コンソール アプリケーション] テンプレートを使用し、プロジェクト名 “MARSSample” にてプロジェクトを作成します。

図 1. コンソール アプリケーションの作成

MARS を利用するコードの実装

プロジェクトを作成した際に、コンソール アプリケーション用に自動生成されたファイル (“Program.cs”) に、MARS を利用するコードを記述します。

まず始めに、SQL Server データ プロバイダの各クラスを利用する際に名前空間を省略できるように、以下の赤字で書かれているコードを記述します。

C#
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;

namespace MARSSample
{
    class Program
    {
        …
    }
}
 

次に、今回使用するデータベースへの接続を行う、以下の赤字で書かれているコードを記述します。

C#
namespace MARSSample
{
    class Program
    {
        static void Main(string[] args)
        {
            using (SqlConnection cnn = new SqlConnection(
                "Data Source=.\\SQLEXPRESS;Initial Catalog=AdventureWorks;" +
                "Integrated Security=true;MultipleActiveResultSets=true"))
            {
                cnn.Open();
            }
        }
    }
}
 

今回のコードでは、using ステートメントを使った典型的な接続パターンを使用しています。

上記の例では、接続文字列としては、同一マシーン上の SQLEXPRESS インスタンスの AdventureWorks データベースへ Windows 認証にて接続を行う形で設定していますので、環境に応じた適切な接続文字列を設定します。

なお、MARS を有効にするための接続文字列 “MultipleActiveResultSets=true” も併せて設定します。

更に、DataReader でのネストしたループ処理によるデータ取得を行うために、以下の赤字で書かれているコードを記述します。

C#
namespace MARSSample {     class Program
    {
        static void Main(string[] args)
        {
            using (SqlConnection cnn = new SqlConnection(
                "Data Source=.\\SQLEXPRESS;Initial Catalog=AdventureWorks;" +
                "Integrated Security=true;MultipleActiveResultSets=true"))
            {
                cnn.Open();
                SqlCommand cmd1 = new SqlCommand(
                    "SELECT * FROM Production.ProductCategory", cnn);

                // 1つ目の結果セットをアクティブ化
                SqlDataReader rdr1 = cmd1.ExecuteReader();
                while (rdr1.Read())
                {
                    SqlCommand cmd2 = new SqlCommand(
                        "SELECT * FROM Production.ProductSubcategory" +
                        " WHERE ProductCategoryID=@ID", cnn);
                    cmd2.Parameters.AddWithValue("@ID", rdr1["ProductCategoryID"]);

                    // 2つ目の結果セットをアクティブ化
                    SqlDataReader rdr2 = cmd2.ExecuteReader();
                    while (rdr2.Read())
                    {
                        Console.WriteLine("{0} / {1}", rdr1["Name"], rdr2["Name"]);
                    }
                }
            }
        }
    }
}
 

上記のコードでは、1 つ目の結果セットによるループの中で 2 つめの結果セットによるループを実施し、取得したデータを順次表示しています。

なお、2 つの結果セットをアクティブ化する際に使用している SqlCommand オブジェクト (cmd1 / cmd2) では、同じ SqlConnection オブジェクト (cnn) を使用しています。

動作と解説

作成したコンソール アプリケーションを実行します。

図 2. サンプル アプリケーションの実行

上記の通り、1 つの接続のみを使用し、1 つ目の結果セット (ProductCategory) をアクティブ化した状態で 2 つめの結果セット (ProductSubcategory) もアクティブ化され、順に取得したデータが表示されます。

次に、MARS を無効化するために接続文字列内の “MultipleActiveResultSets” の設定を “false” へ修正後、再度コンソール アプリケーションを実行します。

図 3. MARS 無効時の複数アクティブ化例外

MARS が無効な場合は、2 つ目の結果セットをアクティブ化しようとすると、上記の通り例外が発生します。

 

 

Multiple Active Result Sets (MARS) は特定の接続にて、複数の結果セットをアクティブ化出来るように SQL Server 2005 で追加された機能です。

従来の SQL Server 2000 などでは、1 つの結果セットしか同時にアクティブ化出来ない制約があったため、複数の結果セットをアクティブ化したい場合、2 つの接続を使用する必要がありました。

ただし、その場合は接続が複数に分かれるため、トランザクション制御や排他制御などを考慮した上で使用する必要がありました。

MARS を利用することにより、複数の結果セットが同じ接続内で利用できるため、1 つのトランザクション内で複数の結果セットを取り扱うことが可能となります。

MARS の詳細については、下記の技術情報を参照ください。

SQL Server 2005 の複数のアクティブな結果セット (MARS)

おわりに

このように、MARS を利用することで、同じ接続にてアクティブな結果セットを複数使用することが出来ます。

これにより、今まで以上に柔軟なデータ アクセスを行うことが可能となります。

MARS の特徴を理解した上でデータ アクセス アプリケーション開発に、ぜひ活用ください。


Code Recipe

ページのトップへ