A JDBCリファレンス情報
この付録では、Java Database Connectivity(JDBC)リファレンス詳細情報について説明します。内容は次のとおりです。
A.1 サポートされているSQLとJDBCデータ型のマッピング
次の表は、特定のSQLデータ型のマッピング先として有効な、すべてのJava型のリストです。Oracle JDBCドライバでは、これらの非デフォルト・マッピングをサポートしています。たとえば、SQL CHARデータをoracle.sql.CHARオブジェクトとしてインスタンス化するには、getCHARメソッドを使用します。java.math.BigDecimalオブジェクトとしてインスタンス化するには、getBigDecimalメソッドを使用します。
ノート:
oracle.jdbc.OracleDataがイタリックで表示されているクラスは、Oracle JVM Webサービス・コールアウト・ユーティリティで生成できます。
表A-1 有効なSQLデータ型-Javaクラス・マッピング
| SQLデータ型 | Java型 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
REF CURSOR |
j
|
|
ユーザー定義の名前付き型、ADT |
|
|
opaque名前付き型 |
|
|
NESTED TABLEおよびVARRAY名前付き型 |
|
|
名前付き型の参照 |
|
脚注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型にする必要があります。
A.2 サポートされているSQLおよびPL/SQLデータ型
この項の表は、SQLとPL/SQLのデータ型、およびこれらのデータ型のOracle JDBCドライバのサポート状況のリストです。次の表は、SQLデータ型に対するOracle JDBCドライバのサポート状況のリストです。
表A-2 SQLデータ型に対するサポート
| SQLデータ型 | JDBCドライバによるサポート |
|---|---|
|
BFILE |
可 |
|
BLOB |
可 |
|
CHAR |
可 |
|
CLOB |
可 |
|
DATE |
可 |
|
NCHAR |
不可脚注7 |
|
NCHAR VARYING |
不可 |
|
NUMBER |
可 |
|
NVARCHAR2 |
可脚注8 |
|
RAW |
可 |
|
REF |
可 |
|
ROWID |
可 |
|
UROWID |
不可 |
|
VARCHAR2 |
可 |
脚注7
NCHAR型が間接的にサポートされています。対応するjava.sql.Types型はありませんが、アプリケーションがformOfUse(NCHAR)メソッドをコールする場合には、これらの型にアクセスできます。
脚注8
JSE 6では、NVARCHAR2型が間接的にサポートされています。J2SE 5.0では、NVARCHAR2型が間接的にサポートされています。対応するjava.sql.Types型はありませんが、アプリケーションがformOfUse(NCHAR)メソッドをコールする場合には、これらの型にアクセスできます。
次の表は、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 |
可 |
次の表は、SQLユーザー定義型に対するOracle JDBCドライバのサポート状況のリストです。
表A-4 SQLユーザー定義型に対するサポート
| SQLユーザー定義型 | JDBCドライバによるサポート |
|---|---|
|
OPAQUE |
可 |
|
参照型 |
可 |
|
オブジェクト型( |
可 |
|
NESTED TABLE型およびVARRAY型 |
可 |
次の表は、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 |
可 |
|
BOOLEAN |
可 |
|
スカラー文字列型 |
|
|
CHAR |
可 |
|
CHARACTER |
可 |
|
LONG |
可 |
|
LONG RAW |
可 |
|
NCHAR |
不可(「ノート」を参照) |
|
NVARCHAR2 |
不可(「ノート」を参照) |
|
RAW |
可 |
|
ROWID |
可 |
|
STRING |
可 |
|
UROWID |
不可 |
|
VARCHAR |
可 |
|
VARCHAR2 |
可 |
|
DATE |
可 |
|
コンポジット型 |
|
|
RECORD |
不可 |
|
TABLE |
不可 |
|
VARRAY |
可 |
|
参照型: |
|
|
REF CURSOR型 |
可 |
|
オブジェクト参照型 |
可 |
|
LOB型: |
|
|
BFILE |
可 |
|
BLOB |
可 |
|
CLOB |
可 |
|
NCLOB |
可 |
ノート:
-
NATURAL、NATURALn、POSITIVE、POSITIVEnおよびSIGNTYPE型は、BINARY INTEGERのサブタイプです。 -
DEC、DECIMAL、DOUBLE PRECISION、FLOAT、INT、INTEGER、NUMERIC、REALおよびSMALLINT型は、NUMBERのサブタイプです。 -
NCHAR型およびNVARCHAR2型は間接的にサポートされています。対応するjava.sql.Types型はありませんが、アプリケーションがformOfUse(NCHAR)をコールする場合には、これらの型にアクセスできます。
A.3 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>)を使用する必要があります。
次のコードでは、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配列の値を取得する方法を示します。
この例では、java.sql.Structオブジェクトのjava.sql.Arrayを戻します。そのStruct要素はそれぞれEMPLOYEES表の1行を表します。
例A-1 データベース表の行のための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.4 埋込みJDBCエスケープ構文の使用
Oracle JDBCドライバは、いくつかの埋込みJDBCエスケープ構文(中カッコで囲んで指定する構文)をサポートしています。現在のサポートは初歩的なものです。
ノート:
JDBCエスケープ構文は、以前はSQL92構文またはSQL92エスケープ構文と呼ばれていました。
この項では、ドライバによって提供される次の構文のサポートについて説明します。
ドライバのサポートが制限されている場合、これらの項では、選択可能な回避策についても説明します。
エスケープ処理の無効化
A.4.1 時刻および日付リテラル
A.4.1.1 日付リテラル
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));
A.4.1.2 時刻リテラル
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'}");
A.4.1.3 タイムスタンプ・リテラル
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.DATEをjava.sql.Timestampにマップしてtimeコンポーネントを維持していました。Oracle Database 9.0.1で初めてTIMESTAMPのサポートが含まれ、9i JDBCドライバがoracle.sql.DATEをjava.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データへのOracleDATEデータのマッピングが可能になっています。ユーザーは、このフラグの値をtrueに設定することによって、OracleDATEデータのtimeコンポーネントを維持できていました。このフラグは11g以降はサポートされなくなりました。それにより制御されるOracle Database 8iとの互換性がもうサポートされないためです。
A.4.2 スカラー関数
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をサポートしています。
A.4.3 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 empWHERE ename LIKE '\\_%' {escape '\\'}");
A.4.4 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();
関連トピック
A.4.5 外部結合
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");
A.4.7 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')
A.5 Oracle JDBCのノートおよび制限事項
A.5.6 DDL文の実行
Data Definition Language (DDL)文は、Statementオブジェクトとともに実行する必要があります。PreparedStatementsオブジェクトまたはCallableStatementsオブジェクトを使用する場合、DDL文は初回の実行時にのみ有効です。SQL文が文キャッシュ内にある場合、これにより予期しない動作になる可能性があります。
A.5.7 名前付きパラメータのバインド
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ドライバ実装によりバインド値がコピーされていないためです。