カテゴリ: C# 更新日: 2026/02/11

C#でデータを取得する基本!ExecuteReader・ExecuteScalarの違いを初心者向けに解説

C#でデータを取得する基本!ExecuteReader・ExecuteScalarの違い
C#でデータを取得する基本!ExecuteReader・ExecuteScalarの違い

先生と生徒の会話形式で理解しよう

生徒

「C#でデータベースからデータを取得する方法ってありますか?」

先生

「はい、C#のADO.NETを使えば、データベースから簡単にデータを取得できます。主にExecuteReaderとExecuteScalarという2つのメソッドを使います。」

生徒

「ExecuteReaderとExecuteScalarって何が違うんですか?」

先生

「取得するデータの量や形式によって使い分けます。詳しく見ていきましょう!」

1. ADO.NETとは?データベース操作の基本を知ろう

1. ADO.NETとは?データベース操作の基本を知ろう
1. ADO.NETとは?データベース操作の基本を知ろう

ADO.NET(エーディーオー・ドット・ネット)は、C#でデータベース操作を行うための技術です。データベースとは、大量のデータを効率的に保存・管理するための仕組みのことです。例えば、ショッピングサイトの商品情報や顧客情報などは、すべてデータベースに保存されています。

ADO.NETを使うことで、C#プログラムからデータベースに接続し、データの取得、追加、更新、削除などの操作ができるようになります。まるで図書館の司書さんが本を検索したり貸し出したりするように、プログラムがデータベースとやり取りできるようになるのです。

ADO.NETには、SqlConnection(データベースへの接続)、SqlCommand(SQL文の実行)、SqlDataReader(データの読み取り)など、さまざまなクラスが用意されています。これらを組み合わせることで、データベース操作を実現します。

2. ExecuteReaderとは?複数行のデータを取得する方法

2. ExecuteReaderとは?複数行のデータを取得する方法
2. ExecuteReaderとは?複数行のデータを取得する方法

ExecuteReaderは、データベースから複数行のデータを取得したいときに使うメソッドです。例えば、社員一覧や商品一覧など、たくさんのデータを一度に取得したい場合に適しています。

ExecuteReaderを実行すると、SqlDataReaderというオブジェクトが返されます。このオブジェクトは、データベースから取得した結果を1行ずつ読み進めることができる、まるで本のページをめくるような仕組みを持っています。

SqlDataReaderには、Read()というメソッドがあります。このメソッドを呼び出すたびに、次の行へと移動します。そして、現在の行のデータを列名やインデックスを指定して取得できます。データがなくなるとReadメソッドはfalseを返すので、while文と組み合わせて全てのデータを処理することができます。

ExecuteReaderは、大量のデータを効率的に処理できるという特徴があります。メモリに全データを一度に読み込むのではなく、必要な分だけ順次読み込んでいくため、パフォーマンスに優れています。

3. ExecuteReaderの使い方とサンプルコード

3. ExecuteReaderの使い方とサンプルコード
3. ExecuteReaderの使い方とサンプルコード

それでは、実際にExecuteReaderを使ってデータを取得するサンプルコードを見てみましょう。このコードでは、データベースから社員情報を取得して画面に表示します。


using System;
using System.Data.SqlClient;

class Program
{
    static void Main()
    {
        // データベース接続文字列
        string connectionString = "Server=localhost;Database=CompanyDB;Integrated Security=true;";
        
        // SQL文(社員テーブルから全データを取得)
        string sql = "SELECT EmployeeID, EmployeeName, Department FROM Employees";
        
        // データベースに接続
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            connection.Open();
            
            // SQLコマンドを作成
            SqlCommand command = new SqlCommand(sql, connection);
            
            // ExecuteReaderでデータを取得
            using (SqlDataReader reader = command.ExecuteReader())
            {
                // データが存在する限りループ
                while (reader.Read())
                {
                    // 各列のデータを取得して表示
                    int id = reader.GetInt32(0);  // 1列目(EmployeeID)
                    string name = reader.GetString(1);  // 2列目(EmployeeName)
                    string dept = reader.GetString(2);  // 3列目(Department)
                    
                    Console.WriteLine($"ID: {id}, 名前: {name}, 部署: {dept}");
                }
            }
        }
    }
}

このコードでは、まずSqlConnectionでデータベースに接続し、SqlCommandでSQL文を実行します。ExecuteReaderを呼び出すことで、SqlDataReaderオブジェクトが返されます。

while文とRead()メソッドを組み合わせることで、取得した全ての行を順番に処理しています。GetInt32やGetStringといったメソッドで、各列のデータを適切な型で取得できます。

実行結果は以下のようになります。


ID: 1, 名前: 山田太郎, 部署: 営業部
ID: 2, 名前: 佐藤花子, 部署: 経理部
ID: 3, 名前: 鈴木一郎, 部署: 開発部

4. ExecuteScalarとは?単一の値を取得する方法

4. ExecuteScalarとは?単一の値を取得する方法
4. ExecuteScalarとは?単一の値を取得する方法

ExecuteScalarは、データベースから単一の値(1つの値)だけを取得したいときに使うメソッドです。例えば、データの件数を取得したり、特定の商品の価格だけを取得したりする場合に適しています。

ExecuteScalarを実行すると、SQL文の実行結果の1行目の1列目の値が返されます。つまり、複数の行や列があったとしても、左上の1つの値だけが返されるということです。

返される値の型はobject型なので、実際に使用する際は適切な型にキャストする必要があります。キャストとは、データの型を変換することで、例えばobject型をint型に変換するといった操作です。

ExecuteScalarは、COUNT関数やMAX関数、MIN関数などの集計関数と組み合わせて使われることが多いです。集計関数とは、データベース内のデータを集計して1つの値を返す関数のことです。例えば、COUNTは件数、MAXは最大値、MINは最小値を返します。

5. ExecuteScalarの使い方とサンプルコード

5. ExecuteScalarの使い方とサンプルコード
5. ExecuteScalarの使い方とサンプルコード

それでは、ExecuteScalarを使って社員数を取得するサンプルコードを見てみましょう。COUNT関数を使って、データベースに登録されている社員の総数を取得します。


using System;
using System.Data.SqlClient;

class Program
{
    static void Main()
    {
        // データベース接続文字列
        string connectionString = "Server=localhost;Database=CompanyDB;Integrated Security=true;";
        
        // SQL文(社員の総数を取得)
        string sql = "SELECT COUNT(*) FROM Employees";
        
        // データベースに接続
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            connection.Open();
            
            // SQLコマンドを作成
            SqlCommand command = new SqlCommand(sql, connection);
            
            // ExecuteScalarで件数を取得
            int employeeCount = (int)command.ExecuteScalar();
            
            Console.WriteLine($"登録されている社員数: {employeeCount}人");
        }
    }
}

このコードでは、COUNT(*)を使って社員テーブルの全行数を取得しています。ExecuteScalarの戻り値はobject型なので、(int)でint型にキャストしています。

ExecuteScalarは非常にシンプルで、SqlDataReaderのようにループ処理を書く必要がありません。単一の値を取得するだけなので、コードも短く読みやすくなります。

実行結果は以下のようになります。


登録されている社員数: 3人

6. ExecuteReaderとExecuteScalarの違いと使い分け

6. ExecuteReaderとExecuteScalarの違いと使い分け
6. ExecuteReaderとExecuteScalarの違いと使い分け

ExecuteReaderとExecuteScalarの最も大きな違いは、取得するデータの量です。ExecuteReaderは複数行・複数列のデータを取得できるのに対し、ExecuteScalarは1つの値だけを取得します。

項目 ExecuteReader ExecuteScalar
取得するデータ量 複数行・複数列 1つの値のみ
戻り値の型 SqlDataReader object
使用例 一覧表示、複数レコード処理 件数取得、最大値・最小値取得
処理の複雑さ ループ処理が必要 シンプルな記述

使い分けの基準としては、複数の社員情報や商品情報など、複数のデータを処理したい場合はExecuteReaderを使用します。一方、データの総数や特定の1つの値だけが必要な場合はExecuteScalarを使用します。

適切なメソッドを選択することで、コードの可読性が向上し、パフォーマンスも最適化されます。無駄なデータ取得を避けることは、効率的なプログラミングにおいて重要なポイントです。

7. ExecuteScalarで特定の値を取得するサンプル

7. ExecuteScalarで特定の値を取得するサンプル
7. ExecuteScalarで特定の値を取得するサンプル

ExecuteScalarのもう1つの使用例として、特定の社員の給料を取得するコードを見てみましょう。WHERE句を使って条件を指定することで、必要なデータだけを取得できます。


using System;
using System.Data.SqlClient;

class Program
{
    static void Main()
    {
        // データベース接続文字列
        string connectionString = "Server=localhost;Database=CompanyDB;Integrated Security=true;";
        
        // 検索したい社員ID
        int targetEmployeeID = 1;
        
        // SQL文(特定社員の給料を取得)
        string sql = "SELECT Salary FROM Employees WHERE EmployeeID = @EmployeeID";
        
        // データベースに接続
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            connection.Open();
            
            // SQLコマンドを作成
            SqlCommand command = new SqlCommand(sql, connection);
            
            // パラメータを設定(SQLインジェクション対策)
            command.Parameters.AddWithValue("@EmployeeID", targetEmployeeID);
            
            // ExecuteScalarで給料を取得
            object result = command.ExecuteScalar();
            
            if (result != null)
            {
                decimal salary = (decimal)result;
                Console.WriteLine($"社員ID {targetEmployeeID} の給料: {salary:C}");
            }
            else
            {
                Console.WriteLine("該当する社員が見つかりませんでした。");
            }
        }
    }
}

このコードでは、パラメータを使用してSQLインジェクション攻撃を防いでいます。SQLインジェクションとは、悪意のあるSQL文を注入される攻撃のことで、パラメータを使うことで安全に値を渡すことができます。

また、ExecuteScalarの戻り値がnullの可能性があるため、nullチェックを行っています。データが見つからない場合はnullが返されるので、この確認は重要です。

実行結果は以下のようになります。


社員ID 1 の給料: ¥350,000

8. 実践的な使用例:データの存在チェック

8. 実践的な使用例:データの存在チェック
8. 実践的な使用例:データの存在チェック

ExecuteScalarは、データの存在チェックにも便利です。特定の条件に合うデータが存在するかどうかを確認する場合、EXISTS句やCOUNT関数と組み合わせて使用します。


using System;
using System.Data.SqlClient;

class Program
{
    static void Main()
    {
        // データベース接続文字列
        string connectionString = "Server=localhost;Database=CompanyDB;Integrated Security=true;";
        
        // チェックしたいメールアドレス
        string email = "yamada@example.com";
        
        // SQL文(メールアドレスの重複チェック)
        string sql = "SELECT COUNT(*) FROM Employees WHERE Email = @Email";
        
        // データベースに接続
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            connection.Open();
            
            // SQLコマンドを作成
            SqlCommand command = new SqlCommand(sql, connection);
            command.Parameters.AddWithValue("@Email", email);
            
            // ExecuteScalarで件数を取得
            int count = (int)command.ExecuteScalar();
            
            if (count > 0)
            {
                Console.WriteLine($"メールアドレス '{email}' は既に登録されています。");
            }
            else
            {
                Console.WriteLine($"メールアドレス '{email}' は使用可能です。");
            }
        }
    }
}

このコードは、新規ユーザー登録時などに、メールアドレスの重複をチェックする場合に使えます。ExecuteScalarで件数を取得し、0より大きければ既に登録済み、0であれば未登録と判断できます。

このような存在チェックは、ユーザー登録システムやログイン機能など、実際のアプリケーション開発で頻繁に使用されるパターンです。

9. エラーハンドリングと例外処理の重要性

9. エラーハンドリングと例外処理の重要性
9. エラーハンドリングと例外処理の重要性

データベース操作では、接続エラーやSQL文のエラーなど、さまざまなエラーが発生する可能性があります。そのため、try-catch文を使った例外処理を実装することが重要です。

例外処理とは、プログラム実行中にエラーが発生したときに、プログラムが異常終了しないように対処する仕組みです。エラーが起きても適切なメッセージを表示したり、ログに記録したりすることで、安定したアプリケーションを作ることができます。

usingステートメントを使うことで、データベース接続やSqlDataReaderなどのリソースが自動的に解放されます。これにより、メモリリークを防ぎ、効率的なリソース管理が可能になります。

また、データベース操作では、接続文字列の管理も重要です。セキュリティの観点から、接続文字列には機密情報が含まれるため、設定ファイルや環境変数に保存し、ソースコードには直接記述しないことが推奨されます。

10. パフォーマンスとベストプラクティス

10. パフォーマンスとベストプラクティス
10. パフォーマンスとベストプラクティス

ExecuteReaderとExecuteScalarを使用する際は、パフォーマンスを意識することが大切です。必要なデータだけを取得するように、SELECT文では列名を明示的に指定することが推奨されます。SELECT *は全ての列を取得してしまうため、不要なデータ転送が発生する可能性があります。

また、データベース接続は貴重なリソースなので、使用後は必ず閉じる必要があります。usingステートメントを使えば、自動的に接続が閉じられるため、閉じ忘れを防げます。

複数のデータベース操作を行う場合は、トランザクションを使用することで、データの整合性を保つことができます。トランザクションとは、複数の操作をまとめて1つの処理単位として扱う仕組みで、途中でエラーが発生した場合は全ての操作を取り消すことができます。

さらに、SQLインジェクション対策として、必ずパラメータ化されたクエリを使用してください。文字列連結でSQL文を構築すると、セキュリティの脆弱性が生じる可能性があります。

これらのベストプラクティスを守ることで、安全で効率的なデータベースアクセスを実現できます。初心者のうちから正しい習慣を身につけることが、将来的に高品質なアプリケーションを開発するための基礎となります。

カテゴリの一覧へ
新着記事
New1
C#
C#のパターンマッチングの基本!switch文の進化系を理解しよう
New2
COBOL
DB2・IMSなどメインフレームDBを活かす!COBOL資産の最新活用術
New3
COBOL
COBOLのMOVE文を完全ガイド!初心者でもわかるデータ移送の基本
New4
COBOL
COBOLのデータ定義をきれいに整えるルールとは?ピクチャ句整列の基本を初心者向けに解説
人気記事
No.1
Java&Spring記事人気No1
C#
C#のpartialクラスとは?初心者でも理解できるクラス分割の基本
No.2
Java&Spring記事人気No2
COBOL
COBOLの数値データ型「PIC 9」の使い方と注意点をやさしく解説!
No.3
Java&Spring記事人気No3
C#
C#のラムダ式の書き方と構文を初心者向けに完全解説
No.4
Java&Spring記事人気No4
COBOL
COBOLのコンパイラと開発環境を徹底解説!初心者にもわかりやすい入門ガイド
No.5
Java&Spring記事人気No5
C#
C#のクエリ式とメソッド式の書き換え方を完全ガイド!LINQの2つの書き方をマスター
No.6
Java&Spring記事人気No6
C#
C#の引数と戻り値の基本!値を受け渡し・返す仕組みを理解しよう
No.7
Java&Spring記事人気No7
C#
C#で型を調べる方法!GetType()・typeof演算子の違いと使い方
No.8
Java&Spring記事人気No8
C#
C#でswitch式を使う方法!C# 8.0以降の新機能を解説