Java ResultSet結果があるかどうかを確認する方法


311

結果セットにhasNextのメソッドがありません。resultSetに値があるかどうかを確認したい

これは正しい方法ですか

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

2
私のような将来の読者のために:私を助けた答えは、FelypeとDermot Dohertyからの回答です
Benj

回答:


238

それは正しいです。最初ResultSetののカーソルは最初の行の前を指しています。最初の呼び出しがnext()戻るとfalse、にデータがありませんでしたResultSet

このメソッドを使用する場合、beforeFirst()現在は最初の行を過ぎて配置されているため、直後に呼び出してリセットする必要があります。

ただし、以下のSeiferの回答は、この質問に対するよりエレガントな解決策であることに注意してください。


37
ただし、/ are /行がある場合、そのテストの後、最初の行を指すことに注意してください。したがって、誤って行をスキップしないようにしてください。
Matthew Flaschen、2009年

1
カーソル(ポインタ)が最初の行を指していることの良い点
JohnMerlino '11年

@MatthewFlaschen、そうです、最初の行をスキップする問題を解決するために、do {...} while(rs.next);を使用しました。
イスラエル、2014

8
を呼び出しisBeforeFirst()て、カーソルを進めずに返された行があるかどうかをテストしてから、通常どおり続行することもできます。
SnakeDoc '

528

新しく返されたものを使用していると仮定します ResultSetカーソルが最初の行の前を指し場合、これを確認する簡単な方法は、を呼び出すことisBeforeFirst()です。これにより、データを読み取る場合にバックトラックする必要がなくなります。

ドキュメント説明されているように、カーソルが最初のレコードの前にない場合、またはResultSetに行がない場合、これはfalseを返します。

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

 


15
ありがとう、はい、知っていますが、同じ問題が発生し、前に進んで確認してから、後ろに読んで読むのに満足していませんでした。この単純な解決策は、同じ状況にいる他の人にもメリットがあると思いました。
Seifer

5
少なくともDB2の場合、結果セットは「スクロール可能な」タイプでなければならないことに注意してください。これは、実行するステートメントを作成するときに設定できます。
Laurence Dougal Myers

1
以下のFelypeの回答はより完全です
Tom Howard

Oracleドキュメントから:注:isBeforeFirstメソッドのサポートは、結果セットタイプがTYPE_FORWARD_ONLYのResultSetのオプションです
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が空の場合はtrueを返し、そうでない場合はfalseを返すか、そのResultSetが閉じている/初期化されていない場合はSQLExceptionをスローします。


12

これには、do {...} while()構文とともにResultSet.next()を使用するのが最適です。

「すべての結果を確認」呼び出し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()」には違いがあります。タイプ "転送のみ"の結果セットに対して行われた場合、最初に例外が生成されます。

2つのスローセクションを比較します。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
まったく同じ結果を得るのは、どのように「やり過ぎない」のですか?first()の目的は、カーソルが最初の行にない場合はそこに移動することです(成功した場合はtrueを返します)。isBeforeFirstは純粋に診断機能であり、作成者の目的により適しているようです。さらに、first()の表現方法は、「有効な行にある」限りtrueを返します...「最初の行にある」と表現されるのは奇妙です。私には、カーソルが進んで最初に戻したくない限り、このシナリオでfirst()を使用する利点はわかりません。
Jon

5

結果セットに行があるかどうかを確認したい場合は、yesで機能します。

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にrawがない場合resultSet.firstはfalseを返すからです。


ただし、カーソルを最初の行に移動する必要はなく、ob "reset"オブジェクトの使用を混乱させ、データが失われる可能性があります
Tigran Babajanyan

これは見栄えはよくなりますが、前方のみのカーソル結果セットでは機能しません。
エリートプロキシ

1

最善の方法は、最初の行を確認して、データを取得するときに、行をスキップするミスを回避できるようにすることです。次のようなもの:if(!resultSet.first()){System.out.println( "no data"); }


1

resultSet.next()を使用すると、resultSetに値が含まれているかどうかに関係なく、簡単に結果を取得できます。

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

既存の回答を繰り返さないでください。
james.garriss 2015年


1

現在の行を最初のインデックスに設定しようとしています(主キーに対処しています)。提案する

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

ResultSetが入力されると、最初の行の前を指します。最初の行(で示されるrs.absolute(1))に設定すると、行1に正常に配置されたことを示すtrueか、行が存在しない場合はfalseが返されます。これを外挿して

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

これは、現在の行を位置iに設定し、行が存在しない場合は失敗します。これは単なる代替方法です

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

あなたの答えは何ですか?
CMedina 16

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

結果セットをチェックする最も簡単な方法は、org.apache.commons.collections.CollectionUtilsパッケージの下のCollectionUtilsを使用することだと思います

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

これにより、nullと空の結果セット条件がチェックされます。

詳細については、次のドキュメントを参照してください。 CollectionUtils


1
ResultSetはコレクションではありません。
Joachim Lous、

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これは良いオプションではありません。なぜデータベースを2回クエリするのですか?呼び出し間でデータが大幅に変化した場合はどうなりますか?これは無駄です。
Toby Caulk

-2

最初は、結果セットオブジェクト(rs)はBFR(最初のレコードの前)を指しています。rs.next()を使用すると、カーソルは最初のレコードをポイントし、rsは「true」を保持します。whileループを使用すると、テーブルのすべてのレコードを印刷できます。すべてのレコードが取得されると、カーソルはALR(最後のレコードの後)に移動し、nullに設定されます。テーブルに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ループでは、返された最初の行を操作する機会がありません。これは、このアプローチにはやや致命的な欠陥のようです。これよりも優れた提案がたくさんあります。
ジュール・
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.