【问题标题】:why does execute() return true on an empty table?为什么execute() 在空表上返回true?
【发布时间】:2013-01-04 05:49:31
【问题描述】:

通过以下 sn-p,我正在尝试运行一个查询,该查询要么更新数据,要么将新数据插入名为 JustPinged 的表中。该表包含名为NodesThatJustPingedLastPingedAt 的列。如果NodesThatJustPinged 中已经有一个节点,那么LastPingedAt 中的时间(以毫秒为单位)将被更新。否则插入新的node 信息。

问题是,下面的 sn -p 无法将数据插入到数据库的表中。原因是声明:

boolean duplicateExists = searchToEliminateDuplicates.execute();

返回 true 开始。 (最初表是空的)为什么这个语句返回true?根据documentation,如果第一个结果是 ResultSet 对象,则返回 true;如果第一个结果是更新计数或没有结果,则返回 false。 所以这里的布尔值应该包含一个 false 值。但它包含一个true 值,因此if 语句始终有效。 (在if 部分,更新查询在没有任何更新时有效!)

String searchQuery = "select NodesThatJustPinged from JustPinged where NodesThatJustPinged = '" + nodeInfo + "'";
PreparedStatement searchToEliminateDuplicates = connection.prepareStatement(searchQuery);
boolean duplicateExists = searchToEliminateDuplicates.execute();

if(duplicateExists) {
    // update the LastPingedAt column in the JustPinged table 
    String updateQuery = "update JustPinged set LastPingedAt='" + pingedAt + "' where NodesThatJustPinged = '" + nodeInfo + "'";
    PreparedStatement updateStatement = connection.prepareStatement(updateQuery);
    updateStatement.executeUpdate();System.out.println("If statement");
} else {
    // make a new entry into the database
    String newInsertionQuery = "insert into JustPinged values('" + nodeInfo + "','" + pingedAt + "')";
    PreparedStatement insertionStatement = connection.prepareStatement(newInsertionQuery);
    insertionStatement.executeUpdate();System.out.println("else statement");              
}

那么我应该如何编辑代码,以便更新重复值并插入新值?

【问题讨论】:

    标签: java sql


    【解决方案1】:

    您的 searchQuery 将返回 ResultSet。因此执行方法返回“真”。尝试改用 executeQuery。

    所以你的代码会变成:

    String searchQuery = "select NodesThatJustPinged from JustPinged where NodesThatJustPinged = '" + nodeInfo + "'";
        Statement searchToEliminateDuplicates = connection.createStatement();
        ResultSet duplicateExists = searchToEliminateDuplicates.executeQuery(searchQuery);
    
        if(duplicateExists.next()) {
            // update the LastPingedAt column in the JustPinged table 
            String updateQuery = "update JustPinged set LastPingedAt='" + pingedAt + "' where NodesThatJustPinged = '" + nodeInfo + "'";
            PreparedStatement updateStatement = connection.prepareStatement(updateQuery);
            updateStatement.executeUpdate();System.out.println("If statement");
        } else {
            // make a new entry into the database
            String newInsertionQuery = "insert into JustPinged values('" + nodeInfo + "','" + pingedAt + "')";
            PreparedStatement insertionStatement = connection.prepareStatement(newInsertionQuery);
            insertionStatement.executeUpdate();System.out.println("else statement");              
          }
    

    附:如果您使用的是 PreparedStatement,请在查询中使用参数并调用 ps.setString 等。

    PPS。不要使用 execute() 方法。使用 executeQuery 或 executeUpdate。在您事先不知道您的查询是 INSERT 还是 UPDATE 时使用 execute()。

    PPPS 完成后立即关闭您的结果集和语句。

    PPPPS 更好的方法是在 SQL 语句中使用 count 聚合函数,即

    select count(NodesThatJustPinged) from JustPinged where NodesThatJustPinged = '" + nodeInfo + "'";

    现在您可以检查 count 是 0 还是大于 1 并相应地分支您的代码。

    【讨论】:

      【解决方案2】:

      返回零行的SELECT 语句仍将返回ResultSet——只是在调用next() 时立即返回false 的语句。您需要检查返回的 ResultSet 中的行数。

      【讨论】:

        猜你喜欢
        • 2017-10-08
        • 2016-03-12
        • 2011-01-12
        • 2015-07-25
        • 2014-09-25
        • 2011-05-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多