我在结果集上得到以下错误
java.sql.SQLException:ResultSet未打开。验证自动提交是否已关闭。 at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(未知来源) at org.apache.derby.client.am.SqlException.getSQLException(未知来源) at org.apache.derby.client.am.ResultSet.next(未知来源)
public ResultSet insertDb(int Id,String firstName,String lastName,String title) throws SQLException{
try {
try {
Class.forName(driver);
con = DriverManager.getConnection(connectionURL);
} catch (SQLException ex) {
Logger.getLogger(Connect.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(Connect.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(con.getAutoCommit());
statement = con.createStatement() ;
res = statement.executeQuery("SELECT * FROM CUSTOMER") ;
con.setAutoCommit(false);
System.out.println(con.getAutoCommit());
while(res.next()){
if(res.getString("ID").equalsIgnoreCase(Integer.toString(Id))){
UNIQUE = false;
error= "Duplicate Entry Found Please Enter New Data";
throw new SQLException("Duplicate info<br>ID " + Id );
}
}
// IF value to be added IS UNIQUE
if(UNIQUE){
String qry1= "insert into CUSTOMER(ID, FIRSTNAME,LASTNAME,TITLE) values(?,?,?,?)";
stm = con.prepareStatement(qry1);
String ID=Integer.toString(Id);
stm.setString(1, ID);
stm.setString(2, firstName);
stm.setString(3, lastName);
stm.setString(4, title);
stm.executeUpdate();
}
}
catch(Exception e){
String errorMessage = "Exception caught : ";
System.out.println(errorMessage + e.toString());
}finally{
if (con != null){
con.close();
}
}
return res;
}
答案 0 :(得分:1)
尝试在创建并执行语句之前将setAutoCommit()
和getAutoCommit()
移动到。 执行语句后更改可能会使查询无效。
答案 1 :(得分:1)
问题是您在阅读结果集之前已关闭查询。关闭查询,关闭结果集,从而导致“ResultSet未打开”错误。您应该在最后一个块中结束查询:
即。 con.setAutoCommit(假);
将关闭查询,并且它也会关闭结果集。
答案 2 :(得分:0)
并非严格相关,但您的代码可能无法达到预期效果。当存在多个并发调用时,这种读 - 修改 - 写代码不能很好地工作。
如果您想象通过代码运行两个调用,很明显,有时,根据执行顺序,BOTH调用可能会到达insert语句。
此外,从不使用WHERE子句的表中进行选择通常不常用。在这种情况下,您选择“*”,然后迭代所有结果以查看“ID”== Id。数据库比java更好。你应该添加一个where子句。 (注意,这仍然不能解决上述问题)
从任何表中“选择*”通常也是一个坏主意。只需选择您需要的列。如果架构发生更改并且您需要的列不再可用,这将“快速失败”,并允许数据库优化器对其磁盘访问执行“正确的事情”。
最后,如果它只是一个你要分配的数字ID,那么通常的做法是使用'autonumber'来实现这些,而不是让程序选择它们。不同的数据库将它们称为不同的东西,因此您可能也将它们称为IDENTITY,或者必须使用序列。
答案 3 :(得分:0)
如果它可以帮助任何人,我在Derby 10.5.1.1 时遇到了同样的错误,结果证明是错误在驱动程序本身会出现一些时间而不是其他根据底层数据。将驱动程序升级到较新版本( 10.8.2.2 )解决了该问题。