目次 | 前項目 | 次項目 JDBCTM ガイド: 「はじめましょう」


5 - ResultSet

この概要は、JavaSoftで現在進行中の JDBCTM Database Access from JavaTM: A Tutorial and Annotated Referenceからの抜粋です。本書は、JDBC用のチュトリアルおよび最終レファレンス・マニュアルで、Javaシリーズの一部として1997年春にAddison-Wesley Publishing Companyから出版されています。

5.1    概要

ResultSet は、SQL 文の条件を満たすべての行を含んでおり、 現在行のさまざまな列にアクセスできる一連の get メソッドによって、これらの行のデータにアクセスする手段を提供します。ResultSet.next メソッドは、ResultSet の次行に移動するために使用され、次行が現在行になるようにします。

結果のセットの一般的な形式は、列の見出しとクエリーの結果に対応する値から成るテーブルです。たとえば、クエリーが SELECT a, b, c FROM Table1であれば、結果セットは次のような形式になります。

        a          b            c
        --------   ---------    -------- 
        12345      Cupertino    CA
        83472      Redmond      WA
        83492      Boston       MA

次のコード断片は、列 1 を int、列 2 を String、そして列 3 をバイトの配列とする行のコレクションを戻す SQL 文の実行例です。

    
    java.sql.Statement stmt = conn.createStatement();
    ResultSet r = stmt.executeQuery("SELECT a, b, c FROM Table1");
    while (r.next()) 
    {
      // print the values for the current row.
      int i = r.getInt("a");
      String s = r.getString("b");
      float f = r.getFloat("c");
      System.out.println("ROW = " + i + " " + s + " " + f);
    }

5.1.1    行とカーソル

ResultSet は現在行のデータを指し示すカーソルを維持します。カーソルは next メソッドが呼び出されるたびに 1 行下に移動します。カーソルは初期には 1 行目の前に位置するので、最初の next の呼び出しでは、カーソルが 1 行目に位置し、この行が現在行になります。ResultSet 行は、最上行から順次下に検索され、次の next の呼び出しのたびにカーソルが 1 行づつ下に移動します。

カーソルは、ResultSet オブジェクトまたはその上位の オブジェクトが閉じられるまで有効になっています。

SQLでは、結果テーブルのカーソルに名前がつけられます。データベースがカーソル位置での更新または削除が可能な場合には、そのカーソルの名前を更新または削除コマンドとして与える必要があります。この名前はメソッド getCursorName を呼び出して取得します。

すべての DBMS がカーソル位置での更新または削除をサポートするとは限らないことに注意してください。DatabaseMetaData.supportsPositionedDelete および supportsPositionedUpdate メソッドを使用すると、特定の接続がこれらのオペレーションをサポートするかどうかを検出できます。これらがサポートされている場合、カーソル位置での更新または削除の際に複数の処理から同じ行を更新することがないよう、DBMS/ドライバは、選択行が正しくロックされているかを確認する必要があります。

5.1.2    列

getXXX メソッドは、現在行から列を検索する手段を提供します。各行で列値を任意の順序に検索できますが、移植性を最大にするため、値は左から右に検索し、列値の読み取りを 1 度だけにします。

データを取り出す元の列の指定には、列名または列番号のどちらでも使用できます。たとえば、 ResultSet オブジェクト rs の 2 列目は "title" という名前がつけられ、値を文字列として格納する場合は、次のどちらでもその列に格納された値を取り出します。

    String s = rs.getString("title");
    String s = rs.getString(2);
列には、左から右へと列 1 から始まる番号がつけられていることに注意してください。また、getXXX メソッドへの入力に使用される列名は大文字小文字を識別しません。

クエリーで列名を指定したユーザが getXXX メソッドの引数として同じ名前を使用できるように、列名を使用するオプションが提供されました。他方、 SELECT 文に列名が指定されていない場合 ("select * from table1" であるか、または列が導き出された列である場合など) には、列番号を使用すべきです。そのような場合では、ユーザが列名を確実に知る方法はありません。

場合によっては、SQL 文の結果が同名の列を複数もつ結果のセットを返すこともあり得ます。 列名が getXXX メソッドを指すパラメータとして使用されている場合には、 getXXX は最初に一致する列名の値を返します。したがって、同名の列が複数ある場合は、正しい列値を取り出したかを確認するために列の添字を使用する必要があります。また、列番号を使用した方が多少効率的かもしれません。

メソッド ResultSet.getMetaData を呼び出すと、ResultSet の中の列に関する情報を入手できます。返される ResultSetMetaData オブジェクトには、その ResultSet オブジェクトの列の番号、型、およびプロパティがついています。

列の名前が既知であるがその添字がわからない場合は、メソッドfindColumn を使用して列番号を検索することができます。

5.1.3    データの型と変換

getXXX メソッドでは、JDBC ドライバは基礎データを指定の Java の型に変換しようと試みてから、適切な Java 値を返します。たとえば、getXXX メソッドが getString であり、基礎のデータベースのデータのデータ型が VARCHAR である場合、JDBCドライバは VARCHAR を Java String に変換します。getString の返却値は Java String オブジェクトになります。

次の表は、 getXXX メソッドでどの JDBC 型を取り出すことができるか、そしてこのメソッドでの取り出しには、どの JDBC 型 (汎用的な SQL 型) が推奨されているかを示しています。小文字の x は、特定のデータ型の正当な getXXX メソッドを示し、大文字の X は、データ型の推奨 getXXX メソッドを示します。たとえば、LONGVARCHAR の値を取り出すには、 getBytes または getBinaryStream を除く任意の getXXX メソッドを使用できますが、どのデータ型が返されるかによって、getAsciiStream または getUnicodeStream が推奨されています。メソッド getObject は、どんなデータ型でも Java Object として返すので、基礎データ型がデータベース固有の抽象型であるときや、汎用アプリケーションがどんなデータ型も受け入れできることが必要になるときには有用です。

ResultSet.getXXX メソッドを使用した共通 JDBC データ型の取り出し。

"x" は、getXXX メソッドが指定の JDBC 型の検索に使用できる可能性があることを示します。

"X" は、getXXX メソッドが指定の JDBC 型の取り出しに推奨されていることを示します。

  T
I
N
Y
I
N
T
S
M
A
L
L
I
N
T
I
N
T
E
G
E
R
B
I
G

N
T
R
E
A
L
F
L
O
A
T
D
O
U
B
L
E
D
E
C
I
M
A
L
N
U
M
E
R
I
C
B
I
T
C
H
A
R
V
A
R
C
H
A
R
L
O
N
G
V
A
R
C
H
A
R
B
I
N
A
R
Y
V
A
R
B
I
N
A
R
Y
L
O
N
G
V
A
R
B
I
N
A
R
Y
D
A
T
E
T
I
M
E
T
I
M
E
S
T
A
M
P
getByte X x x x x x x x x x x x x            
getShort x X x x x x x x x x x x x            
getInt x x X x x x x x x x x x x            
getLong x x x X x x x x x x x x x            
getFloat x x x x X x x x x x x x x            
getDouble x x x x x X X x x x x x x            
getBigDecimal x x x x x x x X X x x x x            
getBoolean x x x x x x x x x X x x x            
getString x x x x x x x x x x X X x x x x x x x
getBytes                           X X x      
getDate                     x x x       X   x
getTime                     x x x         X x
getTimestamp                     x x x       x   X
getAsciiStream                     x x X x x x      
getUnicodeStream                     x x X x x x      
getBinaryStream                           x x X      
getObject x x x x x x x x x x x x x x x x x x x

5.1.4     行の極めて大きな値にストリームを使用する

ResultSet では、大きな LONGVARBINARY または LONGVARCHAR データを任意に検索することが可能になります。メソッド getBytesgetString は、1つの大きなかたまりのようなデータを返します。 (Statement.getMaxFieldSize の返却値によって課された限界まで)。しかし、大きなデータを小さい固定サイズに分割して取得することもできます。 これを行うには、データをかたまりで読み取ることができる ResultSet クラス返却値 java.io.Input ストリームが必要です。 このストリームは次の ResultSetgetXXX 呼び出しで自動的に閉じられるため、これらにすぐにアクセスしなければならないことに注意してください。(この動作は、大きなかたまりのアクセスでの基本的な実装の制約によって強制されます。)

JDBC API にはストリームを取得する個別メソッドが3つあり、それぞれが異なった返却値を返します。

これは、タイプされないバイト数を返し、 ASCII 文字と Unicode 文字の両方に使用できる (たとえば) Java ストリームとは異なることに注意してください。

次のコードは、getAsciiStream の使用例を示しています。

    java.sql.Statement stmt = con.createStatement();
    ResultSet r = stmt.executeQuery("SELECT x FROM Table2");
    // Now retrieve the column 1 results in 4 K chunks:
    byte buff = new byte[4096];
    while (r.next()) { 
      Java.io.InputStream fin = r.getAsciiStream(1);
      for (;;) {
        int size = fin.read(buff);
        if (size == -1) { // at end of stream
              break;
    }
        // Send the newly-filled buffer to some ASCII output stream:
        output.write(buff, 0, size);
    }
    }

5.1.5     NULL の結果値

与えられた結果の値が JDBC NULL であるかどうかを判別するため、まず列を読み取り、次に ResultSet.wasNull メソッドを使用して、読み取った値が JDBC NULLを 返したかどうかを判断しなければなりません。

ResultSet.getXXX メソッドの 1つを使用して JDBC NULL を読み取ったときは、メソッド wasNull は次の値の 1つを返します。

5.1.6     オプションの結果、または複数の結果のセット

通常、SQL 文は、executeQuery (単一の ResultSet を返す) または executeUpdate (どんな種類のデータベース UPDATE 文にも使用でき、更新された行のカウントを返す) のどちらかを使用して実行されます。しかし、状況によっては、アプリケーションが与えられた文が実行されるまで結果のセットを返すかどうか、不明である場合があります。さらに、ストアードプロシージャによっては、いくつかの異なる結果のセットまたは更新カウント、あるいはこの両方を返すものがあります。

これらの状況に対処するため、JDBC は、アプリケーションが文を実行し、さらに結果のセットおよび更新カウントの任意の収集結果を処理することができるようなメカニズムを提供します。このメカニズムは、最初は完全に汎用的な execute メソッドの呼び出し、続いて他の 3 つのメソッド、すなわち getResultSetgetUpdateCount、および getMoreResults の呼び出しに基づいています。これらのメソッドでは、アプリケーションが文の結果を一度に 1 つづつ探し出し、与えられた結果が ResultSet または更新カウントのどちらであるかを判別することができます。

ResultSet を閉じるには、何もする必要がありません。これは、Statement が閉じられるとき、再実行されるとき、または一連の複数結果から次の結果を検索するために使用されるときに、ResultSet を生成した Statement が自動的に閉じるからです。



目次 | 前項目 | 次項目
jdbc@wombat.eng.sun.com または jdbc-odbc@wombat.eng.sun.com
Copyright (C) 1996, 1997 Sun Microsystems, Inc. All rights reserved.