程式碼:
String sql = "insert into User(name,password) values(?,?)";
PreparedStatement st = conn.prepareStatement(sql);
st.setString(1, name);
st.setString(2, password);
int num = st.executeUpdate(sql); // ❌ 錯誤:再次傳遞 SQL 字串
拋出異常:MySQLSyntaxErrorException: ... syntax to use near '?,?)'
PreparedStatement.executeUpdate(String sql) 簽名是針對 Statement 介面設計,會直接執行傳入的 SQL 字串,忽略先前設定的參數綁定。導致資料庫收到字面 insert into User(name,password) values(?,?),而非替換後的值,產生語法錯誤。
String sql = "insert into User(name,password) values(?,?)";
PreparedStatement st = conn.prepareStatement(sql);
st.setString(1, name);
st.setString(2, password);
int num = st.executeUpdate(); // ✅ 正確:無參數版本,使用預編譯 SQL 與已綁定參數
| 方法 | 適用介面 | 行為 |
|---|---|---|
executeUpdate() | PreparedStatement | 執行預編譯 SQL,使用已綁定參數 ✅ |
executeUpdate(String sql) | Statement | 直接執行字串 SQL,忽略參數綁定 ❌ |
executeQuery() | PreparedStatement | 查詢操作,使用已綁定參數 ✅ |
execute() | PreparedStatement | 通用執行,使用已綁定參數 ✅ |
public static void insert(String name, String password) {
String sql = "INSERT INTO User(name, password) VALUES(?, ?)";
// try-with-resources 自動關閉資源 (JDBC 4.1+)
try (Connection conn = DbUtils.getConn();
PreparedStatement st = conn.prepareStatement(sql)) {
st.setString(1, name);
st.setString(2, password);
int affectedRows = st.executeUpdate(); // 關鍵:無參數版本
if (affectedRows > 0) {
System.out.println("插入成功,影響行數: " + affectedRows);
} else {
System.out.println("插入失敗,無資料異動");
}
} catch (SQLException e) {
System.err.println("資料庫操作異常: " + e.getMessage());
e.printStackTrace();
throw new RuntimeException("插入失敗", e);
}
}
String sql = "INSERT INTO User(name, password) VALUES(?, ?)";
try (Connection conn = DbUtils.getConn();
PreparedStatement st = conn.prepareStatement(sql)) {
conn.setAutoCommit(false); // 關閉自動提交
for (User user : userList) {
st.setString(1, user.getName());
st.setString(2, user.getPassword());
st.addBatch(); // 加入批次
}
int[] results = st.executeBatch(); // 一次執行批次
conn.commit(); // 手動提交
System.out.println("批次插入完成,筆數: " + results.length);
}
| 錯誤代碼 | 原因 | 修正 |
|---|---|---|
| MySQLSyntaxErrorException near '?,?' | executeUpdate(sql) 重複傳遞 SQL | 改用 executeUpdate() |
| Parameter index out of range | setString 索引超過 ? 數量 | 檢查 SQL 佔位符數量與 set 索引對應 |
| Data truncation | 欄位長度不足/型別不符 | 調整資料庫結構或資料預處理 |
| Connection is closed | Connection 提前關閉 | 調整 try-with-resources 範圍 |