2010-12-03 8 views
14

Я использую JDBC для очень простой связи с базой данных.JDBC возвращает пустой набор результатов

Я создал свой оператор connection/statement и выполнил запрос. Я проверяю объект запроса инструкции в отладчике, чтобы подтвердить, что он отправляет правильный запрос. Затем я дважды проверил запрос (скопированный прямо из отладчика) в базу данных, чтобы убедиться, что он возвращает данные. Возвращенный результирующий набор, однако, дает значение false .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; 
} 

EDIT: на основе предложений, которые я в основном модернизированных мой код, но все еще есть та же проблема. Ниже приведена упрощенная часть кода, которая имеет ту же проблему.

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; 
    } 

} 

Я также жестко запросил запрос на устранение этого источника ошибки. Та же проблема, что и раньше (это происходит со всеми запросами). Отладчик показывает все объекты, получающие экземпляр, и трассировки стека не печатаются. Кроме того, я могу использовать тот же код (и более сложный код, указанный ранее) в другом проекте.

+1

Пожалуйста, внесите свой код. Без кода здесь недостаточно информации для предоставления ответа. – Asaph 2010-12-03 06:37:18

+0

Возможно, он находится внутри функции getResults, если вы могли бы опубликовать это, но это очень помогло бы. – Brains1994 2010-12-03 07:01:17

+0

извините, добавил это также. – dpsthree 2010-12-03 07:08:00

ответ

18

Я понял, что глупому Oracle не понравилось количество одновременных подключений, которые у меня были (все два, один для консоли, один для java). К сожалению, сервер не находится под моим контролем, поэтому мне просто придется иметь дело с ним. Вы могли бы подумать, что Oracle обеспечит лучший ответ. Вместо этого он просто возвращает пустые наборы результатов.

Спасибо за ответы

редактировать Так как это было предложено/ответили там было много людей, отметил, что основной причиной является более вероятно, связано с настройками фиксации/транзакций в использовании. Пожалуйста, не забудьте увидеть другие ответы для дополнительных советов и возможных решений.

3

Наиболее распространенным является наличие нескольких заявлений в запросе:

desc table; 
select * from sometable where etc.; 

Для операторов, которые не возвращают результаты, вы должны использовать другую конструкцию. Даже это заставит клиент задыхаться:

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

две одинаковые-образные наборы результатов будут Биф клиента.

2

Затем я дважды проверил запрос (скопированный прямо из отладчика) в базу данных, чтобы убедиться, что он возвращает данные.

У меня были инженеры с этой проблемой, демонстрирующие эту проверку передо мной. Оказывается, они вошли в систему с одной учетной записью базы данных в программе и с другой учетной записью базы данных в интерактивной оболочке SQL. [Это был Oracle 8.]

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 операторов, чтобы вы могли видеть, где все может пойти не так.

5

В java.sql.Connection вы должны вызвать этот метод, после создания соединения:

conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); 

может быть, есть подобный метод в Oracle.

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 (). Затем я сделал все, что у меня было, по данным локальной структуры данных после изящного закрытия набора результатов. Такое поведение было у Oracle 10 на клиенте Unix backend/JDK 1.6.0_22 под Windows XP.

Надеюсь, это поможет.

0

В моем случае запрос, который работал в sql-разработчике, не работал в JAVA.

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

верстку process_date СИМВОЛУ помогли сделать его работу в JAVA

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

Для меня проблема заключалась в том, что на создание столбца первичного ключа я имел NOT NULL ВКЛЮЧИТЬ. Как и в ...

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.

3

То же самое произошло со мной. Я использовал SQL Developer, чтобы вставить тестовые данные в мою базу данных и тестовое чтение с использованием JDBC. Но все, что у меня было, было пустым набором результатов. Я мог получить имена столбцов и все, но имел проблемы с чтением данных. Как указывалось ранее dpsthree, я отключился от IDE SQL Developer, а затем попросил меня завершить работу.

Voila! Проблема заключалась в том, что изменения в базах данных с использованием команды insert не выполнялись.

Для SQL Developer это находится в Preferences> База данных> Дополнительно> Autocommit

Это решило мою проблему.

0

Да, у меня была та же проблема, что и у ОП. Это происходит, когда у вас есть два или более открытых соединения с базой данных для одного и того же пользователя. Например, одно соединение в SQL Developer и одно соединение в Java. Результат - пустой набор результатов.

EDIT: Кроме того, я заметил, что это происходит, когда вы выполняете процедуру или вставляете в базу данных, и вы не совершаете транзакции.

0

Я зарегистрировался на сервере, используя клиент plsql, и, хотя я пытался подключиться к своему коду, я успешно подключился, но в результирующем наборе записей не было. Только после выхода из сервера набор результатов был заполнен. Я согласен с @dpsthree, Oracle должен предоставить соответствующее сообщение об ошибке/предупреждении.

0

Результат возвращает false, даже если вы должны получить значения строк для запроса, а rs.next() дает false, потому что вы, возможно, не указали commit; на вашем sql-терминале для запроса. После этого вы получите rs.next() как True.

Смежные вопросы