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: 将截断字符串或二进制数据。