SqlDataReader

C# ADO.NET ストアドプロシージャの呼び出しと SqlDataReader

SQL Server ストアドプロシージャを呼び出し、SqlDataReader でクエリ結果をストリーム読み込みする、主なポイント:

  1. SqlCommand.CommandType = CommandType.StoredProcedure でストアドプロシージャ実行を指定
  2. SqlParameterを使ってストアドプロシージャにパラメータを渡す
  3. ExecuteReader(CommandBehavior.CloseConnection) でストリームデータを取得
  4. SqlDataReaderは順方向専用・読み取り専用のストリームリーダー。利用後は必ず閉じる

ストアドプロシージャ定義

事前にデータベース上にストアドプロシージャを作成してから呼び出してください。

create proc myProc
@id int
as
select * from [dbo].[Article] where id>@id
go

-- 呼び出しテスト
exec myProc @id=5Code language: JavaScript (javascript)

引数@idを受け取り、Articleテーブルからidが渡した値より大きいレコードを取得します。

C#からストアドプロシージャを呼び出す

ExecuteReaderによりSqlDataReaderを取得し、複数行のデータを読み取れます。

string connectionString = "Data Source=.;Initial Catalog=db;Integrated Security=SSPI;";
using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();
    SqlCommand sqlCom = new SqlCommand();
    sqlCom.Connection = conn;
    sqlCom.CommandText = "myProc";
    sqlCom.CommandType = CommandType.StoredProcedure;

    SqlParameter param = new SqlParameter("@id", SqlDbType.Int, 8);
    param.Value = 4;
    param.Direction = ParameterDirection.Input;
    sqlCom.Parameters.Add(param);

    SqlDataReader reader = sqlCom.ExecuteReader(CommandBehavior.CloseConnection);
    StringBuilder sb = new StringBuilder();
    while (reader.Read())
    {
        sb.AppendLine(reader[0] + "-" + reader[1]);
    }
    reader.Close();
    MessageBox.Show(sb.ToString());
}Code language: C# (cs)
usingでReaderを解放しリソースリークを防ぐ
string connectionString = "Data Source=.;Initial Catalog=db;Integrated Security=SSPI;";
using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();
    using (SqlCommand sqlCom = new SqlCommand("myProc", conn))
    {
        sqlCom.CommandType = CommandType.StoredProcedure;//コマンドがストアドプロシージャであることを指定
        // 入力パラメータ追加
        sqlCom.Parameters.Add("@id", SqlDbType.Int).Value = 4;

        // CommandBehavior.CloseConnection:reader閉鎖時に接続も自動で閉じる
        using (SqlDataReader reader = sqlCom.ExecuteReader(CommandBehavior.CloseConnection))
        {
            StringBuilder sb = new StringBuilder();
            while (reader.Read())
            {
                // reader[0]が1列目、reader[1]が2列目。reader["カラム名"]でも参照可
                sb.AppendLine($"{reader[0]}-{reader[1]}");
            }
            MessageBox.Show(sb.ToString());
        }
        // reader.Close()の手動呼び出し不要、usingが自動解放
    }
}Code language: C# (cs)

CommandType 3種類の列挙値

  • CommandType.Text:通常のSQL文を実行
  • CommandType.StoredProcedureストアドプロシージャ実行
  • CommandType.TableDirect:テーブルを直接読み込み

StoredProcedureを設定しないと、プロシージャ名を普通のSQLとみなし実行エラーになります!

SqlParameter パラメータ方向

  • ParameterDirection.Input:入力パラメータ(値を渡す、最もよく使う)
  • ParameterDirection.Output:出力パラメータ
  • ParameterDirection.InputOutput:入出力両用パラメータ
  • ParameterDirection.ReturnValue:ストアドプロシージャ戻り値

CommandBehavior.CloseConnectionの働き

SqlDataReaderClose()呼び出し、または解放された際、紐付いているSqlConnectionを自動的に閉じます
利用シーン:メソッドからReaderオブジェクトを返し、外部でデータ読み終わった後接続を自動回収する場合。

SqlDataReader 重要な特徴

  1. 順方向専用・読取専用Read()で下へ進むだけ、戻ったりデータ変更は不可
  2. 接続を占有:Readerオープン中は同一接続で別操作を実行できない
  3. リソース解放必須:手動でreader.Close()、推奨はusingによる自動解放
  4. カラム取得の2通り:
    csharp reader[0]; // インデックス指定 reader["Title"]; // フィールド名指定(可読性高い)

注意点

  1. CommandType.StoredProcedureの設定漏れ → 実行エラー
  2. パラメータ名の大文字小文字・スペルがプロシージャと不一致 → パラメータ不整合
  3. Readerを閉じ忘れ → 接続が解放されずコネクションプール枯渇
  4. while(reader.Read())内部で新たなDBクエリ実行:同一接続で複数Readerは使用不可
  5. ストアドプロシージャのパラメータ不足、型不一致 → 実行時エラー

比較

実行メソッド適用場面戻りオブジェクト
ExecuteNonQuery登録・更新・削除のストアドプロシージャ影響行数 int
ExecuteScalar1行1列を返す(集計クエリ)object
ExecuteReader複数行データセット取得SqlDataReader(ストリーム読み取り)

SqlDataReader

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です