ヘッダーをスキップ
Oracle® Database JDBC開発者ガイド
12cリリース1 (12.1)
B71308-02
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

4 Oracle拡張機能

Oracleには、Java Database Connectivity(JDBC)標準の実装を拡張するJavaクラスとインタフェースが用意されており、開発者は、Oracleデータ型にアクセスして操作し、Oracleパフォーマンス拡張機能を使用できます。この章では、JDBC標準実装を拡張するためにOracleで提供されるクラスとインタフェースの概要を示します。また、この拡張機能がサポートする主な機能についても説明します。

この章の内容は次のとおりです。


注意:

この章では、主に型拡張機能について説明します。パフォーマンス拡張機能の詳細は、第21章「パフォーマンス拡張機能」で説明します。

Oracle拡張機能の概要

標準機能に加えて、Oracle JDBCドライバにはOracle固有型拡張機能およびパフォーマンス拡張機能があります。これらの拡張機能は、次のJavaパッケージに用意されています。

  • oracle.sql

    Oracle形式でSQLデータを示すクラスを提供します。

  • oracle.jdbc

    Oracle型形式でのデータベース・アクセスおよび更新をサポートするためのインタフェースを提供します。

Oracle拡張機能

JDBCへのOracle拡張機能には、Oracle Databaseを操作する能力を高めるいくつかの機能があります。それは次の機能です。

JDBCを使用したデータベース管理

Oracle Database 11gリリース1以降、2つのJDBCメソッド、startupおよびshutdownoracle.jdbc.OracleConnectionインタフェースに追加されており、これによりOracle Databaseインスタンスの起動と停止を実行できます。Oracle Databaseのデータベース変更通知機能もサポートされています。これらの新機能については「データベース管理」で詳しく説明します。


注意:

My Oracle Supportノート335754.1に、Oracle Database 11g JDBCドライバでoracle.jdbc.driver.*パッケージがサポート対象外であることが記載されています。つまり、Oracle Database 10gリリース2がこのパッケージをサポートする最後のデータベースであり、現在のリリースのデータベースでは、oracle.jdbc.driver.*パッケージに依存するすべてのAPIはコンパイルできなくなります。このようなAPIを削除して、標準のAPIに移行する必要があります。たとえば、コードでoracle.jdbc.CustomDatumおよびoracle.jdbc.CustomDatumFactoryインタフェースを使用する場合、これらをjava.sql.Structまたはjava.sql.SQLDataインタフェースで置き換える必要があります。


関連項目:

詳細は、My Oracle Supportノート1364193.1「Oracleタイプの新しいJDBCインタフェース」を参照してください。

Oracleデータ型のサポート

Oracle JDBC拡張機能の1つは、oracle.sqlパッケージの型のサポートです。このパッケージには、Oracle形式でのデータの正確な表現であるクラスが含まれています。プログラムでoracle.sql型を使用する際には、次の重要な点に注意してください。

  • 数値型データの場合、標準Java型への変換では、データ変換プロセスの制限のために完全な精度が維持されません。データ損失の問題を最小限に抑えるには、BigDecimal型を使用してください。

  • 特定のデータ型では、標準Java型への変換がシステムの設定によって決まる可能性があり、プログラムが予想どおりに実行されない場合があります。これは、oracle.sql型から標準Java型へのデータ変換中に発生することが知られている制限です。

  • プログラムの機能が、1つの表からのデータの読取りと、もう1つの表への同じデータの書込みに限定されている場合、数値および日付データについては、標準Java型と比べてoracle.sql型の方がわずかに速くなります。しかし、比較や印刷などの単純なデータ操作が1つでも含まれている場合は、標準Java型の方が速くなります。

  • oracle.sql.CHARはOracle形式に従うデータの正確な表現ではありません。oracle.sql.CHARjava.lang.Stringから構成されます。java.lang.Stringの方が常に高速で、同じキャラクタ・セットを表すため、いくつかのサポートされていないキャラクタ・セットを除いて、oracle.sql.CHARを使用する利点がありません。


注意:

標準のJava型を使用して、既存のoracle.sql型のデータを標準のJava型に変換することを強くお薦めします。内部的には、Oracle JDBCドライバはJava標準型のパフォーマンスを最適化するように動作します。oracle.sql型は、下位互換性のためにのみサポートされており、使用は推奨されません。

Oracleオブジェクトのサポート

Oracle JDBCはデータベース内の構造化オブジェクトの使用をサポートしています。ここで、オブジェクトのデータ型はネスト属性を持つユーザー定義の型です。たとえば、ユーザー・アプリケーションがEmployeeオブジェクト型を定義し、各Employeeオブジェクトが、firstname属性(文字列)、lastname属性(文字列)およびemployeenumber属性(整数値)を持つ例が考えられます。

Oracle JDBCは、Oracleオブジェクト・データ型をサポートします。JavaアプリケーションでOracleオブジェクト・データ型を使用する場合、次の点を考慮する必要があります。

  • Oracleオブジェクト・データ型とJavaクラス間のマップ方法

  • Oracleオブジェクトの属性を対応するJavaオブジェクトに格納する方法

  • SQLとJava形式間で属性データを変換する方法

  • データへのアクセス方法

Oracleオブジェクトは、弱い型指定のjava.sql.Struct、または強い型指定のカスタマイズされたクラスのいずれかにマップできます。これらの強い型指定はカスタムJavaクラスと呼ばれ、標準java.sql.SQLDataインタフェースまたはOracle拡張機能oracle.jdbc.OracleDataインタフェースのいずれかを実装する必要があります。各インタフェースは、SQLとJavaとの間でデータ変換を行うメソッドを指定します。


注意:

Oracle Database 12cリリース1 (12.1)以降、OracleDataインタフェースはORADataインタフェースに置き換わりました。

Oracleオブジェクトに対応するカスタムJavaクラスを作成する場合は、Oracle JPublisherユーティリティを使用することをお薦めします。Oracle JPublisherは、この作業をコマンドライン・オプションでシームレスに実行し、SQLDataまたはOracleDataインタフェース実装のいずれかを生成できます。

SQLDataインタフェース実装の場合、型マップによって、Oracleオブジェクト・データ型とJavaクラス間の対応関係が定義されます。型マップは、各Oracleオブジェクト・データ型に対応するJavaクラスを指定するオブジェクトです。Oracle JDBCはこれらの型マップを使用して、結果セットからOracleオブジェクト・データを取り出す際に、どのJavaクラスのインスタンス化およびデータ移入を行うかを決定します。


注意:

移植性が重要ではない場合は、SQLDataインタフェースのかわりにOracleDataインタフェースを使用することをお薦めします。OracleDataインタフェースは、Oracleプラットフォームが提供する、Javaを使用するその他の機能とともに、より容易にかつ柔軟に動作します。

JPublisherは、カスタムJavaクラスのgetXXXメソッドを自動的に定義します。このメソッドはデータをJavaアプリケーションに取り込みます。


関連項目:


スキーマの命名サポート

Oracleオブジェクト・データ型クラスには、完全修飾スキーマ名の受入れおよび復帰を行う機能があります。完全修飾スキーマ名は、次の構文になります。

{[schema_name].}[sql_type_name] 
 

ここで、schema_nameはスキーマの名前、sql_type_nameはオブジェクトのSQL型名で、schema_namesql_type_nameはピリオド(.)で区切られています。

JDBCでオブジェクト型を指定するには、その完全修飾名を使用します。型名が現行ネームスペース内、つまり現行スキーマ内にある場合は、スキーマ名を入力する必要はありません。スキーマは、次の規則に従って命名されます。

  • スキーマ名と型名は、どちらも引用符で囲んでも囲まなくてもかまいません。ただし、CORPORATE.EMPLOYEEのように、SQL型名にピリオドが含まれている場合は、型名を引用符で囲む必要があります。

  • JDBCドライバは、オブジェクト名内の引用符で囲まれていない最初のピリオドを検索して、ピリオドの前の文字列をスキーマ名として使用し、ピリオドの後の文字列を型名として使用します。ピリオドが見つからない場合、JDBCドライバは現行スキーマをデフォルトとします。つまり、オブジェクト型名が現行スキーマに属している場合は、完全修飾名を指定するかわりに、スキーマを指定せずに型名のみを指定できます。これが、型名にピリオドが含まれない場合に型名を引用符で囲む理由です。

    たとえば、ユーザーHRperson.addressという型を作成し、自分のセッション内でそれを使用するとします。HRは、スキーマ名を省略して、person.addressで型をJDBCドライバに渡します。この場合、person.addressを引用符で囲まないとピリオドが検出され、JDBCドライバはpersonをスキーマ名、addressを型名として誤って解釈してしまいます。

  • JDBCは、オブジェクト型名の文字列をデータベースにそのまま渡します。つまり、JDBCドライバは、オブジェクト型名が引用符で囲まれていてもその大/小文字を変更しません。

    たとえば、HR.PersonTypeがJDBCドライバにオブジェクト型名として渡されると、JDBCドライバはその文字列をそのままデータベースに渡します。別の例として、型名の文字列内に空白文字が含まれている場合、JDBCドライバは空白文字を削除しません。

DML RETURNING

Oracle Databaseでは、データ操作言語(DML)文にRETURNING句を使用できます。これによって、2つのSQL文を1文に結合できます。DML RTURNINGは、Oracle JDBC Oracle Call Interface(OCI)ドライバとOracle JDBC Thinドライバの両方でサポートされます。


関連項目:

「DML RETURNING」

PL/SQL連想配列へのアクセス

Oracle JDBCドライバを使用すると、JDBCアプリケーションで、連想配列パラメータを使用してPL/SQLをコールできます。Oracle JDBCドライバは、スカラー・データ型のPL/SQL連想配列をサポートします。

Oracle JDBCパッケージ

この項では、Oracle JDBC拡張機能をサポートする、次のJavaパッケージについて説明します。

パッケージoracle.sql

oracle.sqlパッケージは、SQL形式でデータへの直接アクセスをサポートしています。このパッケージは、主に、SQLデータ型とそのサポート・クラスへのJavaマッピングを提供するクラスで構成されています。実質的に、このクラスはSQLデータのJavaコンテナとして機能します。

oracle.sql.*データ型の各クラスは、すべてのデータ型に共通する機能をカプセル化したスーパークラスのoracle.sql.Datumを拡張します。その中には、JDBC 2.0準拠のデータ型に対応したクラスもあります。これらのクラスは、oracle.sql.Datumクラスを拡張すると同時に、java.sqlパッケージの標準JDBC 2.0インタフェースを実装します。

LONGおよびLONG RAWのSQL型と、REF CURSOR型カテゴリには、oracle.sql.*クラスは含まれません。これらの型では、標準JDBC機能を使用してください。たとえば、LONGまたはLONG RAWデータを、標準JDBC結果セットおよびコール可能文メソッドgetBinaryStreamおよびgetCharacterStreamを使用して入力ストリームとして取り出します。REF CURSOR型にはgetCursorメソッドを使用します。


注意:

可能な場合はJDBC標準型またはJava型の使用をお薦めします。パッケージoracle.sql.*の方は主に下位互換性、またはOracleの少数の特定機能(OPAQUEOracleDataTIMESTAMPTZなど)のサポートのために用意されています。

oracle.sql.*データ型の一般的なサポート

各Oracleデータ型クラスは、特に次の機能をサポートします。

  • SQLデータ用のJavaバイト配列であるデータ記憶域。

  • SQLデータをバイト配列で戻すgetBytes()メソッド。

  • JDBC仕様の定義に従って、データを対応するJavaクラスのオブジェクトに変換するtoJdbc()メソッド。

    JDBCドライバは、BFILEなどの、JDBC仕様の一部ではないOracle固有のデータ型を変換しません。ドライバは、対応するoracle.sql.*形式でオブジェクトを戻します。

  • SQLデータをJava型に変換するのに適切なxxxValueメソッド。たとえば、stringValueintValuebooleanValuedateValueおよびbigDecimalValueがあげられます。

  • 補足的な変換メソッド。データをストリームとして取り出すラージ・オブジェクト(LOB)クラスのメソッド、およびオブジェクト参照を使用してオブジェクト・データの取出しや設定を行うREFクラスのメソッドなど、データ型の機能に適したgetXXXおよびsetXXX

クラスoracle.sql.STRUCTの概要

oracle.sql.STRUCTクラスは、java.sql.StructインタフェースのOracle実装です。このクラスは値クラスです。構成後にクラスの内容を変更しないでください。このクラスは、すべてのoracle.sql.*データ型のクラスと同様に、oracle.sql.Datumクラスのサブクラスです。


注意:

Oracle Database 12cリリース1 (12.1)以降、oracle.sql.STRUCTクラスは非推奨となり、oracle.jdbc.OracleStructインタフェースに置き換えられています。このインタフェースはoracle.jdbcパッケージに属します。標準互換性には(可能であれば)java.sqlパッケージの使用可能なメソッドを使用し、Oracle固有の拡張機能にはoracle.jdbcパッケージの使用可能なメソッドを使用することを強くお薦めします。oracle.jdbc.OracleStructインタフェースの詳細は、My Oracle Supportノート1364193.1を参照してください。


関連項目:

Oracle Database JDBC Java APIリファレンス

クラスoracle.sql.REFの概要

oracle.sql.REFクラスは、Oracleオブジェクト参照をサポートする一般クラスです。このクラスは、すべてのoracle.sql.*データ型のクラスと同様に、oracle.sql.Datumクラスのサブクラスです。


注意:

Oracle Database 12cリリース1 (12.1)以降、oracle.sql.REFクラスは非推奨となり、oracle.jdbc.OracleRefインタフェースに置き換えられています。このインタフェースはoracle.jdbcパッケージに属します。標準互換性には(可能であれば)java.sqlパッケージの使用可能なメソッドを使用し、Oracle固有の拡張機能にはoracle.jdbcパッケージの使用可能なメソッドを使用することを強くお薦めします。oracle.jdbc.OracleRefインタフェースの詳細は、My Oracle Supportノート1364193.1を参照してください。

REFクラスには、オブジェクト参照を取り出して渡すためのメソッドがあります。ただし、オブジェクト参照の選択によって取り出されるのは、オブジェクトへのポインタのみです。これによってオブジェクト自体がインスタンス化されることはありません。ただし、REFクラスにはオブジェクト・データを取り出して渡すためのメソッドも含まれています。JDBCアプリケーションではREFオブジェクトを作成できません。データベースから取り出すことができるのは、既存のREFオブジェクトのみです。

oracle.sql.REFを使用するのではなく、JDBC標準型、java.sql.RefおよびJDBC標準メソッドを使用する必要があります。コードを移植可能にする場合、Oracle JDBCドライバのみがoracle.sql.REF型のインスタンスを使用するので、標準型を使用する必要があります。


関連項目:

Oracle Database JDBC Java APIリファレンス

クラスoracle.sql.BLOB、oracle.sql.CLOB、oracle.sql.BFILEの概要

バイナリ・ラージ・オブジェクト(BLOB)、キャラクタ・ラージ・オブジェクト(CLOB)およびバイナリ・ファイル(BFILE)は、大きすぎてデータベース表に直接格納できないデータ項目に使用します。一方、データベース表はデータの実際の場所を指すロケータを格納します。


注意:

  • Oracle Database 12cリリース1 (12.1)以降、oracle.sql.BLOBクラスおよびOracle.sql.CLOBクラスは非推奨となり、それぞれoracle.jdbc.OracleBlobインタフェースおよびoracle.jdbc.OracleClobインタフェースに置き換えられています。これらのインタフェースはoracle.jdbcパッケージに属します。標準互換性には(可能であれば)java.sqlパッケージの使用可能なメソッドを使用し、Oracle固有の拡張機能にはoracle.jdbcパッケージの使用可能なメソッドを使用することを強くお薦めします。oracle.jdbc.OracleBlobインタフェースおよびoracle.jdbc.OracleClobインタフェースの詳細は、My Oracle Supportノート1364193.1を参照してください。

  • oracle.sql.BFILEはOracle独自の拡張機能であり、これに相当するJDBC標準機能はありません。


oracle.sqlパッケージは、これらのデータ型を次のいくつかの方法でサポートします。

  • BLOBは、ラージ非構造化バイナリ・データ項目を指し、oracle.sql.BLOBクラスによりサポートされます。

  • CLOBは、ラージ文字データ項目を指し、oracle.sql.CLOBクラスによりサポートされます。

  • BFILEは、外部ファイル(オペレーティング・システム・ファイル)の内容を指し、oracle.sql.BFILEクラスによりサポートされます。BFILEは読取り専用です。

BLOB、CLOBまたはBFILEの各ロケータは、標準的なSELECT文を使用してデータベースから選択できます。ただし、受け取るのはデータではなく、ロケータのみです。データの取出しには、追加処理が必要です。

クラスoracle.sql.DATE、oracle.sql.NUMBERおよびoracle.sql.RAWの概要

これらのクラスは、プリミティブSQLデータ型を、Oracleネイティブの表現で保持します。ほとんどの場合、ドライバはこれらの型を内部的に使用しません。なるべく標準JDBC型を使用してください。

JavaのDouble値およびFloat NaN値には、等価のOracleのNUMBER表現がありません。たとえば、OracleのBINARY_FLOATデータ型およびBINARY_DOUBLEデータ型の場合、負のゼロは正のゼロに強制変換され、NaNはすべて正規のものに強制変換されます。そのため、oracle.sql.NUMBERクラスを使用して、Double.NaN値またはFloat.NaN値がOracleのNUMBERに変換されると、必ずNullPointerExceptionがスローされます。たとえば、次のコードにより、NullPointerExceptionが発生します。

oracle.sql.NUMBER n = new oracle.sql.NUMBER(Double.NaN); 
System.out.println(n.doubleValue());  // throws NullPointerException

関連項目:

『Oracle Database SQL言語リファレンス』

クラスoracle.sql.TIMESTAMP、oracle.sql.TIMESTAMPTZおよびoracle.sql.TIMESTAMPLTZの概要

JDBCドライバでは、次のような日付/時刻データ型をサポートしています。

  • TIMESTAMP(TIMESTAMP)

  • TIMESTAMP WITH TIME ZONE(TIMESTAMPTZ)

  • TIMESTAMP WITH LOCAL TIME ZONE(TIMESTAMPLTZ)

JDBCドライバでは、DATEと日付/時刻データ型の間での変換が可能です。たとえば、DATE値としてTIMESTAMP WITH TIME ZONE列にアクセスできます。

JDBCドライバは、業界で最も一般的なタイムゾーン名と、JDKで定義されたタイムゾーン名をサポートしています。タイムゾーンは、java.util.TimeZoneクラスを使用して指定します。


注意:

  • タイムゾーン・オブジェクトの作成にはTimeZone.getTimeZoneを使用しないでください。これは、Oracleのタイムゾーン・データ型では、JDKよりも多くのタイムゾーン名をサポートしているためです。

  • 結果セットのTIMESTAMPLTZ列の後にLONG列が続く場合、LONG列を読み取ろうとするとエラーになります。


次のコードは、JDKに定義されていないタイムゾーン名であるUS_PACIFICTimeZoneオブジェクトとCalendarオブジェクトを作成する方法を示します。

TimeZone tz = TimeZone.getDefault();
tz.setID("US_PACIFIC");
GregorianCalendar gcal = new GregorianCalendar(tz);

次のJavaクラスは、SQL日付/時刻データ型を表します。

  • oracle.sql.TIMESTAMP

  • oracle.sql.TIMESTAMPTZ

  • oracle.sql.TIMESTAMPLTZ

TIMESTAMP WITH LOCAL TIME ZONEデータにアクセスする前に、OracleConnection.setSessionTimeZone(String regionName)メソッドをコールして、セッション・タイム・ゾーンを設定します。このメソッドがコールされると、JDBCドライバは接続のセッション・タイム・ゾーンを設定、保存して、JDBCを介してアクセスされるTIMESTAMP WITH LOCAL TIME ZONEデータをセッション・タイム・ゾーンを使用して調整できるようにします。


注意:

TIMESTAMP WITH TIME ZONE型とTIMESTAMP WITH LOCAL TIME ZONE型は、標準のjava.sql.Timestamp型として表せます。TIMESTAMP WITH TIME ZONE型とTIMESTAMP WITH LOCAL TIME ZONE型のjava.sql.Timestampに対するバイト表現は簡単です。これは、TIMESTAMP WITH TIME ZONEデータ型とTIMESTAMP WITH LOCAL TIME ZONEデータ型の内部形式はGMTで、java.sql.Timestamp型オブジェクトは内部では、エポックからのミリ秒数であるミリ秒時間値を使用するためです。ただし、これらのデータ型のString表現には、サーバーから動的に取得され、クライアント側にキャッシュされているタイム・ゾーン情報が必要です。

JDBCドライバの旧バージョンでは、タイム・ゾーンのキャッシュは様々な接続で共有されていました。このため、様々なタイム・ゾーンでの非互換性が原因で問題が発生することがよくありました。Oracle Database 11リリース2のJDBCドライバから、タイム・ゾーン・キャッシュは、データベースが提供するタイム・ゾーンのバージョンを基礎とします。この新設計のキャッシュは、タイム・ゾーンのバージョン非互換性に関連するどのような問題も回避します。


クラスoracle.sql.OPAQUEの概要

oracle.sql.OPAQUEクラスは、OPAQUE型の名前と特性および任意の属性を提供します。OPAQUE型では、インスタンスの連続バイトにのみアクセスできます。


注意:

Oracle Database 12cリリース1 (12.1)以降、oracle.sql.OPAQUEクラスは非推奨となり、oracle.jdbc.OracleOpaqueインタフェースに置き換えられています。このインタフェースはoracle.jdbcパッケージに属します。標準互換性には(可能であれば)java.sqlパッケージの使用可能なメソッドを使用し、Oracle固有の拡張機能にはoracle.jdbcパッケージの使用可能なメソッドを使用することをお薦めします。oracle.jdbc.OracleOpaqueインタフェースの詳細は、My Oracle Supportノート1364193.1を参照してください。

パッケージoracle.jdbc

oracle.jdbcパッケージのインタフェースは、java.sqlのインタフェースに対するOracle拡張機能を定義します。これらの拡張機能は、Oracle SQL形式データおよびOracle固有の他の機能(Oracleパフォーマンス拡張機能など)にアクセスできます。

Oracle文字データ型のサポート

Oracle文字データ型には、SQL CHARおよびNCHARデータ型が含まれます。次の各項では、oracle.sql.*クラスを使用してこれらのデータ型にアクセスする方法について説明します。

SQL CHARデータ型

SQL CHARデータ型には、CHARVARCHAR2およびCLOBデータ型が含まれます。これらのデータ型を使用すると、文字データをデータベース・キャラクタ・セットのコード体系で格納できます。データベースのキャラクタ・セットは、データベースの作成時に決まります。

SQL NCHARデータ型

SQL NCHARデータ型は、グローバリゼーション・サポート用に作成されたものです。SQL NCHARデータ型には、NCHARNVARCHAR2およびNCLOBデータ型が含まれます。これらのデータ型を使用すると、UnicodeデータをデータベースNCHARキャラクタ・セットのコード体系で格納できます。NCHARキャラクタ・セットは、データベースの作成時に決まり、変更されることはありません。


注意:

UnicodeStreamクラスが非推奨となってCharacterStreamクラスが導入されたため、NCHARデータ型でのアクセスではsetUnicodeStreamメソッドとgetUnicodeStreamメソッドはサポートされません。ストリーム・アクセスを使用する場合、setCharacterStreamメソッドとgetCharacterStreamメソッドを使用します。

SQL NCHARデータ型の使用方法は、SQL CHARデータ型の場合に類似しています。JDBCでは、対応するSQL CHARデータ型で使用されるのと同じクラスおよびメソッドを使用して、SQL NCHARデータ型にアクセスします。したがって、oracle.sqlパッケージには、SQL NCHARデータ型用の対応する別のクラスが定義されていません。同様に、SQL NCHARデータ型用のoracle.jdbc.OracleTypesクラスにも、対応する別の定数は定義されていません。

次のコードは、SQL NCHARデータにアクセスする方法を示します。

// 
// Table TEST has the following columns: 
// - NUMBER 
// - NVARCHAR2 
// - NCHAR 
// 
oracle.jdbc.OraclePreparedStatement pstmt = 
  (oracle.jdbc.OraclePreparedStatement) 
conn.prepareStatement("insert into TEST values(?, ?, ?)");

// 
// oracle.jdbc.OraclePreparedStatement.FORM_NCHAR should be used for all NCHAR, 
// NVARCHAR2 and NCLOB data types.
//

pstmt.setInt(1, 1);                    // NUMBER column
pstmt.setNString(2, myUnicodeString1);  // NVARCHAR2 column
pstmt.setNString(3, myUnicodeString2);  // NCHAR column
pstmt.execute();

クラスoracle.sql.CHAR

oracle.sql.CHARクラスは、文字データを処理および変換するためにOracle JDBCによって使用されます。このクラスは、文字データを変換するためのグローバリゼーション・サポート機能を提供します。このクラスには、グローバリゼーション・サポート・キャラクタ・セットおよび文字データという2つの主要な属性があります。グローバリゼーション・サポート・キャラクタ・セットは、文字データのエンコーディングを定義します。これは、CHARオブジェクトの作成時に必ず渡されるパラメータです。グローバリゼーション・サポート・キャラクタ・セット情報がない状態では、CHARオブジェクト内のデータ・バイトは無意味です。oracle.sql.CHARクラスは、SQL CHARおよびSQL NCHARの両方のデータ型に使用されます。


注意:

10g リリース1より前のバージョンのOracle JDBCドライバでは、oracle.SQL.CHARを使用することでパフォーマンス上の利点がありました。Oracle Database 10g以上では、このような利点はありません。実際には、java.lang.Stringを使用することで最適なパフォーマンスを実現できます。すべてのOracle JDBCドライバが、Java UCS2キャラクタ・セット内のすべての文字データを処理します。oracle.sql.CHARを使用すると、データベース・キャラクタ・セットとUCS2キャラクタ・セットとの間の変換が発生します。

oracle.sql.CHARクラスに残された唯一の使用方法は、文字データをOracleグローバリゼーション・サポート・キャラクタ・セットでエンコードされたRAWバイトの形式で処理する場合です。Oracle Databaseから取り出された文字データはすべてjava.lang.Stringクラスを使用してアクセスしてください。別のソースからのバイト・データを処理する場合は、oracle.sql.CHARを使用してバイトをjava.lang.Stringに変換できます。

oracle.sql.CHARを変換するには、データ・バイトと、そのデータ・バイトのエンコードに使用するグローバリゼーション・サポート・キャラクタ・セットを示すoracle.sql.CharacterSetインスタンスを用意する必要があります。

Oracleオブジェクト属性であるCHARオブジェクトは、データベース・キャラクタ・セットで戻されます。

CHARオブジェクトは、必要に応じてJDBCドライバで自動的に作成されるため、まれに作成する必要がある場合でも、JDBCアプリケーション・コードでCHARオブジェクトを直接作成する必要はほとんどありません。

CHARオブジェクトを作成する場合は、CharacterSetクラスのインスタンスによって、CHARオブジェクトにキャラクタ・セット情報を提供する必要があります。このクラスの各インスタンスは、Oracleがサポートしているグローバリゼーション・サポート・キャラクタ・セットの1つを表します。CharacterSetインスタンスは、キャラクタ・セットのメソッドおよび属性をカプセル化し、主に他のキャラクタ・セットとの相互変換機能を提供します。

oracle.sql.CHARオブジェクトの作成

CHARオブジェクトを構築する際、次の一般的な手順に従ってください。

  1. CharacterSetオブジェクトは、static CharacterSet.makeメソッドをコールして作成します。

    このメソッドは、キャラクタ・セット・インスタンスのファクトリです。makeメソッドは、Oracleがサポートするキャラクタ・セットIDに対応する整数を入力として取ります。たとえば、次のようになります。

    int oracleId = CharacterSet.JA16SJIS_CHARSET; // this is character set ID,
                                                  // 832
    ...
    CharacterSet mycharset = CharacterSet.make(oracleId);
    

    Oracleがサポートする各キャラクタ・セットは、事前定義済の一意なOracle IDを保持します。

  2. CHARオブジェクトを作成します。

    文字列または文字列を表すバイトを、キャラクタ・セットに基づくバイトの解釈方法を指定するCharacterSetオブジェクトとともに、コンストラクタに渡します。たとえば、次のようになります。

    String mystring = "teststring";
    ...
    CHAR mychar = new CHAR(teststring, mycharset);
    

    CHARには、CharacterSetオブジェクトとともに、Stringbyte配列またはオブジェクトを入力として使用できる複数のコンストラクタがあります。Stringの場合、文字列は、CharacterSetオブジェクトが示すキャラクタ・セットに変換されてから、CHARオブジェクトに格納されます。


    注意:

    • CharacterSetオブジェクトをNULL値にすることはできません。

    • CharacterSetクラスは抽象クラスであるため、コンストラクタを持ちません。インスタンスを作成するには、makeメソッドを使用するのが唯一の方法です。

    • サーバーは、特別な値であるCharacterSet.DEFAULT_CHARSETをデータベース・キャラクタ・セットとして認識します。クライアントの場合、この値は無意味です。

    • ユーザーがCharacterSetクラスを拡張することを、オラクル社は意図しておらず、お薦めもしません。


oracle.sql.CHAR Conversionメソッド

CHARクラスは、文字データを文字列に変換するための次のようなメソッドを提供します。

  • getString

    このメソッドは、CHARオブジェクトによって表された文字のシーケンスを文字列に変換し、Java Stringオブジェクトを戻します。無効なOracleIDを入力した場合、キャラクタ・セットは認識されず、getStringメソッドはSQLException例外をスローします。

  • toString

    このメソッドはgetStringメソッドと同じです。ただし、無効なOracleIDを入力すると、キャラクタ・セットが認識されず、toStringメソッドによりCHARデータの16進表現が戻されます。SQLException例外はスローされません

  • getStringWithReplacement

    このメソッドはgetStringメソッドと同一ですが、CHARオブジェクトのキャラクタ・セットにUnicode表現のない文字が、デフォルトの置換文字で置き換えられる点が異なります。デフォルトの置換文字はキャラクタ・セットによって異なりますが、多くの場合は疑問符(?)です。

データベース・サーバーとクライアント、またはクライアント上で動作するアプリケーションでは、異なるキャラクタ・セットを使用できます。CHARクラスのメソッドを使用してデータをサーバーとクライアント間で転送する場合、JDBCドライバはデータをサーバーのキャラクタ・セットからクライアントのキャラクタ・セットに(またはその逆に)変換する必要があります。データを変換する際、ドライバはグローバリゼーション・サポートを使用します。

その他のOracle型拡張機能

Oracle JDBCドライバは、Oracle固有のBFILEデータ型、ROWIDデータ型およびREF CURSOR型をサポートしますが、これらは標準JDBC仕様に含まれていません。このセクションでは、ROWIDおよびREF CURSOR型の拡張について説明します。ROWIDはJava文字列としてサポートされ、REF CURSOR型はJDBC結果セットとしてサポートされます。

この項の内容は次のとおりです。

Oracle ROWID型

ROWIDは、Oracle Database表の行ごとに一意の識別タグです。ROWIDは、各行のIDを含む仮想列とみなすこともできます。

oracle.sql.ROWIDクラスは、ROWID SQLデータ型のコンテナとして提供されます。

ROWIDは、java.sql.ResultSetインタフェースで指定されるgetCursorNameメソッドおよびjava.sql.Statementインタフェースで指定されるsetCursorNameメソッドに類似した機能を提供します。

問合せにROWID擬似列を指定した場合は、結果セットgetStringメソッドを使用してROWIDを取得できます。また、setStringメソッドを使用すると、ROWIDにPreparedStatementパラメータをバインドできます。これによって、次の例に示すように、埋込み更新を実行できます。


注意:

oracle.sql.ROWIDクラスを使用するのは、J2SE 5.0を使用する場合のみとしてください。JSE 6の場合は、標準のjava.sql.RowIdインタフェースを使用してください。

次の例では、ROWIDデータに対するアクセスおよび操作の方法を示します。


注意:

次の例は、JSE 6でのみ動作します。

Statement stmt = conn.createStatement(); 

// Query the employee names with "FOR UPDATE" to lock the rows. 
// Select the ROWID to identify the rows to be updated. 

ResultSet rset =  
   stmt.executeQuery ("SELECT first_name, rowid FROM employees FOR UPDATE"); 

// Prepare a statement to update the first_name column at a given ROWID 

PreparedStatement pstmt = 
   conn.prepareStatement ("UPDATE employees SET first_name = ? WHERE rowid = ?"); 

// Loop through the results of the query 
while (rset.next ()) 
{ 
    String ename = rset.getString (1); 
 RowId rowid = rset.getROWID(2); // Get the ROWID as a String 
    pstmt.setString (1, ename.toLowerCase ()); 
    pstmt.setROWID (2, rowid); // Pass ROWID to the update statement 
    pstmt.executeUpdate ();     // Do the update 
} 

Oracle REF CURSOR型カテゴリ

カーソル変数は、問合せ作業領域の(内容でなく)メモリーの場所を保持します。カーソル変数を宣言すると、ポインタが作成されます。SQLでは、ポインタはデータ型REF xを取ります。ここで、REFREFERENCEの省略形で、xは参照されるエンティティを表します。したがって、REF CURSORはカーソル変数への参照を表します。多くの作業領域を参照する多くのカーソル変数が存在する可能性があるため、REF CURSORは、異なる多くの型のカーソル変数を識別するカテゴリまたはデータ型指定子と考えることができます。


注意:

REF CURSORインスタンスはスクロール可能ではありません。

カーソル変数を作成するには、まずREF CURSORカテゴリに属する型を識別します。たとえば、次のようになります。

DECLARE TYPE DeptCursorTyp IS REF CURSOR

次に、カーソル変数をDeptCursorTyp型と宣言することによって、カーソル変数を作成します。

dept_cv DeptCursorTyp  - - declare cursor variable
...
 

REF CURSORは、特定のデータ型ではなく、データ型のカテゴリです。

ストアド・プロシージャにより、REF CURSORカテゴリのカーソル変数が戻されます。この出力は、データベース・カーソルまたはJDBC結果セットと等価です。REF CURSORには、基本的に問合せの結果が格納されます。

JDBCでは、REF CURSORは、ResultSetオブジェクトとしてインスタンス化され、次の方法でアクセスできます。

  1. ストアド・プロシージャをコールするにはJDBCコール可能文を使用します。出力パラメータがあるため、プリコンパイルされたSQL文ではなく、コール可能文を使用する必要があります。

  2. ストアド・プロシージャによってREF CURSORが戻されます。

  3. Javaアプリケーションによってコール可能文がOracleコール可能文にキャストされ、OracleCallableStatementクラスのgetCursorメソッドを使用してREF CURSORがJDBC ResultSetオブジェクトとしてインスタンス化されます。

  4. 結果セットは要求どおりに処理されます。


    重要:

    REF CURSORと関連付けられたカーソルは、そのREF CURSORを作成したStatementオブジェクトがクローズされるたびにクローズされます。

    過去のリリースとは異なり、REF CURSORのインスタンス化が行われた結果セット・オブジェクトがクローズされても、REF CURSORに関連付けられたカーソルはクローズされません


この例では、REF CURSORデータにアクセスする方法を示します。

import oracle.jdbc.*;
...
CallableStatement cstmt;
ResultSet cursor;

// Use a PL/SQL block to open the cursor
cstmt = conn.prepareCall
         ("begin open ? for select first_name from employees; end;");

cstmt.registerOutParameter(1, OracleTypes.CURSOR);
cstmt.execute();
cursor = ((OracleCallableStatement)cstmt).getCursor(1);

// Use the cursor like a standard ResultSet
while (cursor.next ())
    {System.out.println (cursor.getString(1));} 

この例について、説明します。

  • CallableStatementオブジェクトは、接続クラスのprepareCallメソッドを使用して作成されます。

  • コール可能文によって、REF CURSORを戻すPL/SQLプロシージャが実装されます。

  • コール可能文の出力パラメータは、通常どおり登録してその型を定義する必要があります。REF CURSORには、型コードOracleTypes.CURSORを使用します。

  • コール可能文が実行され、REF CURSORが戻されます。

  • 標準JDBC APIのOracle拡張機能getCursorメソッドを使用するため、CallableStatementオブジェクトをOracleCallableStatementにキャストします。REF CURSORResultSetオブジェクトに戻されます。

Oracle BINARY_FLOAT型およびBINARY_DOUBLE型

Oracle BINARY_FLOAT型およびBINARY_DOUBLE型は、IEEE 574のfloat型とdouble型のデータを格納するために使用します。これらの型は、負とゼロおよびNaNを除いて、Javaのfloatスカラー型とdoubleスカラー型に相当します。


関連項目:

『Oracle Database SQL言語リファレンス』

BINARY_DOUBLE列を問合せに含めると、データはデータベースからバイナリ形式で取り出されます。getDoubleメソッドも、データをバイナリ形式で戻します。一方、NUMBERデータ型の列の場合は、数値ビットが戻り、Javaのdoubleデータ型に変換されます。


注意:

SQL FLOAT型、DOUBLE PRECISION型およびREALデータ型のOracle表現は、Oracle NUMBER表現を使用します。BINARY_FLOAT型とBINARY_DOUBLEデータ型は、独自の型とみなされます。

PreparedStatementインタフェースのJDBC標準setDouble(int, double)メソッドのコールは、Javaのdouble引数をOracleのNUMBERスタイル・ビットに変換してからデータベースに送信します。一方、oracle.jdbc.OraclePreparedStatementインタフェースのsetBinaryDouble(int, double)メソッドは、データを内部バイナリ・ビットに変換してからデータベースに送信します。

使用するデータ形式が、PreparedStatementインタフェースのターゲット・パラメータの型と一致していることを確認してください。この確認によって、データの正確性が保持され、CPUの使用も最小限に抑えられます。NUMBERパラメータにsetBinaryDoubleを使用すると、バイナリ・ビットはサーバーに送信され、NUMBER形式に変換されます。データの正確性は保持されますが、サーバーのCPU負荷は増加します。BINARY_DOUBLEパラメータにsetDoubleを使用すると、データは、クライアントでNUMBERビットに変換されてからサーバーに送信され、そこでバイナリ形式に再変換されます。この方法では、クライアントとサーバーの両方でCPU負荷が増大し、データの精度も低下する可能性があります。

SetFloatAndDoubleUseBinary接続プロパティがtrueに設定されていると、JDBC標準API、setFloat(int, float)setDouble(int, double)、およびすべての変数では、NUBMERビットではなく、内部バイナリ・ビットを送信するようになります。


注意:

ここでは、主にBINARY_DOUBLEについて説明しましたが、BINARY_FLOATについても同じ内容が適用されます。

Oracle SYS.ANYTYPE型およびSYS.ANYDATA型

Oracle Database 12cリリース1 (12.1)では、SYS.ANYTYPEおよびSYS.ANYDATAというOracle型にアクセスするためのJavaインタフェースがサポートされています。


関連項目:

これらのOracle型の詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

SYS.ANYTYPE型のインスタンスには、オブジェクト型およびコレクション型も含め、SQL型の型記述(永続か一時、名前付きか名前なし)が含まれます。oracle.sql.TypeDescriptorクラスを使用すると、SYS.ANYTYPE型にアクセスできます。ANYTYPEインスタンスは、PL/SQLのプロシージャまたはSQLのSELECT文(SYS.ANYTYPEを列型として使用)を使用して取り出すことができます。ANYTYPEインスタンスをデータベースから取り出すには、getObjectメソッドを使用します。このメソッドは、TypeDescriptorのインスタンスを戻します。

次の任意のANYTYPEインスタンスを取り出すことができます。

  • 一時オブジェクト型

  • 一時事前定義済型

  • 永続オブジェクト型

  • 永続事前定義済型

例4-1 SYS.ANYTYPE型へのアクセス

次のコードは、ANYTYPEのインスタンスをデータベースから取り出す方法を示しています。

...
ResultSet rs = stmt.executeQuery("select anytype_column from my_table");
TypeDescriptor td = (TypeDescriptor)rs.getObject(1);
short typeCode = td.getInternalTypeCode();
if(typeCode == TypeDescriptor.TYPECODE_OBJECT)
{
  // check if it's a transient type
  if(td.isTransientType())
  {
    AttributeDescriptor[] attributes = ((StructDescriptor)td).getAttributesDescriptor();
    for(int i=0; i<attributes.length; i++)
      System.out.println(attributes[i].getAttributeName());
  }
  else
  {    System.out.println(td.getTypeName());  }}
...

例4-2 一時オブジェクト型のPL/SQLによる作成とJDBCによる取出し

次のサンプル・コードは、JDBCによる一時オブジェクト型の取出し方法を示しています。

...
OracleCallableStatement cstmt = (OracleCallableStatement)conn.prepareCall
  ("BEGIN ? := transient_obj_type (); END;");
cstmt.registerOutParameter(1,OracleTypes.OPAQUE,"SYS.ANYTYPE");
cstmt.execute();
TypeDescriptor obj = (TypeDescriptor)cstmt.getObject(1);
if(!obj.isTransient())
  System.out.println("This must be a JDBC bug");
cstmt.close();
return obj;
...

例4-3 ANYTYPEをINパラメータとして受け取るPL/SQLストアド・プロシージャのコール

次のコードは、ANYTYPEINパラメータとして受け取るPL/SQLストアド・プロシージャのコール方法を示しています。

...
CallableStatement cstmt = conn.prepareCall("BEGIN ? := dumpanytype(?); END;");
cstmt.registerOutParameter(1,OracleTypes.VARCHAR);
// obj is the instance of TypeDescriptor that you have retrieved
cstmt.setObject(2,obj);
cstmt.execute();
String str = (String)cstmt.getObject(1);
...

oracle.sql.ANYDATAクラスを使用すると、データベースからSYS.ANYDATAインスタンスにアクセスできます。このクラスのインスタンスは、oracle.sql.Datumの任意の有効なインスタンスから取得できます。convertDatumファクトリ・メソッドは、Datumのインスタンスを受け取り、ANYDATAのインスタンスを戻します。このファクトリ・メソッドの構文は、次のとおりです。

public static ANYDATA convertDatum(Datum datum) throws SQLException

oracle.sql.ANYDATAのインスタンスを作成するためのサンプル・コードを、次に示します。

// struct is a valid instance of oracle.sql.STRUCT that either comes from the 
// database or has been constructed in Java.
ANYDATA myAnyData = ANYDATA.convertDatum(struct);

例4-4 ANYDATAのインスタンスに対するデータベースからのアクセス

...
// anydata_table has been created as:
// CREATE TABLE anydata_tab (data SYS.ANYDATA)
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select data from my_anydata_tab");
while(rs.next())
{
  ANYDATA anydata = (ANYDATA)rs.getObject(1);
  if(!anydata.isNull())
  {
    TypeDescriptor td = anydata.getTypeDescriptor();
    if(td.getTypeCode() == OracleType.TYPECODE_OBJECT)
      STRUCT struct = (STRUCT)anydata.accessDatum();
  }
}
...

例4-5 データベース表へのANYDATAとしてのオブジェクトの挿入

表およびオブジェクト型が次のように定義されているものとします。

CREATE TABLE anydata_tab ( id NUMBER, data SYS.ANYDATA)

CREATE OR REPLACE TYPE employee AS OBJECT ( employee_id NUMBER, first_name VARCHAR2(10) )

次の方法で、SQLオブジェクト型EMPLOYEEのインスタンスを作成し、anydata_tableに挿入することができます。

...
PreparedStatement pstmt = conn.prepareStatement("insert into anydata_table values (?,?)");
Struct myEmployeeStr = conn.createStruct("EMPLOYEE", new Object[]{1120, "Papageno"});
ANYDATA anyda = ANYDATA.convertDatum(myEmployeeStr);
pstmt.setInt(1,123);
pstmt.setObject(2,anyda);
pstmt.executeUpdate();
...

例4-6 データベース表からのANYDATA列の選択

...
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select data from anydata_table");
while(rs.next())
{
  ANYDATA obj = (ANYDATA)rs.getObject(1);
  TypeDescriptor td = obj.getTypeDescriptor();
}
rs.close();
stmt.close();
...

oracle.jdbcパッケージ

oracle.jdbcパッケージのインタフェースは、java.sqlのインタフェースに対するOracle拡張機能を定義します。これらの拡張機能によって、この章に記載されているSQL形式のデータへのアクセスが可能になります。また、Oracleパフォーマンス拡張要素など、Oracle固有の他の機能へのアクセスも可能になります。

表4-1に、oracle.jdbcパッケージに含まれる接続に使用する主なインタフェースとクラス、文および結果セットのリストを示します。

表4-1 oracle.jdbcパッケージの主なインタフェースおよびクラス

名前 インタフェースまたはクラス 主要機能

OracleDriver

クラス

java.sql.Driverを実装します。

OracleConnection

インタフェース

Oracle Databaseインスタンスを起動または停止するためのメソッド、Oracle Statementオブジェクトを戻すメソッド、および現行接続で実行される任意の文に対応したOracleパフォーマンス拡張機能を設定するメソッドを提供します。

java.sql.Connectionを実装します。

OracleStatement

インタフェース

文ごとにOracleパフォーマンス拡張機能を設定するメソッドを提供します。

OraclePreparedStatementおよびOracleCallableStatementのスーパータイプです。

java.sql.Statementを実装します。

OraclePreparedStatement

インタフェース

oracle.sql.*型をプリコンパイルされたSQL文にバインドするsetXXXメソッドを提供します。

SELECT文を実行しないでプリコンパイルされたSQL文からメタデータを取得するgetMetaDataメソッドを提供します。

java.sql.PreparedStatementを実装します。

OracleStatementを機能拡張します。

OracleCallableStatementのスーパータイプです。

OracleCallableStatement

インタフェース

データをoracle.sql形式で取り出すgetXXXメソッド、およびoracle.sql.*型をコール可能文にバインドするsetXXXメソッドを提供します。

java.sql.CallableStatementを実装します。

OraclePreparedStatementを機能拡張します。

OracleResultSet

インタフェース

oracle.sql形式でデータを取り出すgetXXXメソッドを提供します。

java.sql.ResultSetを実装します。

OracleResultSetMetaData

インタフェース

列名やデータ型などのOracle結果セットのメタデータ情報を取得するメソッドを提供します。

java.sql.ResultSetMetaDataを実装します。

OracleDatabaseMetaData

クラス

データベース製品名/バージョン、表情報、デフォルト・トランザクション分離レベルなどのデータベースに関するメタデータ情報を取得するメソッドを提供します。

java.sql.DatabaseMetaDataを実装します。

OracleTypes

クラス

SQL型を識別する整数定数を定義します。

標準型の場合、同じ値を標準java.sql.Typesクラスとして使用します。さらに、Oracle拡張型に対応した定数も追加します。

OracleArray

インタフェース

配列全体を取り出し、配列要素のサブセットを取り出し、配列要素のSQLベース型名を取り出すための機能があります。

OracleStruct

インタフェース


OracleClob

インタフェース


OracleBlob

インタフェース


OracleRef

インタフェース


OracleOpaque

インタフェース



この項の内容は次のとおりです。

インタフェースoracle.jdbc.OracleConnection

このインタフェースは、標準JDBC接続機能を拡張して、Oracle Statementオブジェクトの作成と取得、Oracleパフォーマンス拡張機能用のフラグやオプションの設定、Oracleオブジェクト用型マップのサポート、およびクライアント識別子のサポートを実施します。

Oracle Database 11gリリース1では、Oracle Databaseインスタンスの起動と停止を実行できる新しいメソッドがこのインタフェースに追加されました。また、OracleConnectionインタフェースでは、可視性および透明性を向上させるために、すべての接続プロパティを定数として定義します。

このインタフェースは、DATEおよびNUMBERのようなoracle.sqlデータ値を構築するために、ファクトリ・メソッドも定義します。ファクトリ・メソッドの使用時には次の点に注意してください。

  • oracle.sql型のインスタンスを構築するすべてのコードで、Oracle拡張ファクトリ・メソッドを使用する必要があります。たとえば、ARRAYBFILEDATEINTERVALDSNUMBERSTRUCTTIMETIMESTAMPなどです。

  • 標準型のインスタンスを構築するすべてのコードで、JDBC4.0標準ファクトリ・メソッドを使用する必要があります。たとえば、CLOBBLOBNCLOBなどです。

  • CHARJAVA_STRUCTArrayDescriptorおよびStructDescriptorにはファクトリ・メソッドがありません。これらの型は内部ドライバの使用のためのみに用意されています。


    注意:

    Oracle Database 11gリリース1より前では、引数としてARRAYおよびSTRUCTクラス・コンストラクタに渡すために、ArrayDescriptorsおよびStructDescriptorsを作成する必要がありました。新しいARRAYおよびStructファクトリ・メソッドは記述子の引数がありません。ドライバはまだ内部で記述子を使用していますが、作成する必要はありません。

クライアント識別子

クライアント識別子を接続プーリング環境で使用すると、データベース・セッションを現在使用している軽量ユーザーを識別できます。クライアント識別子を使用すると、異なるデータベース・セッション間でグローバル・アクセス・アプリケーション・コンテキストを共有することもできます。データベース・セッションで設定されたクライアント識別子は、データベース監査がオンにされたときに監査されます。


関連項目:

『Oracle Database開発ガイド』およびOracle Database JDBC Java APIリファレンス

インタフェースoracle.jdbc.OracleStatement

このインタフェースは標準のJDBC文機能を拡張するもので、OraclePreparedStatementクラスとOracleCallableStatementクラスのスーパーインタフェースです。拡張された機能には、Oracleパフォーマンス拡張機能用の設定フラグとオプションの文単位でのサポートが含まれます。OracleConnectionインタフェースでは、それらを接続単位で設定していました。

インタフェースoracle.jdbc.OraclePreparedStatement

このインタフェースは、OracleStatementインタフェースを拡張し、標準JDBCのプリコンパイルされたSQL文の機能を拡張します。また、oracle.jdbc.OraclePreparedStatementインタフェースはOracleCallableStatementインタフェースによって拡張されます。拡張機能は次の機能から構成されます。

  • oracle.sql.*型とオブジェクトをプリコンパイルされたSQL文にバインドするためのsetXXXメソッド

  • SELECT文を実行しないで、プリコンパイルされたSQL文からメタデータを取得するためのgetMetaDataメソッド

  • 文単位でOracleパフォーマンス拡張機能をサポートするためのメソッド


注意:

:NEWまたは:OLD列を参照するトリガーの作成にPreparedStatementインタフェースを使用しないでください。かわりに、Statementを使用してください。PreparedStatementを使用すると、実行が失敗し、メッセージ「java.sql.SQLException: INまたはOUTパラメータがありません - 索引:: 1」が発行されます。

インタフェースoracle.jdbc.OracleCallableStatement

このインタフェースは、OracleStatementインタフェースを拡張するOraclePreparedStatementインタフェースを機能拡張し、標準JDBCのコール可能文機能を組み込みます。


注意:

:NEWまたは:OLD列を参照するトリガーの作成にCallableStatementインタフェースを使用しないでください。かわりにStatementを使用してください。CallableStatementを使用すると、実行が失敗し、メッセージ「java.sql.SQLException: INまたはOUTパラメータがありません - 索引:: 1」が発行されます。


注意:

  • setXXX(String,...)registerOutParameter(String,...)メソッドは、すべてのバインドがプロシージャまたは関数パラメータのみの場合にかぎり使用できます。文はそれ以外のバインドを含むことができません。パラメータ・バインドは疑問符で示す必要があります(:XXではなく、?)

  • setXXX(int,...)またはsetXXXAtName(String,...)メソッドを使用している場合、出力パラメータは、名前付きパラメータを指定するためのregisterOutParameter(String,...)ではなく、registerOutParameter(int,...)を使用してバインドされます。


インタフェースoracle.jdbc.OracleResultSet

このインタフェースは、標準JDBC結果セットの機能を拡張し、getXXXメソッドを実装してデータをoracle.sql.*オブジェクト内に取得します。

インタフェースoracle.jdbc.OracleResultSetMetaData

このインタフェースは、標準JDBC結果セットのメタデータ機能を拡張して、Oracle結果セット・オブジェクトの情報を取得します。

クラスoracle.jdbc.OracleTypes

OracleTypesクラスは、JDBCがSQL型を識別するのに使用する定数を定義します。このクラス内の各変数は、整数の定数値を持ちます。oracle.jdbc.OracleTypesクラスには、標準Java java.sql.Typesクラスの型コード定義の複製と、次のOracle拡張機能用の補足的な型コードが含まれます。

  • OracleTypes.BFILE

  • OracleTypes.ROWID

  • OracleTypes.CURSOR(REF CURSOR型の場合)

  • OracleTypes.CHAR_BYTES(同じ列のsetNullsetCHARメソッドをコールする場合)

java.sql.Typesの場合と同様に、変数名はすべて大文字にする必要があります。

JDBCは、OracleTypesクラスの要素によって識別されたSQL型を、出力パラメータの登録、およびPreparedStatementクラスのsetNullメソッドという2つの分野で使用します。

OracleTypesと出力パラメータの登録

java.sql.Typesまたはoracle.jdbc.OracleTypesの型コードは、java.sql.CallableStatementインタフェースおよびoracle.jdbc.OracleCallableStatementインタフェースのregisterOutParameterメソッドで出力パラメータのSQL型を識別します。

次に、CallableStatementインタフェースおよびOracleCallableStatementインタフェースでregisterOutputParameterメソッドが使用可能な形式を示します。

cs.registerOutParameter(int index, int sqlType);

cs.registerOutParameter(int index, int sqlType, String sql_name);

cs.registerOutParameter(int index, int sqlType, int scale);

これらのシグネチャでは、indexにはパラメータ索引が、sqlTypeにはSQLデータ型の型コードが入ります。sql_nameにはデータ型に与えられた名前が入りますが、sqlTypeSTRUCTREFまたはARRAY型コードの場合にはユーザー定義型の名前が入ります。さらに、sqlTypeNUMERICまたはDECIMAL型コードの場合には、scaleに、小数点の右側にある桁の数が入ります。

次の例は、CallableStatementインタフェースを使用して、charoutという名前付きプロシージャをコールしています。CHARデータ型が戻されます。registerOutParameterメソッドにおけるOracleTypes.CHAR型のコードの使用に注意してください。

CallableStatement cs = conn.prepareCall ("BEGIN charout (?); END;");
cs.registerOutParameter (1, OracleTypes.CHAR);
cs.execute ();
System.out.println ("Out argument is: " + cs.getString (1));

次の例は、CallableStatementインタフェースを使用して、structoutをコールしています。STRUCTデータ型が戻されます。registerOutParameterの形式では、型コードにTypes.STRUCTまたはOracleTypes.STRUCT、SQL名にEMPLOYEEを指定する必要があります。

この例では、EMPLOYEE型でいかなる型マップも宣言されていないことを前提としているため、STRUCTデータ型内に取得されます。oracle.sql.STRUCTオブジェクトとしてEMPLOYEEの値を取り出すために、Statemenオブジェクトcsは、OracleCallableStatementにキャストされ、Oracle拡張機能getSTRUCTメソッドが実行されます。

CallableStatement cs = conn.prepareCall ("BEGIN structout (?); END;");
cs.registerOutParameter (1, OracleTypes.STRUCT, "EMPLOYEE");
cs.execute ();

// get the value into a STRUCT because it 
// is assumed that no type map has been defined
STRUCT emp = ((OracleCallableStatement)cs).getSTRUCT (1);

OracleTypesおよびsetNullメソッド

TypesおよびOracleTypesでの型コードは、データ項目のSQL型を特定します。setNullメソッドがそれをNULLに設定します。setNullメソッドは、java.sql.PreparedStatementインタフェースとoracle.jdbc.OraclePreparedStatementインタフェースにあります。

次に、PreparedStatementおよびOraclePreparedStatementオブジェクトでsetNullメソッドが使用可能な形式を示します。

ps.setNull(int index, int sqlType);

ps.setNull(int index, int sqlType, String sql_name);

これらのシグネチャでは、indexがパラメータ索引を表します。sqlTypeはSQLデータ型のための型コードです。sql_nameは、sqlTypeSTRUCTREFまたはARRAY型コードである場合に、ユーザー定義のデータ型に対して指定される名前です。無効なsqlTypeを入力すると、ParameterTypeConflict例外がスローされます。

次の例では、プリコンパイルされたSQL文を使用してNULL値をデータベースに挿入します。NULLに設定する数値オブジェクトの識別にはOracleTypes.NUMERICを使用することに注意してください。ただし、Types.NUMERICも使用されることがあります。

PreparedStatement pstmt =
    conn.prepareStatement ("INSERT INTO num_table VALUES (?)");

pstmt.setNull (1, OracleTypes.NUMERIC);
pstmt.execute ();

この例では、プリコンパイルされたSQL文を使用して、EMPLOYEE型のNULL STRUCTオブジェクトをデータベースに挿入します。

PreparedStatement pstmt = conn.prepareStatement 
                               ("INSERT INTO employees VALUES (?)");

pstmt.setNull (1, OracleTypes.STRUCT, "EMPLOYEE");
pstmt.execute ();

同じ列のsetCHARメソッドもコールする場合、OracleTypes.CHAR_BYTES型をsetNullメソッドで使用することもできます。たとえば、次のようになります。

 ps.setCHAR(n, aCHAR);
  ps.addBatch();
  ps.setNull(n, OracleTypes.CHAR_BYTES);
  ps.addBatch();

この例では、OracleTypes.CHAR_BYTES型以外のどの型を使用しても、データベースとの余計なラウンドトリップが発生します。また、setNullメソッドを使用しないでコードを記述することもできます。たとえば、次の例のようにコードを記述することもできます。

ps.setCHAR(n, null);

DML RETURNING

DML RETURNING機能は、自動生成キーの取出しに比べて、より豊富な機能を提供します。この機能は、自動生成キーの取出しに使用できますが、アプリケーションで使用する可能性がある他の列や値の取出しにも使用できます。


注意:

  • サーバー側内部ドライバは、DML RETURNINGおよび自動生成キーの取出しをサポートしていません。

  • 同一文中でDML RETURNINGと自動生成キーの取得の両方を使用することはできません。


次の各項では、DML RETURNING機能のサポートについて説明します。

Oracle固有のAPI

OraclePreparedStatementインタフェースは、DML RETURNINGをサポートするOracle固有のApplication Program Interface(API)に伴って機能拡張されました。DML RETURNINGによって戻されるパラメータおよび取り出されるデータを登録するために、registerReturnParameterメソッドおよびgetReturnResultSetメソッドがoracle.jdbc.OraclePreparedStatementインタフェースに追加されています。

DML RETURNING機能の戻りパラメータは、registerReturnParameterメソッドを使用して登録します。エラーが発生した場合、メソッドはSQLExceptionインスタンスをスローします。戻りパラメータの索引を指定する正の整数を渡す必要があります。また、戻りパラメータの型も指定する必要があります。戻りパラメータの最大バイト数または最大文字数も指定できます。このメソッドは、charまたはRAW型でのみ使用できます。SQL構造型の完全修飾名も指定できます。


注意:

戻りパラメータの最大サイズが不明な場合は、デフォルトの最大サイズを選択するregisterReturnParameter(int paramIndex, int externalType)を使用してください。戻りパラメータの最大サイズが判明している場合は、registerReturnParameter(int paramIndex, int externalType, int maxSize)を使用することでメモリー消費を抑制できます。

getReturnResultSetメソッドは、DML RETURNING機能で戻されたデータをフェッチし、ResultSetオブジェクトとして戻します。エラーが検出された場合は、SQLException例外が発生します。


注意:

DML RETURNING機能のためのOracle固有のAPIは、Java Development Kit (JDK) 6.0の場合はojdbc6.jar、JDK 7の場合はojdbc7.jarに含まれています。

DML RETURNING文の実行

DML RETURNING文を実行する前に、JDBCアプリケーションが、registerReturnParameterメソッドを1つ以上コールする必要があります。これらのメソッドは、戻りパラメータに関する型やサイズなどの情報をJDBCドライバに提供します。DML RETURNING文は、executeUpdateまたはexecuteのいずれかの標準JDBC APIを使用して処理されます。戻されたパラメータは、oracle.jdbc.OraclePreparedStatementインタフェースのgetReturnResultSetメソッドを使用して、ResultSetオブジェクトとしてフェッチできます。

ResultSetオブジェクトの値を読み取るには、基礎となるStatementオブジェクトをオープンする必要があります。基礎となるStatementオブジェクトがクローズされている場合は、戻されたResultSetオブジェクトもクローズ状態となります。この状態は、SQL問合せ文を処理することで取り出されたResultSetオブジェクトの状態と一致します。

DML RETURNING文を実行する場合、getReturnResultSetメソッドで戻されるResultSetオブジェクトの同時実行性はCONCUR_READ_ONLYであり、そのResultSetオブジェクト型はTYPE_FORWARD_ONLYまたはTYPE_SCROLL_INSENSITIVEである必要があります。

DML RETURNINGの例

ここでは、DML RETURNING機能に関する2つのコード例を示します。

次のコードは、DML RETURNING機能の使用例です。この例では、name列の最大サイズを100文字と仮定します。name列の最大サイズが判明しているため、registerReturnParameter(int paramIndex, int externalType, int maxSize)メソッドを使用します。

...
OraclePreparedStatement pstmt = (OraclePreparedStatement)conn.prepareStatement(
       "delete from tab1 where age < ? returning name into ?");
pstmt.setInt(1,18);

/** register returned parameter
  * in this case the maximum size of name is 100 chars
  */
pstmt.registerReturnParameter(2, OracleTypes.VARCHAR, 100);

// process the DML returning statement
count = pstmt.executeUpdate();
if (count>0)
{
  ResultSet rset = pstmt.getReturnResultSet(); //rest is not null and not empty
  while(rset.next())
  {
    String name = rset.getString(1);
    ...
  }
}
...

次のコードも、DML RETURNING機能の使用例です。ただし、この例では、戻りパラメータの最大サイズが不明です。したがって、registerReturnParameter(int paramIndex, int externalType)メソッドを使用します。

...
OraclePreparedStatement pstmt = (OraclePreparedStatement)conn.prepareStatement(
  "insert into lobtab values (100, empty_clob()) returning col1, col2 into ?, ?");

// register return parameters
pstmt.registerReturnParameter(1, OracleTypes.INTEGER);
pstmt.registerReturnParameter(2, OracleTypes.CLOB);

// process the DML returning SQL statement
pstmt.executeUpdate();
ResultSet rset = pstmt.getReturnResultSet();
int r;
CLOB clob;
if (rset.next())
{
  r = rset.getInt(1);
  System.out.println(r);
  clob = (CLOB)rset.getClob(2);
  ...
}
...

DML RETURNINGの制限事項

DML RETURNING機能を使用する場合は、次の点に注意してください。

  • getReturnResultSetメソッドを複数回起動した場合は、その戻り値が不正確になります。そのため、これに関連するアクションには依存しないようにします。

  • DML RETURNING文の実行で戻るResultSetオブジェクトは、ResultSetMetaData型をサポートしません。したがって、アプリケーションでは、DML RETURNING文を実行する前に、戻りパラメータの情報を把握している必要があります。

  • DML RETURNINGでは、ストリームはサポートされません。

  • DML RETURNING機能をバッチ更新と組み合せることはできません。

  • 単一のSQL DML文の中で自動生成キー機能とDML RETURNING機能を両方とも使用することはできません。たとえば、次のような使用方法は許可されません。

    ...
    PreparedStatement pstmt = conn.prepareStatement('insert into orders (?, ?, ?) returning order_id into ?");
    pstmt.setInt(1, seq01.NEXTVAL);
    pstmt.setInt(2, 100);
    pstmt.setInt(3, 966431502);
    pstmt.registerReturnParam(4, OracleTypes.INTEGER);
    pstmt.executeUpdate;
    ResultSet rset = pstmt.getGeneratedKeys;
    ...
    

PL/SQL連想配列へのアクセス

Oracle JDBCドライバを使用すると、JDBCアプリケーションで、連想配列パラメータを使用してPL/SQLをコールできます。PL/SQLでは、連想配列はキー値ペアのセットです。キーはPLS_INTEGERsまたは文字列の場合があります。キーは任意の値であり、稠密である必要はありません。クライアント・アプリケーションから、PLS_INTEGERキーのみを使用できます。このキーは正の数で稠密である必要があります。


注意:

連想配列は、以前は索引付き表と呼ばれていました。

この項の内容は次のとおりです。

概要

Oracle JDBCドライバは、VARCHAR型およびNUMBER型のPL/SQL連想配列をサポートします。通常のOracle JDBC入力バインド、出力登録、およびデータ・アクセス・メソッドは、PL/SQL連想配列をサポートしません。この項では、これらの型をサポートする追加メソッドを説明します。

OraclePreparedStatementおよびOracleCallableStatementクラスは、追加のメソッドを定義します。これらのメソッドには次のものがあります。

  • setPlsqlIndexTable

  • registerIndexTableOutParameter

  • getOraclePlsqlIndexTable

  • getPlsqlIndexTable

これらのメソッドは、PL/SQL連想配列をINOUTまたはIN OUTパラメータとして、ファンクション戻り値も含めて処理します。


注意:

文字列のデータ型を使用する場合、サイズはPL/SQLのサイズ(32767文字)に制限されます。サーバー側内部ドライバの場合、制限は小さくなります。これらのメソッドの詳細は、Javadocを参照してください。


関連項目:

『Oracle Database PL/SQL言語リファレンス』

INパラメータのバインド

PL/SQL連想配列パラメータをINパラメータ・モードでバインドするには、OraclePreparedStatementおよびOracleCallableStatementの各クラスで定義されたsetPlsqlIndexTableメソッドを使用します。

synchronized public void setPlsqlIndexTable (int paramIndex, Object arrayData, int maxLen, int curLen, int elemSqlType,
 int elemMaxLen) throws SQLException

表4-2では、getPlsqlIndexTableメソッドの引数について説明しています。

表4-2 setPlsqlIndexTableメソッドの引数

引数 説明

int paramIndex

文内のパラメータの位置を示します。

Object arrayData

PL/SQL連想配列パラメータにバインドされる値の配列です。この値はjava.lang.Object型に関する値です。この値には、int[]などのJavaプリミティブ型配列、またはBigDecimal[]などのJavaオブジェクト配列を指定できます。

int maxLen

一括更新で利用できる最大のcurLenを定義する、連想配列バインド値の表の最大長を指定します。スタンドアロンのバインドの場合、maxLenにはcurLenと同じ値を使用してください。この引数は必須です。

int curLen

arrayDataの連想配列バインド値の実際のサイズを指定します。curLen値がarrayDataのサイズより小さい場合は、curLenで指定した数の表要素のみがデータベースに渡されます。curLen値がarrayDataのサイズよりも大きい場合は、arrayData全体がデータベースに送信されます。

int elemSqlType

OracleTypesクラスに定義されている値に基づいて、連想配列の要素型を指定します。

int elemMaxLen

要素型がCHARVARCHARまたはRAWである場合に連想配列の要素の最大長を指定します。この値は、他の型では無視されます。


次のコード例では、連想配列をINとしてバインドするsetPlsqlIndexTableメソッドを使用します。

// Prepare the statement
OracleCallableStatement procin = (OracleCallableStatement) 
   conn.prepareCall ("begin procin (?); end;"); 

// Associative Array bind value 
int[] values = { 1, 2, 3 }; 

// maximum length of the Associative Array bind value. This 
// value defines the maximum possible "currentLen" for batch 
// updates. For standalone binds, "maxLen" should be the 
// same as "currentLen". 
int maxLen = values.length; 

// actual size of the Associative Array bind value 
int currentLen = values.length; 

// Associative Array element type 
int elemSqlType = OracleTypes.NUMBER; 

// Associative Array element length in case the element type 
// is CHAR, VARCHAR or RAW. This value is ignored for other 
// types. 
int elemMaxLen = 0; 

// set the value 
procin.setPlsqlIndexTable (1, values, 
                           maxLen, currentLen, 
                           elemSqlType, elemMaxLen); 

// execute the call 
procin.execute (); 

OUTパラメータの受取り

この項では、PL/SQL連想配列をOUTパラメータとして登録する方法について説明します。また、様々なマッピング・スタイルでOUTバインド値にアクセスする方法について説明します。


注意:

この項で説明するメソッドは、ファンクション戻り値およびIN OUTパラメータ・モードに適用されます。

OUTパラメータの登録

PL/SQL連想配列をOUTパラメータとして登録するには、OracleCallableStatementクラスで定義されたregisterIndexTableOutParameterメソッドを使用します。

synchronized public void registerIndexTableOutParameter 
(int paramIndex, int maxLen, int elemSqlType, int elemMaxLen) throws SQLException

表4-3では、registerIndexTableOutParameterメソッドの引数について説明しています。

表4-3 registerIndexTableOutParameterメソッドの引数

引数 説明

int paramIndex

文内のパラメータの位置を示します。

int maxLen

戻される連想配列バインド値の表の最大長を指定します。

int elemSqlType

OracleTypesクラスに定義されている値に基づいて、連想配列の要素型を指定します。

int elemMaxLen

要素型がCHARVARCHARまたはFIXED_CHARである場合に連想配列の要素の最大長を指定します。この値は、他の型では無視されます。


次のコード例では、registerIndexTableOutParameterメソッドを使用して、連想配列をOUTパラメータとして登録します。

// maximum length of the Associative Array value. This 
// value defines the maximum table size to be returned.
int maxLen = 10;

// Associative Array element type
int elemSqlType = OracleTypes.NUMBER;

// Associative Array element length in case the element type
// is CHAR, VARCHAR or FIXED_CHAR. This value is ignored for other
// types
int elemMaxLen = 0;

// register the return value
funcnone.registerIndexTableOutParameter
   (1, maxLen, elemSqlType, elemMaxLen);

OUTパラメータ値へのアクセス

OUTバインド値へアクセスするために、OracleCallableStatementクラスでは、様々なマッピング・スタイルの連配列の値を戻す複数のメソッドを定義します。JDBCドライバでは、次の3つのマッピングを選択できます。

マッピング 使用するメソッド
JDBCデフォルト・マッピング getPlsqlIndexTable(int)
Oracleマッピング getOraclePlsqlIndexTable(int)
Javaプリミティブ型マッピング getPlsqlIndexTable(int, Class)

型マッピング

この項の内容は次のとおりです。

JDBCデフォルト・マッピング

getPlsqlIndexTable(int)メソッドは、JDBCデフォルト・マッピングを使用して連想配列の要素を戻します。このメソッドの構文は次のとおりです。

public Object getPlsqlIndexTable (int paramIndex)
   throws SQLException

表4-4では、getPlsqlIndexTableメソッドの引数について説明しています。

表4-4 getPlsqlIndexTableメソッドの引数

引数 説明

int paramIndex

この引数は、文内のパラメータの位置を示します。


戻り値はJava配列です。この配列の要素は、要素のSQL型に対応するデフォルトのJava型です。たとえば、NUMERIC型コードの要素による連想配列の場合、要素値はOracle JDBCドライバによってBigDecimalにマップされ、getPlsqlIndexTableメソッドがBigDecimal[]配列を戻します。JDBCアプリケーションの場合、戻り値をBigDecimal[]にキャストして表要素値にアクセスする必要があります。

次のコード例では、getPlsqlIndexTableメソッドを使用して、JDBCデフォルト・マッピングで連想配列の要素を戻します。

// access the value using JDBC default mapping 
BigDecimal[] values = 
   (BigDecimal[]) procout.getPlsqlIndexTable (1); 

// print the elements 
for (int i=0; i<values.length; i++) 
   System.out.println (values[i].intValue()); 

Oracleマッピング

getOraclePlsqlIndexTableメソッドは、Oracleマッピングを使用して連想配列要素を戻します。

public Datum[] getOraclePlsqlIndexTable (int paramIndex)
      throws SQLException 

表4-5では、getOraclePlsqlIndexTableメソッドの引数について説明しています。

表4-5 getOraclePlsqlIndexTableメソッドの引数

引数 説明

int paramIndex

文内のパラメータの位置を示します。


戻り値はoracle.sql.Datum配列で、配列の要素は、要素のSQL型に対応するデフォルトのDatum型です。たとえば、数値要素の連想配列の要素値は、Oracleマッピングでoracle.sql.NUMBER型にマップされ、getOraclePlsqlIndexTableメソッドはoracle.sql.NUMBER要素を含むoracle.sql.Datum配列を戻します。

次のコード例では、getOraclePlsqlIndexTableメソッドを使用して、PL/SQL連想配列のOUTパラメータの要素に、Oracleマッピングを使用してアクセスします。

// Prepare the statement 
OracleCallableStatement procout = (OracleCallableStatement)
                                  conn.prepareCall ("begin procout (?); end;");

...

// run the call
procout.execute ();
 
// access the value using Oracle JDBC mapping
Datum[] outvalues = procout.getOraclePlsqlIndexTable (1);

// print the elements
for (int i=0; i<outvalues.length; i++)
   System.out.println (outvalues[i].intValue());

Javaプリミティブ型マッピング

getPlsqlIndexTable(int, Class)メソッドは、Javaプリミティブ型の連想配列の要素を戻します。戻り値はJava配列です。このメソッドの構文は次のとおりです。

synchronized public Object getPlsqlIndexTable
(int paramIndex, Class primitiveType) throws SQLException

表4-6では、getPlsqlIndexTableメソッドの引数について説明しています。

表4-6 getPlsqlIndexTableメソッドの引数

引数 説明

int paramIndex

文内のパラメータの位置を示します。

Class primitiveType

連想配列の要素の変換先となるJavaプリミティブ型を指定します。たとえば、java.lang.Integer.TYPEを指定すると、戻り値はint配列になります。

このパラメータには、次の値を指定できます。

java.lang.Integer.TYPE

java.lang.Long.TYPE

java.lang.Float.TYPE

java.lang.Double.TYPE

java.lang.Short.TYPE


次のコード例では、getPlsqlIndexTableメソッドを使用して、数値のPL/SQL連想配列の要素にアクセスします。この例では、2つ目のパラメータはjava.lang.Integer.TYPEを指定し、getPlsqlIndexTableメソッドはint配列を戻します。

OracleCallableStatement funcnone = (OracleCallableStatement) 
   conn.prepareCall ("begin ? := funcnone; end;"); 

// maximum length of the Associative Array value. This 
// value defines the maximum table size to be returned. 
int maxLen = 10; 

// Associative Array element type 
int elemSqlType = OracleTypes.NUMBER; 

// Associative Array element length in case the element type 
// is CHAR, VARCHAR or RAW. This value is ignored for other 
// types 
int elemMaxLen = 0; 

// register the return value 
funcnone.registerIndexTableOutParameter (1, maxLen, 
                                        elemSqlType, elemMaxLen); 
// execute the call 
funcnone.execute (); 

// access the value as a Java primitive array. 
int[] values = (int[]) 
   funcnone.getPlsqlIndexTable (1, java.lang.Integer.TYPE); 

// print the elements 
for (int i=0; i<values.length; i++) 
   System.out.println (values[i]);