【问题标题】:Error in the syntax of the SQL insert query using variables使用变量的 SQL 插入查询的语法错误
【发布时间】:2018-12-11 19:45:00
【问题描述】:

在尝试在 sql 表中插入一条记录时,我在表中的 10 列中使用了 10 个变量,但是当我运行查询时它会引发错误。我试过查看我的代码中是否有任何拼写错误,但找不到:

线程“main”中的异常 java.sql.SQLSyntaxErrorException:您的 SQL 语法有错误;查看与您的 MySQL 服务器版本相对应的手册,了解在 '','2019','12','3','10660','2018-12-11','UTC','' 附近使用的正确语法{"sleepIQScore": {"min": 0, "max"' 在第 1 行

我的代码是:

public void insertDataTable1() throws SQLException {
    connection = new MyConnection().getConnection();
    Random random = new Random();
    String timeZone = "UTC";
    String dummyJson = "'{\"sleepIQScore\": {\"min\": 0, \"max\": 0, \"sum\": 0, \"count\": 0}}')";
    int longestSessionDuration = 1000 + random.nextInt(9999), bamUserID = 1000000 + random.nextInt(9999999);
    int year = 2019, month = 12, sleepSessionCount =3;
    java.sql.Date longestSessionStart = new java.sql.Date(Calendar.getInstance().getTime().getTime());

    String sql = "INSERT INTO aggregates_all_time(bam_user,year,month,sleep_session_count," +
            "longest_session_total_duration,longest_session_start,timezone, current_stats, second_longest_session_stats, prior_stats)"
            + "VALUES ("+bamUserID+"','"+year+"','"+month+"','"+sleepSessionCount+"','"+longestSessionDuration+"','" +
            ""+longestSessionStart+"','"+timeZone+"','"+dummyJson+" ','"+dummyJson+"','"+dummyJson+")";

    PreparedStatement preparedStatement = connection.prepareStatement(sql);
    int i = preparedStatement.executeUpdate();
    System.out.println(i + " Row/s inserted");

}

【问题讨论】:

  • 打印“sql”变量中的字符串并分享
  • "VALUES ("+bamUserID+"','" 中你可能可以删除第一个单引号
  • 这不是你应该使用准备好的语句的方式。不要将值连接到查询字符串中。这是不安全的和/或导致像你的问题这样的错误。请改用参数。
  • 避免连接字符串。请改用 PreparedStatement。您的代码对 SQL 注入不安全。

标签: java mysql sql jdbc


【解决方案1】:

您不应该将值连接到这样的查询字符串中。这是不安全的,因为它会将您的应用程序打开到 SQL 注入,这是导致安全问题的主要原因之一。此外,由于缺少引号等,它会导致诸如您的问题之类的错误。

但是,解决方案不是添加那些缺少的引号,因为这仍然会使您面临 SQL 注入风险。相反,您需要在执行前使用参数并设置这些参数的值。

基于您问题中的查询的简化示例:

try (PreparedStatement preparedStatement = connection.prepareStatement(
        "INSERT INTO aggregates_all_time(bam_user, year, month, ..) values (?, ?, ?, ..)")) {
    preparedStatement.setInt(bamUserID);
    preparedStatement.setInt(year);
    preparedStatement.setInt(month);
    // other values

    preparedStatement.executeUpdate();
}

另请参阅 JDBC 教程中的 Using Prepared Statements

【讨论】:

  • 非常感谢马克。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-16
  • 2020-01-14
相关资源
最近更新 更多