JDBC使用PreparedStatement连接MySQL执行SQL报语法错误问题咨询
问题排查结论
这个报错和MySQL Connector 8.0.27的版本兼容性无关,完全是代码编写逻辑错误导致的,具体错误点如下:
- 错误1:错误拼接多条SQL构造PreparedStatement
PreparedStatement的设计目标是预编译单条SQL模板,你直接把多个不相关的INSERT、UPDATE、DELETE、SELECT语句无分隔符拼接后传入构造方法,得到的SQL本身就是语法非法的,比如拼接后的开头是INSERT INTO Clientes(nome) VALUES(?)INSERT INTO Clientes(nome) VALUES(?),两条SQL连分号分隔符都没有,自然触发语法报错。 - 错误2:调用带参数的execute方法
PreparedStatement的execute(String sql)是继承自父类Statement的方法,调用这个方法时会直接执行你传入的SQL字符串,完全忽略之前预编译的SQL和设置的占位符参数,你传入的拼接SQL本身语法错误,直接触发报错。 - 错误3:参数类型与占位符逻辑不匹配
你的DELETE语句模板是DELETE FROM Clientes WHERE id = ?,你给占位符设置的是字符串类型的姓名,而id是整数类型,就算前面语法修正,执行时也会报类型不匹配错误。 - 错误4:SQL中的字段名和实际表结构不匹配
你建表时主键字段命名为id_cliente,但UPDATE、DELETE语句里写的WHERE条件是id = ?,字段名完全不一致,就算前面问题都修复,也会报字段不存在的错误。
正确实现思路
- 单条SQL模板对应一个PreparedStatement,同模板的批量操作可以用
addBatch()+executeBatch()复用同一个实例 - 执行PreparedStatement时调用无参的
execute()、executeUpdate()(写操作)、executeQuery()(读操作),不要传入SQL字符串 - 匹配正确的字段名和参数类型,WHERE条件字段使用
id_cliente,传入对应整数类型的id值
修正后代码示例
package uni.jdbc.preparedStatement; import java.sql.*; public class Main { public static void main(String[] args) { try { Class.forName("com.mysql.cj.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/banco_Teste","root","password"); // 批量执行INSERT String insertSql = "INSERT INTO Clientes(nome) VALUES(?)"; try (PreparedStatement insertPs = conn.prepareStatement(insertSql)){ // 第一条插入 insertPs.setString(1, "João"); insertPs.addBatch(); // 第二条插入 insertPs.setString(1, "Maria"); insertPs.addBatch(); // 执行批量插入 insertPs.executeBatch(); } // 批量执行UPDATE 假设要修改id为1和2的记录 String updateSql = "UPDATE Clientes SET nome = ? WHERE id_cliente = ?"; try (PreparedStatement updatePs = conn.prepareStatement(updateSql)){ // 第一条更新 updatePs.setString(1, "John"); updatePs.setInt(2, 1); updatePs.addBatch(); // 第二条更新 updatePs.setString(1, "Marya"); updatePs.setInt(2, 2); updatePs.addBatch(); // 执行批量更新 updatePs.executeBatch(); } // 批量执行DELETE 假设要删除id为1和2的记录 String deleteSql = "DELETE FROM Clientes WHERE id_cliente = ?"; try (PreparedStatement deletePs = conn.prepareStatement(deleteSql)){ // 第一条删除 deletePs.setInt(1, 1); deletePs.addBatch(); // 第二条删除 deletePs.setInt(1, 2); deletePs.addBatch(); // 执行批量删除 deletePs.executeBatch(); } // 执行查询 String selectSql = "SELECT * FROM Clientes"; try (PreparedStatement selectPs = conn.prepareStatement(selectSql); ResultSet rs = selectPs.executeQuery()){ while (rs.next()){ System.out.println("id: "+rs.getInt("id_cliente") + " 姓名: "+rs.getString("nome")); } } }catch(SQLException | ClassNotFoundException e){ e.printStackTrace(); System.out.println("操作失败!"); } } }
内容的提问来源于stack exchange,提问作者Guilherme Aguiar
相关产品推荐
相关产品推荐

