この章では、Oracle Java Database Connectivity(JDBC)ドライバ・バージョン、データベース・バージョンおよびJava Development Kit(JDK)バージョン間の互換性について説明します。また、クライアント・インストールと構成のテスト、および簡単なアプリケーションの実行方法の基本を説明します。この章の内容は次のとおりです。
この項では、一般的なJDBCバージョンの互換性について説明します。
下位互換性
JDBCドライバは、現在サポートされているバージョンのOracle Databaseで動作することが確認されています。たとえば、Oracle Database 11gリリース2(11.2)JDBC Thinドライバは、Oracle Databaseリリース10.2.x、10.1.x、9.2.xおよび9.0.1.xで動作します。ただし、8.0.xおよび7.xなどの旧リリースですでにサポート期間が終了しているデータベース・リリースへの接続はサポートしません。
上位互換性
既存のサポートされているJDBCドライバは、Oracle Database 11gリリース2(11.2)で動作することが確認されています。
|
注意:
|
JDBCクライアント・インストールを検証するには、次の操作をすべて実行する必要があります。
Oracle JDBCドライバのインストールは、プラットフォームによって異なります。プラットフォーム固有の情報が記載されたマニュアルの、ドライバのインストール手順に従ってください。
この項では、選択したドライバのインストールが完了しているものとして、JDBCドライバのOracleクライアントのインストールを検証する手順を説明します。
JDBC Thinドライバのインストールを行った場合は、クライアント・コンピュータにその他のインストールは必要ありません。
|
注意: JDBC Thinドライバでは、データベースがインストールされているコンピュータ上にTCP/IPリスナーが必要です。 |
JDBC Oracle Call Interface(OCI)ドライバのインストールを行った場合は、Oracleクライアント・ソフトウェアもインストールする必要があります。これには、Oracle NetおよびOCIライブラリが含まれます。
Oracle Java製品をインストールすると、次のディレクトリが作成されます。
ORACLE_HOME/jdbc
ORACLE_HOME /jlib
次のディレクトリおよびファイルがORACLE_HOME/jdbcディレクトリに作成および格納されているかどうかを確認してください。
demo
このディレクトリには、圧縮ファイルdemo.zipまたはdemo.tarが格納されています。この圧縮ファイルを解凍すると、samplesディレクトリおよびSamples-Readme.txtファイルが作成されます。samplesディレクトリには、JDBCエスケープ構文とOracle SQLの構文、PL/SQLブロック、ストリーム、ユーザー定義型、追加Oracle型拡張機能、Oracleパフォーマンス拡張機能の使用方法の例などのサンプル・プログラムが格納されています。
doc
このディレクトリには、Oracle JDBC Application Program Interface(API)のドキュメントであるjavadoc.zipファイルが格納されています。
lib
libディレクトリには、次のような必須Javaクラスが格納されています。
orai18n.jarおよびorai18n-mapping.jar
グローバリゼーション用およびマルチバイト・キャラクタ・セット・サポート用のクラスが含まれています。
ojdbc5.jar、ojdbc5_g.jar、ojdbc6.jarおよびojdbc6_g.jar
JDK 1.5およびJDK 1.6で使用するためのJDBCドライバ・クラスが含まれています。
|
注意:
|
Readme.txt
製品の他のドキュメントで説明されていない、ドライバに関するリリース固有の最新情報が記載されています。
次のディレクトリがORACLE_HOME /jlibディレクトリに作成され、ファイルが格納されているかどうか確認してください。
jta.jarおよびjndi.jar
これらのファイルには、Java Transaction API(JTA)とJava Naming and Directory Interface(JNDI)のためのクラスが含まれています。これらのファイルが必要になるのは、分散トランザクション管理のためのJTA機能、またはネーミング・サービスのためのJNDI機能を使用する場合のみです。
|
注意: Sun社のWebサイトからもこれらのファイルを入手できます。しかし、Oracleドライバでテスト済のOracle提供のバージョンを使用することをお薦めします。 |
ons.jar
このJARファイルには、Oracle Notification Servicesのクラスが含まれています。このファイルは、高速アプリケーション通知(FAN)を使用して、他のプロセスに構成やサービス・レベルの情報について通知する場合に必要です。
この項では、主にSun Solaris、LinuxおよびMicrosoft Windowsプラットフォームに関して、JDBC OCIドライバとJDBC Thinドライバのために設定する必要がある環境変数について説明します。
インストールしたJDBC OCIまたはThinドライバ用のCLASSPATH環境変数を設定する必要があります。CLASSPATH環境変数には次のものを含めます。
ORACLE_HOME/jdbc/lib/ojdbc5.jar ORACLE_HOME/jlib/orai18n.jar
|
注意: JTA機能およびJNDI機能を使用する場合は、jta.jarとjndi.jarもCLASSPATH環境変数に指定する必要があります。 |
JDBC OCIドライバ
JDBC OCIドライバをインストールする場合は、ライブラリ・パス環境変数に次の値を設定する必要もあります。
Sun SolarisまたはLinuxの場合は、LD_LIBRARY_PATH環境変数を次のように設定します。
ORACLE_HOME/lib
このディレクトリには、libocijdbc11.so共有オブジェクト・ライブラリが格納されます。
|
注意: 64ビットのクライアントまたはデータベースに対して32ビットのJava仮想マシン(JVM)を動作させる場合は、ORACLE_HOME/lib32もLD_LIBRARY_PATH環境変数に追加する必要があります。 |
Microsoft Windowsでは、次のようにPATH環境変数を設定します。
ORACLE_HOME\bin
このディレクトリには、ocijdbc11.dll動的リンク・ライブラリが格納されます。
ライブラリ・パス環境変数にJDBC OCI Instant Clientデータ共有ライブラリを指定すると、すべてのJDBC OCIデモ用プログラムをInstant Clientモードで実行できます。
JDBC Thinドライバ
JDBC Thinドライバをインストールする場合は、他の環境変数を指定する必要はありません。ただし、JDBCサーバー側Thinドライバを使用するには、許可を設定する必要があります。
サーバー側Thinドライバの許可の設定
JDBCサーバー側Thinドライバは、データベースへの接続用のソケットをオープンします。Oracle DatabaseではJavaセキュリティ・モデルを施行しているため、SocketPermissionオブジェクトについてチェックが実行されます。
JDBCサーバー側Thinドライバを使用するには、接続するユーザーに適切な許可を付与する必要があります。次の例は、ユーザーSCOTTに許可を付与する方法を示しています。
CREATE ROLE jdbcthin;
CALL dbms_java.grant_permission('JDBCTHIN', 'java.net.SocketPermission', '*', 'connect');
GRANT jdbcthin TO SCOTT;
grant_permissionコールのJDBCTHINは大文字で指定する必要があることに注意してください。アスタリスク(*)はパターンです。特定のコンピュータまたはポートのみに接続する許可を付与してユーザーへの許可を制限できます。
|
関連項目: 『Oracle Database Java開発者ガイド』 |
Javaがクライアント・システムで正しく設定されたことを確認するには、ORACLE_HOME/jdbc/demoの下のsamplesディレクトリに移動します。次に、コマンドラインで次のコマンドを順に入力して、JavaコンパイラおよびJavaインタプリタがエラーなく実行されていることを確認します。
javac java
これらの各コマンドは、オプションとパラメータのリストを表示して終了します。可能であれば、jdbc/demo/samples/generic/SelectExampleなどの簡単なテスト・プログラムを使用して、コンパイルと実行の確認をしてください。
インストールしたJDBCドライバのバージョンを確認するには、OracleDatabaseMetaDataクラスのgetDriverVersionメソッドをコールします。
次のサンプル・コードは、ドライバのバージョンを確認する方法を示しています。
import java.sql.*;
import oracle.jdbc.*;
import oracle.jdbc.pool.OracleDataSource;
class JDBCVersion
{
public static void main (String args[]) throws SQLException
{
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:scott/tiger@<host>:<port>:<service>");
Connection conn = ods.getConnection();
// Create Oracle DatabaseMetaData object
DatabaseMetaData meta = conn.getMetaData();
// gets driver info:
System.out.println("JDBC driver version is " + meta.getDriverVersion());
}
}
次のコマンドを実行すると、JDBCドライバのバージョンを確認できます。
java -jar ojdbc5.jar
java -jar ojdbc6.jar
samplesディレクトリには、特定のOracle JDBCドライバ用のサンプル・プログラムが格納されています。その1つであるJdbcCheckup.javaは、JDBCおよびデータベース接続のテスト用です。このプログラムには、ユーザー名、パスワードおよび接続するデータベース名の入力が必要です。このプログラムは、データベースに接続し、「Hello World」という文字列の問合せを行い、それを画面に出力します。
samplesディレクトリでJdbcCheckup.javaプログラムをコンパイルして実行します。問合せの結果の画面出力でエラーが発生しなければ、JavaおよびJDBCは正しくインストールされています。
JdbcCheckup.javaは簡単なプログラムですが、次の操作を実行することにより、いくつかの重要な機能を示します。
JDBCクラスを含む、必要なJavaクラスのインポート
DataSourceインスタンスの作成
データベースへの接続
単純な問合せの実行
問合せ結果の画面への出力
JDBC OCIドライバを使用するJdbcCheckup.javaプログラムは次のとおりです。
/*
* This sample can be used to check the JDBC installation.
* Just run it and provide the connect information. It will select
* "Hello World" from the database.
*/
// You need to import the java.sql and JDBC packages to use JDBC
import java.sql.*;
import oracle.jdbc.*;
import oracle.jdbc.pool.OracleDataSource;
// We import java.io to be able to read from the command line
import java.io.*;
class JdbcCheckup
{
public static void main(String args[]) throws SQLException, IOException
{
// Prompt the user for connect information
System.out.println("Please enter information to test connection to
the database");
String user;
String password;
String database;
user = readEntry("user: ");
int slash_index = user.indexOf('/');
if (slash_index != -1)
{
password = user.substring(slash_index + 1);
user = user.substring(0, slash_index);
}
else
password = readEntry("password: ");
database = readEntry("database(a TNSNAME entry): ");
System.out.print("Connecting to the database...");
System.out.flush();
System.out.println("Connecting...");
// Open an OracleDataSource and get a connection
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:oci:@" + database);
ods.setUser(user);
ods.setPassword(password);
Connection conn = ods.getConnection();
System.out.println("connected.");
// Create a statement
Statement stmt = conn.createStatement();
// Do the SQL "Hello World" thing
ResultSet rset = stmt.executeQuery("select 'Hello World' from dual");
while (rset.next())
System.out.println(rset.getString(1));
// close the result set, the statement and the connection
rset.close();
stmt.close();
conn.close();
System.out.println("Your JDBC installation is correct.");
}
// Utility function to read a line from standard input
static String readEntry(String prompt)
{
try
{
StringBuffer buffer = new StringBuffer();
System.out.print(prompt);
System.out.flush();
int c = System.in.read();
while (c != '\n' && c != -1)
{
buffer.append((char)c);
c = System.in.read();
}
return buffer.toString().trim();
}
catch(IOException e)
{
return "";
}
}
}
JDBCクライアント・インストールの検証が完了すると、JDBCアプリケーションの作成を開始できます。Oracle JDBCドライバを使用する場合は、プログラムに特定のドライバ固有情報を含める必要があります。この項では、ドライバ固有情報の追加場所と追加方法について、チュートリアルの形式で説明します。チュートリアルは、クライアントからデータベースへの接続および問合せを行うコードを作成する方法を、手順を追って説明します。
次のタスクを実行するコードを記述する必要があります。
|
注意: 最初の3つのタスク用のOracleドライバ固有情報を指定して、プログラムがJDBC Application Program Interface(API)を使用してデータベースにアクセスできるようにします。その他のタスクについては、Javaアプリケーションの場合と同様に、標準JDBC Javaコードを使用できます。 |
使用するOracle JDBCドライバの種類にかかわらず、表2-1に示されているimport文をプログラムの最初に記述する必要があります。
表2-1 JDBCドライバ用のimport文
| import文 | 提供パッケージ |
|---|---|
|
標準のJDBCパッケージ |
|
|
|
|
|
|
JDBCに対するOracleの拡張機能。これはオプションです。
Oracle型拡張機能。これはオプションです。 |
オプションとなっているOracleパッケージは、Oracle JDBCドライバの拡張機能へのアクセスを提供しますが、この項の例には必要ありません。
|
注意: ワイルド・カードのアスタリスク(*)は使用せずに、アプリケーションに必要なクラスのみをインポートすることをお薦めします。このガイドでは簡単にするためにアスタリスク(*)を使用していますが、クラスおよびインタフェースのインポート方法としてはお薦めしません。 |
最初に、OracleDataSourceインスタンスを作成する必要があります。次に、OracleDataSource.getConnectionメソッドを使用してデータベースへの接続をオープンします。取り出した接続のプロパティは、OracleDataSourceインスタンスから導出されたものです。URL接続プロパティを設定した場合は、TNSEntryName、DatabaseName、ServiceName、ServerName、PortNumber、Network Protocolおよびドライバのタイプを含む他のプロパティはすべて無視されます。
次のコードは、データソースのURL、ユーザー名およびパスワードを設定します。
OracleDataSource ods = new OracleDataSource(); ods.setURL(url); ods.setUser(user); ods.setPassword(password);
次の例では、JDBC Thinドライバを使用して、パスワードがtigerのユーザーscottを、サービス名がorclのデータベースに、ホストmyhostのポート1521経由で接続します。
OracleDataSource ods = new OracleDataSource();
String url = "jdbc:oracle:thin:@//myhost:1521/orcl",
ods.setURL(url);
ods.setUser("scott");
ods.setPassword("tiger");
Connection conn = ods.getConnection();
|
注意: 引数で指定されたユーザー名とパスワードは、URLで指定されたユーザー名とパスワードをオーバーライドします。 |
次の例では、JDBC Oracle Call Interface(OCI)ドライバを使用して、パスワードがtigerのユーザーscottを、Transparent Network Substrate(TNS)エントリがmyTNSEntryであるデータベース・ホストに接続します。この場合、URLは、ユーザー名とパスワードを含む、唯一の入力パラメータです。
String url = "jdbc:oracle:oci:scott/tiger@myTNSEntry"); ods.setURL(url); Connection conn = ods.getConnection();
Thinドライバを使用して接続する場合は、ポート番号を指定する必要があります。たとえば、ポート1521上にTCP/IPリスナーを持つホストmyhost上のデータベースに接続し、サービス識別子がorclである場合は、次のようなコードを記述します。
String URL = "jdbc:oracle:thin:scott/tiger@//myhost:1521/orcl"); ods.setURL(URL); Connection conn = ods.getConnection();
データベースに接続し、そのプロセスでConnectionオブジェクトを作成した後、次に、Statementオブジェクトを作成します。JDBC ConnectionオブジェクトのcreateStatementメソッドは、JDBC Statement型のオブジェクトを返します。前の項の、Connectionオブジェクトconnが作成された例の続きとして、Statementオブジェクトを作成する方法の例を示します。
Statement stmt = conn.createStatement();
データベースへの問合せを行う場合、StatementオブジェクトのexecuteQueryメソッドを使用します。このメソッドは、入力としてSQL文を受け取り、JDBC ResultSetオブジェクトを戻します。
|
注意:
|
この例のStatementオブジェクトstmt作成後の次の処理は、問合せを実行し、EMPという従業員の表のename列の内容が含まれたResultSetオブジェクトを戻すことです。
ResultSet rset = stmt.executeQuery ("SELECT ename FROM emp");
問合せの実行後は、ResultSetオブジェクトのnext()メソッドを使用して結果を反復します。このメソッドは、結果セットを行ごとに進み、結果セットの最後に達するとそれを検出します。
結果セット内を反復しながらデータを引き出すには、ResultSetオブジェクトの適切なgetXXXメソッドを使用します。このXXXには、Javaのデータ型が対応します。
たとえば、次のコードは、以前の項のResultSetオブジェクトrset内を反復して、各従業員名の取出しおよび出力を行います。
while (rset.next()) System.out.println (rset.getString(1));
next()メソッドは、結果セットの最後に達するとfalseを戻します。従業員名は、Java String値として実体化されます。
ResultSetとStatementオブジェクトの使用後に、明示的にこれらをクローズする必要があります。これは、Oracle JDBCドライバの使用時に作成した、すべてのResultSetおよびStatementオブジェクトに適用されます。ドライバには、ファイナライザ・メソッドがありません。クリーン・アップ・ルーチンは、ResultSetおよびStatementクラスのcloseメソッドで実行されます。明示的にResultSetおよびStatementオブジェクトをクローズしないと、深刻なメモリー・リークが発生する場合があります。また、データベースのカーソルが不足します。結果セットと文の両方をクローズすると、データベース内の対応するカーソルが解放されます。結果セットのみをクローズすると、カーソルは解放されません。
たとえば、ResultSetオブジェクトがrsetで、Statementオブジェクトがstmtの場合は、次のコードの行を使用して結果セットと文をクローズできます。
rset.close(); stmt.close();
指定したConnectionオブジェクトが作成するStatementオブジェクトをクローズする場合、接続自体はオープンしたままになります。
|
注意: 一般に、close文はfinally句に書き込みます。 |
DML操作
INSERT操作またはUPDATE操作などのDML(データ操作言語)操作を実行するには、StatementオブジェクトまたはPreparedStatementオブジェクトのいずれかを作成します。PreparedStatementオブジェクトによって、様々な入力パラメータのセットで文を実行できます。JDBC ConnectionオブジェクトのprepareStatementメソッドを使用すると、様々なバインド・パラメータを取り、文定義でJDBC PreparedStatementオブジェクトを戻す文を定義できます。
データベースに送信するプリコンパイルされたSQL文にデータをバインドするには、PreparedStatementでsetXXXメソッドを使用します。
次の例では、プリコンパイルされたSQL文を使用して、EMP表に2行を追加するINSERT操作を実行する方法を示します。
// Prepare to insert new names in the EMP table
PreparedStatement pstmt = null;
try{
pstmt = conn.prepareStatement ("insert into EMP (EMPNO, ENAME) values (?, ?)");
// Add LESLIE as employee number 1500
pstmt.setInt (1, 1500); // The first ? is for EMPNO
pstmt.setString (2, "LESLIE"); // The second ? is for ENAME
// Do the insertion
pstmt.execute ();
// Add MARSHA as employee number 507
pstmt.setInt (1, 507); // The first ? is for EMPNO
pstmt.setString (2, "MARSHA"); // The second ? is for ENAME
// Do the insertion
pstmt.execute ();
}
finally{
if(pstmt!=null)
// Close the statement
pstmt.close();
}
DDL操作
データ定義言語(DDL)操作を実行するには、StatementオブジェクトまたはPreparedStatementオブジェクトのいずれかを作成します。次の例では、Statementオブジェクトを使用してデータベースに表を作成する方法を示しています。
//create table EMP with columns EMPNO and ENAME
String query;
Statement stmt=null;
try{
query="create table EMP " +
"(EMPNO int, " +
"ENAME varchar(50))";
stmt = conn.createStatement();
stmt.executeUpdate(query);
}
finally{
//close the Statement object
stmt.close();
}
コードでDDL操作の再実行が必要な場合は、文を再実行する前に、その文をもう一度準備する必要があります。次の例では、再実行の前にDDL文を準備する方法を示しています。
//
PreparedStatement pstmt = null;
PreparedStatement tstmt = null;
try{
pstmt = conn.prepareStatement ("insert into EMP (EMPNO, ENAME) values (?, ?)");
// Add LESLIE as employee number 1500
pstmt.setInt (1, 1500); // The first ? is for EMPNO
pstmt.setString (2, "LESLIE"); // The second ? is for ENAME
// Do the insertion
pstmt.execute ();
tstmt = conn.prepareStatement("truncate table EMP");
tstmt.executeUpdate();
// Add MARSHA as employee number 507
pstmt.setInt (1, 507); // The first ? is for EMPNO
pstmt.setString (2, "MARSHA"); // The second ? is for ENAME
// Do the insertion
pstmt.execute ();
tstmt.close();
tstmt = conn.prepareStatement("truncate table EMP");
tstmt.executeUpdate();
}
finally{
if(pstmt!=null)
// Close the statement
pstmt.close();
}
デフォルトでは、データ操作言語(DML)操作は実行時に自動的にコミットされます。これは自動コミット・モードともいいます。ただし、Connectionオブジェクトでの次のメソッドのコールによって、自動コミット・モードを無効にできます。
conn.setAutoCommit(false);
自動コミット・モードを無効にした場合は、Connectionオブジェクトで適切なメソッドをコールして、変更を手動でコミットするか、ロールバックする必要があります。
conn.commit();
または
conn.rollback();
COMMIT操作またはROLLBACK操作は、直前のCOMMITまたはROLLBACK以降に実行されたすべてのDML文に影響を与えます。
|
注意:
|
トランザクションによりデータベースを更新すると、この更新に対応するREDOエントリが生成されます。Oracle Databaseでは、トランザクションの完了まで、このREDOを一時的にメモリーに保存します。トランザクションをコミットすると、ログ・ライター(LGWR)プロセスによりコミットのREDOエントリが、そのトランザクションにおけるすべての変更について累積したREDOエントリとともに、ディスクに書き込まれます。デフォルトでは、Oracle Databaseは、コールがクライアントに戻る前にREDOをディスクに書き込みます。アプリケーションはREDOエントリがディスクに保存されるまで待つ必要があるため、この動作によりコミットに待機時間が生じます。
アプリケーションに非常に高いトランザクション・スループットが必要で、コミット待機時間を短縮するためにコミットの永続性を犠牲にしてもよいという場合は、アプリケーションの必要に応じて、デフォルトのCOMMIT操作の動作を変更できます。COMMIT操作の動作は、次のオプションにより変更できます。
WAIT
NOWAIT
WRITEBATCH
WRITEIMMED
|
関連項目: これらのオプションの詳細は、次のWebサイトにあるOracle Javadocを参照してください。
|
これらのオプションを指定すると、コミット段階の2つの異なる面を制御できます。
COMMITコールが、サーバーによって処理されるまで待機するかどうか。これには、WAITオプションまたはNOWAITオプションを使用します。
ログ・ライターがコールをバッチ処理するかどうか。これには、WRITEIMMEDオプションまたはWRITEBATCHオプションを使用します。
異なるオプションを組み合せることもできます。たとえば、COMMITコールがサーバーによる処理を待たずに戻り、ログ・ライターがコミットをバッチ処理するようにするには、NOWAITオプションとWRITEBATCHオプションを一緒に使用します。たとえば、次のようになります。
((OracleConnection)conn).commit(
EnumSet.of(
OracleConnection.CommitOption.WRITEBATCH,
OracleConnection.CommitOption.NOWAIT));
|
注意: WAITオプションとNOWAITオプションは、逆の意味を持つため、一緒に使用できません。一緒に使用すると、JDBCドライバは例外をスローします。同じことが、WRITEIMMEDオプションとWRITEBATCHオプションにも当てはまります。 |
次の例は、前の項で説明した処理を例証するものです。Oracle JDBC Thinドライバを使用してデータソースを作成し、データベースに接続し、Statementオブジェクトを作成して問合せを実行し、結果セットを処理します。
Statementオブジェクトの作成、問合せの実行、ResultSetの戻りと処理、および文と接続のクローズを行うコードは、標準JDBC APIを使用していることに注意してください。
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.SQLException;
import oracle.jdbc.pool.OracleDataSource;
class JdbcTest
{
public static void main (String args []) throws SQLException
{
OracleDataSource ods = null;
Connection conn = null;
Statement stmt = null;
ResultSet rset = null;
// Create DataSource and connect to the local database
ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:@//myhost:1521/orcl");
ods.setUser("scott");
ods.setPassword("tiger");
conn = ods.getConnection();
try
{
// Query the employee names
stmt = conn.createStatement ();
rset = stmt.executeQuery ("SELECT ename FROM emp");
// Print the name out
while (rset.next ())
System.out.println (rset.getString (1));
}
//Close the result set, statement, and the connection
finally{
if(rset!=null) rset.close();
if(stmt!=null) stmt.close();
if(conn!=null) conn.close();
}
}
}
OCIドライバ用のコードを利用する場合は、OracleDataSource.setURLメソッドのコールを次の文で置き換えます。
ods.setURL("jdbc:oracle:oci:@MyHostString");
MyHostStringには、TNSNAMES.ORAファイル内のエントリを指定します。
この項では、Oracle JDBCドライバが次の種類のストアド・プロシージャをサポートする方法について説明します。
Oracle JDBCドライバは、PL/SQLストアド・プロシージャおよび無名ブロックの処理をサポートします。このドライバは、PL/SQLブロック構文とほとんどのJDBCエスケープ構文をサポートします。次のPL/SQLコールは、任意のOracle JDBCドライバで使用できます。
// JDBC escape syntax
CallableStatement cs1 = conn.prepareCall
( "{call proc (?,?)}" ) ; // stored proc
CallableStatement cs2 = conn.prepareCall
( "{? = call func (?,?)}" ) ; // stored func
// PL/SQL block syntax
CallableStatement cs3 = conn.prepareCall
( "begin proc (?,?); end;" ) ; // stored proc
CallableStatement cs4 = conn.prepareCall
( "begin ? := func(?,?); end;" ) ; // stored func
Oracle構文の使用例として、ここでは、ストアド・ファンクションを作成するPL/SQLコードの一部を使用します。PL/SQLファンクションは、文字列を取得し、それに接尾辞を連結します。
create or replace function foo (val1 char) return char as begin return val1 || 'suffix'; end;
JDBCプログラム内のファンクションの起動は、次のようになります。
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:oci:@<hoststring>");
ods.setUser("scott");
ods.setPassword("tiger");
Connection conn = ods.getConnection();
CallableStatement cs = conn.prepareCall ("begin ? := foo(?); end;");
cs.registerOutParameter(1,Types.CHAR);
cs.setString(2, "aa");
cs.executeUpdate();
String result = cs.getString(1);
エラー状況を処理するために、Oracle JDBCドライバはSQL例外をスローし、java.sql.SQLExceptionクラスまたはそのサブクラスのインスタンスを作成します。エラーはJDBCドライバまたはデータベース自体のいずれかで発生する可能性があります。表示されるメッセージには、エラーおよびエラーを発行したメソッドの説明が含まれます。ランタイム情報が追加されることもあります。
JDBC 3.0では、SQLExceptionという単一の例外しかサポートされていません。ただし、エラーはカテゴリが多いので、区別すると便利です。そのため、JDBC 4.0では様々なカテゴリのエラーを特定するためにSQLException例外の一連のサブクラスが導入されています。この機能の詳細は、「JDBC 4.0標準のサポート」を参照してください。
基本例外処理には、エラー・メッセージの取出し、エラー・コードの取出し、SQL状態の取出しおよびスタック・トレースの出力が含まれます。SQLExceptionクラスには、使用可能な場合にこのようなすべての情報を取り出す機能があります。
エラー情報の取出し
SQLExceptionクラスの次のメソッドで、基本エラー情報を取り出すことができます。
次の例はgetMessage()メソッド・コールからの情報を出力します。
catch(SQLException e)
{
System.out.println("exception: " + e.getMessage());
}
これはJDBCドライバで発生したエラーに対して、次のような情報を出力します。
exception: Invalid column type
|
注意: Oracleでサポートされている言語とキャラクタ・セットでエラー・メッセージ・テキストを使用できます。 |
スタック・トレースの出力
SQLExceptionクラスには、スタック・トレースを出力するためのprintStackTrace()メソッドがあります。このメソッドは、スロー可能なオブジェクトのスタック・トレースを標準エラー・ストリームに出力します。出力のために、java.io.PrintStreamオブジェクトまたはjava.io.PrintWriterオブジェクトも指定できます。
次のコード・フラグメントは、SQLの例外を捕捉してスタック・トレースを表示する方法を示しています。
try { <some code> }
catch(SQLException e) { e.printStackTrace (); }
JDBCドライバでエラーを処理する方法を説明するために、次のコードでは不適切な列索引を使用していると仮定します。
// Iterate through the result and print the employee names
// of the code
try {
while (rset.next ())
System.out.println (rset.getString (5)); // incorrect column index
}
catch(SQLException e) { e.printStackTrace (); }
列索引が不適切であると仮定すると、このプログラムの実行によって次のエラー・テキストが生成されます。
java.sql.SQLException: Invalid column index at oracle.jdbc.driver.OracleResultSetImpl.getDate(OracleResultSetImpl.java:1556) at Employee.main(Employee.java:41)