EDIT-这个问题源于在使用调试模式时在Eclipse上发现的一个错误。这个问题中给出的代码不是我最初的尝试,现在一切都解决了——只要我不在调试模式下运行该方法
我现在正在开发一个不是我的项目,我是java的新手,尤其是准备好的语句和结果集。我之所以使用预先准备好的语句,是因为它经常在这个项目中使用,我想我也会这么做。
我的目标是提取查询"sql"给出的唯一记录。然而,由于这个查询只提供一条记录,或者不提供任何记录,所以我很难用一种不会导致"exhaust"错误或其他sql异常的方式来编码它。唯一允许的例外是,如果查询给出零个或多个结果,因为它确实不应该。
这是实现的代码:
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;
}
谢谢你的帮助!
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(从Java7开始)确保即使在出现异常和返回的情况下也能自动关闭。
您可以将循环更改为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。