ヘッダーをスキップ
Oracle Database JDBC開発者ガイドおよびリファレンス
10g リリース2(10.2)
B19275-03
  目次へ
目次
索引へ
索引

前へ
前へ
次へ
次へ
 

13 Oracleデータへのアクセスと操作

この章では、oracle.sql.*形式でのデータ・アクセスについて、標準Java形式と対比させて説明します。 oracle.sql.*形式はOracle Java Database Connectivity(JDBC)拡張要素のキーとなる要因であり、SQLデータを操作する際の効率と精度を大きく向上させます。

oracle.sql.*形式の使用には、結果セットおよび文を適宜OracleResultSetOracleStatementOraclePreparedStatementおよびOracleCallableStatementにキャストすること、およびこれらのクラスのgetOracleObjectsetOracleObjectgetXXXおよびsetXXXメソッド(XXXoracle.sqlパッケージの型に対応)を使用することが関係しています。

次の項目が含まれます。

データ型マッピング

Oracle JDBCドライバは、Oracle固有のデータ型に加えて、標準JDBC型をサポートしています。この項では、標準およびOracle固有のSQL-Javaデフォルト型マッピングについて説明します。この項では、次の項目について説明します。

マッピングの表

表13-1に、SQLデータ型、JDBC型コード、標準Java型およびOracle拡張型間のデフォルト・マッピングを示します。

SQLデータ型列には、Oracle Database 10gに存在するSQL型をリストします。JDBC型コード列には、JDBC標準によってサポートされ、java.sql.Typesクラス、またはoracle.jdbc.OracleTypesクラスでOracleによって定義されるデータの型コードをリストします。標準型の型コードは、この2つのクラスで同一です。

標準Java型列には、Java言語で定義される標準型をリストします。Oracle拡張機能Java型列には、データベース内の各SQLデータ型に対応するoracle.sql.* Java型をリストします。これらは、oracle.sql.* Java型でSQLデータすべての取出しを可能にするOracle拡張機能です。SQLデータをoracle.sql.*データ型として操作すると、変換が最小限になり、パフォーマンスが向上し、変換の無駄がなくなります。

表13-1 SQL型とJava型間のデフォルト・マッピング

SQLデータ型 JDBC型コード 標準Java型 Oracle拡張機能Java型


標準JDBC 1.0型:



CHAR

java.sql.Types.CHAR

java.lang.String

oracle.sql.CHAR

VARCHAR2

java.sql.Types.VARCHAR

java.lang.String

oracle.sql.CHAR

LONG

java.sql.Types.LONGVARCHAR

java.lang.String

oracle.sql.CHAR

NUMBER

java.sql.Types.NUMERIC

java.math.BigDecimal

oracle.sql.NUMBER

NUMBER

java.sql.Types.DECIMAL

java.math.BigDecimal

oracle.sql.NUMBER

NUMBER

java.sql.Types.BIT

boolean

oracle.sql.NUMBER

NUMBER

java.sql.Types.TINYINT

byte

oracle.sql.NUMBER

NUMBER

java.sql.Types.SMALLINT

short

oracle.sql.NUMBER

NUMBER

java.sql.Types.INTEGER

int

oracle.sql.NUMBER

NUMBER

java.sql.Types.BIGINT

long

oracle.sql.NUMBER

NUMBER

java.sql.Types.REAL

float

oracle.sql.NUMBER

NUMBER

java.sql.Types.FLOAT

double

oracle.sql.NUMBER

NUMBER

java.sql.Types.DOUBLE

double

oracle.sql.NUMBER

RAW

java.sql.Types.BINARY

byte[]

oracle.sql.RAW

RAW

java.sql.Types.VARBINARY

byte[]

oracle.sql.RAW

LONGRAW

java.sql.Types.LONGVARBINARY

byte[]

oracle.sql.RAW

DATE

java.sql.Types.DATE

java.sql.Date

oracle.sql.DATE

DATE

java.sql.Types.TIME

java.sql.Time

oracle.sql.DATE

TIMESTAMP

java.sql.Types.TIMESTAMP

javal.sql.Timestamp

oracle.sql.TIMESTAMP


標準JDBC 2.0型:



BLOB

java.sql.Types.BLOB

java.sql.Blob

oracle.sql.BLOB

CLOB

java.sql.Types.CLOB

java.sql.Clob

oracle.sql.CLOB

ユーザー定義オブジェクト

java.sql.Types.STRUCT

java.sql.Struct

oracle.sql.STRUCT

ユーザー定義参照

java.sql.Types.REF

java.sql.Ref

oracle.sql.REF

ユーザー定義コレクション

java.sql.Types.ARRAY

java.sql.Array

oracle.sql.ARRAY


Oracle拡張機能:



BFILE

oracle.jdbc.OracleTypes.BFILE

N/A

oracle.sql.BFILE

ROWID

oracle.jdbc.OracleTypes.ROWID

N/A

oracle.sql.ROWID

REF CURSOR

oracle.jdbc.OracleTypes.CURSOR

java.sql.ResultSet

oracle.jdbc.OracleResultSet

TIMESTAMP

oracle.jdbc.OracleTypes.TIMESTAMP

java.sql.Timestamp

oracle.sql.TIMESTAMP

TIMESTAMP WITH TIME ZONE

oracle.jdbc.OracleTypes.TIMESTAMPTZ

java.sql.Timestamp

oracle.sql.TIMESTAMPTZ

TIMESTAMP WITH LOCAL TIME ZONE

oracle.jdbc.OracleTypes.TIMESTAMPLTZ

java.sql.Timestamp

oracle.sql.TIMESTAMPLTZ



注意:

バージョン8.1.7など、TIMESTAMPデータ型をサポートしていないデータベースのバージョンの場合、TIMESTAMPDATEにマップされます。

マッピングに関する注意

この項では、NUMBERおよびユーザー定義型のマッピングに関する詳細を提供します。

NUMBER型

Oracle NUMBER値が対応できる様々な型コードでは、マッピングを正しく動作させるために、データのサイズに適切なgetterルーチンをコールします。たとえば、-128 < x < 128の項目xに対してJava tinyint値を取得するには、getByteをコールします。

ユーザー定義型

オブジェクト、オブジェクト参照およびコレクションなどのユーザー定義型は、デフォルトでjava.sql.Structなどの弱いJava型にマップされますが、かわりに強い型指定のカスタムJavaクラスにもマップできます。カスタムJavaクラスは、次のいずれかのインタフェースを実装できます。

  • 標準java.sql.SQLData

  • Oracle固有oracle.sql.ORAData

データ変換での考慮事項

JDBCプログラムでSQLデータをJavaに取り込む場合は、標準Java型またはoracle.sqlパッケージの型を使用できます。この項には、次の項目が含まれます。

標準型とOracle型

oracle.sqlのOracleデータ型では、データベースで使用されているのと同じビット形式でデータが格納されます。Oracle Database 10gより前のバージョンのOracle JDBCドライバでは、通常、Oracleデータ型の方が効率性に優れていました。Oracle Database 10g JDBCドライバは大幅に更新されました。その結果、ほとんどの場合は、oracle.sqlのデータ型よりも標準Java型が優先されるようになりました。特に、java.lang.Stringは、効率性の面でoracle.sql.CHARよりもとても優れています。

一般的にはJava標準型の使用をお薦めします。例外として次のような場合があります。

  • OraDataの機能の方がニーズに合っている場合は、java.sql.SqlDataではなく、oracle.sql.OraDataを使用します。

  • 浮動小数点数の値を正確に保持する必要がある場合は、java.lang.Doubleではなくoracle.sql.NUMBERを使用します。Oracle NUMBERは10進表現ですが、Java DoubleおよびFloatは2進表現となります。ある形式から別の形式へ変換を行うと、その結果が実際の表現値から少し変動した値となる可能性があります。さらに、2つの形式では、表現できる値の範囲がそれぞれ異なります。

  • JDK 5.0以前のバージョンを使用している場合、または最大限のパフォーマンスを実現する必要がある場合は、java.sql.Dateまたはjava.sql.Timestampではなく、oracle.sql.DATEまたはoracle.sql.TIMESTAMPを使用します。また、多くの日付値を読み込む場合や、一握りのデータしか計算または表示しない場合にも、oracle.sqlデータ型を使用できます。JDK 5.1より前のすべてのバージョンでは、不具合によりjava.lang.Dateおよびjava.lang.Timestampオブジェクトの作成処理が遅くなるという問題があります(特に、マルチスレッド環境において)。この不具合は、JDK 5.1で修正されました。


注意:

oracle.sqlデータ型をJava標準データ型に変換した場合、oracle.sqlデータ型を使用する利点は失われます。

SQL NULLデータの変換

Javaは、SQL NULLデータを、Javaの値nullで表現します。Javaデータ型は、プリミティブ型(byteintfloatなど)とオブジェクト型(クラス・インスタンスなど)の2つのカテゴリに分類されます。プリミティブ型でNULLを表すことはできません。かわりに、JDBC仕様で定義されているように、nullを0(ゼロ)値として格納します。これは、結果の解釈時にあいまいさが生じる原因ともなります。

一方、Javaオブジェクト型はNULLを表現できます。Java言語は、nullを表現可能な各プリミティブ型に対応したオブジェクト・ラッパー型を定義します。オブジェクト・ラッパー型は、SQLデータがSQL NULLをあいまいさを残さずに検出するためのターゲットとして使用する必要があります。

NULLのテスト

関係演算子を使用してNULL値同士の比較、またはNULL値と他の値を比較することはできません。たとえば、次のSELECT文は、COMM列にNULL値が1つ以上存在する場合でも行を戻しません。

PreparedStatement pstmt = conn.prepareStatement(
  "SELECT * FROM EMP WHERE COMM = ?");
pstmt.setNull(1, java.sql.Types.VARCHAR);

次の例では、戻り値にNULLが含まれる可能性がある場合に値が等しいかどうかを比較する方法を示します。このコードは、COMMに値100が存在しない場合、EMP表からENAMESNULLとして戻します。

PreparedStatement pstmt = conn.prepareStatement("SELECT ENAME FROM EMP
  WHERE COMM =? OR  ((COMM IS NULL) AND (? IS NULL))");
pstmt.setBigDecimal(1, new BigDecimal(100));
pstmt.setNull(2, java.sql.Types.VARCHAR);

結果セットと文拡張要素

JDBC Statementオブジェクトは、java.sql.ResultSetとして型指定されたOracleResultSetオブジェクトを戻します。標準JDBCメソッドのみをオブジェクトに適用する場合は、オブジェクトのResultSet型を維持してください。ただし、オブジェクト上でOracle拡張機能を使用する場合は、Oracle拡張機能をOracleResultSetにキャストする必要があります。OracleのResultSet拡張機能は、すべてoracle.jdbc.OracleResultSetインタフェースに含まれ、Statement拡張機能は、すべてoracle.jdbc.OracleStatementインタフェースに含まれています。

たとえば、標準Statementオブジェクトstmtがあり、標準JDBC ResultSetメソッドのみを使用する場合、次のように記述します。

ResultSet rs = stmt.executeQuery("SELECT * FROM emp");

JDBCに対するOracle拡張機能を使用する場合は、結果を標準ResultSet変数内に選択し、次にその変数をOracleResultSetにキャストします。

同様に、コール可能文を使用してストアド・プロシージャを実行するためにexecuteQueryを使用する場合、戻されるオブジェクトはOracleCallableStatementです。executeQuery()の戻り値の型は、java.sql.CallableStatementです。アプリケーションで標準のJDBCメソッドのみが必要な場合は、変数をキャストする必要はありません。ただし、Oracle拡張機能を活用するには、変数をOracleCallableStatementにキャストする必要があります。prepareStatementprepareCallなどにも同じ規則が適用されます。

結果セット・クラスおよび文クラスへの主要拡張機能には、getOracleObjectおよびsetOracleObjectメソッドが含まれます。これらのメソッドは、oracle.sql.*形式でデータへのアクセスおよび操作を実行するために使用します。

Oracleのgetおよびsetメソッドと標準JDBCの比較

この項では、getおよびsetメソッド、特にJDBC標準getObjectsetObjectメソッドおよびOracle固有のgetOracleObjectsetOracleObjectメソッドについて説明します。また、oracle.sql.*形式のデータへのアクセス方法をJava形式と比較しながら説明します。

Oracle SQL型には、すべて、対応する特定のgetXXXメソッドがありますが、便宜上または簡素化の目的で、または受け取るデータの型が不明な場合は、一般的なgetメソッドを使用できます。

この項には、次の項目が含まれます。


注意:

表名を使用して列名を修飾し、その列名をパラメータとしてgetXXXメソッドに渡すことはできません。たとえば、次のようになります。
ResultSet rset = stmt.executeQuery("SELECT emp.deptno, dept.deptno FROM emp, dept");
rset.getInt("emp.deptno");

このコード例の場合、getIntメソッドで例外が発生します。getXXXメソッドで列を一意に識別するには、列索引を使用するか、または問合せで列別名を指定してその別名をgetXXXメソッドで使用します。


標準getObjectメソッド

結果セットまたはコール可能文の標準getObjectメソッドの戻り型は、java.lang.Objectです。戻されるオブジェクトのクラスは、次に示すようにSQL型に基づきます。

  • Oracle固有ではないSQLデータ型の場合、JDBC仕様のマッピングに従い、getObjectは列のSQL型に対応するデフォルトのJava型を戻します。

  • Oracle固有のデータ型の場合、getObjectは適切なoracle.sql.*クラス(oracle.sql.ROWIDなど)のオブジェクトを戻します。

  • Oracleデータベース・オブジェクトの場合、getObjectは、使用する型マップで指定されたクラスのJavaオブジェクトを戻します。型マップは、データベース型名からJavaクラスへのマッピングを指定します。getObject(parameter_index)メソッドは、接続のデフォルト型マップを使用します。getObject(parameter_index, map)を使用すると、型マップでの引渡しが可能です。型マップが特定のOracleオブジェクトのマッピングを提供しない場合、getObjectoracle.sql.STRUCTオブジェクトを戻します。

Oracle getOracleObjectメソッド

結果セットまたはコール可能文からデータをoracle.sql.*オブジェクトとして取り出す場合は、特殊なプロセスに従う必要があります。ResultSetの場合は、結果セット自体をoracle.jdbc.OracleResultSetにキャストしてから、getObjectのかわりにgetOracleObjectをコールする必要があります。CallableStatementおよびoracle.jdbc.OracleCallableStatementにも同じことが適用されます。

getOracleObjectの戻り型はoracle.sql.Datumです。 実際に戻されるオブジェクトは、該当するoracle.sql.*クラスのインスタンスです。メソッド・シグネチャは次のとおりです。

public oracle.sql.Datum getOracleObject(int parameter_index)

Datum変数内にデータを取り出した場合は、標準Java instanceof演算子を使用して、実際のoracle.sql.*型を決定します。

例: 結果セットでのgetOracleObjectの使用方法

次の例では、CHARデータの列を含む表およびBFILEロケータを含む列を作成します。SELECT文では、表の内容を結果セットとして取り出します。getOracleObjectCHARデータをchar_datum変数に、BFILEロケータをbfile_datum変数に取り出します。getOracleObjectDatumオブジェクトを戻すため、戻り値をそれぞれCHARおよびBFILEにキャストする必要があります。

stmt.execute ("CREATE TABLE bfile_table (x VARCHAR2 (30), b BFILE)");
stmt.execute
    ("INSERT INTO bfile_table VALUES ('one', BFILENAME ('TEST_DIR', 'file1'))");

ResultSet rset = stmt.executeQuery ("SELECT * FROM bfile_table");
while (rset.next ())
{
   CHAR char_datum = (CHAR) ((OracleResultSet)rset).getOracleObject (1);
   BFILE bfile_datum = (BFILE) ((OracleResultSet)rset).getOracleObject (2);
   ...
}

例: コール可能文でのgetOracleObjectの使用方法

次の例では、文字列を日付と対応付けるプロシージャmyGetDateへのコールを作成します。このプログラムは、SCOTTを準備済コールに渡し、DATE型を出力パラメータとして登録します。コールの実行後、getOracleObjectSCOTTに対応付けられている日付を取り出します。getOracleObjectDatumオブジェクトを戻すため、結果セットはDATEにキャストされる点に留意してください。

OracleCallableStatement cstmt = (OracleCallableStatement)conn.prepareCall
                                   ("begin myGetDate (?, ?); end;");

cstmt.setString (1, "SCOTT");
cstmt.registerOutParameter (2, Types.DATE);
cstmt.execute ();

DATE date = (DATE) ((OracleCallableStatement)cstmt).getOracleObject (2);
...

getObjectおよびgetOracleObject戻り型のまとめ

表13-2に、各Oracle SQL型のgetObjectメソッドとgetOracleObjectメソッドに対応した、基礎となる戻り型を示します。

ただし、これらのメソッドを使用する際は、次のことを念頭に置いてください。

  • getObjectは、データを常にjava.lang.Objectインスタンスに戻します。

  • getOracleObjectは、データを常にoracle.sql.Datumインスタンスに戻します。

いずれかの特殊機能を使用するには、戻されたオブジェクトをキャストする必要があります。

表13-2 getObjectおよびgetOracleObject戻り型

Oracle SQL型 getObjectの基礎となる戻り型 getOracleObjectの基礎となる戻り型

CHAR

String

oracle.sql.CHAR

VARCHAR2

String

oracle.sql.CHAR

LONG

String

oracle.sql.CHAR

NUMBER

java.math.BigDecimal

oracle.sql.NUMBER

RAW

byte[]

oracle.sql.RAW

LONGRAW

byte[]

oracle.sql.RAW

DATE

java.sql.Date

oracle.sql.DATE

TIMESTAMP

java.sql.Timestamp脚注 1 

oracle.sql.TIMESTAMP

TIMESTAMP WITH TIME ZONE

oracle.sql.TIMESTAMPTZ

oracle.sql.TIMESTAMPTZ

TIMESTAMP WITH LOCAL TIME ZONE

oracle.sql.TIMESTAMPLTZ

oracle.sql.TIMESTAMPLTZ

BINARY_FLOAT

java.lang.Float

oracle.sql.BINARY_FLOAT

BINARY_DOUBLE

java.lang.Double

oracle.sql.BINARY_DOUBLE

INTERVAL DAY TO SECOND

oracle.sql.INTERVALDS

oracle.sql.INTERVALDS

INTERVAL YEAR TO MONTH

oracle.sql.INTERVALYM

oracle.sql.INTERVALYM

ROWID

oracle.sql.ROWID

oracle.sql.ROWID

REF CURSOR

java.sql.ResultSet

(未サポート)

BLOB

oracle.sql.BLOB

oracle.sql.BLOB

CLOB

oracle.sql.CLOB

oracle.sql.CLOB

BFILE

oracle.sql.BFILE

oracle.sql.BFILE

Oracleオブジェクト

型マップで指定されたクラス

またはoracle.sql.STRUCT(型マップにエントリがない場合)

oracle.sql.STRUCT

Oracleオブジェクト参照

oracle.sql.REF

oracle.sql.REF

コレクション(VARRAYまたはNESTED TABLE)

oracle.sql.ARRAY

oracle.sql.ARRAY


脚注 1 ResultSet.getObjectは、oracle.jdbc.J2EE13Compliant接続プロパティがTUREに設定されている場合のみjava.sql.Timestampを戻します。そうでない場合、このメソッドはoracle.sql.TIMESTAMPを戻します。

注意:

ResultSet.getObjectメソッドは、接続プロパティoracle.jdbc.J2EE13CompliantTRUEに設定されている場合のみ、TIMESTAMP SQL型のjava.sql.Timestampを戻します。このプロパティは、接続の取得時に設定する必要があります。この接続プロパティが設定されていない場合、または接続の取得後に設定した場合、ResultSet.getObjectメソッドはTIMESTAMP SQL型のoracle.sql.TIMESTAMPを戻します。

oracle.jdbc.J2EE13Compliant接続プロパティは、コードを変更せずに、次の方法で設定できます。

  • classes12dms.jarファイルおよびojdbc14dms.jarファイルをCLASSPATHに含めます。これらのファイルでは、デフォルトでoracle.jdbc.J2EE13CompliantTRUEに設定されます。これらのファイルは$ORACLE_HOME/jdbc/libにあります。

  • javaコマンドをフラグ-Doracle.jdbc.J2EE13Compliant=trueを指定してコールし、システム・プロパティを設定します。たとえば、次のようになります。

    java -Doracle.jdbc.J2EE13Compliant=true ...
    
    

J2EE13CompliantTRUEに設定されると、動作はJDBC仕様の表B-3のようになります。



関連項目:

すべてのSQL型とJava型との型互換性については、表A-1「有効なSQLデータ型-Javaクラス・マッピング」を参照してください。

その他のgetXXXメソッド

標準JDBCでは、各標準Java型に対応したgetXXXgetBytegetIntgetFloatなど)が提供されます。これらの各メソッドは、そのメソッド名が意味する内容を正確に戻します。

さらに、OracleResultSetクラスとOracleCallableStatementクラスは、すべてのoracle.sql.*型に対応したgetXXXメソッドを完全に補完します。各getXXXメソッドは、oracle.sql.XXXオブジェクトを戻します。たとえば、getROWIDメソッドは、oracle.sql.ROWIDオブジェクトを戻します。

特定のgetXXXメソッドを使用してもパフォーマンス上の利点はありません。ただし、戻り型は戻されるオブジェクトに固有であるため、面倒なキャストの必要がなくなります。

この項には、次の項目が含まれます。

getXXXメソッドの戻り型

表13-3では、getXXXメソッドごとの戻り型を要約し、どれがJava Development Kit(JDK)1.2.xでのOracle拡張機能であるかを示します。Oracle拡張機能であるメソッドを使用するには、戻されたオブジェクトをOracleResultSetまたはOracleCallableStatementにキャストする必要があります。

表13-3 getXXX戻り型のまとめ

メソッド 戻り型(メソッド・シグネチャでの型) 戻されるオブジェクトの型 JDK 1.2.xでのOracle拡張機能

getArray

java.sql.Array

oracle.sql.ARRAY

なし

getARRAY

oracle.sql.ARRAY

oracle.sql.ARRAY

あり

getAsciiStream

java.io.InputStream

java.io.InputStream

なし

getBfile

oracle.sql.BFILE

oracle.sql.BFILE

あり

getBFILE

oracle.sql.BFILE

oracle.sql.BFILE

あり

getBigDecimal(後述の説明を参照)

java.math.BigDecimal

java.math.BigDecimal

なし

getBinaryStream

java.io.InputStream

java.io.InputStream

なし

getBlob

java.sql.Blob

oracle.sql.BLOB

なし

getBLOB

oracle.sql.BLOB

oracle.sql.BLOB

あり

getBoolean(後述の説明を参照)

boolean

boolean

なし

getByte

byte

byte

なし

getBytes

byte[]

byte[]

なし

getCHAR

oracle.sql.CHAR

oracle.sql.CHAR

あり

getCharacterStream

java.io.Reader

java.io.Reader

なし

getClob

java.sql.Clob

oracle.sql.CLOB

なし

getCLOB

oracle.sql.CLOB

oracle.sql.CLOB

あり

getDate

java.sql.Date

java.sql.Date

なし

getDATE

oracle.sql.DATE

oracle.sql.DATE

あり

getDouble

double

double

なし

getFloat

float

float

なし

getInt

int

int

なし

getINTERVALDS

oracle.sql.INTERVALDS

oracle.sql.INTERVALDS

あり

getINTERVALYM

oracle.sql.INTERVALYM

oracle.sql.INTERVALYM

あり

getLong

long

long

なし

getNUMBER

oracle.sql.NUMBER

oracle.sql.NUMBER

あり

getOracleObject

oracle.sql.Datum

oracle.sql.Datumのサブクラス

あり

getRAW

oracle.sql.RAW

oracle.sql.RAW

あり

getRef

java.sql.Ref

oracle.sql.REF

なし

getREF

oracle.sql.REF

oracle.sql.REF

あり

getROWID

oracle.sql.ROWID

oracle.sql.ROWID

あり

getShort

short

short

なし

getString

String

String

なし

getSTRUCT

oracle.sql.STRUCT

oracle.sql.STRUCT.

あり

getTime

java.sql.Time

java.sql.Time

なし

getTimestamp

java.sql.Timestamp

java.sql.Timestamp

なし

getTIMESTAMP

oracle.sql.TIMESTAMP

oracle.sql.TIMESTAMP

あり

getTIMESTAMPTZ

oracle.sql.TIMESTAMPTZ

oracle.sql.TIMESTAMPTZ

あり

getTIMESTAMPLTZ

oracle.sql.TIMESTAMPLTZ

oracle.sql.TIMESTAMPLTZ

あり

getUnicodeStream

java.io.InputStream

java.io.InputStream

なし

getURL

java.net.URL

java.net.URL

なし


getXXXメソッドに関する特別な注意

この項では、いくつかのgetXXXメソッドについて追加の詳細情報を示します。

getBigDecimal

JDBC 2.0では、getBigDecimalメソッドのメソッド・シグネチャが単純になっています。以前の入力シグネチャは次のいずれかでした。

(int columnIndex, int scale) or (String columnName, int scale)

単純になった入力シグネチャは次のとおりです。

(int columnIndex) or (String columnName)

小数点の右にある数字の数を指定するために使用するscaleパラメータは不要になりました。Oracle JDBCドライバは、完全な精度で数値を取り出します。

getBoolean

BOOLEANデータベース型が存在しないため、getBooleanを使用すると必ずデータ型変換が実行されます。getBooleanメソッドは数値用の列に対してのみサポートされます。このような列に対してgetBooleanが適用されると、0(ゼロ)値はfalseとして、それ以外の値はtrueとして解釈されます。別の種類の列に適用された場合は、getBooleanは例外java.lang.NumberFormatExceptionを戻します。

getObjectおよびgetXXXから戻されるオブジェクトのデータ型

getObjectの戻り型はjava.lang.Objectです。戻り型は、java.lang.Objectのサブクラスのインスタンスです。同様に、getOracleObjectの戻り型はoracle.sql.Datumで、戻り値のクラスはoracle.sql.Datumのサブクラスです。通常、適切なクラスの特定のメソッドおよび機能を使用するには、戻されたオブジェクトをそのクラスにキャストします。

また、汎用のgetObjectメソッドやgetOracleObjectメソッドのかわりに、特定のgetXXXメソッドも使用できます。getXXXの戻り型は、戻されるオブジェクトの型に対応しているため、getXXXメソッドを使用することにより、キャストを回避できます。たとえば、getCLOBの戻り型は、java.lang.Objectではなくoracle.sql.CLOBです。

戻り値のキャストの例

この例では、NUMBER型のデータを結果セットの最初の列としてフェッチしたものとします。 NUMBERデータの精度を保持したまま操作するため、結果セットをOracleResultSetにキャストし、getOracleObjectを使用して、oracle.sql.*形式でNUMBERデータを戻します。結果セットをキャストしない場合は、getObjectを使用する必要があります。このメソッドは、数値データをJava Floatに戻すため、SQLデータの精度がいくらか失われます。

getOracleObjectメソッドは、出力がキャストされるまで、oracle.sql.NUMBERオブジェクトをoracle.sql.Datum戻り変数内に戻します。NUMBER戻り変数を使用し、そのクラスの特殊機能のいずれかを使用する場合は、getOracleObjectの出力をoracle.sql.NUMBERにキャストしてください。

NUMBER x = (NUMBER)ors.getOracleObject(1);

あるいは、汎用のoracle.sql.Datum戻り変数にオブジェクトを戻しておき、後でNUMBER固有のメソッドを使用するときにこのオブジェクトをキャストする方法もあります。

Datum rawdatum = ors.getOracleObject(1);
...
CharacterSet cs = ((NUMBER) rawdatum).FIXME();

前述の例では、oracle.sql.NUMBERFIXMEメソッドを使用しています。FIXMEメソッドはoracle.sql.Datumに対しては定義されていないため、キャストしないと到達不可能です。

setObjectおよびsetOracleObjectメソッド

結果セットとコール可能文に標準getObjectとOracle固有のgetOracleObjectがあるように、OraclePreparedStatementOracleCallableStatementにも標準setObjectメソッドとOracle固有のsetOracleObjectメソッドがあります。 setOracleObjectメソッドは、oracle.sql.*を入力パラメータとして取ります。

標準Java型をプリコンパイルされたSQL文またはコール可能文にバインドするには、setObjectメソッドを使用します。このメソッドはjava.lang.Objectを入力として取ります。 setObjectメソッドはoracle.sql.*型のいくつかをサポートします。 ただし、このメソッドの実装によって、BlobClobStructRefおよびArrayの各JDBC標準型に対応するoracle.sql.*クラスのインスタンスの入力が可能になります。

プリコンパイルされたSQL文またはコール可能文にoracle.sql.*型をバインドするには、setOracleObjectメソッドを使用します。このメソッドはoracle.sql.Datumのサブクラスを入力として取ります。setOracleObjectを使用するには、プリコンパイルされたSQL文またはコール可能文をOraclePreparedStatementまたはOracleCallableStatementにキャストする必要があります。

setObjectとsetOracleObjectの使用例

プリコンパイルされたSQL文には、charVal変数により提示されたoracle.sql.CHARデータがsetOracleObjectメソッドによってバインドされます。 oracle.sql.*データをバインドするには、プリコンパイルされたSQL文をOraclePreparedStatementにキャストする必要があります。同様に、setObjectメソッドは、変数strValで表現されたJava Stringデータをバインドします。

PreparedStatement ps= conn.prepareStatement("text_of_prepared_statement");
((OraclePreparedStatement)ps).setOracleObject(1,charVal);
ps.setObject(2,strVal);

その他のsetXXXメソッド

getXXXメソッドの場合と同様、固有のsetXXXメソッドがいくつか存在します。標準setXXXメソッドは、標準Java型のバインド用に提供されます。また、Oracle固有のsetXXXメソッドは、Oracle固有の型のバインド用に提供されます。

同様に、setNullメソッドには次の2つの形式があります。

  • void setNull(int parameterIndex, int sqlType)

    これは、標準のjava.sql.PreparedStatementインタフェースで指定されるシグネチャです。このシグネチャは、java.sql.Typesまたはoracle.jdbc.OracleTypesクラスによって定義されるパラメータ索引とSQL型コードを取得します。REFARRAYまたはSTRUCT以外のオブジェクトをNULLに設定する場合は、このシグネチャを使用します。

  • void setNull(int parameterIndex, int sqlType, String sql_type_name)

    JDBC 2.0の場合、このシグネチャは標準のjava.sql.PreparedStatementインタフェースにも指定されます。このメソッドは、パラメータ索引およびSQL型コードに加え、SQL型名を取ります。このメソッドは、SQL型コードがjava.sql.Types.REFARRAYまたはSTRUCTの場合に使用します。型コードがREFARRAYまたはSTRUCT以外の場合、指定されたSQL型名は無視されます。

同様に、registerOutParameterメソッドには、REFARRAYまたはSTRUCTデータとともに使用するためのシグネチャがあります。

void registerOutParameter
            (int parameterIndex, int sqlType, String sql_type_name)

標準Java型のバインドのためのメソッドではなく、適切なsetXXXメソッドを使用してOracle固有型をバインドすると、多少パフォーマンスが向上することがあります。

この項には、次の項目が含まれます。

setXXXメソッドの入力パラメータ型

表13-4では、すべてのsetXXXメソッドの入力型の概要を示し、どれがJDK 1.2.xでのOracle拡張機能であるかを示します。Oracle拡張機能のメソッドを使用するには、OraclePreparedStatementまたはOracleCallableStatementに文をキャストする必要があります。

表13-4 setXXX入力パラメータ型のまとめ

メソッド 入力パラメータ型 JDK 1.2.xでのOracle拡張機能

setArray

java.sql.Array

なし

setARRAY

oracle.sql.ARRAY

あり

setAsciiStream (後述の「追加の入力を取得するsetterメソッド」を参照)

java.io.InputStream

なし

setBfile

oracle.sql.BFILE

あり

setBFILE

oracle.sql.BFILE

あり

setBigDecimal

BigDecimal

なし

setBinaryFloat

floatまたはoracle.sql.BINARY_FLOAT

あり

setBinaryDouble

doubleまたはoracle.sql.BINARY_DOUBLE

あり

setBinaryStream(後述の「追加の入力を取得するsetterメソッド」を参照)

java.io.InputStream

なし

setBlob

java.sql.Blob

なし

setBLOB

oracle.sql.BLOB

あり

setBoolean

boolean

なし

setByte

byte

なし

setBytes

byte[]

なし

setCHAR(setFixedCHARメソッドも参照)

oracle.sql.CHAR

あり

setCharacterStream(後述の「追加の入力を取得するsetterメソッド」を参照)

java.io.Reader

なし

setClob

java.sql.Clob

なし

setCLOB

oracle.sql.CLOB

あり

setDate(後述の「追加の入力を取得するsetterメソッド」を参照)

java.sql.Date

なし

setDATE

oracle.sql.DATE

あり

setDouble

double

なし

setFixedCHAR(「setFixedCHAR」を参照)

java.lang.String

あり

setFloat

float

なし

setInt

int

なし

setINTERVALDS

oracle.sql.INTERVALDS

あり

setINTERVALYM

oracle.sql.INTERVALYM

あり

setLong

long

なし

setNUMBER

oracle.sql.NUMBER

あり

setRAW

oracle.sql.RAW

あり

setRef

java.sql.Ref

なし

setREF

oracle.sql.REF

あり

setROWID

oracle.sql.ROWID

あり

setShort

short

なし

setString

String

なし

setSTRUCT

oracle.sql.STRUCT

あり

setTime

java.sql.Time

なし

setTimestamp

java.sql.Timestamp

なし

setTIMESTAMP

oracle.sql.TIMESTAMP

あり

setTIMESTAMPTZ

oracle.sql.TIMESTAMPTZ

あり

setTIMESTAMPLTZ

oracle.sql.TIMESTAMPLTZ

あり

setUnicodeStream

java.io.InputStream

なし

setURL

java.net.URL

なし


setterメソッドのサイズ制限

表13-5に、SQLをバインドするためのsetBytesメソッドとsetStringメソッドのサイズ制限をリストします


注意:

これらの制限は、PL/SQLバインドには適用されません。

表13-5 setBytesメソッドとsetStringメソッドのサイズ制限

メソッド名 サイズ制限

setBytes

2000バイト

setString

4000バイト



関連項目:

ストリームApplication Program Interface(API)を使用してこれらの制限を回避する方法については、「setBytesとsetStringへの制限を回避するためのストリームの使用方法」を参照してください。

追加の入力を取得するsetterメソッド

次の各setXXXメソッドは、パラメータ索引とデータ項目自体の他に、追加の入力パラメータを取ります。

  • setAsciiStream(int paramIndex, InputStream istream, int length)

    ストリーム長をバイト単位で取得します。

  • setBinaryStream(int paramIndex, InputStream istream, int length)

    ストリーム長をバイト単位で取得します。

  • setCharacterStream(int paramIndex, Reader reader, int length)

    ストリーム長を文字数で取得します。

  • setUnicodeStream(int paramIndex, InputStream istream, int length)

    ストリーム長をバイト単位で取得します。

特に、LONGVARCHARパラメータへの入力が非常に大きなUnicode値の場合は、java.io.Readerオブジェクトを通じて送信したほうが実用的であるため、setCharacterStreamメソッドが役立ちます。JDBCはファイル終りマークに達するまで、必要に応じてストリームからデータを読み込みます。JDBCドライバは、必要に応じてUnicodeをデータベース・キャラクタ形式に変換します。


注意:

前述のストリーム・メソッドは、ラージ・オブジェクト(LOB)にも使用できます。詳細は、「BLOBおよびCLOBデータの読込みと書込み」を参照してください。

次の各メソッドも、パラメータ索引とデータ項目自体の他に追加のパラメータを取ります。

  • setDate(int paramIndex, Date x, Calendar cal)

  • setTime(int paramIndex, Time x, Calendar cal)

  • setTimestamp(int paramIndex, Timestamp x, Calendar cal)

WHERE句にCHARデータをバインドするためのメソッドsetFixedCHAR

データベース内のCHARデータは、列幅まで埋め込まれます。このため、SELECT文のWHERE句に文字データをバインドするためのsetCHARメソッドの使用に関して、制限が生じます。WHERE句の文字データも、SELECT文で合致させるために、列幅まで埋め込む必要があります。これは特に列幅がわからない場合に問題になります。

これを修正するために、OracleはOraclePreparedStatementクラスにsetFixedCHARメソッドを追加しました。このメソッドは埋込みなしの比較を実行します。


注意:

  • setFixedCHARメソッドを使用するには、必ずプリコンパイルされたSQL文オブジェクトをOraclePreparedStatementにキャストしてください。

  • INSERT文で、setFixedCHARを使用する必要はありません。データベースは挿入時に、常にそのデータを列幅まで自動的に埋め込みます。


次の例では、setCHARメソッドとsetFixedCHARメソッドの違いを示します。

/* Schema is :
 create table my_table (col1 char(10));
 insert into my_table values ('JDBC');
*/
 PreparedStatement pstmt = conn.prepareStatement
                    ("select count(*) from my_table where col1 = ?");

 pstmt.setString (1, "JDBC");  // Set the Bind Value
 runQuery (pstmt);             // This will print " No of rows are 0"

 CHAR ch = new CHAR("JDBC      ", null);
 ((OraclePreparedStatement)pstmt).setCHAR(1, ch); // Pad it to 10 bytes
 runQuery (pstmt);             // This will print "No of rows are 1"

 ((OraclePreparedStatement)pstmt).setFixedCHAR(1, "JDBC");
  runQuery (pstmt);            // This will print "No of rows are 1"

 void runQuery (PreparedStatement ps)
 {
   // Run the Query
   ResultSet rs = pstmt.executeQuery ();

   while (rs.next())
     System.out.println("No of rows are " + rs.getInt(1));

   rs.close();
   rs = null;
 }

結果セット・メタデータ拡張要素の使用方法

oracle.jdbc.OracleResultSetMetaDataインタフェースはJDBC 2.0に準拠していますが、Oracle Database 10gによってサポートされていないため、getSchemaNameメソッドとgetTableNameメソッドは実装されません。ただし、Oracleは、Oracle結果セットに関する情報を取り出すために、多くのメソッドを実装しています。

主要メソッドは次のとおりです。

次の例は、OracleResultSetMetadataインタフェースのメソッドをいくつか使用して、EMP表から列数を取り出し、各列の数値型とSQL型名を取り出します。

DatabaseMetaData dbmd = conn.getMetaData();
ResultSet rset = dbmd.getTables("", "SCOTT", "EMP", null);

 while (rset.next())
 {
   OracleResultSetMetaData orsmd = ((OracleResultSet)rset).getMetaData();
   int numColumns = orsmd.getColumnCount();
   System.out.println("Num of columns = " + numColumns);

   for (int i=0; i<numColumns; i++)
   {
     System.out.print ("Column Name=" + orsmd.getColumnName (i+1));
     System.out.print (" Type=" + orsmd.getColumnType (i + 1) );
     System.out.println (" Type Name=" + orsmd.getColumnTypeName (i + 1));
  }
}

このプログラムは次の出力を戻します。

Num of columns = 5
Column Name=TABLE_CAT Type=12 Type Name=VARCHAR2
Column Name=TABLE_SCHEM Type=12 Type Name=VARCHAR2
Column Name=TABLE_NAME Type=12 Type Name=VARCHAR2
Column Name=TABLE_TYPE Type=12 Type Name=VARCHAR2
Column Name=TABLE_REMARKS Type=12 Type Name=VARCHAR2