ヘッダーをスキップ
Oracle Database JDBC開発者ガイド
11gリリース2(11.2)
B56281-01
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

A JDBCリファレンス情報

この付録では、Java Database Connectivity(JDBC)リファレンス詳細情報について説明します。内容は次のとおりです。

有効なSQL-JDBCデータ型マッピング

表11-1は、Oracle JDBCドライバでサポートされているJavaクラスとSQLデータ型とのデフォルトのマッピングです。表11-1のJDBC型コード、標準Java型およびSQLデータ型の列の内容と、表A-1の内容を比較してください。

表A-1は、特定のSQLデータ型のマッピング先として有効な、すべてのJava型のリストです。Oracle JDBCドライバでは、これらの非デフォルト・マッピングをサポートしています。たとえば、SQL CHARデータをoracle.sql.CHARオブジェクトとしてインスタンス化するには、getCHARメソッドを使用します。java.math.BigDecimalオブジェクトとしてインスタンス化するには、getBigDecimalメソッドを使用します。


注意:

oracle.sql.ORADataがイタリックで表示されているクラスでは、JPublisherで生成できます。

表A-1 有効なSQLデータ型-Javaクラス・マッピング

SQLデータ型 Java型

CHARVARCHAR2LONG

java.lang.String

oracle.sql.CHAR

NUMBER

boolean

char

byte

short

int

long

float

double

java.lang.Byte

java.lang.Short

java.lang.Integer

java.lang.Long

java.lang.Float

java.lang.Double

java.math.BigDecimal

oracle.sql.NUMBER

BINARY_INTEGER

boolean

char

byte

short

int

long

BINARY_FLOAT

oracle.sql.BINARY_FLOAT

BINARY_DOUBLE

oracle.sql.BINARY_DOUBLE

DATE

oracle.sql.DATE

RAW

oracle.sql.RAW

BLOB

oracle.sql.BLOB

CLOB

oracle.sql.CLOB

BFILE

oracle.sql.BFILE

ROWID

oracle.sql.ROWID

TIMESTAMP

oracle.sql.TIMESTAMP

TIMESTAMPWITHTIMEZONE

oracle.sql.TIMESTAMPLTZ

TIMESTAMPWITHLOCALTIMEZONE

oracle.sql.TIMESTAMPLTZ

REFカーソル

java.sql.ResultSet

sqlj.runtime.ResultSetIterator

ユーザー定義の名前付き型、ADT

oracle.sql.STRUCT

opaque名前付き型

oracle.sql.OPAQUE

NESTED TABLEおよびVARRAY名前付き型

oracle.sql.ARRAY

名前付き型の参照

oracle.sql.REF



注意:

  • UROWID型はサポートされていません。

  • oracle.sql.Datumは抽象クラスです。oracle.sql.Datum型のパラメータに渡す値は、基礎となるSQL型に対応するJava型にする必要があります。同様に、戻り型oracle.sql.Datumのメソッドから戻される値は、基礎となるSQL型に対応するJava型にする必要があります。


サポートされているSQLおよびPL/SQLデータ型

この項の表は、SQLとPL/SQLのデータ型、およびOracle JDBCドライバがこれらのデータ型をサポートしているかどうかのリストです。表A-2は、SQLデータ型に対するOracle JDBCドライバのサポート状況のリストです。

表A-2 SQLデータ型に対するサポート

SQLデータ型 JDBCドライバによるサポート

BFILE

BLOB

CHAR

CLOB

DATE

NCHAR

不可脚注1 

NCHAR VARYING

不可

NUMBER

NVARCHAR2

脚注2 

RAW

REF

ROWID

UROWID

不可

VARCHAR2


脚注1 NCHAR型が間接的にサポートされています。対応するjava.sql.Types型はありませんが、アプリケーションがformOfUse(NCHAR)メソッドをコールする場合には、これらの型にアクセスできます。

脚注2 JSE 6では、NVARCHAR2型が直接サポートされています。J2SE 5.0では、NVARCHAR2型が間接的にサポートされています。対応するjava.sql.Types型はありませんが、アプリケーションがformOfUse(NCHAR)メソッドをコールする場合には、これらの型にアクセスできます。

表A-3は、ANSIでサポートされているSQLデータ型に対するOracle JDBCドライバのサポート状況のリストです。

表A-3 ANSI-92 SQLデータ型に対するサポート

ANSIでサポートされているSQLデータ型 JDBCドライバによるサポート

CHARACTER

DEC

DECIMAL

DOUBLE PRECISION

FLOAT

INT

INTEGER

NATIONAL CHARACTER

不可

NATIONAL CHARACTER VARYING

不可

NATIONAL CHAR

NATIONAL CHAR VARYING

不可

NCHAR

NCHAR VARYING

不可

NUMERIC

REAL

SMALLINT

VARCHAR


表A-4は、SQLユーザー定義型に対するOracle JDBCドライバのサポート状況のリストです。

表A-4 SQLユーザー定義型に対するサポート

SQLユーザー定義型 JDBCドライバによるサポート

OPAQUE

参照型

オブジェクト型(JAVA_OBJECT)

NESTED TABLE型およびVARRAY型


表A-5は、PL/SQLデータ型に対するOracle JDBCドライバのサポート状況のリストです。PL/SQLデータ型には、次のカテゴリがあります。

表A-5 PL/SQLデータ型に対するサポート

PL/SQLデータ型 JDBCドライバによるサポート

スカラー型


BINARY INTEGER

DEC

DECIMAL

DOUBLE PRECISION

FLOAT

INT

INTEGER

NATURAL

NATURALn

不可

NUMBER

NUMERIC

PLS_INTEGER

POSITIVE

POSITIVEn

不可

REAL

SIGNTYPE

SMALLINT

スカラー文字列型


CHAR

CHARACTER

LONG

LONG RAW

NCHAR

不可(「注意」を参照)

NVARCHAR2

不可(「注意」を参照)

RAW

ROWID

STRING

UROWID

不可

VARCHAR

VARCHAR2

BOOLEAN

DATE

コンポジット型


RECORD

不可

TABLE

不可

VARRAY

参照型


REF CURSOR型

オブジェクト参照型

LOB型


BFILE

BLOB

CLOB

NCLOB



注意:

  • NATURALNATURALnPOSITIVEPOSITIVEnおよびSIGNTYPE型は、BINARY INTEGERのサブタイプです。

  • DECDECIMALDOUBLE PRECISIONFLOATINTINTEGERNUMERICREALおよびSMALLINT型は、NUMBERのサブタイプです。

  • NCHAR型およびNVARCHAR2型は間接的にサポートされています。対応するjava.sql.Types型はありませんが、アプリケーションがformOfUse(NCHAR)をコールする場合には、これらの型にアクセスできます。詳細は、「JDK 1.5のNCHAR、NVARCHAR2、NCLOBおよびdefaultNCharプロパティ」を参照してください。


埋込みJDBCエスケープ構文

Oracle JDBCドライバは、いくつかの埋込みJDBCエスケープ構文(中カッコで囲んで指定する構文)をサポートしています。現在のサポートは初歩的なものです。


注意:

JDBCエスケープ構文は、以前はSQL92構文またはSQL92エスケープ構文と呼ばれていました。

この項では、OracleのJDBCドライバによって提供される次の構文のサポートについて説明します。

ドライバのサポートが制限されている場合、これらの項では、選択可能な回避策についても説明します。

エスケープ処理の無効化

JDBCエスケープ構文の処理はデフォルトで有効です。このため、SQLコードをデータベースに送信する前にJDBCドライバがエスケープ置換を実行します。ドライバが通常のOracle SQL構文(JDBCエスケープ構文処理より効率的です)を使用するようにするには、次の文を使用します。

stmt.setEscapeProcessing(false);

時刻および日付リテラル

日付、時刻およびタイムスタンプのリテラルに使用する構文は、データベースによって異なります。JDBCでは、特定の形式で記述された日付および時刻のみがサポートされています。この項では、SQL文内で使用する必要のある日付、時刻およびタイムスタンプのリテラルについて説明します。

日付リテラル

JDBCドライバは、次の形式で記述されたSQL文内の日付リテラルをサポートしています。

{d 'yyyy-mm-dd'}

yyyy-mm-ddは、年、月および日を表します。たとえば、次のようになります。

{d '1995-10-22'}

JDBCドライバは、このエスケープ句を等価のOracleの表現「22 OCT 1995」に置換します。

次のコードの抜粋には、SQL文内での日付リテラルの使用例が含まれています。

// Connect to the database
// You can put a database name after the @ sign in the connection URL.
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:oci:@");
ods.setUser("scott");
ods.setPassword("tiger");
Connection conn = ods.getConnection();

// Create a Statement
Statement stmt = conn.createStatement ();

// Select the ename column from the emp table where the hiredate is Jan-23-1982
ResultSet rset = stmt.executeQuery 
                 ("SELECT ename FROM emp WHERE hiredate = {d '1982-01-23'}");

// Iterate through the result and print the employee names
while (rset.next ())
   System.out.println (rset.getString (1));

時刻リテラル

JDBCドライバは、次の形式で記述されたSQL文内の時刻リテラルをサポートしています。

{t 'hh:mm:ss'}

hh:mm:ssは、時、分および秒を表します。たとえば、次のようになります。

{t '05:10:45'}

JDBCドライバは、このエスケープ句を等価のOracleの表現「05:10:45」に置換します。

次のように時刻が指定されているとします。

{t '14:20:50'}

サーバーが24時間制のクロックを使用しているとすれば、等価のOracleの表現は「14:20:50」になります。

次のコードの抜粋には、SQL文内での時刻リテラルの使用例が含まれています。

ResultSet rset = stmt.executeQuery 
                 ("SELECT ename FROM emp WHERE hiredate = {t '12:00:00'}");

タイムスタンプ・リテラル

JDBCドライバは、次の形式で記述されたSQL文内のタイムスタンプ・リテラルをサポートしています。

{ts 'yyyy-mm-dd hh:mm:ss.f...'} 

yyyy-mm-dd hh:mm:ss.f...は、年、月、日、時、分および秒を表します。端数秒の部分(.f...)は省略できます。たとえば、{ts '1997-11-01 13:22:45'}は、Oracle形式ではNOV 01 1997 13:22:45と表されます。

次のコードの抜粋には、SQL文内でのタイムスタンプ・リテラルの使用例が含まれています。

ResultSet rset = stmt.executeQuery 
    ("SELECT ename FROM emp WHERE hiredate = {ts '1982-01-23 12:00:00'}");

Oracleオブジェクト型からSQL DATEデータ型へのマッピング

Oracle Database 8iおよびそれ以前のリリースではTIMESTAMPデータはサポートされませんでしたが、Oracle DATEデータには、SQL標準を拡張するtimeコンポーネントがありました。このため、JDBCドライバのOracle Database 8iおよびそれ以前のリリースは、oracle.sql.DATEjava.sql.Timestampにマップしてtimeコンポーネントを維持していました。Oracle Database 9.0.1で初めてTIMESTAMPのサポートが含まれ、9i JDBCドライバがoracle.sql.DATEjava.sql.Dateにマップするようになりました。このマッピングは不正確で、Oracle DATEデータのtimeコンポーネントを切り詰めました。この問題を解決するために、Oracle Database 11.1では、新しいフラグmapDateToTimestampが導入されました。このフラグのデフォルト値はtrueで、これは、ドライバがoracle.sql.DATEをデフォルトでjava.sql.Timestampに正しくマップすることを意味します。不正確でも10gとの互換性があるoracle.sql.DATEからjava.sql.Dateへのマッピングを使用する場合は、mapDateToTimestampフラグの値をfalseに設定します。


注意:

  • Oracle Database 11gで、SQL問合せが使用するための索引がDATE列上にある場合、高速で正確な結果を入手するには、次のようにsetObjectメソッドを使用する必要があります。

    Date d = parseIsoDate(val);
    Timestamp t = new Timestamp(d.getTime());
    stmt.setObject(pos, new oracle.sql.DATE(t, (Calendar)UTC_CAL.clone()));
    

    これは、setDateメソッドを使用する場合はOracle DATEデータのtimeコンポーネントが失われ、setTimestampメソッドを使用する場合はDATE列上の索引が使用されないためです。

  • oracle.sql.DATEからjava.sql.Dateへのマッピングの問題を解決するために、Oracle Database 9.2でフラグV8Compatibleが導入されました。このフラグのデフォルト値はfalseで、これによりjava.sql.DateデータへのOracle DATEデータのマッピングが可能になっています。ユーザーは、このフラグの値をtrueに設定することによって、Oracle DATEデータのtimeコンポーネントを維持できていました。このフラグは11gではサポートされません。それにより制御されるOracle Database 8iとの互換性がもうサポートされないためです。


スカラー関数

Oracle JDBCドライバでサポートしていないスカラー関数もあります。ドライバがサポートする関数を調べるには、Oracle固有のoracle.jdbc.OracleDatabaseMetaDataクラスおよび標準Javaのjava.sql.DatabaseMetadataインタフェースでサポートされている次のメソッドを使用します。

  • getNumericFunctions()

    ドライバによってサポートされている数値演算関数をカンマで区切られたリストで戻します。たとえば、「ABS, COS, SQRT」です。

  • getStringFunctions()

    ドライバによってサポートされている文字列関数をカンマで区切られたリストで戻します。たとえば、「ASCII, LOCATE」です。

  • getSystemFunctions()

    ドライバによってサポートされているシステム関数をカンマで区切られたリストで戻します。たとえば、「DATABASE, USER」です。

  • getTimeDateFunctions()

    ドライバによってサポートされている時刻および日付関数をカンマで区切られたリストで戻します。たとえば、「CURDATE, DAYOFYEAR, HOUR」です。


    注意:

    Oracle JDBCドライバは、ファンクション・キーワードのfnをサポートしています。

LIKEエスケープ文字

SQL LIKE句では、文字%および_には特別な意味があります。%は0文字以上の一致、_は1文字のみの一致に使用します。これらの文字を文字列内で文字どおりに使用する場合は、その前に特別なエスケープ文字を置きます。たとえば、アンパサンド&をエスケープ文字として使用する場合は、SQL文内では次のように識別させます。

Statement stmt = conn.createStatement ();

// Select the empno column from the emp table where the ename starts with '_'
ResultSet rset = stmt.executeQuery
          ("SELECT empno FROM emp WHERE ename LIKE '&_%' {ESCAPE '&'}");

// Iterate through the result and print the employee numbers
while (rset.next ())
   System.out.println (rset.getString (1));

注意:

円記号(\)をエスケープ文字として使用する場合は、2回入力する(\\とする)必要があります。たとえば、次のようになります。
ResultSet rset = stmt.executeQuery("SELECT empno FROM emp
                WHERE ename LIKE '\\_%' {escape '\\'}");

外部結合

OracleのJDBCドライバは、外部結合構文をサポートしていません。回避策は、Oracle外部結合構文を使用することです。

次の構文のかわりに、

Statement stmt = conn.createStatement ();
ResultSet rset = stmt.executeQuery
     ("SELECT ename, dname 
       FROM {OJ dept LEFT OUTER JOIN emp ON dept.deptno = emp.deptno} 
       ORDER BY ename");

Oracle SQL構文を使用します。

Statement stmt = conn.createStatement ();
ResultSet rset = stmt.executeQuery
     ("SELECT ename, dname 
       FROM emp b, dept a WHERE a.deptno = b.deptno(+)
       ORDER BY ename");

ファンクション・コール構文

Oracle JDBCドライバは、次のプロシージャおよびファンクション・コール構文をサポートしています。

プロシージャ・コール:

{ call procedure_name (argument1, argument2,...) } 

ファンクション・コール:

{ ? = call procedure_name (argument1, argument2,...) }

JDBCエスケープ構文からOracle SQL構文変換例

JDBCエスケープ構文をOracle SQL構文に変換する簡単なプログラムを記述できます。次のプログラムは、ファンクション・コール、日付リテラル、時刻リテラルおよびタイムスタンプ・リテラルのためのJDBCエスケープ構文を使用する文に対して、それに対応するOracle SQL構文を出力します。このプログラムでは、oracle.jdbc.OracleSqlクラスのparse()メソッドで変換します。

public class Foo 
{ 
   static oracle.jdbc.OracleDriver driver = new oracle.jdbc.OracleDriver();
   public static void main (String args[]) throws Exception 
   { 
      show ("{call foo(?, ?)}"); 
      show ("{? = call bar (?, ?)}"); 
      show ("{d '1998-10-22'}"); 
      show ("{t '16:22:34'}"); 
      show ("{ts '1998-10-22 16:22:34'}"); 
   } 
 
   public static void show (String s) throws Exception 
   { 
      System.out.println (s + " => " + 
         driver.processSqlEscapes(s)); 
   } 
}

対応するSQL構文の出力です。

{call foo(?, ?)} => BEGIN foo(:1, :2); END; 
{? = call bar (?, ?)} => BEGIN :1 := bar (:2, :3); END;
{d '1998-10-22'} => TO_DATE ('1998-10-22', 'YYYY-MM-DD')
{t '16:22:34'} => TO_DATE ('16:22:34', 'HH24:MI:SS')
{ts '1998-10-22 16:22:34'} => TO_TIMESTAMP ('1998-10-22 16:22:34', 'YYYY-MM-DD 
HH24:MI:SS.FF')

Oracle JDBCの注意および制限事項

Oracle JDBC実装には次の制限がありますが、すべて、ほとんど影響がないか、簡単な対処法があります。この項の内容は次のとおりです。

CursorName

Oracle JDBCドライバは、get getCursorNameメソッドおよびsetCursorNameをサポートしません。それらをOracle構造にマップする便利な手段がないためです。かわりにROWIDを使用することをお薦めします。


関連項目:

ROWIDの使用および操作方法の詳細は、「Oracle ROWID型」を参照してください。

JDBC外部結合エスケープ

Oracle JDBCドライバでは、JDBC外部結合エスケープがサポートされません。かわりに、Oracle SQL構文で+を使用してください。

PL/SQL TABLE、BOOLEANおよびRECORD型

Oracle JDBCドライバでは、PL/SQLのRECORDBOOLEAN、またはスカラー以外の要素型を持つ表の引数コールまたは戻り値をサポートできません。ただし、Oracle JDBCドライバはスカラー要素型のPL/SQL索引付き表をサポートします。

PL/SQLのRECORDBOOLEANまたはスカラー以外の表型に対する対処法としては、JDBCによってサポートされている型としてデータを処理するコンテナ・プロシージャを作成します。たとえば、PL/SQLブーリアンを使用するストアド・プロシージャをラップするには、JDBCから文字または数値を取得し、BOOLEANとして元のプロシージャに渡すストアド・プロシージャを作成するか、出力パラメータの場合は、元のプロシージャからBOOLEAN引数を受け取り、CHARまたはNUMBERとしてJDBCに渡します。同様に、PL/SQLレコードを使用するストアド・プロシージャをラップするには、その個々のコンポーネントの形式で(CHARNUMBERなど)、または構造化オブジェクト型でレコードを処理するストアド・プロシージャを作成します。PL/SQL表を使用するストアド・プロシージャをラップするには、データをコンポーネントに分割するか、場合によってはOracleコレクション型を使用します。


関連項目:

BOOLEANの回避方法の例は、「PL/SQLストアド・プロシージャのブール型パラメータ」を参照してください。

IEEE 754浮動小数点との互換性

Oracle NUMBER型の算術演算は、浮動小数演算に関してIEEE 754規格に準拠していません。このため、Oracleによる演算結果とJavaによる演算結果に小さな誤差が生じることがあります。

Oracleでは、10進数演算と互換性のある形式で数値を格納し、小数点以下38桁までの精度を保証しています。このため、0(ゼロ)、無限大の負数、無限大の正数を正確に表現できます。各正数に対して、同じ絶対値の負数も表せます。

10-30から(1 – 10-38) * 10126を38桁の完全精度で表せます。

DatabaseMetaDataコールへのCatalog引数

特定のDatabaseMetaDataメソッドによりcatalogパラメータが定義されます。このパラメータは、そのメソッドの選択条件の1つです。Oracleには複数カタログはありませんが、複数パッケージはあります。


関連項目:

Oracle JDBCドライバによるcatalog引数の処理方法の詳細は、「DatabaseMetaData TABLE_REMARKSレポート」を参照してください。

SQLWarningクラス

java.sql.SQLWarningクラスは、データベースのアクセス警告に関する情報を提供します。警告には、通常、警告の説明と警告を識別するコードが含まれます。警告は、オブジェクトが報告される原因になったメソッドに、通知なしで関連付けられます。Oracle JDBCドライバは、通常、SQLWarningをサポートしません。その例外として、スクロール可能な結果セットの操作ではSQL警告が生成されますが、SQLWarningインスタンスは、データベース内でなくクライアント上で作成されます。


関連項目:

「SQL例外の処理」

DDL文の実行

Data Definition Language (DDL)文は、Statementオブジェクトとともに実行する必要があります。PreparedStatementsオブジェクトまたはCallableStatementsオブジェクトを使用する場合、DDL文は初回の実行時にのみ有効です。SQL文が文キャッシュ内にある場合、これにより予期しない動作になる可能性があります。

名前付きパラメータのバインド

setXXXメソッドを使用する場合、名前によるバインドはサポートされていません。特定の環境下では、以前のバージョンのOracle JDBCドライバは、setXXXメソッドの使用時にも名前によって文変数をバインドできました。次の文では、名前付き変数EmpIdが整数314159とバインドされます。

PreparedStatement p = conn.prepareStatement
  ("SELECT name FROM emp WHERE id = :EmpId");
  p.setInt(1, 314159);

set XXXメソッドを使用して名前を基準にバインドするこの機能は、JDBC仕様には含まれず、Oracleではサポートされません。JDBCドライバは、SQLExceptionをスローしたり、予想外の結果になったりすることがあります。Oracle Database 10g のJDBCドライバ以降、名前を基準としたバインドはsetXXXAtNameメソッドを使用してサポートされています。

executeメソッドをコールするまで、ドライバはバインド値をコピーしません。このためexecuteメソッドをコールする前にバインド値を変更すると、バインド値が変更されることがあります。たとえば、次のコードを考えてみましょう。

PreparedStatement p;
.......
Date d = new Date(1181676033917L);
p.setDate(1, d);
d.setTime(0);
p.executeUpdate();

このコードはデータベースにDate(1181676033917L)でなくDate(0)を挿入します。これは、パフォーマンス上の理由でJDBCドライバ実装によりバインド値がコピーされていないためです。