一、メソッドの説明
SqlCommand.ExecuteNonQuery()
利用シーン:INSERT(登録)、UPDATE(更新)、DELETE(削除)。SELECT文には使用しないでください
戻り値:int型、SQL実行後に影響を受けた行数を返します
仕組み:DML文を実行するとデータベースから変更行数が返り、プログラム側でこの数値を見て処理が適用されたか確認します。
戻り値による業務判断ロジック
- INSERT:正常登録完了 →
1を返却;失敗時は例外が発生; - UPDATE:
- 条件に合致するレコードを更新 → ≥1 を返却
WHERE条件に該当行なし →0を返却(SQL自体は正常完了、ただし更新対象が存在しない)
- DELETE:
- 該当データを削除 → ≥1 を返却
- 該当データなし →
0を返却
重要な区別:戻り値0=プログラムエラーではない。SQLの文法は問題なく実行されているが、条件に合致するレコードが存在しなかっただけです。
INSERT 登録サンプル
private void button2_Click(object sender, EventArgs e)
{
string connectionString = "Data Source=.;Initial Catalog=db;Integrated Security=True";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand sqlCom = new SqlCommand();
sqlCom.Connection = conn;
// SQLインジェクション対策のパラメータ化SQL
sqlCom.CommandText = "INSERT INTO [dbo].[Article]([Title]) VALUES(@Title)";
sqlCom.CommandTimeout = 60;
SqlParameter param = new SqlParameter("@Title", SqlDbType.NVarChar, 250);
param.Value = "新しいタイトル" + DateTime.Now;
param.Direction = ParameterDirection.Input;
sqlCom.Parameters.Add(param);
int res = sqlCom.ExecuteNonQuery();
MessageBox.Show(res.ToString());
// 登録成功時 res=1
}
}Code language: JavaScript (javascript)
メリット:パラメータ化クエリ。文字列連結によるSQLインジェクションの脆弱性を回避します。
UPDATE 更新サンプル
conn.Open();
SqlCommand sqlCom = new SqlCommand();
sqlCom.Connection = conn;
sqlCom.CommandText = "UPDATE [dbo].[Article] SET [Title] = @Title WHERE id = @id";
sqlCom.CommandTimeout = 60;
SqlParameter param = new SqlParameter("@Title", SqlDbType.NVarChar, 250);
param.Value = "新しいタイトル"+DateTime.Now;
param.Direction = ParameterDirection.Input;
sqlCom.Parameters.Add(param);
// 2通りのパラメータ追加方法、どちらも同じ動作
//方式1:インスタンス生成後に追加
SqlParameter param2 = new SqlParameter("@id", SqlDbType.Int);
param2.Value = 5;
sqlCom.Parameters.Add(param2);
//方式2:チェーン記述(コメントアウトしている書き方)
//sqlCom.Parameters.Add(new SqlParameter("@id", SqlDbType.Int){Value=5});
int res = sqlCom.ExecuteNonQuery();
MessageBox.Show(res.ToString());Code language: JavaScript (javascript)
- テーブルに
id=5のレコードが存在 →res=1 id=5のレコードが存在しない →res=0
業務上の判定例:
if(res > 0)
{
MessageBox.Show("更新完了");
}
else
{
MessageBox.Show("対象レコードが見つからなかったため更新されませんでした");
}Code language: JavaScript (javascript)
補足事項
- 例外が発生しないだけで処理成功と判断してはいけません
SQLエラーが出なくてもデータが変更されていない場合があります(条件に該当行が無く戻り値0)。必ず影響行数で業務結果を確認してください。 ExecuteNonQueryをSELECTに使わない
SELECT実行時は常に-1が返り、取得データを受け取れません。データ参照にはExecuteReader()/ExecuteScalar()を使用してください。- using構文のメリット
using(SqlConnection conn)ブロック終了時に自動でDB接続を解放し、接続リークを防ぎます。 - パラメータ名は完全一致させる
SQL内の@Title、@idはコード側のSqlParameter名と完全に揃える必要があります。大文字小文字は区別されませんが名称の誤りは不可。
3種類のSqlCommandメソッド比較
| メソッド | 用途 | 戻り値 |
|---|---|---|
| ExecuteNonQuery | 登録/更新/削除(INSERT/UPDATE/DELETE) | int 影響を受けた行数 |
| ExecuteScalar | 1行1列取得(COUNT、自動採番ID取得など) | object 先頭行先頭列の値 |
| ExecuteReader | 複数行複数列のSELECT | SqlDataReader データストリーム |
ExecuteNonQuery
Previous: 実行の最適化とパラメータ受け渡し