Java 结果集未打开
我在结果集上得到以下错误 java.sql.SQLException:结果集未打开。确认自动提交已关闭。 位于org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(未知源) 位于org.apache.derby.client.am.SqlException.getSQLException(未知源) 位于org.apache.derby.client.am.ResultSet.next(未知源)Java 结果集未打开,java,jdbc,derby,Java,Jdbc,Derby,我在结果集上得到以下错误 java.sql.SQLException:结果集未打开。确认自动提交已关闭。 位于org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(未知源) 位于org.apache.derby.client.am.SqlException.getSQLException(未知源) 位于org.apache.derby.client.am.ResultSet.next(未知源) public Result
public ResultSet insertDb(int-Id,String-firstName,String-lastName,String-title)抛出SQLException{
试一试{
试一试{
Class.forName(驱动程序);
con=DriverManager.getConnection(connectionURL);
}catch(SQLException-ex){
Logger.getLogger(Connect.class.getName()).log(Level.SEVERE,null,ex);
}捕获(ClassNotFoundException ex){
Logger.getLogger(Connect.class.getName()).log(Level.SEVERE,null,ex);
}
System.out.println(con.getAutoCommit());
statement=con.createStatement();
res=语句.executeQuery(“从客户中选择*);
con.setAutoCommit(假);
System.out.println(con.getAutoCommit());
while(res.next()){
if(res.getString(“ID”).equalsIgnoreCase(Integer.toString(ID))){
唯一=错误;
error=“找到重复条目,请输入新数据”;
抛出新的SQLException(“重复信息
ID”+ID);
}
}
//如果要添加的值是唯一的
如果(唯一){
字符串qry1=“插入客户(ID、名字、姓氏、头衔)值(?、、?、?)”;
stm=合同准备声明(qry1);
字符串ID=整数。toString(ID);
stm.setString(1,ID);
stm.setString(2,名字);
stm.setString(3,姓氏);
stm.setString(4,标题);
stm.executeUpdate();
}
}
捕获(例外e){
String errorMessage=“捕获异常:”;
System.out.println(errorMessage+e.toString());
}最后{
如果(con!=null){
con.close();
}
}
返回res;
}
在创建和执行语句之前,请尝试将setAutoCommit()
和getAutoCommit()
移动到。在执行语句后更改它可能会使查询无效。问题是在读取结果集之前已关闭查询。关闭查询将关闭结果集,因此会出现“结果集未打开”错误。您应该在finally块的末尾关闭查询:
i、 e.con.setAutoCommit(错误)
将关闭查询,并同时关闭结果集。不严格相关,但您的代码可能没有达到预期效果。当存在多个并发调用时,这种读-修改-写代码无法正常工作 如果您想象两个调用在代码中运行,那么很明显,有时,根据执行顺序,两个调用都可能到达insert语句 此外,从表中选择而不使用WHERE子句通常是没有用的。在本例中,您选择“*”,然后迭代所有结果以查看“ID”==ID。数据库在这方面比java好得多。您应该添加where子句。(请注意,这仍然无法解决上述问题) 从任何表中“选择*”通常也是个坏主意。只需选择所需的列。如果架构发生更改且所需的列不再可用,这将“快速失败”,并允许数据库优化程序对其磁盘访问执行“正确的操作”
最后,如果您希望分配的只是一个数字ID,通常的做法是对这些ID使用“自动编号”,而不是让程序选择它们。不同的数据库称它们为不同的东西,因此您可能也知道它们是身份,或者必须使用序列。如果它能帮助任何人,我在Derby10.5.1.1中也遇到了同样的错误,结果是驱动程序本身出现了一个错误,根据底层数据,它有时会出现,有时不会出现。将驱动程序升级到更新版本(10.8.2.2)解决了此问题 你不应该这样做。您应该尝试插入并捕获唯一性异常(如果发生)。这样做只会将开销增加一倍,或者更糟,因为您应该编写一个WHERE子句,而不是自己扫描整个表。这里的练习很差。
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;
}