執行 `cmd.ExecuteNonQuery()` 時拋出「附近有語法錯誤」,90% 以上原因是 **SQL 字串拼接錯誤**,而非 C# 代碼本身。本文以題目代碼為例,演示如何快速定位並修復。
string sql = string.Format(
"insert into Daily(Date,StarTime,Endtime,Person,Failure,Reason,Solution,Message) " +
"values ('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}'", // <-- 這裡缺少右括號 ')'
txtDdate.Text, txtDstartime.Text, txtDendtime.Text, txtDperson.Text,
txtDfailure.Text, txtDreason.Text, txtDstartime.Text, txtDmessage.Text);
string.Format 生成的 SQL 字串以 values ('...','...','...','...','...','...','...','...' 結束,**缺少右括號 `)`** 閉合 `values (...)` 子句。INSERT ... VALUES ('v1','v2',...'v8' → 語法解析失敗,報錯位置指向語句末尾附近。string sql = string.Format(
"insert into Daily(Date,StarTime,Endtime,Person,Failure,Reason,Solution,Message) " +
"values ('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}')", // <-- 補上 ')'
txtDdate.Text, txtDstartime.Text, txtDendtime.Text, txtDperson.Text,
txtDfailure.Text, txtDreason.Text, txtDstartime.Text, txtDmessage.Text);
絕對不要用字串拼接/Format 構建 SQL! 改用 `SqlParameter`:
string sql = @"INSERT INTO Daily (Date, StarTime, Endtime, Person, Failure, Reason, Solution, Message)
VALUES (@Date, @StarTime, @Endtime, @Person, @Failure, @Reason, @Solution, @Message)";
using (SqlConnection conn = new SqlConnection(connString))
using (SqlCommand cmd = new SqlCommand(sql, conn)) {
cmd.Parameters.AddWithValue("@Date", txtDdate.Text);
cmd.Parameters.AddWithValue("@StarTime", txtDstartime.Text);
cmd.Parameters.AddWithValue("@Endtime", txtDendtime.Text);
cmd.Parameters.AddWithValue("@Person", txtDperson.Text);
cmd.Parameters.AddWithValue("@Failure", txtDfailure.Text);
cmd.Parameters.AddWithValue("@Reason", txtDreason.Text);
cmd.Parameters.AddWithValue("@Solution", txtDsolution.Text); // 注意:原代碼這裡用了 txtDstartime.Text 兩次,疑為複製錯誤
cmd.Parameters.AddWithValue("@Message", txtDmessage.Text);
conn.Open();
int x = cmd.ExecuteNonQuery();
if (x > 0) MessageBox.Show("成功");
else MessageBox.Show("失敗");
}
若必須用拼接 (如動態表名、列名無法參數化),**執行前輸出完整 SQL 到日誌/控制台**,用資料庫客戶端工具 (SSMS、DBeaver) 直接執行驗證:
System.Diagnostics.Debug.WriteLine("SQL: " + sql);
// 或
Console.WriteLine(sql);
| 問題 | 現象 | 修正 |
|---|---|---|
| 字串值含單引號 (如 O'Neil) | SQL 斷裂 | 參數化查詢 / 替換為兩個單引號 '' |
| 日期格式不匹配 | 資料庫報類型轉換錯誤 | 參數化傳 DateTime 物件 / 統一用 ISO 格式 'YYYY-MM-DD' |
| 欄位名為保留字 (如 Date, Order, Key) | 語法錯誤 | 加方括號 [Date] 或反引號 `Date` |
| VALUES 子句數量與列數不符 | 列數/值數不匹配 | 逐一對照,參數化自動對應 |
本案例錯誤純屬 **SQL 字串漏寫右括號 `)`**。
**鐵律:永遠使用參數化查詢 (`SqlParameter`)**,同時解決語法錯誤、SQL 注入、特殊字元、效能四大問題。若遇語法錯誤,第一步輸出完整 SQL 字串在資料庫工具中跑一次,立竿見影。