Java 结果集更新行不工作

Java 结果集更新行不工作,java,mysql,jdbc,Java,Mysql,Jdbc,当我在结果集中循环时,我想在我的结果集中更新raw。下面是我的代码 try { String query="SELECT * FROM smsmessage WHERE recipient = ? and sent_status = 'pending' LIMIT ? "; PreparedStatement prepStmt = conn.prepareStatement(query); prepStmt.setString(1,shortCode); prepStmt

当我在结果集中循环时,我想在我的结果集中更新raw。下面是我的代码

try {
    String query="SELECT * FROM smsmessage WHERE recipient = ? and sent_status = 'pending' LIMIT ? ";
PreparedStatement prepStmt = conn.prepareStatement(query);
    prepStmt.setString(1,shortCode);
    prepStmt.setInt(2, Integer.parseInt(batchSize));
    ResultSet rs=prepStmt.executeQuery();
    while (rs.next()) {

        //update the selected message sent status to "sent" from "pending"
        rs.updateString("sent_status","sent");
        rs.updateRow();
    }

} catch (SQLException e) {
    log.error("MySQL exception",e);
}
可能的原因是什么

我得到以下错误

com.mysql.jdbc.notupdateable:结果集不可更新。这个结果集 必须来自使用结果集类型创建的语句 ResultSet.CONCUR\u可更新,查询只能选择一个表,可以 不使用函数,必须从该表中选择所有主键。 有关更多详细信息,请参阅JDBC2.1API规范第5.6节 结果集必须来自使用结果创建的语句 如果将ResultSet.CONCUR\u的类型设置为可更新,则查询只能选择一个 表,不能使用函数,必须从中选择所有主键 那张桌子。有关更多信息,请参阅JDBC 2.1 API规范第5.6节 细节


正如stacktrace所说,您必须创建一条语句,允许其结果集可更新:

PreparedStatement prepStmt= conn.prepareStatement(query,
    ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
从ResultSet()的API中:

默认的ResultSet对象是不可更新的,其光标仅向前移动。因此,您只能遍历它一次,并且只能从第一行到最后一行。可以生成可滚动和/或可更新的ResultSet对象。下面的代码片段(con是一个有效的连接对象)说明了如何创建一个可滚动、对其他人的更新不敏感且可更新的结果集。有关其他选项,请参见结果集字段

   Statement stmt = con.createStatement(
                                  ResultSet.TYPE_SCROLL_INSENSITIVE,
                                  ResultSet.CONCUR_UPDATABLE);
   ResultSet rs = stmt.executeQuery("SELECT a, b FROM TABLE2");
   // rs will be scrollable, will not show changes made by others,
   // and will be updatable

首先,您应该仔细阅读错误文本:

com.mysql.jdbc.notupdateable
:结果集不可更新。这个结果 集合必须来自使用结果集创建的语句
ResultSet.CONCUR\u updateable的类型,查询只能选择一个
表,不能使用函数,必须从中选择所有主键
那张桌子。有关更多信息,请参阅JDBC 2.1 API规范第5.6节
细节

这意味着结果集不可更新。无法更新不可更新的结果集

它还指出,此结果集必须来自一个使用结果集类型
ResultSet.CONCUR\u updateable
创建的语句。这意味着您的语句(在本例中为
PreparedStatement
)必须使用该选项创建

最后,它将引导您访问文档。JDBC2.1有点过时,您可以在通常的J2SE文档中找到所有相关数据。让我们从的文档开始。它说:

默认的ResultSet对象是不可更新的,并且具有 只向前移动。因此,您只能在其中迭代一次 仅从第一行到最后一行。生产是可能的 可滚动和/或可更新的ResultSet对象。以下 代码片段(其中con是有效的连接对象)说明了 如何创建可滚动且对更新不敏感的结果集 由其他人,这是可更新的。有关其他信息,请参见结果集字段 选项

它显示的代码片段是:

   Statement stmt = con.createStatement(
                                  ResultSet.TYPE_SCROLL_INSENSITIVE,
                                  ResultSet.CONCUR_UPDATABLE);
   ResultSet rs = stmt.executeQuery("SELECT a, b FROM TABLE2");
   // rs will be scrollable, will not show changes made by others,
   // and will be updatable
您可以看到,他们使用的是一个语句,您可以在其中添加两个参数,使您能够滚动数据并对其进行更新。但是他们使用的是
语句
,而不是
PreparedStatement
。这是否也适用于
PreparedStatement

转到
PreparedStatement
文档对您没有多大帮助,但是请稍候,您正在使用连接对象来准备语句,也许它会对您有所帮助

是的,实际上,有一个允许您传递参数的函数,就像示例中的
语句

PreparedStatement prepareStatement(String sql,
                                 int resultSetType,
                                 int resultSetConcurrency)
                                   throws SQLException
所以现在你必须问问自己,我需要什么样的
resultsetype
,以及什么样的
resultSetConcurrency

当前问题不需要滚动语句,因此可以使用默认值。如果你看一下,你会看到:

使用返回的
PreparedStatement
对象创建的结果集将 默认情况下,类型为
type\u FORWARD\u ONLY
,并发级别为
CONCUR\u只读
。创建的结果集的可保持性可以是 通过调用
getHoldability()
确定

…顺便说一下,这就是为什么您最初准备的语句不可更新的原因。但无论如何,它告诉您滚动类型的默认值是
type\u FORWARD\u ONLY

更新是最重要的部分吗?好的,选项是
CONCUR\u READ\u
CONCUR\u updateable
。所以你需要使用第二个。毕竟,这是错误消息告诉您的

结论: 你需要使用

PreparedStatement prepStmt = conn.prepareStatement(
                                  query,
                                  ResultSet.TYPE_FORWARD_ONLY,
                                  ResultSet.CONCUR_UPDATABLE);
这将为您提供一个可更新的结果集


这是如何从收到的错误消息中找到答案。

请显示创建准备好的语句的代码(通过编辑问题)。使用代码编辑问题异常堆栈跟踪在哪里?无论如何,请阅读javadoc。它解释了使结果集可更新所需的操作: