SQLServerException:为更新生成结果集

时间:2014-03-12 18:31:36

标签: java sql jdbc

我正在尝试将新记录插入到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)
);

我不认为我在这里做任何非常复杂的事情,但我想不出为什么我会得到这个例外。我在同一个类中有一个方法,它执行完全相同的插入类型(字面上相同的查询具有不同的表名和值的数量),并且它没有问题。有没有人对如何解决这个问题有任何想法?

5 个答案:

答案 0 :(得分:6)

此指令stmt.executeUpdate()未返回commentId,它返回ResultSet,然后您可以从中获取commentId。像这样的东西,

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

答案 1 :(得分:5)

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

要测试是否是这种情况,您可以尝试:

  • 使用executeQuery()代替executeUpdate() - 并显示结果。
  • 在MySQL Workbench,SQL Server Management Studio等工具中执行插入操作,或者DBMS可以使用任何类型的数据库设计工具,以查看是否返回了结果。

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

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

答案 2 :(得分:2)

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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

我遇到了类似的问题,过了一会儿,自动编号表上的插入会产生"生成的结果集用于更新。"随意的。我使用连接池,不知怎的,驱动程序可以进入一个状态,其中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();
}