一、方法說明
SqlCommand.ExecuteNonQuery()
適用場景:INSERT(新增)、UPDATE(更新)、DELETE(刪除),請勿用於SELECT查詢
回傳值:int 型別,代表SQL執行後受影響的資料列數
運作原理:資料庫執行DML陳述式後會回傳異動的列數,程式透過這個數值判斷操作是否生效。
回傳值的業務判斷邏輯
- INSERT:正常新增成功 → 回傳
1;失敗則拋出例外; - UPDATE:
- 找到符合條件資料並完成修改 → 回傳 ≥1
WHERE條件找不到任何資料 → 回傳0(語法沒有報錯,但沒有任何資料被更新)
- 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);
// 兩種寫法效果完全相同
//方式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)程式區塊結束後會自動釋放資料庫連線,避免連線洩漏問題。 - 參數名稱必須完全對應
SQL裡的@Title、@id要和SqlParameter的參數名稱一模一樣,大小寫不敏感但名稱不能寫錯。
三種SqlCommand方法比較
| 方法 | 用途 | 回傳值 |
|---|---|---|
| ExecuteNonQuery | 新增/刪除/修改(INSERT/UPDATE/DELETE) | int 受影響列數 |
| ExecuteScalar | 查詢單行單欄(如COUNT、取得自動編號ID) | object 第一列第一欄的數值 |
| ExecuteReader | 多列多行SELECT查詢 | SqlDataReader 資料流 |
ExecuteNonQuery
Previous: 執行最佳化與參數傳遞
Next: SqlTransaction 資料庫事務