“if (rs.next())” 的意思是什么?(涉及IT技术)

13

我目前遇到了以下错误,

java.sql.SQLException: Method 'executeQuery(String)' not allowed on prepared statement.

因为我正在使用

PreparedStatement stmt = conn.prepareStatement(sql);

而且还有

ResultSet rs = stmt.executeQuery(sql);

在我的代码中。

现在我需要删除ResultSet行,但这会留下以下代码让我处理:

if (rs.next()) {
    messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("login.successful"));
    request.getSession(true).setAttribute("USERNAME", rs.getString("USERNAME"));
    request.getSession(true).setAttribute("BALANCE", rs.getString("BALANCE"));
    request.setAttribute("msg", "Logged in successfully");

我不确定我完全理解了什么

 if (rs.next())

能否有人向我解释一下这段代码?如果我能更好地理解它,我相信我会更好地处理使用PreparedStatement结果的逻辑。同时,对于修改该逻辑的任何帮助也将不胜感激。

7个回答

10

关于那个SQLException的具体问题,您需要进行替换。

ResultSet rs = stmt.executeQuery(sql);

通过

ResultSet rs = stmt.executeQuery();

因为你正在使用PreparedStatement子类而不是Statement。当使用PreparedStatement时,你已经将SQL字符串传递给了Connection#prepareStatement()。你只需要在上面设置参数,然后直接调用executeQuery()方法,而不需要重新传递SQL字符串。

另请参阅:


关于rs.next()的具体问题,它将光标移动到来自数据库的结果集的下一行,并返回true如果有任何行,否则返回false。与while不同,与if语句结合使用,这意味着程序员只期望或感兴趣的是第一行。

另请参阅:


非常感谢!这非常有帮助! - Turk
1
@Turk 为你辩护,异常解释并不是很清楚。它暗示你使用了错误的方法而不是错误的参数。 - Menefee

5
next()方法会将结果集中的游标向前移动一行。因此,if(rs.next())表示如果下一行不为null(即存在下一行),则可以继续执行代码。
针对您的问题,...
ResultSet rs = stmt.executeQuery(sql);  //This is wrong
                                  ^       

请注意,如果您使用 SQL 查询作为字符串,则使用 executeQuery(String)
而当您使用 PreparedStatement 时,请使用 executeQuery(),该方法将在此 PreparedStatement 对象中执行 SQL 查询,并返回查询生成的 ResultSet 对象。
解决方案:
使用:ResultSet rs = stmt.executeQuery();

非常感谢!您非常清楚地解释了我需要进行的更改! - Turk

3
next()方法(官方文档在此处)仅将结果行集的指针移动到下一行(如果可以)。无论如何,您也可以从官方文档中了解到以下信息:

将光标向下移动一行,以从其当前位置。

此方法返回true如果有另一行或否则为false。


3
我假设你正在使用Java 6,并且您正在使用的ResultSet是java.sql.ResultSet

ResultSet.next()方法的JavaDoc说明:

将光标从当前位置向前移动一行。 ResultSet光标最初定位在第一行之前; 调用next方法后,第一行成为当前行; 第二次调用使第二行成为当前行,依此类推。

当调用next方法返回false时,光标位于最后一行之后。 任何需要当前行的ResultSet方法的调用都会导致抛出SQLException。

因此,if(rs.next(){ //do something }表示“如果结果集仍有结果,请移动到下一个结果并执行某些操作”。

正如BalusC所指出的那样, 您需要替换

ResultSet rs = stmt.executeQuery(sql);

使用

ResultSet rs = stmt.executeQuery();

由于您已经在前一行中设置了要在语句中使用的SQL,因此

PreparedStatement stmt = conn.prepareStatement(sql);

如果您没有使用PreparedStatement,那么ResultSet rs = stmt.executeQuery(sql);就可以工作。

抱歉,我没有足够的声望来完成这个任务。 - Turk

1

看这张图片,它是一个查询 select * from employee 的结果集

enter image description here

ResultSet类的next()方法可以帮助将光标移动到返回结果集(在您的示例中为rs)的下一行。

:)


0

由于结果集是一个接口,当您通过JDBC调用获取对ResultSet的引用时,您将获得实现ResultSet接口的类的实例。该类提供了所有ResultSet方法的具体实现。

接口用于将实现与接口分离。这允许创建通用算法和对象创建的抽象。例如,不同数据库的JDBC驱动程序将返回不同的ResultSet实现,但您不必更改代码即可使其与不同的驱动程序一起使用。

简而言之,如果您的ResultSet包含结果,则使用rs.next返回true,如果您有记录集,则返回false。


0

首先,你不需要写

ResultSet rs = stmt.executeQuery(sql);

只需要写

ResultSet rs = stmt.executeQuery();

上述语法用于语句,而不是 PreparedStatement。

第二件事,rs.next() 检查结果集是否包含任何值。它返回一个布尔值,并将光标移动到结果集中的第一个值,因为最初它位于 BEFORE FIRST 位置。因此,如果您想访问结果集中的第一个值,您需要编写 rs.next()。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接