Java Result Налаштуйте, як перевірити, чи є результати


311

Набір результатів не має методу hasNext. Я хочу перевірити, чи має результат resultSet якесь значення

це правильний шлях

if (!resultSet.next() ) {
    System.out.println("no data");
} 

2
Для читачів в майбутньому , як я: відповіді , які допомогли мені ті з Felype і Дермот Доерті
Benj

Відповіді:


237

Це правильно, спочатку ResultSetкурсор вказує на перший рядок, якщо перший дзвінок next()повертається, falseтоді в папці не було даних ResultSet.

Якщо ви використовуєте цей метод, вам, можливо, доведеться зателефонувати beforeFirst()одразу після його скидання, оскільки він розмістився повз перший рядок зараз.

Слід зазначити, що відповідь Сейфера нижче є більш елегантним рішенням цього питання.


37
Але майте на увазі, якщо є / є / рядки, після цього тесту ви будете вказувати на перший рядок. Тому переконайтеся, що ви випадково не пропустили рядок.
Метью Флашен

1
Добре, що курсор (вказівник) вказує на перший рядок
ДжонМерліно

@MatthewFlaschen, ти маєш рацію, щоб вирішити питання пропустити перший рядок, я використав do {...} while (rs.next);
Ізраїль

8
Ви також можете просто зателефонувати, isBeforeFirst()щоб перевірити, чи є рядки, повернуті без просування курсору, а потім продовжити нормально.
SnakeDoc

528

Якщо припустити, що ви працюєте з нещодавно поверненим ResultSet, курсор якого вказує перед першим рядом, простішим способом перевірити це - просто зателефонувавши isBeforeFirst(). Це дозволяє уникнути повторного відстеження, якщо дані потрібно читати.

Як пояснено в документації , це повертає помилку, якщо курсор не знаходиться до першої записи або якщо у ResultSet немає рядків .

if (!resultSet.isBeforeFirst() ) {    
    System.out.println("No data"); 
} 

 


15
Дякую, так, я знаю, але я зіткнувся з тією ж проблемою, і не був задоволений видом руху вперед, щоб перевірити, а потім прочитати назад. Я вважав, що це спрощення рішення піде на користь і іншим, хто опинився в тій же ситуації.
Сейфер

5
Зауважте, що принаймні для DB2 набір результатів повинен бути "прокручуваним" типом. Це можна встановити під час створення оператора, який потрібно виконати.
Лоранс Дугал Майерс


З документації Oracle: Примітка: Підтримка методу isBeforeFirst не є обов’язковою для ResultSets з типом набору результатів TYPE_FORWARD_ONLY
emi-le

52

ви завжди можете зробити наступний фронт, і просто зробити перевірку після циклу

if (!resultSet.next() ) {
    System.out.println("no data");
} else {

    do {
     //statement(s)
    } while (resultSet.next());
}

21

Ви зазвичай робите щось подібне:

while ( resultSet.next() ) { 
   // Read the next item
   resultSet.getString("columnName");
}

Якщо ви хочете повідомити про порожній набір, додайте змінну підрахунку прочитаних елементів. Якщо вам потрібно прочитати лише один предмет, то ваш код адекватний.


16

Щоб бути повністю впевненим у тому, що набір результатів порожній чи ні, незалежно від положення курсору, я б зробив щось подібне:

public static boolean isMyResultSetEmpty(ResultSet rs) throws SQLException {
    return (!rs.isBeforeFirst() && rs.getRow() == 0);
}

Ця функція повернеться істинною, якщо ResultSet порожній, помилковим, якщо ні, або кинутим SQLException, якщо цей ResultSet закритий / неініціалізований.


12

Найкраще використовувати ResultSet.next () разом із синтаксисом do {...} while ().

Виклик "перевірити наявність результатів" ResultSet.next () переміщує курсор до першого рядка, тому використовуйте синтаксис do {...} while () для обробки цього рядка, продовжуючи обробляти решта, повернуті циклом.

Таким чином ви зможете перевірити наявність будь-яких результатів, в той же час також обробляючи результати, що повертаються.

if(resultSet.next()) { // Checks for any results and moves cursor to first row,
    do { // Use 'do...while' to process the first row, while continuing to process remaining rows

    } while (resultSet.next());
}

8

Відповідно до найбільш життєздатної відповіді, пропонується використовувати "isBeforeFirst ()". Це не найкраще рішення, якщо у вас немає типу "тільки вперед" .

Існує метод під назвою " .first () ". Це менш зайвий рівень, щоб отримати точно такий же результат. Ви перевіряєте, чи є щось у вашому "наборі результатів", і не просунете курсор.

У документації зазначено: "(...) false, якщо в наборі результатів немає рядків ".

if(rs.first()){
    //do stuff      
}

Ви також можете просто зателефонувати isBeforeFirst (), щоб перевірити чи повертаються рядки без просування курсору, а потім продовжувати нормально. - SnakeDoc 2 вересня '14 о 19:00

Однак існує різниця між "isBeforeFirst ()" та "first ()". Спочатку створюється виняток, якщо це робиться на основі результатів з типу "тільки вперед".

Порівняйте два розділи кидка: http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#isBeforeFirst () http://docs.oracle.com/javase/7/docs /api/java/sql/ResultSet.html#first ()

Гаразд, в основному це означає, що ви повинні використовувати "isBeforeFirst", якщо у вас є тип "тільки вперед". Інакше використовувати "first ()" менше зайвого.


1
Як же "менше зайвих" отримати такий самий результат? Мені здається, мета першого () - перемістити курсор до першого ряду, якщо його вже немає (і повернути true, якщо це вдалося). isBeforeFirst - це виключно діагностична функція і, здається, більше підходить до цілей автора. Плюс до того, що сформульовано first (), воно повертається істиною до тих пір, поки воно знаходиться "на дійсному рядку" ... що дивно, як можна було б подумати, що це було б сформульовано як "у першому рядку". Для мене я не бачу переваги використання first () у цьому сценарії, якщо ваш курсор не просунувся, і ви не хочете повернути його до початку.
Джон

5

Це спрацює, якщо ви хочете побачити, чи є рядки в наборі результатів так.

Зауважте, що next()завжди переходить до наступного ряду, тому якщо ви плануєте робити будь-яке читання з набору результатів, потрібно врахувати це.

Звичайне використання ResultSet (при простому читанні):

while (resultSet.next())
{
   ... read from the row here ...
}

Що очевидно не спрацює правильно, якщо ви next()один раз вже викликали, щоб перевірити чи порожній набір результатів, тому стежте за цим. Хоча існують методи "резервного копіювання", вони підтримуються не для всіх типів наборів результатів.


5

Я вважаю, це практичний та легкий для читання твір.

        if (res.next()) {
            do {

                // successfully in. do the right things.

            } while (res.next());
        } else {
           // no results back. warn the user.
        }

2
if (!resultSet.isAfterLast() ) {    
System.out.println("No data"); 
} 

isAfterLast() також повертає false для порожнього набору результатів, але оскільки курсор все-таки знаходиться перед першим рядком, цей метод здається більш зрозумілим.


2
if(resultSet.first) {

} else { 
    system.out.println("No raw or resultSet is empty");
}

Тому що якщо у ResultSet немає сировини, то resultSet.firstповертається false.


Але він переміщує курсор на перший рядок непотрібно, і це може сплутати подальше використання об’єкта "скидання" і може втратити дані
Tigran Babajanyan

Хоча це виглядає краще, воно не працюватиме на наборі результатів лише курсором.
eliteproxy

1

Найкраще зробити це - перевірити перший рядок, щоб, коли ви збираєтесь отримати дані, ви змогли уникнути помилки пропуску рядка. Щось на зразок: if (! ResultSet.first ()) {System.out.println ("немає даних"); }


1

Використовуючи resultSet.next (), ви можете легко отримати результат, будь то результат, що містить будь-яке значення чи ні

ResultSet resultSet = preparedStatement.executeQuery();
if(resultSet.next())
 //resultSet contain some values
else
 // empty resultSet

Не повторюйте існуючі відповіді.
james.garriss


1

Я намагався встановити поточний рядок на перший індекс (маючи справу з первинними ключами). Я б запропонував

if(rs.absolute(1)){
    System.out.println("We have data");
} else {
    System.out.println("No data");
}

Коли ResultSet заповнений, він вказує на перший рядок. Якщо встановити його на перший рядок (вказаний rs.absolute(1)), він поверне справжнє, що означає, що він був успішно розміщений у рядку 1, або помилковим, якщо рядок не існує. Ми можемо екстраполювати це на

for(int i=1; rs.absolute(i); i++){
    //Code
}

який встановлює поточний рядок у позицію i, і не буде, якщо рядка не існує. Це лише альтернативний метод

while(rs.next()){
    //Code
}

Яка ваша відповідь?
CMedina

1

Я створив наступний метод, щоб перевірити, чи ResultSet порожній.

public static boolean resultSetIsEmpty(ResultSet rs){        
    try {
        // We point the last row
        rs.last();
        int rsRows=rs.getRow(); // get last row number

        if (rsRows == 0) {
            return true;
        }

        // It is necessary to back to top the pointer, so we can see all rows in our ResultSet object.
        rs.beforeFirst();
        return false;
    }catch(SQLException ex){            
        return true;
    }
}

Дуже важливо мати такі міркування:

Об'єкт CallableStatement повинен бути налаштований так, щоб об'єкт ResultSet переходив наприкінці і повертався до вершини.

TYPE_SCROLL_SENSITIVE : ResultSet об'єкт може зміщуватися в кінці і повертатися до вершини. Далі можна знайти останні зміни.

CONCUR_READ_ONLY : Ми можемо читати дані об’єкта ResultSet, але не можемо оновити.

CallableStatement proc = dbconex.prepareCall(select, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);

1

Я думаю, що найпростіший спосіб перевірити набір результатів - це через CollectionUtils під пакетом org.apache.commons.collections.CollectionUtils

if(CollectionUtils.isNotEmpty(resultList)){
  /**
  * do some stuff
  */
}

Це дозволить перевірити нульову та порожню умову набору результатів.

Для отримання більш детальної інформації ви можете звернутися до наступного документа. CollectionUtils


1
ResultSet не є колекцією.
Йоахім Лус

1

Чому б не використовувати rs.getRow ()?

int getRow()
           throws SQLException
Retrieves the current row number. The first row is number 1, the second number 2, and so on.
Note:Support for the getRow method is optional for ResultSets with a result set type of TYPE_FORWARD_ONLY

Returns:
the current row number; 0 if there is no current row
Throws:
SQLException - if a database access error occurs or this method is called on a closed result set
SQLFeatureNotSupportedException - if the JDBC driver does not support this method
Since:
1.2

Для мене встановіть прапорець "if (rs.getRow ()! = 0)", здається, працює добре.



0
ResultSet rs = rs.executeQuery();
if(rs.next())
{
  rs = rs.executeQuery();
  while(rs.next())
  {
    //do code part
  }
}
else
{
  //else if no result set
}

Краще повторно виконати запит, тому що коли ми зателефонуємо в if(rs.next()){....}перший рядок ResultSet, буде виконаний і після нього всередині while(rs.next()){....}ми отримаємо результат з наступного рядка. Тому я думаю, що повторне виконання запиту всередині ifє кращим варіантом.


5
-1 Це не кращий варіант. Навіщо запитувати базу даних двічі? Що робити, якщо дані різко змінюються між дзвінками? Це марно.
Toby Caulk

-2

Спочатку об'єкт набору результатів (rs) вказує на BFR (до першого запису). Як тільки ми використовуємо rs.next (), курсор вказує на перший запис і rs утримує "true". За допомогою циклу while можна надрукувати всі записи таблиці. Після отримання всіх записів курсор переміщується в ALR (Після останнього запису), і він буде встановлений на нуль. Розглянемо, що в таблиці є 2 записи.

if(rs.next()==false){
    // there are no records found
    }    

while (rs.next()==true){
    // print all the records of the table
    }

Коротше кажучи, ми також можемо записати умову як while (rs.next ()).


3
Ваш цикл while не отримає шансу оперувати першим поверненим рядом, що виглядає дещо фатальним недоліком при такому підході. Вище є багато пропозицій, які кращі за цю.
Жуль
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.