为什么execute()在空表上返回true?

时间:2013-01-04 05:49:31

标签: java sql

通过以下代码段,我尝试运行一个查询,该查询可以更新数据或将新数据插入名为JustPinged的表中。该表包含一个名为NodesThatJustPingedLastPingedAt的列。如果NodesThatJustPinged中已存在节点,则更新LastPingedAt中的时间(以毫秒为单位)。否则,会插入新的node信息。

问题是,以下代码段无法将数据插入数据库的表中。原因是声明:

boolean duplicateExists = searchToEliminateDuplicates.execute();

首先返回true。 (最初表是空的)为什么这个语句返回true?根据{{​​3}},如果第一个结果是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");              
}

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

2 个答案:

答案 0 :(得分:1)

您的searchQuery将返回ResultSet。因此execute方法返回'true'。请尝试使用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");              
      }

P.S。如果您正在使用PreparedStatement,那么请在查询中使用参数并调用ps.setString等。

PPS。不要使用execute()方法。使用executeQuery或executeUpdate。如果您事先不知道查询是INSERT还是UPDATE,则使用execute()。

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

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

从JustPinged中选择count(NodesThatJustPinged),其中NodesThatJustPinged ='“+ nodeInfo +”'“;

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

答案 1 :(得分:1)

返回零行的SELECT语句仍会返回ResultSet - 只有一个在调用next()时立即返回false。您需要检查返回的ResultSet中的行数。