C# ADO.NET ストアドプロシージャの呼び出しと SqlDataReader
SQL Server ストアドプロシージャを呼び出し、SqlDataReader でクエリ結果をストリーム読み込みする、主なポイント:
SqlCommand.CommandType = CommandType.StoredProcedureでストアドプロシージャ実行を指定SqlParameterを使ってストアドプロシージャにパラメータを渡すExecuteReader(CommandBehavior.CloseConnection)でストリームデータを取得- 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の働き
SqlDataReaderがClose()呼び出し、または解放された際、紐付いているSqlConnectionを自動的に閉じます。
利用シーン:メソッドからReaderオブジェクトを返し、外部でデータ読み終わった後接続を自動回収する場合。
SqlDataReader 重要な特徴
- 順方向専用・読取専用:
Read()で下へ進むだけ、戻ったりデータ変更は不可 - 接続を占有:Readerオープン中は同一接続で別操作を実行できない
- リソース解放必須:手動で
reader.Close()、推奨はusingによる自動解放 - カラム取得の2通り:
csharp reader[0]; // インデックス指定 reader["Title"]; // フィールド名指定(可読性高い)
注意点
CommandType.StoredProcedureの設定漏れ → 実行エラー- パラメータ名の大文字小文字・スペルがプロシージャと不一致 → パラメータ不整合
- Readerを閉じ忘れ → 接続が解放されずコネクションプール枯渇
while(reader.Read())内部で新たなDBクエリ実行:同一接続で複数Readerは使用不可- ストアドプロシージャのパラメータ不足、型不一致 → 実行時エラー
比較
| 実行メソッド | 適用場面 | 戻りオブジェクト |
|---|---|---|
| ExecuteNonQuery | 登録・更新・削除のストアドプロシージャ | 影響行数 int |
| ExecuteScalar | 1行1列を返す(集計クエリ) | object |
| ExecuteReader | 複数行データセット取得 | SqlDataReader(ストリーム読み取り) |
SqlDataReader
Previous: SqlTransaction データベーストランザクション
Next: SqlDataAdapter