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

前
 
次
 

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.jdbc.OracleDataがイタリックで表示されているクラスでは、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.jdbc.OracleBlob脚注1 

CLOB

oracle.jdbc.OracleClob脚注2 

BFILE

oracle.sql.BFILE

ROWID

oracle.sql.ROWID

TIMESTAMP

oracle.sql.TIMESTAMP

TIMESTAMPWITHTIMEZONE

oracle.sql.TIMESTAMPTZ

TIMESTAMPWITHLOCALTIMEZONE

oracle.sql.TIMESTAMPLTZ

REFカーソル

java.sql.ResultSet

sqlj.runtime.ResultSetIterator

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

oracle.jdbc.OracleStruct脚注3 

opaque名前付き型

oracle.jdbc.OracleOpaque脚注4 

NESTED TABLEおよびVARRAY名前付き型

oracle.jdbc.OracleArray脚注5 

名前付き型の参照

oracle.jdbc.OracleRef脚注6 


脚注 1  Oracle Database 12cリリース1 (12.1)以降、oracle.sql.BLOBクラスは非推奨となり、oracle.jdbc.OracleBlobインタフェースに置き換えられています。

脚注 2  Oracle Database 12cリリース1 (12.1)以降、oracle.sql.CLOBクラスは非推奨となり、oracle.jdbc.OracleClobインタフェースに置き換えられています。

脚注 3  Oracle Database 12cリリース1 (12.1)以降、oracle.sql.STRUCTクラスは非推奨となり、oracle.jdbc.OracleStructインタフェースに置き換えられています。

脚注 4  Oracle Database 12cリリース1 (12.1)以降、oracle.sql.OPAQUEクラスは非推奨となり、oracle.jdbc.OracleOpaqueインタフェースに置き換えられています。

脚注 5  Oracle Database 12cリリース1 (12.1)以降、oracle.sql.ARRAYクラスは非推奨となり、oracle.jdbc.OracleArrayインタフェースに置き換えられています。

脚注 6  Oracle Database 12cリリース1 (12.1)以降、oracle.sql.REFクラスは非推奨となり、oracle.jdbc.OracleRefインタフェースに置き換えられています。


注意:

  • 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データ型には、次のカテゴリがあります。

  • スカラー型

  • スカラー文字列型(DATEデータ型を含みます。)

  • コンポジット型

  • 参照型

  • ラージ・オブジェクト(LOB)型

表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

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)をコールする場合には、これらの型にアクセスできます。詳細は、「NCHAR、NVARCHAR2、NCLOBおよびdefaultNCharプロパティ」を参照してください。


PL/SQLタイプの使用

Oracle Database 12cリリース1 (12.1)以降、スキーマ・レベルのPL/SQLタイプを汎用のjava.sql.Structタイプとして、PL/SQLコレクションをjava.sql.Arrayタイプとしてマップできます。そのため、バインディング用にPL/SQLパッケージ・タイプにマップされるスキーマ・レベルのタイプを作成するかわりに、JDBC APIのみを使用して、PL/SQLタイプの記述およびバインドを行うことができます。

たとえば、Connection.createStruct(type_name)メソッドをコールして、まずPL/SQLタイプの記述に使用できる記述子を作成し、次にクライアントでこのタイプの新しいSTRUCT表現を作成することができます。Oracle Database 12cリリース1 (12.1)以降、type_name”schema.package.typename”または”package.typename”として指定して、このAPIを再利用できます。

PL/SQLパッケージ・タイプはすべて、システム全体で一意の名前にマップされます。この名前は、サーバー側のタイプ・メタデータを取得するためにJDBCで使用できます。名前の形式は次のとおりです。

[SCHEMA.]<PACKAGE>.<TYPE>

注意:

スキーマがパッケージ名と同じ場合、また、PL/SQLタイプと同じ名前のタイプがある場合、2つのパート名の形式(<package>.<type>)のオブジェクトを識別できません。このような場合、3つのパート名(<schema>.<package>.<type>)を使用する必要があります。

例A-1では、PL/SQLパッケージで宣言されたタイプをバインドする方法を説明しています。

例A-1 PL/SQLパッケージで宣言されたタイプのバインド

/*
---------------------------
# Perform the following SQL operations prior to running this sample
---------------------------
conn HR/hr;
create or replace package TEST_PKG is
   type V_TYP is varray(10) of varchar2(200);
   type R_TYP is record(c1 pls_integer, c2 varchar2(100));
   procedure VARR_PROC(p1 in V_TYP, p2 OUT V_TYP);
   procedure REC_PROC(p1 in R_TYP, p2 OUT R_TYP);
end;
/
create or replace package body TEST_PKG is
 procedure VARR_PROC(p1 in V_TYP, p2 OUT V_TYP) is
  begin
    p2 := p1;
  end;
  procedure REC_PROC(p1 in R_TYP, p2 OUT R_TYP) is
  begin
    p2 := p1;
  end;
end;
/ 
*/

import java.sql.Array;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Struct;
import java.sql.Types;
 
import oracle.jdbc.OracleConnection;
public class PLSQLTypesSample
{
  public static void main(String[] args) throws SQLException
  {
    System.out.println("begin...");
    Connection conn = null;
    oracle.jdbc.pool.OracleDataSource ods = new oracle.jdbc.pool.OracleDataSource();
    ods.setURL("jdbc:oracle:oci:localhost:5521:orcl");
    ods.setUser("HR");
    ods.setPassword("hr"); 
    //get connection
    conn = ods.getConnection();
 
    //call procedure TEST_PKG.VARR_PROC
    CallableStatement cstmt = null;
    try {
      cstmt = conn.prepareCall("{ call TEST_PKG.VARR_PROC(?,?) }");
      //PLSQL VARRAY type binding
      Array arr = ((OracleConnection)conn).createArray("TEST_PKG.V_TYP", new String[]{"A", "B"});
      cstmt.setArray(1, arr);
      cstmt.registerOutParameter(2, Types.ARRAY, "TEST_PKG.V_TYP");
      cstmt.execute();
      //get PLSQL VARRAY type out parameter value
      Array outArr = cstmt.getArray(2);
      //... 
    }
    catch( Exception e) {
      e.printStackTrace();
    }finally {
      if (cstmt != null)
        cstmt.close();
    }
 
    //call procedure TEST_PKG.REC_PROC
    try {
      cstmt = conn.prepareCall("{ call TEST_PKG.REC_PROC(?,?) }");
      //PLSQL RECORD type binding
      Struct struct = conn.createStruct("TEST_PKG.R_TYP", new Object[]{12345, "B"});
      cstmt.setObject(1, struct);
      cstmt.registerOutParameter(2, Types.STRUCT, "TEST_PKG.R_TYP");
      cstmt.execute();
      //get PLSQL RECORD type out parameter value
      Struct outStruct = (Struct)cstmt.getObject(2);
      //... 
    }
    catch( Exception e) {
      e.printStackTrace();
    }finally {
      if (cstmt != null)
        cstmt.close();
    }
    
    if (conn != null) 
      conn.close(); 
      
    System.out.println("done!");
  }
}

%ROWTYPE属性を使用する各行のJavaレベルのオブジェクトの作成方法

%ROWTYPE属性を使用して、Javaレベルのオブジェクトを作成できます。この場合、表の各行はjava.sql.Structオブジェクトとして作成されます。たとえば、パッケージpack1では、次のように指定します。


関連項目:

%ROWTYPE属性の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。

CREATE OR REPLACE PACKAGE PACK1 AS
  TYPE EMPLOYEE_ROWTYPE_ARRAY IS TABLE OF EMPLOYEES%ROWTYPE;
END PACK1;
/

次のコードの抜粋に、JDBC APIを使用してEMPLOYEE_ROWTYPE_ARRAY配列の値を取得する方法を示します。

例A-2 データベース表の行のためのSTRUCTオブジェクトの作成

CallableStatement cstmt = conn.prepareCall("BEGIN SELECT * BULK COLLECT INTO :1 FROM EMPLOYEE; END;");
cstmt.registerOutParameter(1,OracleTypes.ARRAY, "PACK1.EMPLOYEE_ROWTYPE_ARRAY");
cstmt.execute();
Array a = cstmt.getArray(1);

例A-2では、java.sql.Structオブジェクトのjava.sql.Arrayを戻します。そのStruct要素はそれぞれEMPLOYEES表の1行を表します。

埋込み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("HR");
ods.setPassword("hr");
Connection conn = ods.getConnection();

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

// Select the first name column from the employees table where the hire date is Jan-23-1982
ResultSet rset = stmt.executeQuery 
                 ("SELECT first_name FROM employees WHERE hire_date = {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 first_name FROM employees WHERE hire_date = {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 first_name FROM employees WHERE hire_date = {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 11gリリース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 '\\'}");

MATCH_RECOGNIZE句

?の文字は、Oracle Database 11g以上のバージョンでMATCH_RECOGNIZE句でのトークンとして使用されます。JDBC標準が?文字をパラメータ・マーカーとして定義するため、JDBCドライバおよびServer SQLエンジンは同じトークンの異なる使用を区別できません。

旧バージョンのJDBCドライバでは、?文字をパラメータ・マーカーではなくMATCH_RECOGNIZEトークンとして変換する場合、PreparedStatementのかわりにStatementを使用してエスケープ処理を無効にする必要があります。ただし、Oracle Database 12cリリース1 (12.1.0.2)以降からは、?文字を使用すると同時に'{\ ... \}'構文を使用することで、JDBCドライバでパラメータ・マーカーとして処理されることなく、SQLエンジンで処理できます。次のコード・スニペットは、'{\ ... \}'構文の使用方法を示しています。

  String sql =
    "select T.firstW, T.lastZ, ? " +  // use of parameter marker
    "from tkpattern_S11 " +
    "MATCH_RECOGNIZE ( " +
    "    MEASURES A.c1 as firstW, last(Z.c1) as lastZ " +
    "    ALL MATCHES " +
    "    PATTERN(A{\?\} X{\*?\} Y{\+?\} Z{\??\}) " +  // use of escape sequence
    "    DEFINE " +
    "        X as X.c2 > prev(X.c2), " +
    "        Y as Y.c2 < prev(Y.c2), " +
    "        Z as Z.c2 > prev(Z.c2)" +
    ") as T";
  PreparedStatement ps = conn.prepareStatatement(sql);
  ps.setString(1, "test");
  ResultSet rs = ps.executeQuery();

外部結合

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構文で+を使用してください。

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ドライバ実装によりバインド値がコピーされていないためです。