JDBC возвращает пустой набор результатов
Я использую JDBC для очень простой связи с базой данных.
Я создал свой оператор connection/и выполнил запрос.
Я проверяю объект запроса инструкции в отладчике, чтобы подтвердить, что он отправляет правильный запрос.
Затем я дважды проверял запрос (скопированный прямо из отладчика) в базе данных, чтобы убедиться, что он возвращает данные.
Однако возвращенный набор результатов дает значение 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
Я понял, что... глупому Oracle не понравилось количество одновременных подключений, которые у меня были (все два, один для консоли, один для java). К сожалению, сервер не находится под моим контролем, поэтому мне просто придется иметь дело с ним. Вы могли бы подумать, что Oracle обеспечит лучший ответ. Вместо этого он просто возвращает пустые результирующие наборы.
Спасибо за ответы
изменить. Поскольку это было спрошено/ответили, было несколько человек, указавших, что основная причина более вероятна в отношении используемых параметров фиксации/транзакции. Пожалуйста, не забудьте увидеть другие ответы для дополнительных советов и возможных решений.
Ответ 2
Я вижу несколько ошибок в вашем коде, есть несколько мест, где все может пойти не так:
Во-первых, использование регулярных операторов. Используйте подготовленные заявления, поэтому у вас не будет проблем с 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
, чтобы вы могли видеть, где все может пойти не так.
Ответ 3
В java.sql.connection вы должны вызвать этот метод после создания своего соединения:
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
возможно, в Oracle существует аналогичный метод.
Ответ 4
То же самое случилось со мной. Я использовал Разработчик SQL, чтобы вставить тестовые данные в мою базу данных и тестовое чтение, использующее JDBC. Но все, что у меня было, было пустым набором результатов. Я мог получить имена столбцов и все, но имел проблемы с чтением данных. Как указывалось ранее dpsthree, я отключился от IDE SQL Developer, а затем попросил меня завершить работу.
Voila! Проблема заключалась в том, что изменения в базах данных с использованием команды insert не выполнялись.
Для SQL Developer это расположено в разделе "Настройки" > "База данных" > "Дополнительно" > "Автокомментировать"
Это решило мою проблему.
Ответ 5
Наиболее распространенным является наличие нескольких запросов в запросе:
desc table;
select * from sometable where etc.;
Для операторов, которые не возвращают результаты, вам нужно использовать другую конструкцию. Даже это заставит клиента задохнуться:
select * from sometable where whatever;
select * from sometable where something else;
Два одинаковых результирующих набора будут бифицировать клиента.
Ответ 6
Затем я дважды проверил запрос (скопированный прямо из отладчика) в базу данных, чтобы убедиться, что он возвращает данные.
У меня были инженеры с этой проблемой, демонстрирующие эту проверку передо мной. Оказывается, они вошли в систему с одной учетной записью базы данных в программе и с другой учетной записью базы данных в интерактивной оболочке SQL. [Это был Oracle 8.]
Ответ 7
В прошлом у меня были похожие проблемы в коде, например:
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.
Надеюсь, что это поможет.
Ответ 8
Пожалуйста, проверьте, жив ли объект соединения и оператора, пока вы не выполните итерацию результирующего набора, иногда мы можем закрыться неосознанно.
Ответ 9
Да, у меня была та же проблема, что и у OP. Это происходит, когда у вас есть два или более открытых соединения с базой данных для одного и того же пользователя. Например, одно соединение в SQL Developer и одно соединение в Java. Результат всегда является пустым набором результатов.
EDIT: Кроме того, я заметил, что это происходит, когда вы выполняете процедуру или вставляете в базу данных, и вы не совершаете транзакции.
Ответ 10
Я вошел на сервер с помощью клиента plsql и попытался подключиться из своего кода.
Я успешно подключался, но в наборе результатов не было записей.
Только после выхода с сервера набор результатов был заполнен.
Я согласен с @dpsthree, Oracle должен предоставить соответствующее сообщение об ошибке/предупреждение.
Ответ 11
Это может быть условие, что ваша таблица не зафиксирована.
Попробуйте вставить новые записи, а затем зафиксировать в своем окне SQL Run Command Window и запустить свой код.
Ответ 12
в моем случае запрос, который работал в 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'*
Ответ 13
Для меня проблема заключалась в том, что при создании столбца первичного ключа у меня не было 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.
Ответ 14
Результирующий набор возвращает false, даже если вы должны получить значения строк для запроса, а значение rs.next() дает false, потому что вы, возможно, не указали commit; на свой SQL-терминал для запроса. После этого вы получите rs.next() как True.