JDBC返回空结果集

我正在使用JDBC进行非常简单的数据库连接。

我创建了我的连接/语句并执行了查询。 我在调试器中检查语句的查询对象以确认它正在发送正确的查询。 然后我仔细检查数据库上的查询(直接从调试器复制)以确保它返回数据。 但是,返回的结果集在.next()上给出了false

这里有什么常见的陷阱,我错过了吗?

public List getGroups() { myDB.sendQuery("select distinct group_name From group_members where username='" + this.username + "'"); ResultSet results = myDB.getResults(); List returnList = new ArrayList(); try { while (results.next()) { returnList.add(new InterestGroup(results.getString("group_name"), myDB)); } return returnList; } catch (SQLException e) { e.printStackTrace(); return null; } } 

和myDB类(简单的包装器,让我将连接/语句代码放入任何项目)

 public void sendQuery(String query){ this.query = query; try { if(statement == null){ statement = connection.createStatement(); } results = statement.executeQuery(query); } catch (SQLException e) { System.out.println(query); currentError = e; results = null; printError(e, "querying"); } } public ResultSet getResults(){ return results; } 

编辑:根据建议,我大多修改了我的代码,但仍然有同样的问题。 下面是具有相同问题的代码的简化部分。

 private boolean attemptLogin(String uName, String pWord) { ResultSet results; try{ try { Class.forName("oracle.jdbc.driver.OracleDriver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } connection =DriverManager.getConnection(connectionString,user,password); PreparedStatement statement = connection.prepareStatement("select username from users where username='testuser'"); results = statement.executeQuery(); if(results != null && results.next()){ System.out.println("found a result"); statement.close(); return true; } System.out.println("did not find a result"); statement.close(); return false; }catch(SQLException e){ e.printStackTrace(); return false; } } 

我现在还硬编码查询以消除错误来源。 与以前相同的问题(所有查询都会发生这种情况)。 调试器显示实例化的所有对象,并且不打印堆栈跟踪。 此外,我能够在不同的项目中使用相同的代码(以及之前列出的更复杂的代码)。

我想通了….愚蠢的Oracle不喜欢我拥有的并发连接数(所有这两个,一个用于控制台,一个用于java)。 不幸的是,服务器不在我的控制之下,所以我只需处理它。 您会认为Oracle会提供更好的响应。 相反,它只返回空结果集。

谢谢你的回复

编辑因为有人问过/回答过,有很多人指出潜在原因更可能与使用中的提交/事务设置有关。 请务必查看其他提示和可能解决方案的其他答案。

我看到你的代码中有一些陷阱,有些地方可能会出错:

首先,使用常规报表。 使用预准备语句,这样您就不会遇到SQL注入问题。

代替

 statement = connection.createStatement(); 

使用

 statement = connection.prepareStatement(String sql); 

有了这个,您的查询就变成了

 "select distinct group_name From group_members where username= ?" 

并设置用户名

  statement.setString(1, username); 

接下来,我不喜欢使用你的myDB类。 如果结果为null怎么办? 您没有在public List getGroups()方法中对此进行任何错误检查。

public void sendQuery(String query)在我看来似乎不应该是void ,但它应该返回一个ResultSet 。 此外,在网上搜索正确的JDBCexception处理方法。

另外,这一行:

 new InterestGroup(results.getString("group_name"), myDB) 

为什么将myDB作为参数?

我建议在代码中添加更多的System.out.println语句,这样你就可以看到出错的地方。

在java.sql.connection中,您应该在创建连接后调用此方法:

 conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); 

也许在Oracle中有类似的方法。

同样的事发生在我身上。 我使用SQL Developer将测试数据插入到我的数据库中并使用JDBC进行测试读取。 但我得到的只是一个空洞的结果集。 我可以得到列名和所有,但是在读取数据时遇到了问题。 正如之前dpsthree指出的那样,我与SQL Developer IDE断开连接,然后它要求我退出时提交。

瞧! 问题是没有提交使用insert命令对数据库的更改。

对于SQL Developer,它位于首选项>数据库>高级>自动提交

这解决了我的问题。

最常见的是在查询中有多个语句:

 desc table; select * from sometable where etc.; 

对于不返回结果的语句,您必须使用不同的结构。 即使这会导致客户窒息:

 select * from sometable where whatever; select * from sometable where something else; 

两个相同形状的结果集将对客户产生影响。

然后我仔细检查数据库上的查询(直接从调试器复制)以确保它返回数据。

我遇到过这个问题的工程师在我面前展示了这个validation。 事实certificate,他们使用程序中的一个数据库帐户登录,并在交互式SQL shell中使用不同的数据库帐户登录。 [这是Oracle 8.]

在过去,我在代码中遇到了类似的问题:

 querystr = "your sql select query string" resultset = statement.executeQuery(querystr) while (resultset.next()) { //do something with the data. //if you do something fairly involved in this block (sequentially, in the same thread) //such as calling a function that acts on the data returned from the resultset etc. //it causes the resultset fetch to wait long enough for resultset.next() to //unexpectedly return null in the middle of everything } 

我在这种情况下所做的是将所有数据加载到本地内存数据结构中,并在resultset.next()上进行最少的等待。 然后,在优雅地关闭结果集之后,我对本地数据结构中的数据执行了任何操作。 此行为是在Windows XP下的Unix后端/ JDK 1.6.0_22客户端上的Oracle 10。

希望这可以帮助。

在迭代结果集之前,请检查连接和语句Object是否存活,有时我们可能会在不知不觉中关闭。

是的,我和OP有同样的问题。 当您在同一用户上与数据库建立两个或更多打开的连接时,会发生这种情况。 例如,SQL Developer中的一个连接和Java中的一个连接。 结果始终为空结果集。

编辑:此外,我注意到,当您执行过程或插入数据库并且您不提交事务时,它会发生。

我使用plsql客户端登录到服务器,当我尝试从我的代码连接时,我成功连接,但结果集中没有记录。 只有在从服务器注销后,才会填充结果集。 我同意@dpsthree,Oracle应提供相应的错误/警告消息。

在我的情况下,在SQL开发人员中工作的查询在JAVA中不起作用。

 *select * from table where process_date like '2014-08-06%'* (worked in sql developer) 

将process_date格式化为char有助于使其在JAVA中运行

 *select * from table where to_char(process_date) = '06-AUG-14'* 

对我来说问题是,在创建主键列时,我有NOT NULL ENABLE。 如…

 CREATE TABLE SYSTEM_SETTINGS ( SYSTEM_SETTING_ID NUMBER(9,0) NOT NULL ENABLE, "KEY" VARCHAR2(50 BYTE), "VALUE" VARCHAR2(128 BYTE), CONSTRAINT "PK_SYSTEM_SETTINGS" PRIMARY KEY (SYSTEM_SETTING_ID)) TABLESPACE USERS; 

当我重新创建没有它的表时

 CREATE TABLE SYSTEM_SETTINGS ( SYSTEM_SETTING_ID NUMBER(9,0), "KEY" VARCHAR2(50 BYTE), "VALUE" VARCHAR2(128 BYTE), CONSTRAINT "PK_SYSTEM_SETTINGS" PRIMARY KEY (SYSTEM_SETTING_ID)) TABLESPACE USERS; 

它开始通过JDBC工作。 我正在使用ojdbc6.jar作为jdbc驱动程序。

即使你应该获得查询的行值,resultSet也会返回false,而rs.next()会给出false,因为你可能没有写过commit; 在您的SQL终端上进行查询。 执行此操作后,您将获得rs.next()为True。

这可能是您的表未提交的条件 。 尝试插入新记录,然后在SQL运行命令窗口中提交并运行代码。