我正在尝试将新记录插入到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)
);
我不认为我在这里做任何非常复杂的事情,但我想不出为什么我会得到这个例外。我在同一个类中有一个方法,它执行完全相同的插入类型(字面上相同的查询具有不同的表名和值的数量),并且它没有问题。有没有人对如何解决这个问题有任何想法?
答案 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()
- 并显示结果。相关: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));
}
答案 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();
}