作者:海蓝透了我的心 | 来源:互联网 | 2022-12-08 12:09
我想从我的数据库" Logs "中选择最大行号并将其存储在变量中m
.
这是我的代码:
ResultSet rs = stmt.executeQuery("Select max(Line) as L from logs");
while (rs.next()) { // Why do I need this
int m = rs.getInt("L");
System.out.println(m);
}
但除非我使用,否则它不起作用while(rs.next())
.
如果我理解正确,rs.next(
)将光标移动到下一行,但在这里,在这个结果中,我只有一行.
那么,有人可以解释为什么循环是必要的吗?我唯一能想到的是第一个光标是在列名上设置的,我是对的吗?
1> Zabuza..:
为什么?
光标最初放在第一个元素之前.您需要前进一次才能访问第一个元素.
这显然是因为使用循环遍历结果非常方便,如您所见.从官方文档:
将光标从当前位置向前移动一行.甲ResultSet
光标最初位于第一行之前 ; 对方法的第一次调用使得第一行成为当前行; 第二个调用使第二行成为当前行,依此类推.
解
因此,虽然您不需要任何循环,但您需要将光标前进一次.单从rs.next();
技术上就足够了:
rs.next();
// Access the result
但是,您可能想要考虑根本没有匹配的情况,因为:
当对next
方法的调用返回时false
,光标位于最后一行之后.任何ResultSet
需要当前行的方法的调用都将导致SQLException
抛出.
所以在这种情况下代码会失败.
因此,您应该考虑案例并使用返回boolean
来保护您的访问权限:
if (rs.next()) {
// Access result ...
} else {
// No match ...
}
没有`group by`的`select max(...)...`语句总是会返回一行,即使没有记录与`where`子句匹配,在这种情况下返回的值是'null`.所以,一个简单的`rs.next();`对于这个SQL是完全正确的.
为了确保清晰,我使用`if(rs.first()){...}`.它会做同样的事情,但阅读起来会更清楚.
@Andreas我会保留检查,所以我的Java的正确性不依赖于不同语言规定的规则.但我认为这是个人偏好.实际上我_may_考虑在一个性能关键的函数中跳过它,如果分支真的引起麻烦,但只有在它上面的注释表明假设是什么.至少,当下次有人改变SQL并且不考虑重新审视周围Java代码的逻辑时,这可以起到保护作用.
2> Eugene..:
从官方文档(你应该阅读btw):
最初,光标位于第一行之前.下一个方法将光标移动到下一行,因为当ResultSet对象中没有更多行时它返回false,它可以在while循环中用于迭代结果集.
你基本上需要移动它,在你的情况下移动它就足够了:
rs.next();
System.out.println(rs.getInt("L"));
3> Makoto..:
您可以将其转换为使用简单的if
语句.
if(rs.next()) {
// other code here
}
while
当你有多行时可以使用.
@YCF_L这取决于确切的查询:考虑一个空表,没有`group by`的`max`将返回带有`null`的单行,但是使用`group by`它将不返回任何行
不需要if条件只是`rs.next(); int m = rs.getInt("L");`因为max总是返回一个结果
@MoritzBoth当然,对于问题中的查询YCF_L是绝对正确的,但是给出的问题 - 很多时候 - 简化的例子,你应该考虑更大的图景.在这种情况下,我的回复是由YCF_L的初始评论中的_always_触发的.
4> Adithya Mora..:
ResultSet游标最初位于第一行之前,第一次调用方法next使第一行成为当前行,第二次调用使第二行成为当前行,依此类推.
认为你有类似的东西.
->1->2->3
^
你的"rs"最初指向1之前,当你调用rs.next()时它会使箭头指向1
->1->2->3
^
因此,如果您不调用next()方法,则不会得到结果.
希望这可以帮助