连接查询字符串时出现SQL语法错误

时间:2015-12-07 23:26:58

标签: java mysql

try(Connection dbConnection = DBConnectionManager.getIntakeConnection();
PreparedStatement preparedStmtSetMaxStrikeId = dbConnection.prepareStatement(
    "SELECT MAX(strike_id) FROM strike WHERE 'SELECT p.party_type_id,"
    + "p.csa_score,p.party_tn,p.rec_create_date,"
    + "s.strike_id, s.strike_date, s.strike_level, s.strike_status,
       s.appealable,s.appeal_status,s.rec_change_date,s.event_id,
       s.is_email_processed,s.policy_id"
    + "FROM strike s "
    + "INNER JOIN parties p"
    + "ON p.party_id = s.party_id"
    + "WHERE p.account ='"+appealStatus.getSubscriberId()
    +"'AND strike_status = '"+OCIRISConstants.STRIKE_STATUS_ACTIVE+"' ");)

错误如下 错误中的整数是订户ID。

  

您的SQL语法有错误;查看与您的MySQL服务器版本对应的手册,以便在第0行'0957936101205'和strike_status ='ACTIVE'附近使用正确的语法

2 个答案:

答案 0 :(得分:0)

特定的语法错误是在查询的最后一行AND之前应该有一个空格:

+"' AND strike_status // ... etc
   ^ Insert a space here

但是,您还有其他一些问题,例如:在换行符周围没有空格,例如

+ "INNER JOIN parties p"
+ "ON p.party_id = s.party_id"

会变成

+ "INNER JOIN parties pON p.party_id = s.party_id"

您应该在每行的开头或结尾适当地插入更多空格。

还有其他语法错误,例如WHERE 'SELECT。您需要非常仔细地检查所有语法。

另外:将值连接到预准备语句中有点失败了准备语句的要点。有关如何正确使用它们的示例,请参阅Javadoc

答案 1 :(得分:0)

错误消息显示:

  

near' 0957936101205'AND strike_status = 'ACTIVE''在第1行

它实际上识别0之后的',它结束了在第一行开始的文本文字,因为这是错误的SQL:

SELECT MAX(strike_id) FROM strike WHERE '...'0957936101205'AND strike_status = 'ACTIVE'
--                                          ^^ BAD

以下是注释注释的代码:

try(Connection dbConnection = DBConnectionManager.getIntakeConnection();
PreparedStatement preparedStmtSetMaxStrikeId = dbConnection.prepareStatement(
      "SELECT MAX(strike_id) FROM strike WHERE 'SELECT p.party_type_id,"
//                                             ^ What is this? Even without ' it makes no sense
//                                             ^ But it STARTS A TEXT LITERAL
    + "p.csa_score,p.party_tn,p.rec_create_date,"
    + "s.strike_id, s.strike_date, s.strike_level, s.strike_status, s.appealable,s.appeal_status,s.rec_change_date,s.event_id,s.is_email_processed,s.policy_id"
    + "FROM strike s "
//     ^ Missing space, but it's in a text literal so doesn't matter
    + "INNER JOIN parties p"
    + "ON p.party_id = s.party_id"
//     ^ Missing space, but it's in a text literal so doesn't matter
    + "WHERE p.account ='"+appealStatus.getSubscriberId()
//     ^ Missing space, but it's in a text literal so doesn't matter
//                      ^ END TEXT LITERAL from first line
//                         ^ error complains about inserted value 0957936101205
    +"'AND strike_status = '"+OCIRISConstants.STRIKE_STATUS_ACTIVE+"' ");)
//    ^ Starts a new text literal
//     ^ Missing space, but it's in a text literal so doesn't matter
//                         ^ end text literal
//                            ^ would complain about inserted value ACTIVE
//                                                                  ^ Dangling '

此外,您不应该使用字符串连接来构建SQL,因为它会导致语法错误并使您容易受到SQL Injection攻击,从而允许黑客窃取您的数据并删除您的表。

假设初始SELECT MAX( ... WHERE '出错,这里是一个清理版本,为清晰起见进行了格式化:

String sql = "SELECT p.party_type_id, p.csa_score, p.party_tn, p.rec_create_date" +
                  ", s.strike_id, s.strike_date, s.strike_level, s.strike_status" +
                  ", s.appealable, s.appeal_status, s.rec_change_date, s.event_id" +
                  ", s.is_email_processed, s.policy_id" +
              " FROM strike s" +
             " INNER JOIN parties p ON p.party_id = s.party_id" +
             " WHERE p.account = ?" +
               " AND strike_status = ?";
try (Connection conn = DBConnectionManager.getIntakeConnection();
     PreparedStatement stmt = conn.prepareStatement(sql)) {
    stmt.setString(1, appealStatus.getSubscriberId());
    stmt.setString(2, OCIRISConstants.STRIKE_STATUS_ACTIVE);