2014-03-12 160 views
3

我试图插入一个新的记录到MS SQL数据库中,我得到了一个我从未见过的异常​​。当我打电话executeUpdate以下异常被抛出:SQLServerException:结果集生成更新

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

该指令stmt.executeUpdate()不返回commentId,它返回一个ResultSet然后你可以得到从commentId。事情是这样的,

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

我在这是形式的同班另一个查询字符串'= NEW_REQUEST“INSERT INTO要求OUTPUT INSERTED.requestId VALUES(...'我找回?这个id与'stmt.executeUpdate()'。是否有任何理由这样的不一致?或者预测它的方式? – Nathan

+0

好吧,你的建议工作。我猜SQL Server没问题,通过' executeUpdate'只在某些情况下,这是一个令人讨厌的不一致性,但我的代码现在可以工作。 – Nathan

1

你正在使用你的插入查询输出,例如,你会得到一个结果查询执行后,并认为你需要一流的ResultSet的对象来保存数据

5

这种特殊错误也可能由INSERT触发器引起,该触发器具有作为触发器代码一部分的SELECT语句。

为了测试是否是这种情况,你可以尝试:用executeQuery()

  • ,而不是executeUpdate() - 并显示结果。
  • 在像MySQL Workbench,SQL Server Management Studio或任何风格的数据库设计工具可用于您的DBMS的工具中执行插入,以查看是否返回结果。

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

我希望这可以帮助其他人在看相同的错误消息,因为它为我做的。我的解决方案是致电executeQuery(),但它只处理潜在问题,而不是修复它。

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(); 
} 
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

+0

谢谢,你救了我的生命 – dtelaroli