目次 | 前の項目 | 次の項目 JDBCTM ガイド: 使用の開始


8 新しい SQL 型

この章と次の章では、バイナリラージオブジェクトや構造化型などの新しい SQL データ型にアクセスするための、JDBC API に追加された機構について説明します。新しい SQL 型をサポートしない JDBC ドライバでは、この章と次の章で説明しているメソッドやインタフェースを実装する必要はありません。

8.1     SQL 型の分類

最新バージョンの ANSI/ISO SQL 規格は、一般に「SQL99」と呼ばれています。JDBC API には、Java アプリケーションとデータベース間のデータ交換に必須のプロパティだけが含まれた、新しい SQL99 の型のモデルが取り入れられています。SQL99 ドラフトが公式の規格となる前に、新しい SQL99 の型の構文やサーバ側のセマンティクスが変更されても、JDBC API はその影響を受けないはずです。

SQL99 ドラフトでは、以下のようなデータ型が規定されています。

REF 値は、データベースに存在する構造化型のインスタンスを永続的に示します。LOCATOR はクライアント環境でだけ使用され、データベースサーバ上のデータを指す一時的で論理的なポインタです。ロケータで参照するのは、一般に、イメージまたはオーディオなど、大きすぎてクライアント上で生成できないデータです。ロケータが参照するデータのランダムアクセス可能な要素を取得するための演算子が SQL レベルで定義されています。

次の項以降では、前述した新しい SQL 型にアクセスするために JDBC API で用意されているデフォルトの機構を説明します。JDBC API では、SQLの弁別型および構造化型の Java クラスへのマッピングをカスタマイズするための機構も用意されています。 この機構については、第 9 章で説明します。

8.2     BLOB と CLOB

8.2.1 BLOB と CLOB の取得

バイナリラージオブジェクト (BLOB) 型とキャラクタラージオブジェクト (CLOB) 型は、JDBC API で定義された既存の組み込み型と同じように扱われます。この 2 つの型の値は、ResultSet インタフェースと CallableStatement インタフェースに含まれる getBlob() メソッドと getClob() メソッドにより取得できます。次に例を示します。

Blob blob = rs.getBlob(1);
Clob clob = rs.getClob(2);


このコードは、結果セットの最初の列から BLOB 値を、2 番目の列から CLOB 値を取得しています。Blob インタフェースには、BLOB の長さを返すメソッドや、BLOB に含まれる特定の範囲のバイトを返すメソッドなどが含まれています。Clob インタフェースには、これに対応する文字ベースのメソッドが含まれています。詳細については、付属の API ドキュメントを参照してください。

アプリケーションは、SQL で定義されている LOCATOR(blob) 型と LOCATOR(clob) 型を直接は扱いません。JDBC ドライバでは、適切なロケータ型を使用して、Blob インタフェースと Clob インタフェースをデフォルトで実装すべきです。また、デフォルトでは、Blob オブジェクトと Clob オブジェクトは、それが作成されたトランザクション内でだけ有効です。このデフォルトの寿命は、JDBC ドライバで変更できます。たとえば、セッションの存在中、有効となるように寿命を変更することができます。ただし、その変更方法については JDBC API では規定していません。

8.2.2 BLOB と CLOB の格納

Blob 値と Clob 値は、setBlob() メソッドと setClob() メソッドをそれぞれ使用することで、ほかのデータ型と同じように PreparedStatement オブジェクトに入力パラメータとして引き渡すことができます。ストリーム値を BLOB として入力するには、setBinaryStream() メソッドと setObject() メソッドを使用します。 また、ストリームを CLOB 値として入力するには、setAsciiStream()setUnicodeStream()setObject() の各メソッドを使用します。

8.2.3 メタデータの追加

BLOBCLOB の新しい 2 つの型コードが java.sql.Types に追加されました。これらの値は、JDBC ドライバがそのデータ型をサポートしていれば、DatabaseMetaData.getTypeInfo()DatabaseMetaData.getColumns() などのメソッドで取得できます。

8.3     配列

8.3.1 配列の取得

SQL 型配列のデータは、ResultSet インタフェースと CallableStatement インタフェースの getArray() メソッドを使用すれば取得できます。次に例を示します。

Array a = rs.getArray(1);


このコードは、結果セットの最初の列から Array の値を取得しています。JDBC ドライバでは、SQL LOCATOR(array) を内部的に使用して Array インタフェースをデフォルトで実装すべきです。また、デフォルトでは、Array オブジェクトはそれが作成されたトランザクション内でだけ有効です。Blob 型と Clob 型について、このデフォルトの寿命を変更できます。 ただし、その変更方法については JDBC API では規定していません。

Array インタフェースには、生成された Java 配列または ResultSet オブジェクトとして、配列の内容をクライアントに返すメソッドが含まれています。 それぞれ、getArray() メソッドと getResultSet() メソッドです。詳細については、別途提供されている API ドキュメントを参照してください。

8.3.2 配列の格納

Array 値を入力パラメータとして PreparedStatement に引き渡すには、PreparedStatement.setArray() メソッドを使用します。Java 配列を入力パラメータとして引き渡すには、PreparedSatement.setObject() を使用します。

8.3.3 メタデータの追加

新しい型コード ARRAYjava.sql.Types に追加されました。この値は、JDBC ドライバが Array データ型をサポートしていれば、DatabaseMetaData.getTypeInfo()DatabaseMetaData.getColumns() などのメソッドで取得できます。

8.4     Ref

8.4.1 REF の取得

SQL の参照は、ResultSet インタフェースと CallableStatement インタフェースの getRef() を使用すれば取得できます。次に例を示します。

Ref ref = rs.getRef(1);


このコードは、結果セットの最初の列から Ref 値を取得しています。デフォルトでは、Ref 値を取得しても、Ref が参照するデータは生成されません。また、デフォルトでは、Ref 値はそれが作成されたセッションまたは接続が開かれている間有効です。このデフォルトの寿命は変更できますが、その方法については JDBC API では規定していません。

Ref インタフェースには、逆参照のためのメソッドは含まれていません。その代わり、Ref は、それが参照するオブジェクトを取り出す適切な SQL 文に入力パラメータとして引き渡すことができるようになっています。詳細については、別途提供されている API ドキュメントを参照してください。

8.4.2 REF の格納

Ref を入力パラメータとして PreparedStatement に引き渡すには、PreparedStatement.setRef() メソッドを使用します。

8.4.3 メタデータの追加

新しい型コード REF java.sql.Types に追加されました。この値は、JDBC ドライバが REF データ型をサポートしていれば、DatabaseMetaData.getTypeInfo()DatabaseMetaData.getColumns() などのメソッドで取得できます。

8.5     弁別型

8.5.1 弁別型の取得

デフォルトでは、SQL DISTINCT 型のデータは、ベースになっているデータ型に対応する getXXX() メソッドを使用すれば取得できます。型宣言の例を次に示します。

      CREATE TYPE MONEY AS NUMERIC(10,2)

MONEY 型の値を取得するには、次のようにします。

java.math.BigDecimal bd = rs.getBigDecimal(1);


これは、ベースになっている SQL NUMERIC 型が、java.math.BigDecimal にマッピングされているからです。

8.5.2 弁別型の格納

弁別型の入力パラメータを PreparedStatement に引き渡すには、その SQL DISTINCT 型のベースになっている型に対応する PreparedStatement.setXXX() メソッドを使用します。たとえば、上の MONEY 型を定義した弁別型の場合は、PreparedStatement.setBigDecimal() を使用します。

8.5.3 メタデータの追加

新しい型コード DISTINCT java.sql.Types. に追加されました。この値は、JDBC ドライバが DISTINCT データ型をサポートしていれば、DatabaseMetaData.getTypeInfo()DatabaseMetaData.getColumns() などのメソッドで取得できます。

SQL DISTINCT 型は、スキーマのテーブル定義で使用する前に、特定のデータベーススキーマの一部として定義しておかなければなりません。スキーマ固有のユーザ定義型 (DISTINCT など) に関する情報は、DatabaseMetaData.getUDTs() メソッドで取得できます。次に例を示します。

int[] types = {Types.DISTINCT};
ResultSet rs = dmd.getUDTs("catalog-name", "schema-name",
	"%", types);

このコードでは、catalog-name.schema-name スキーマで定義されているすべての SQL DISTINCT 型の情報が返されます。ドライバが UDT をサポートしていない場合や、一致する UDT が見つからない場合は、空の結果セットが返されます。

それぞれの型の情報は、次の列で構成されます。

TYPE_CATString => 型のカタログ (NULL も可)
TYPE_SCHEMString => 型のスキーマ (NULL も可)
TYPE_NAMEString => データベースの型名
JAVA_CLASS String => Java クラス名またはインタフェース名
DATA_TYPEshort => java.sql.Types で定義されている値 (DISTINCT など)
REMARKSString => 型に関する説明

ほとんどの列については特に説明しません。TYPE_NAME は、上の例で DISTINCT 型に与えられた SQL の型名 (MONEY) です。これは、CREATE TABLE 文で、この型の列を指定するために使用する名前です。

DATA_TYPETypes.DISTINCT の場合、JAVA_CLASS 列には、完全指定 Java クラス名が含まれます。このクラスのインスタンスは、この DISTINCT 型の列に対して getObject() を使用すると作成されます。たとえば、JAVA_CLASS は、上記の MONEY の場合はデフォルトで java.math.BigDecimal になります。JDBC API では、JAVA_CLASS で指定されたクラスのサブタイプをドライバが返すのを禁止していません。JAVA_CLASS の値は、その使用時、カスタム型マッピングを反映した値になります。 詳細は、第 9 章を参照してください。

8.6     構造化型

8.6.1 構造化型の取得

SQL の構造化型の値は、常に getObject() メソッドにより取得できます。デフォルトでは、getObject() は特定の構造化型に対応する Struct 型の値を返します。次に例を示します。

Struct struct = (Struct)rs.getObject(1);

このコードは、結果セット rs の現在の行の最初の列から Struct 値を取得しています。Struct インタフェースには、構造化型の属性を java.lang.Object 値の配列として取得するためのメソッドが含まれています。JDBC ドライバでは、Struct への参照をアプリケーションに返す前に、Struct の内容をデフォルトで生成する必要があります。また、デフォルトでは、Struct オブジェクトは Java アプリケーションでその参照が保持されている間有効です。このデフォルトの存続期間は、JDBC ドライバで変更できます (SQL LOCATOR が使用できるようにするなど)。 ただし、その方法については JDBC API では規定していません。

8.6.2 構造化型の格納

Struct を入力パラメータとして PreparedStatement に引き渡すには、PreparedStatement.setObject() メソッドを使用します。

8.6.3 メタデータの追加

新しい型コード STRUCT java.sql.Types に追加されました。この値は、JDBC ドライバが STRUCT データ型をサポートしていれば、DatabaseMetaData.getTypeInfo()DatabaseMetaData.getColumns() などのメソッドで取得できます。

SQL の構造化型は、スキーマのテーブル定義で使用する前に、特定のデータベーススキーマの一部として定義しておかなければなりません。スキーマ固有のユーザ定義型 (STRUCT など) に関する情報は、DatabaseMetaData.getUDTs() メソッドで取得できます。次に例を示します。

int[] types = {Types.STRUCT};
ResultSet rs = dmd.getUDTs("catalog-name", "schema-name",
	"%", types);

このコードでは、catalog-name.schema-name スキーマで定義されているすべての SQL 構造化型の情報が返されます。ドライバが UDT をサポートしていない場合や、一致する UDT が見つからない場合は、空の結果セットが返されます。 getUDTs() によって返される結果セットについては、8.5.3 項を参照してください。

getUDTs() で返される DATA_TYPETypes.STRUCT の場合、JAVA_CLASS 列には、Java クラスの完全指定 Java クラス名が含まれます。このクラスのインスタンスは、この STRUCT 型の列に対して getObject() を使用すると、JDBC ドライバにより作成されます。したがって、JAVA_CLASS は、構造化型の場合はデフォルトで java.sql.Struct になります。 このデフォルトの動作を Java アプリケーションで変更する方法については、第 9 章で説明しています。なお、JDBC API では、JAVA_CLASS で指定されたクラスのサブタイプをドライバが返すのを禁止していません。



目次 | 前の項目 | 次の項目
jdbc@eng.sun.com または jdbc-business@eng.sun.com
Copyright © 1996-1999 Sun Microsystems, Inc. All rights reserved.