JDBC返回空结果集

时间:2010-12-03 06:34:50

标签: java sql oracle jdbc resultset

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

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

上给出了错误

这里有什么常见的陷阱我不在吗?

public List<InterestGroup> getGroups() {
    myDB.sendQuery("select distinct group_name From group_members where
            username='" + this.username + "'");
    ResultSet results = myDB.getResults();
    List<InterestGroup> returnList = new ArrayList<InterestGroup>();
    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;
    }

}

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

15 个答案:

答案 0 :(得分:21)

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

感谢您的回复

编辑由于有人问过/已经回答,有很多人指出,潜在原因更可能与正在使用的提交/交易设置有关。请务必查看其他答案以获取更多提示和可能的解决方案。

答案 1 :(得分:9)

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

首先,使用常规语句。使用prepared statements,这样您就不会遇到SQL injection

的问题

而不是

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<InterestGroup> getGroups()方法中没有对此进行任何错误检查。

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

此外,这一行:

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

为什么将myDB作为参数?

我建议您在代码中添加更多System.out.println语句,这样您就可以看到问题出在哪里。

答案 2 :(得分:5)

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

conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

也许Oracle中有类似的方法。

答案 3 :(得分:4)

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

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

对于SQL Developer,它位于 Preferences&gt;数据库&gt;高级&gt;自动提交

这解决了我的问题。

答案 4 :(得分:3)

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

desc table;
select * from sometable where etc.;

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

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

这两个相同形状的结果集将会影响客户。

答案 5 :(得分:2)

  

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

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

答案 6 :(得分:2)

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

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。

希望这有帮助。

答案 7 :(得分:1)

在迭代结果集之前,请检查连接和语句对象是否存活,有时我们可能会在不知情的情况下关闭。

答案 8 :(得分:1)

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

编辑:另外,我注意到当你在数据库中执行过程或插入并且你没有提交你的交易时会发生这种情况。

答案 9 :(得分:1)

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

答案 10 :(得分:1)

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

答案 11 :(得分:0)

在我的情况下,在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'*

答案 12 :(得分:0)

对我来说问题是,在创建主键列时,我有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驱动程序。

答案 13 :(得分:0)

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

答案 14 :(得分:0)

这是因为输入的数据不会保存在表格中。 一旦将值插入表中,只需提交表。这类似于我们文件系统中的保存选项。