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

MySQL CommandBuilder 更新 DataTable 失效:拋棄它,改用參數化 Command

     編輯:程式設計綜合問答

現象:使用 `MySqlCommandBuilder` 自動生成 `UpdateCommand`,呼叫 `adapter.Update(dataTable)` 時報錯或無效果。

核心問題

  • `CommandBuilder` 要求 `SelectCommand` 必須包含主鍵欄位且為單表查詢,否則無法生成正確的 `WHERE` 條件。
  • 若 SQL 包含 `JOIN`、衍生欄位、或未選主鍵,生成的 `UpdateCommand` 會失效(`hardwareparameter_delectcommand` 為 null)。
  • 自動生成的 SQL 效能差、難除錯、不支援複雜型別映射。

推薦做法:手寫參數化 Command

// 1. 定義 UpdateCommand
string sql = @"UPDATE hardware_parameter 
               SET param_value = @val, update_time = NOW() 
               WHERE id = @id";

MySqlCommand cmd = new MySqlCommand(sql, conn);
cmd.Parameters.Add("@val", MySqlDbType.VarChar, 255, "param_value");
cmd.Parameters.Add("@id", MySqlDbType.Int32, 0, "id"); // SourceColumn 對應 DataTable 欄位
cmd.UpdatedRowSource = UpdateRowSource.None;

adapter.UpdateCommand = cmd;

// 2. 呼叫 Update
adapter.Update(dataTable); // 逐行執行參數化 SQL,安全高效

關鍵點

  1. SourceColumn:參數的 `SourceColumn` 屬性對應 `DataTable` 的欄位名,`Update` 時自動取值。
  2. 參數化防注入:避免字串拼接,型別安全。
  3. 顯式控制:可加入 `WHERE` 版本號(樂觀鎖)、審計欄位、觸發器配合等進階邏輯。

完整範例(含 Insert/Delete)

adapter.InsertCommand = new MySqlCommand(
    "INSERT INTO hardware_parameter (param_name, param_value) VALUES (@name, @val)", conn);
adapter.InsertCommand.Parameters.Add("@name", MySqlDbType.VarChar, 100, "param_name");
adapter.InsertCommand.Parameters.Add("@val", MySqlDbType.VarChar, 255, "param_value");

adapter.DeleteCommand = new MySqlCommand(
    "DELETE FROM hardware_parameter WHERE id = @id", conn);
adapter.DeleteCommand.Parameters.Add("@id", MySqlDbType.Int32, 0, "id");

避坑清單

  • ❌ 依賴 `CommandBuilder` 處理複雜查詢。
  • ❌ `SelectCommand` 未包含主鍵。
  • ❌ 參數 `SourceColumn` 拼寫錯誤(區分大小寫)。
  • ✅ 所有 CRUD 顯式定義 `MySqlCommand`,程式碼可讀、可測、可維護。

拋棄 `CommandBuilder`,擁抱顯式參數化 Command,是 ADO.NET/MySqlConnector 開發的專業標誌。

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