Java - ResultSet错误,如何正确地构造它?

时间:2016-04-29 12:22:51

标签: java sql jdbc resultset

编辑 - 这个问题源于Eclipse上发现的一个bug,同时使用调试模式。此问题中提供的代码不是我最初的尝试,现在一切都已解决 - 只要我不在调试模式下运行该方法。

我现在正在开发一个不是我的项目,而且我是java的新手,特别是准备好的语句和结果集。我使用预处理语句的原因是因为它经常在这个项目中使用,我想我也是这样做的。

我的目标是提取查询" sql"给人。 但是,由于此查询仅提供一条记录或者没有记录,因此我很难以不会导致“排除”的方式对此进行编码。错误或其他广告。允许的唯一例外是查询给出零或多于1的结果,因为它确实不应该。

这是已实现的代码:

private long getOriginalValue() throws EProjectException {
    long value = 0;


    PreparedStatement psValue = null;
    java.sql.Connection connection;
    ResultSet rsValue = null;

    String sql = "SELECT value FROM value_table WHERE value ='" + name + "'";

    try {           

        connection = (Connection) eContext.getConnection(EContext.DB_CONNECTION, "edinforsys");
        psValue = connection.prepareStatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,
                ResultSet.CONCUR_UPDATABLE,
                ResultSet.HOLD_CURSORS_OVER_COMMIT);

        rsValue = psValue.executeQuery();

        try {
            rsValue.beforeFirst();
            value = rsValue.getLong(1);
            if(rsValue.next())
                System.out.println("Duplicate Value");
        } catch (Exception ex){
            throw new EProjectException(UBSCMMessage.GENERAL_ERROR, ex.getMessage());
        } finally {
            rsValue.close();
        }           

        if(value == 0)
            throw new EProjectException(UBSCMMessage.GENERAL_ERROR);



    } catch (Exception ex) {
        throw new EProjectException(UBSCMMessage.GENERAL_ERROR, ex.getMessage());
    } finally {
        try {
            psValue.close();

        } catch (SQLException e) {
            e.printStackTrace();
        }           
    }       

    return value;
}

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

getLong在您加载下一条记录的每next()后过早完成。

由于有些部分功能更好,这里更正了代码:

String sql = "SELECT value FROM value_table WHERE value = ?";
try {           
    connection = (Connection) eContext.getConnection(EContext.DB_CONNECTION, "edinforsys");
    try (PreparedStatement psValue = connection.prepareStatement(sql,
            ResultSet.TYPE_SCROLL_INSENSITIVE,
            ResultSet.CONCUR_UPDATABLE,
            ResultSet.HOLD_CURSORS_OVER_COMMIT)) {

        psValue.setString(1, name); // Escapes single quotes and such
        try (ResultSet rsValue = psValue.executeQuery()) {
            //rsValue.beforeFirst();
            if (rsValue.next()) {
                long value = rsValue.getLong(1);
                System.out.println("Duplicate Value");
                return value; or whatever
            }
        } // Closes rsValue
    } // Closes psValue
} catch (SQLException ex){
    throw new EProjectException(UBSCMMessage.GENERAL_ERROR, ex.getMessage(), ex);
    // Better add the entire ex as cause if possible
}           

JDBC SQL驱动程序填写参数的PreparedStatement非常重要。它不仅可以逃避像"Marie d'Alembert"这样的名称(单引号),而且还可以防范黑客攻击,SQL注入。当然,sql不能是与变量的字符串连接。

try-with-resources(从Java 7开始)即使在异常和返回的情况下也能确保自动关闭。

答案 1 :(得分:0)

您可以将循环更改为while循环,如下所示

int counter=0;
while(rsValue.next()) {
   counter++;
    value= rsValue.getLong(1);
if(counter>1)
{
throw new Exception("your Exception");
}
}
//your code continues here

基本上当我们得到结果集时,它指向第一行之前,因此需要这个rsValue.next(),然后才能从中检索数据。

如文档中所述。如果ResultSet中没有行,.next将返回false。