Java 11 JDBC执行SET foreign_key_checks语句报错,求解决方法
问题分析与解决
错误原因
你的代码存在两个核心问题导致语法错误:
- PreparedStatement不支持默认执行多语句:你在
PreparedStatement的SQL里拼接了INSERT ...; SET FOREIGN_KEY_CHECKS=0这种多语句组合,但MySQL Connector/J默认禁止在单个PreparedStatement中执行多条SQL(防SQL注入),这直接触发了1064语法错误。 - 冗余重复设置:try块开头已经通过
Statement关闭了外键检查,循环里又重复设置,完全没必要。
修复步骤
步骤1:移除PreparedStatement中的多语句
将循环内的SQL修改为仅保留INSERT语句,删除末尾多余的; SET FOREIGN_KEY_CHECKS=0:
String query = "insert into " + tableName + " (" + columns + ") values (" + questionMakrs + ")";
步骤2:保留单次外键开关设置
你开头和finally块里用Statement执行SET foreign_key_checks的写法本身是合法的,单独执行这类单语句不会有语法问题,无需修改。
优化后的完整代码
try { // 关闭外键检查 Statement checks = connection.createStatement(); checks.execute("set foreign_key_checks=0"); checks.close(); String tableName = json.getString("table"); RowOperation rowOperation = RowOperation.valueOf(json.getString("activity")); JSONArray rows = json.getJSONArray("rows"); for (Object obj : rows) { JSONObject row = (JSONObject) obj; List<String> keys = new ArrayList<>(row.keySet()); String columns = keys.stream().collect(Collectors.joining(",")) + ",rowOperation,rowCreatedOn"; String questionMakrs = keys.stream().map(x -> "?").collect(Collectors.joining(",")) + ",?,?"; // 仅保留INSERT语句 String query = "insert into " + tableName + " (" + columns + ") values (" + questionMakrs + ")"; PreparedStatement stmt = connection.prepareStatement(query); int i = 0; for (i = 0; i < keys.size(); i++) { String key = keys.get(i); stmt.setString(i + 1, String.valueOf(row.get(key))); } stmt.setString(i + 1, rowOperation.name()); i++; stmt.setTimestamp(i + 1, Timestamp.valueOf(LocalDateTime.now())); stmt.execute(); stmt.close(); } } finally { // 恢复外键检查 Statement checks = connection.createStatement(); checks.execute("set foreign_key_checks=1"); checks.close(); }
额外说明
如果确实需要在JDBC中执行多语句,可在连接URL中添加allowMultiQueries=true参数(如jdbc:mysql://localhost:3306/your_db?allowMultiQueries=true),但这种方式存在SQL注入风险,非必要不建议使用。
内容的提问来源于stack exchange,提问作者Vicky
相关产品推荐
相关产品推荐

