使用Prepared Statement创建数据库报java.sql.SQLSyntaxErrorException如何解决
错误原因
java.sql.SQLSyntaxErrorException报错的核心是你违反了PreparedStatement的使用规则:
?占位符仅可用来替换SQL语句中的值参数,不能替换数据库名、表名、列名这类SQL标识符- 你代码中给数据库名用
?占位的写法,执行时JDBC会自动给替换后的内容加上单引号,最终生成的非法SQL为:CREATE DATABASE IF NOT EXISTS 'test_name',MySQL不允许数据库名被单引号包裹,因此触发语法错误。
解决方法
动态拼接数据库名这类标识符时,直接用字符串拼接即可,注意必须加合法性校验避免SQL注入风险,修正后的代码如下:
public class DBConnector { private Statement statement; private ResultSet result; private PreparedStatement preparedStatement; // 注意connection需提前完成初始化 private Connection connection; public void createDB() { try { String tableName = "test_name"; // 先校验库名合法性,仅允许字母、数字、下划线,避免SQL注入 if (!tableName.matches("^[a-zA-Z0-9_]+$")) { throw new IllegalArgumentException("数据库名称仅允许包含字母、数字、下划线"); } // 直接拼接合法的库名到SQL语句中 String sql = "CREATE DATABASE IF NOT EXISTS " + tableName; preparedStatement = connection.prepareStatement(sql); int myResult = preparedStatement.executeUpdate(); if(myResult == 1){ System.out.println("Database successfully created."); }else{ System.out.println("Database with that name already exists. Please try again with different name."); createDB(); } }catch (SQLException e) { System.out.println("Database creation failed."); e.printStackTrace(); } } }
补充说明
- 只有当你传入的是WHERE条件值、INSERT字段值、UPDATE修改值这类内容时,才使用
?占位符,JDBC会自动处理类型转义,不需要手动加引号。 - 所有动态拼接到SQL中的标识符都必须做严格校验,不要直接拼接用户未经过滤的输入内容,防止SQL注入漏洞。
内容的提问来源于stack exchange,提问作者Koleff
相关产品推荐
相关产品推荐

