SQLServerException:为更新生成了一个结果集

Posted

技术标签:

【中文标题】SQLServerException:为更新生成了一个结果集【英文标题】:SQLServerException: A result set was generated for update 【发布时间】:2014-03-12 18:31:36 【问题描述】:

我正在尝试向 MS SQL 数据库中插入一条新记录,但遇到了一个我以前从未见过的异常​​。当我调用executeUpdate 时,会引发以下异常:

com.microsoft.sqlserver.jdbc.SQLServerException: A result set was generated for update.

这是产生错误的 Java 代码:

// addComment method adds a new comment for a given requestId
public CommentBean addComment(CommentBean comment) 
    PreparedStatement stmt = null;
    INative nat = null;
    Connection conn = null;

    try 
        nat = dbConn.retrieveNative();
        conn = (Connection)nat.getNative("java.sql.Connection");
        stmt = conn.prepareStatement(ADD_COMMENT);
        stmt.setInt(1, comment.getRequestId());
        stmt.setString(2, comment.getComment());
        stmt.setString(3, new SimpleDateFormat("MM/dd/yyyy").format(comment.getDateCreated()));
        stmt.setString(4, comment.getCreatedBy());
        comment.setCommentId(stmt.executeUpdate()); // exception
     catch(Exception ex) 
        System.err.println("ProjectRegistration::SQLDAO - addComment");
        ex.printStackTrace();
     finally 
        try 
            if (stmt != null) stmt.close();
         catch (Exception e) 
    

    return comment;
// end addComment

其中 ADD_COMMENT 定义为字符串:

private static final String ADD_COMMENT = "INSERT INTO RequestComments OUTPUT INSERTED.commentId VALUES(?,?,?,?)";

为了彻底起见,表定义为:

CREATE TABLE RequestComments (
    commentId int NOT NULL PRIMARY KEY IDENTITY(1,1),
    requestId int FOREIGN KEY REFERENCES Requests(requestId),
    comment varchar(400),
    dateCreated date,
    createdBy varchar(12)
);

我认为我在这里没有做任何非常复杂的事情,但我想不出为什么会出现这个异常。我在同一个类中有一个方法,它执行完全相同类型的插入(实际上是相同的查询,但表名和值的数量不同),它没有问题。有人对如何解决此问题有任何想法吗?

【问题讨论】:

【参考方案1】:

这条指令stmt.executeUpdate() 没有返回commentId,它返回一个ResultSet,然后您可以从中获取commentId。像这样的,

ResultSet rs = stmt.executeQuery(); // Not update, you're returning a ResultSet.
if (rs.next()) 
  comment.setCommentId(rs.getInt(1));

【讨论】:

我在同一个类中有另一个查询,其格式为String NEW_REQUEST = "INSERT INTO Requests OUTPUT INSERTED.requestId VALUES(?,...。我用stmt.executeUpdate() 检索ID。这样的不一致有什么理由吗?还是一种预测方法? 嗯,你的建议有效。我猜 SQL Server 只在某些情况下可以通过executeUpdate 返回结果。这是一个令人讨厌的不一致,但我的代码现在可以工作了。【参考方案2】:

此特定错误也可能由 INSERT 触发器引起,该触发器将 SELECT 语句作为触发器代码的一部分。

要测试是不是这样,可以试试:

使用executeQuery(),而不是executeUpdate() - 并显示结果。 执行插入工具,如 mysql Workbench、SQL Server Management Studio 或任何可用于 DBMS 的数据库设计工具,以查看是否返回结果。

相关:sql server error "A result set was generated for update"

我希望这可以帮助其他人看到相同的错误消息,就像它对我一样。我的解决方案是调用executeQuery(),尽管它只处理一个潜在问题,而不是修复它。

【讨论】:

我使用 mssql。 “使用 executeQuery(),而不是 executeUpdate() - 并显示结果。”结果救了我【参考方案3】:

您在插入查询中使用 OUTPUT,即在查询执行后您将获得一个结果集,并认为您需要一个 ResultSet 类的对象来保存该数据

【讨论】:

【参考方案4】:

SqlServer:当 SET NOCOUNT 为 ON 时,不返回计数。当 SET NOCOUNT 为 OFF 时,返回计数。

Connection conn = DriverManager.getConnection(connectDB,user,pwd);
String sql = " set nocount off;INSERT INTO test (name) values (1)";   

PreparedStatement prepareStatement = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
System.out.println(prepareStatement.executeUpdate());

ResultSet generatedKeys = prepareStatement.getGeneratedKeys();
if(generatedKeys.next())
    System.out.println(generatedKeys.getString(1));

相关: set-nocount-on-usage

【讨论】:

谢谢,你救了我的命【参考方案5】:

我遇到过类似的问题,一段时间后,在自动编号表上插入会给出“已生成结果集以进行更新”。随机。我使用连接池,并且驱动程序可以以某种方式进入 executeUpdate 与 Statement.RETURN_GENERATED_KEYS 组合不再起作用的状态。我发现在这种状态下,executeQuery 可以解决问题,但在初始状态下,executeQuery 不起作用。这导致我采用以下解决方法:

PreparedStatement psInsert = connection.prepareStatement("INSERT INTO XYZ (A,B,C) VALUES(?,?,?)", Statement.RETURN_GENERATED_KEYS);
ResultSet rs = null;
try 
    psInsert.setString(1, "A");
    psInsert.setString(2, "B");
    psInsert.setString(3, "C");
    Savepoint savePoint = connection.setSavepoint();
    try 
        psInsert.executeUpdate();
        rs = psInsert.getGeneratedKeys();
     catch (SQLServerException sqe)
    
        if (!sqe.getMessage().equals("A result set was generated for update."))
            throw sqe;
        connection.rollback(savePoint);
        rs = psInsert.executeQuery();
    
    rs.next();
    idField = rs.getInt(1);
 finally 
    if(rs != null)
        rs.close();
    psInsert.close();

【讨论】:

以上是关于SQLServerException:为更新生成了一个结果集的主要内容,如果未能解决你的问题,请参考以下文章

解决sqoop报错:SQLServerException: 将字符串转换为 uniqueidentifier 时失败。

SQLServerException:将截断字符串或二进制数据的解决方法

com.microsoft.sqlserver.jdbc.SQLServerException: 将截断字符串或二进制数据。

基本插入在数据库中有效,但在 java 类中无效

如何修复“SQLServerException:连接已关闭”。在这个 Try-With-Resources 块中出现?

DBFit jdbc.SQLServerException:关键字“as”附近的语法不正确