string accesstr = "update [管理員] set [用戶]='" + text1 + "'"; // ❌ 無 WHERE
OleDbCommand cmd = new OleDbCommand(accestr, cnn);
cmd.ExecuteNonQuery(); // 導致所有行 [用戶] 列都變為 text1
SQL `UPDATE` 無 `WHERE` 子句 → **更新表中所有行**。
// 假設表有主鍵 [編號] (AutoNumber/主鍵)
string sql = "UPDATE [管理員] SET [用戶] = @user WHERE [編號] = @id";
using (OleDbConnection cnn = new OleDbConnection(connStr)) {
cnn.Open();
using (OleDbCommand cmd = new OleDbCommand(sql, cnn)) {
// 參數化:防注入、處理特殊字符、類型安全
cmd.Parameters.AddWithValue("@user", text1);
cmd.Parameters.AddWithValue("@id", targetId); // 從 UI 獲取:DataGridView 選中行、TextBox 輸入等
int rows = cmd.ExecuteNonQuery();
if (rows > 0) MessageBox.Show("更新成功");
else MessageBox.Show("未找到指定記錄");
}
}
| UI 場景 | 獲取 ID 方式 |
|---|---|
| DataGridView 選中行 | `int id = Convert.ToInt32(dgv.CurrentRow.Cells["編號"].Value);` |
| ListBox 選中項 | `int id = ((DataRowView)listBox.SelectedItem).Row.Field |
| TextBox 手動輸入 | `int id = int.Parse(txtId.Text);` (需驗證) |
| ComboBox 選中 | `int id = (int)comboBox.SelectedValue;` (ValueMember="編號") |
public bool UpdateUser(int adminId, string newUserName) {
const string sql = "UPDATE [管理員] SET [用戶] = @user WHERE [編號] = @id";
string connStr = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\test.mdb";
try {
using (var cnn = new OleDbConnection(connStr))
using (var cmd = new OleDbCommand(sql, cnn)) {
cmd.Parameters.Add("@user", OleDbType.VarWChar).Value = newUserName;
cmd.Parameters.Add("@id", OleDbType.Integer).Value = adminId;
cnn.Open();
return cmd.ExecuteNonQuery() > 0;
}
} catch (OleDbException ex) {
// 記錄日誌
throw new ApplicationException("數據庫更新失敗", ex);
}
}
| 錯誤寫法 | 問題 | 正確寫法 |
|---|---|---|
| 字符串拼接 SQL | 注入風險、格式錯誤 | 參數化 `@param` |
| 無 WHERE 條件 | 全表更新 | 主鍵 WHERE |
| 不釋放連接/命令 | 連接泄漏、鎖表 | `using` 自動釋放 |
| AddWithValue 類型推斷 | 隱式轉換可能錯誤 | 顯式 `Add(type).Value` |
**UPDATE 必須帶 WHERE**,定位主鍵。**參數化查詢**是底線。Access (Jet/ACE) 同樣支持參數化,語法 `@param` / `?` 均可。`using` 確保資源釋放,拒絕手動 `Dispose()`。