首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C# ADO.NET ExecuteNonQuery 語法錯誤排查:SQL 字串拼接缺失右括號

     編輯:程式設計疑難解答

執行 `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 (...)` 子句。
  • 資料庫收到不完整 SQL:INSERT ... VALUES ('v1','v2',...'v8' → 語法解析失敗,報錯位置指向語句末尾附近。
  • C# 的 `ExecuteNonQuery` 僅負責發送命令,**不會驗證 SQL 語法**,錯誤由資料庫引擎拋回。

修正後的代碼

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 注入攻擊 (原代碼直接拼接用戶輸入,極度危險)。
  • 執行計畫複用,資料庫效能更好。
  • 代碼可讀性高,SQL 模板與參數分離,易維護。

調試技巧:輸出實際 SQL 字串

若必須用拼接 (如動態表名、列名無法參數化),**執行前輸出完整 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 字串在資料庫工具中跑一次,立竿見影。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved