![]() |
![]() |
|
|
| |
Oracle の高度な機能
この章では、Oracle の高度な機能について説明します。
大文字/小文字を区別せずにメタデータを扱う方法
WebLogic Server では、allowMixedCaseMetaData
プロパティを設定できます。このプロパティをブール値 true
に設定すると、このプロパティは、DatabaseMetaData
メソッドの呼び出しで大文字/小文字を区別しないように、Connection オブジェクトを設定します。このプロパティを false
に設定した場合、Oracle は、データベース メタデータについて大文字
をデフォルトで使用します。
次のサンプル コードは、この機能を利用するためのプロパティの設定方法を示します。
Properties props = new Properties();
props.put("user", "scott");
props.put("password", "tiger");
props.put("server", "DEMO");
props.put("allowMixedCaseMetaData", "true");
Driver myDriver = (Driver)
Class.for.Name(weblogic.jdbc.oci.Driver).newInstance();
Connection conn =
myDriver.connect("jdbc:weblogic:oracle", props);
このプロパティを設定しなかった場合、WebLogic Server は Oracle のデフォルト設定を使用するので、データベース メタデータについては大文字
が使用されます。
次の表は、Oracle データ型と Java 型との推奨マッピングを示します。この他にも、Oracle データ型を Java で表現する方法はあります。結果セットの処理中に getObject()
メソッドを呼び出した場合、クエリ対象の Oracle カラムに対するデフォルトの Java データ型が返されます。
図5-1 Oracle と WebLogic Server の型の対応表
* PreparedStatement.setBoolean()
を呼び出すと、VARCHAR
型は 1
または 0
(文字列)に、NUMBER
型は 1
または 0
(数字)に変換されます。
WebLogic Server と Oracle の NUMBER カラム
Oracle には NUMBER
というカラム タイプがあります。このカラム タイプは、オプションとして NUMBER(P)
および NUMBER(P,S)
の形式で精度とスケールを指定できます。修飾されていない単純な NUMBER
形式でも、このカラムは、小さな整数値から非常に大きな浮動小数点までのすべての数値タイプを高い精度で保持できます。
WebLogic Server アプリケーションがこうしたカラムの値を要求すると、WebLogic Server は、カラム内の値を要求された Java 型に変換します。getInt()
で 123.456 という値が要求された場合、当然、値は丸められます。
ただし、getObject()
メソッドの場合は、これより若干複雑になります。WebLogic Server は、NUMBER
カラムの値を同様の精度で表現する Java オブジェクトで必ず返します。つまり、値 1 は Integer
として返されますが、123434567890.123456789 のような値は BigDecimal
でのみ返されます。
カラムの値の最大精度を Oracle から報告するメタデータはありません。したがって、WebLogic Server は、それぞれの値に基づいて、どのような種類のオブジェクトを返すかを判断する必要があります。つまり、1 つの ResultSet が、NUMBER カラムに対して getObject()
から複数の Java 型を返す場合があるということです。整数値だけのテーブルはすべて Integer
として getObject()
から返されることもあり、浮動小数点単位のテーブルは主に Double
で返されますが、「123.00」のような値は Integer
として返される場合があります。Oracle からは、NUMBER
値の「1」と「1.0000000000」を識別するための情報は提供されていません。
修飾された NUMBER
カラム、つまり、特定の精度が定義されているカラムは、動作の信頼性が高くなります。Oracle のメタデータはこれらのパラメータをドライバに提供するため、WebLogic Server はテーブルの値にかかわりなく、常に特定の精度とスケールに合わせて適切な Java オブジェクトを返します。
カラム定義 |
getObject() の戻り値の型 |
|
|
|
|
|
|
|
|
|
|
Oracle の Long raw データ型の使い方
WebLogic Server では、Blob、Clob、Long、および Long raw といった Oracle のデータ型を使用する場合に備えて、2 つのプロパティを提供しています。Blob および Clob データ型は、Oracle バージョン 8 と JDBC 2.0 でサポートされているだけですが、これらのプロパティは、Oracle バージョン 7 で使用可能な Oracle の Long raw データ型に対しても適用できます。
Oracle リソース上の待機
注意: waitOnResources()
メソッドは、Oracle 8 API 使用時にはサポートされません。
WebLogic Server のドライバは、Oracle の oopt()
C 関数をサポートしています。これは、リソースが使用可能になるまでクライアントが待機できるようにする機能です。Oracle C 関数は、要求されたリソースが使用可能でない場合のオプション(ロックを待機するかどうかなど)を設定します。
開発者は、クライアントが DBMS リソースを待機するか、または直ちに例外を受け取るかを指定できます。次のコードは、サンプル コード ファイル(examples
\jdbc
\oracle
\waiton.java
)からの抜粋です。
java.util.Properties props = new java.util.Properties();
props.put("user", "scott");
props.put("password", "tiger");
props.put("server", "myserver");
Driver myDriver = (Driver)
Class.forName("weblogic.jdbc.oci.Driver").newInstance();
// この拡張機能を利用するために Connection を
// weblogic.jdbc.oci.Connection としてキャストする必要がある
Connection conn =(weblogic.jdbc.oci.Connection)
myDriver.connect("jdbc:weblogic:oracle", props);
// オブジェクトの作成後、直ちに
// waitOnResources メソッドを呼び出す
conn.waitOnResources(true);
このメソッドを使用すると、短期間ロックされる内部リソースを待つ間に、いくつかのエラー リターン コードが発生する場合があります。
この機能を使用するには、次の処理を行う必要があります。
この関数については、The OCI Functions for C のセクション 4-97 に記載されています。
自動コミット
JDBC WebLogic Server のデフォルト トランザクション モードでは、自動コミットを true と仮定します。Connection オブジェクトの作成後、次の文で自動コミットを false に設定することで、プログラムの性能を改善できます。
Connection.setAutoCommit(false);
トランザクションのアイソレーション レベル
WebLogic Server は、以下のトランザクションのアイソレーション レベルをサポートしています。
Oracle DBMS はこれら 2 つのアイソレーション レベルのみをサポートしています。他の JDBC ドライバと違い、WebLogic Server は、開発者がサポートされていないアイソレーション レベルを使おうとした場合に例外を生成します。一部のドライバは、サポートされていないアイソレーション レベルを設定しようとした場合に、例外を生成することなく無視します。
READ_UNCOMMITTED
トランザクション アイソレーション レベルはサポートされていません。
JDBC と WebLogic Server は、Java 内の文字列を Unicode 文字列として扱います。Oracle DBMS は別のコードセットを使用するため、Unicode から Oracle が使用するコードセットに変換する必要があります。WebLogic Server は、Oracle の環境変数 NLS_LANG
内の値を調べて、変換に使用する JDK のコードセットを選択します。コードセットのマッピングには、
表 5-1が使用されます。NLS_LANG
変数が設定されていない場合、または JDK に認識できないコードセットに設定されていた場合、ドライバは正しいコードセットを選択できません。(NLS_LANG
の正しい構文の詳細については、Oracle のドキュメントを参照してください。)
コードセットを変換する場合は、コード内で接続を確立するときに Driver.connect()
メソッドを使用して、次のプロパティを WebLogic Server に渡す必要があります。
props.put("weblogic.oci.min_bind_size", 660);
このプロパティは、バインドされるバッファの最小サイズを定義します。デフォルトでは 2000 バイトで、これは最大値でもあります。コードセットを変換する場合は、このプロパティを使用して、バインド サイズを最大 2000 バイトの 1/3 の最大 660 に減らす必要があります。この理由は、Oracle コード変換では、拡張を考慮してバッファが 3 倍に拡大されるからです。
WebLogic Server では、Java コード内からコードセットを設定できます。接続プロパティの weblogic.codeset
を設定すると、NLS_LANG
環境変数内の値をオーバーライドできます。たとえば、次のサンプルのように、cp863 コードセットを使用するには、Driver.connect()
を呼び出す前に、Properties オブジェクトを作成し、weblogic.codeset
プロパティを設定します。
java.util.Properties props = new java.util.Properties();
props.put("weblogic.codeset", "cp863");
props.put("user", "scott");
props.put("password", "tiger");
String connectUrl = "jdbc:weblogic:oracle";
Driver myDriver = (Driver)
Class.forName("weblogic.jdbc.oci.Driver").newInstance();
Connection conn =
myDriver.connect(connectUrl, props);
コードセット サポートは、JVM の種類によって異なります。特定のコードセットがサポートされているかどうかについては、使用している JDK のドキュメントをチェックしてください。
表5-1 NLS_LANG 設定と JDK コードセットのマッピング対応表
WebLogic Server は、Oracle 配列フェッチをサポートしています。ResultSet.next()
を最初に呼び出したときには、1 行を取り出すのではなく、行の配列を取得して、それをメモリに格納します。それ以降の next()
に対する各呼び出しは、メモリに格納した行をそれぞれ 1 行読み取ります。この操作はメモリ内の行がなくなるまで続き、行がなくなると、next()
への呼び出しはデータベースに戻ります。
配列フェッチのサイズを制御するには、プロパティ(java.util.Property
)を設定します。このプロパティは weblogic.oci.cacheRows
で、デフォルトで 100 に設定されています。このプロパティを 300 に設定する例を次に示します。これは、next()
への呼び出しは、クライアントが取り出す 300 行につき 1 回だけデータベースをヒットすることを意味します。
Properties props = new Properties();
props.put("user", "scott");
props.put("password", "tiger");
props.put("server", "DEMO");
props.put("weblogic.oci.cacheRows", "300");
Driver myDriver = (Driver)
Class.forName("weblogic.jdbc.oci.Driver").newInstance();
Connection conn = myDriver.connect("jdbc:weblogic:oracle", props);
この JDBC 拡張機能を利用することで、クライアントの性能を改善し、データベース サーバの負荷を緩和できます。ただし、クライアントでの行のキャッシングは、クライアント リソースを必要とします。ネットワーク コンフィグレーションとアプリケーションに応じて、性能とクライアント リソースのバランスが最適になるようにアプリケーションを調整してください。
SELECT 内のカラムが LONG、BLOB、または CLOB 型の場合、WebLogic Server は、その select 文に関連付けられている ResultSet のキャッシュ サイズを一時的に 1 にリセットします。
ストアド プロシージャの使い方
この節では、Oracle に固有のストアド プロシージャのさまざまな実装について説明します。
Oracle カーソルへのパラメータのバインド
WebLogic は、ストアド プロシージャのパラメータを Oracle カーソルにバインドできるようにする JDBC の拡張機能(weblogic.jdbc.oci.CallableStatement
)を作成しました。ストアド プロシージャの結果を使って、JDBC ResultSet オブジェクトを作成できます。これによって、複数の ResultSet を整理して返すことができます。ResultSet は実行時にストアド プロシージャ内で決定されます。
次に例を示します。まず、次のようにストアド プロシージャを定義します。
create or replace package
curs_types as
type EmpCurType is REF CURSOR RETURN emp%ROWTYPE;
end curs_types;
/
create or replace procedure
single_cursor(curs1 IN OUT curs_types.EmpCurType,
ctype in number) AS BEGIN
if ctype = 1 then
OPEN curs1 FOR SELECT * FROM emp;
elsif ctype = 2 then
OPEN curs1 FOR SELECT * FROM emp where sal 2000;
elsif ctype = 3 then
OPEN curs1 FOR SELECT * FROM emp where deptno = 20;
end if;
END single_cursor;
/
create or replace procedure
multi_cursor(curs1 IN OUT curs_types.EmpCurType,
curs2 IN OUT curs_types.EmpCurType,
curs3 IN OUT curs_types.EmpCurType) AS
BEGIN
OPEN curs1 FOR SELECT * FROM emp;
OPEN curs2 FOR SELECT * FROM emp where sal 2000;
OPEN curs3 FOR SELECT * FROM emp where deptno = 20;
END multi_cursor;
/
Java コード内で、ストアド プロシージャを使用して CallableStatements
を作成し、出力パラメータをデータ型 java.sql.Types.OTHER
で登録します。データを ResultSet 内に取り出すときに、出力パラメータのインデックスを getResultSet()
メソッドの引数として使用します。
java.sql.CallableStatement cstmt = conn.prepareCall(
"BEGIN OPEN ? " +
"FOR select * from emp; END;");
cstmt.registerOutParameter(1, java.sql.Types.OTHER);
cstmt.execute();
ResultSet rs = cstmt.getResultSet(1);
printResultSet(rs);
rs.close();
cstmt.close();
java.sql.CallableStatement cstmt2 = conn.prepareCall(
"BEGIN single_cursor(?, ?); END;");
cstmt2.registerOutParameter(1, java.sql.Types.OTHER);
cstmt2.setInt(2, 1);
cstmt2.execute();
rs = cstmt2.getResultSet(1);
printResultSet(rs);
cstmt2.setInt(2, 2);
cstmt2.execute();
rs = cstmt2.getResultSet(1);}
printResultSet(rs);
cstmt2.setInt(2, 3);
cstmt2.execute();
rs = cstmt2.getResultSet(1);
printResultSet(rs);
cstmt2.close();
java.sql.CallableStatement cstmt3 = conn.prepareCall(
"BEGIN multi_cursor(?, ?, ?); END;");
cstmt3.registerOutParameter(1, java.sql.Types.OTHER);
cstmt3.registerOutParameter(2, java.sql.Types.OTHER);
cstmt3.registerOutParameter(3, java.sql.Types.OTHER);
cstmt3.execute();
ResultSet rs1 = cstmt3.getResultSet(1);
ResultSet rs2 = cstmt3.getResultSet(2);
ResultSet rs3 = cstmt3.getResultSet(3);
printResultSet()
メソッドを含むこのサンプルの全コードについては、samples
\examples
\jdbc
\oracle
\ ディレクトリにあるサンプルを参照してください。
Oracle ストアド プロシージャの文字列のデフォルト サイズは 256K です。
CallableStatement の使用上の注意
CallableStatement の OUTPUT パラメータにバインドされる文字列のデフォルト長は 128 文字です。バインド パラメータに割り当てた値がこの長さを超えると、次のエラーが発生します。
ORA-6502: value or numeric error
バインド パラメータの値の長さは、明示的な長さを scale 引数を使って CallableStatement.registerOutputParameter()
メソッドに渡すことによって調節できます。256 文字を超えない VARCHAR
をバインドするコード サンプルを次に示します。
CallableStatement cstmt =
conn.prepareCall("BEGIN testproc(?); END;");
cstmt.registerOutputParameter(1, Types.VARCHAR, 256);
cstmt.execute();
System.out.println(cstmt.getString());
cstmt.close();
この節では、Oracle に固有の DatabaseMetaData メソッドの実装について説明します。
DatabaseMetaData
メソッドで無視されます。
DatabaseMetaData.getProcedureColumns()
メソッドでは、
JDBC 拡張 SQL のサポート
JavaSoft JDBC 仕様には、SQL 拡張が含まれています。SQL 拡張は SQL Escape 構文とも呼ばれています。すべての WebLogic jDriver は拡張 SQL をサポートしています。拡張 SQL によって、DBMS 間で移植可能な共通の SQL 拡張機能にアクセスできます。
たとえば、日付から曜日を取り出す関数は、SQL 標準では定義されていません。Oracle の SQL では次のようになります。
select to_char(date_column, 'DAY') from table_with_dates
同等の関数は、Sybase や Microsoft SQL Server では次のようになります。
select datename(dw, date_column) from table_with_dates
拡張 SQL を使うと、どちらの DBMS に対しても、次のようにして曜日を取り出すことができます。
select {fn dayname(date_column)} from table_with_dates
次のサンプルは、拡張 SQL の機能のいくつかを示します。
String query =
"-- This SQL includes comments and " +
"JDBC extended SQL syntax.\n" +
"select into date_table values( \n" +
" {fn now()}, -- current time \n" +
" {d '1997-05-24'}, -- a date \n" +
" {t '10:30:29' }, -- a time \n" +
" {ts '1997-05-24 10:30:29.123'}, -- a timestamp\n" +
" '{string data with { or } will not be altered}'\n" +
"-- Also note that you can safely include" +
" { and } in comments or\n" +
"-- string data.";
Statement stmt = conn.createStatement();
stmt.executeUpdate(query);
拡張 SQL は、一般の SQL と区別するために中括弧(「{}
」)で囲ってあります。コメントはダブルハイフンで始まり、改行コード(「\n
」)で終わっています。コメント、SQL、および拡張 SQL を含む拡張 SQL のシーケンス全体は、二重引用符で囲み、Statement
オブジェクトの execute()
メソッドに渡します。CallableStatement
の一部に拡張 SQL を使った例を次に示します。
CallableStatement cstmt =
conn.prepareCall("{ ? = call func_squareInt(?)}");
次のサンプルは、拡張 SQL 式をネストできるということを示しています。
select {fn dayname({fn now()})}
サポートされている拡張 SQL 関数の一覧は、DatabaseMetaData オブジェクトから取り出すことができます。次のサンプルは、JDBC ドライバがサポートしている関数のすべてをリストする方法を示しています。
DatabaseMetaData md = conn.getMetaData();
System.out.println("Numeric functions: " +
md.getNumericFunctions());
System.out.println("\nString functions: " +
md.getStringFunctions());
System.out.println("\nTime/date functions: " +
md.getTimeDateFunctions());
System.out.println("\nSystem functions: " +
md.getSystemFunctions());
conn.close();
Oracle 用 JDBC 2.0 の概要
WebLogic jDriver for Oracle で実装されている JDBC 2.0 の機能は以下のとおりです。
以前のバージョンで利用可能だった既存の JDBC 機能に加えて、上記の新機能も WebLogic Server で利用できるようになりました。前バージョンのドライバで使用していた既存のコードは、すべてこの新 WebLogic jDriver for Oracle でも動作します。
JDBC 2.0 のサポートに必要なコンフィグレーション
WebLogic Server バージョン 6.1 は JDK 1.3.1 上で動作するので、JDBC 2.0 には Java 2 環境が必要となります。サポートされているコンフィグレーションの全リストについては、「WebLogic プラットフォーム サポート」ページを参照してください。
BLOB と CLOB
BLOB(Binary Large Object)および CLOB(Character Large Object)データ型は、Oracle バージョン 8 のリリースで利用できるようになりました。JDBC 2.0 仕様と WebLogic Server もこれらのデータ型をサポートしています。この節では、これらのデータ型の使い方について説明します。
注意: 次の制限に注意してください。WebLogic jDriver for Oracle と組み合わせて RMI ドライバ使用する場合、BLOB と CLOB を使用することはできません。BLOB および CLOB はシリアライズできないため、WebLogic Server 6.x で使用する JDBC RMI ドライバではサポートされません。
トランザクション境界
Oracle での BLOB と CLOB は、トランザクション境界(SQL の commit または rollback 文の前に発行された文)に関しては、他のデータ型とは動作が異なります。BLOB または CLOB は、トランザクションがコミットされると直ちに非アクティブになります。AutoCommit が TRUE に設定されている場合、その接続で各コマンドが発行された後に、トランザクションはそれぞれ自動的にコミットされます。SELECT 文の場合でもコミットされます。この理由により、複数の SQL 文にまたがって BLOB または CLOB を保持する必要がある場合には、AutoCommit を false に設定しなければなりません。トランザクションを適切なタイミングで手動でコミット(またはロールバック)することが必要になります。AutoCommit を false に設定するには、次のコマンドを入力します。
conn
.setAutoCommit(false); //conn
は対象となる connection オブジェクト
Oracle バージョン 8 で使用可能になった BLOB データ型を使用すると、Oracle テーブルに大きなバイナリ オブジェクトを保存したり、テーブルから取り出したりできます。BLOB は JDBC 2.0 仕様の一部として定義されていますが、仕様では、テーブル内の BLOB カラムを更新するためのメソッドが提供されていません。しかし、BEA WebLogic の BLOB の実装は、JDBC 2.0 を拡張することでこの機能を提供します。
Connection プロパティ
weblobic.oci.selectBlobChunkSize
flush()
処理を実行します。これにより、データは DBMS に送られます。
この値を明示的に設定することは、クライアントのメモリ使用量の制御に役立ちます。
このプロパティの値が設定されていない場合には、デフォルト値 65534 が使用されます。
このプロパティを、プロパティとして Connection オブジェクトに渡すことで設定します。たとえば、次のコードは weblobic.oci.selectBlobChunkSize
を 1200 に設定します。
Properties props = new Properties();
props.put("user", "scott");
props.put("password", "tiger");
props.put("server", "DEMO" );
props.put ("weblobic.oci.selectBlobChunkSize","1200");
Driver myDriver = (Driver)
Class.forName("weblogic.jdbc.oci.Driver").newInstance();
Connection conn =
driver.connect("jdbc:weblogic:oracle:myServer", props);
weblogic.oci.insertBlobChunkSize
BLOB チャンク機能を使用して、Oracle DBMS に Blob を挿入するには、このプロパティを正の整数に設定します。デフォルトでは、このプロパティは、BLOB チャンクを使用しないことを意味するゼロ(0)に設定されています。
Import 文
この節で説明されている BLOB 機能を使用するには、クライアント コードに以下のクラスをインポートします。
import java.sql.*;
import java.util.*;
import java.io.*;
import weblogic.jdbc.common.*;
BLOB フィールドの初期化
BLOB データ型が入った行を最初に挿入するときには、実際のデータを使ってそのフィールドを更新する前に、「空の」BLOB を持つ行を挿入する必要があります。空の BLOB を挿入するには、Oracle EMPTY_BLOB() 関数を使用します。
BLOB フィールドを初期化する手順は以下のとおりです。
EMPTY_BLOB()
関数を使用して、空の BLOB カラムを 1 つ持つ行を 1 つ挿入します。
stmt.execute("INSERT into myTable values (1,EMPTY_BLOB()");
java.sql.Blob myBlob = null;
Statement stmt2 = conn.createStatement();
stmt2.execute("SELECT myBlobColumn from myTable
where pk = 1 for update");
ResultSet rs = stmt2.getResultSet();
rs.next() {
myBlob = rs.getBlob("myBlobColumn");
// 取得した BLOB を使用して何かする
}
BLOB へのバイナリ データの書き込み
BLOB
カラムにバイナリ データを書き込む手順は以下のとおりです。
java.io.InputStream is = // 入力ストリームを作成する
weblogic.jdbc.common.OracleBlob
にキャストしなければなりません。
java.io.OutputStream os =
((weblogic.jdbc.common.OracleBlob) myBlob).getBinaryOutputStream();
OutputStream
オブジェクトの flush()
メソッドを呼び出したときに終了します。
byte[] inBytes = new byte[65534]; // 下記の「注意」を参照
int numBytes = is.read(inBytes);
while (numBytes > 0) {
os.write(inBytes, 0, numBytes);
numBytes = is.read(inBytes);
}
os.flush();
注意: 上記コードの中の値 [65534]
は、65534
というデフォルト値を持つ weblogic.oci.select.BlobChunkSize
プロパティが未設定であると仮定したものです。このプロパティを設定してある場合、byte[] の値を weblogic.oci.select.BlobChunkSize property
に設定した値に合わせると、データを最も効率的に扱えるようになります。このプロパティの詳細については、「
Connection プロパティ」を参照してください。
os.close();
pstmt.close();
conn.close();
BLOB オブジェクトの書き込み
BLOB オブジェクトをテーブルに書き込むには、Prepared Statements を使用します。たとえば、myBlob
オブジェクトをテーブル myOtherTable
に書き込むコードは以下のとおりです。
PreparedStatement pstmt = conn.preparedStatement(
"UPDATE myOtherTable SET myOtherBlobColumn = ? WHERE id = 12");
pstmt.setBlob(1, myBlob);
Prepared Statement を使用した CLOB 値の更新
Prepared Statement を使用して CLOB を更新する場合、新しい値が古い値より短いと、更新の際に明示的に置換されなかった文字が CLOB に残ります。たとえば、現在の値が abcdefghij
である CLOB を Prepared Statement で zxyw
という値に更新すると、更新後の CLOB の値は zxywefghij
になります。Prepared Statement で更新した結果を正しい値にするには、dbms_lob.trim
プロシージャを使って、更新後に残っている余分な文字を削除する必要があります。dbms_lob.trim
プロシージャの詳細については、Oracle のマニュアルを参照してください。
BLOB データの読み取り
getBlob()
メソッドを使用して BLOB カラムを取り出してから、SQL SELECT 文の実行結果 ResultSet
を使用した場合は、BLOB データへのポインタだけが返されます。バイナリ データは実際にはクライアントに転送されていません。getBinaryStream()
メソッドを呼び出して初めて、データがストリーム オブジェクトに書き込まれます。
Oracle テーブルから BLOB データを読み取る手順は以下のとおりです。
stmt2.execute("SELECT myBlobColumn from myTable");
int STREAM_SIZE = 10;
byte[] r = new byte[STREAM_SIZE];
ResultSet rs = stmt2.getResultSet();
java.sql.Blob myBlob = null;
while (rs.next) {
myBlob = rs.getBlob("myBlobColumn");
java.io.InputStream readis = myBlob.getBinaryStream();
for (int i=0 ; i < STREAM_SIZE ; i++) {
r[i] = (byte) readis.read();
System.out.println("output [" + i + "] = " + r[i]);
}
rs.close();
stmt2.close();
注意: また、CallableStatement
を使用して、ResultSet
を生成することもできます。この ResultSet
は、上記と同じように使用できます。詳細については、JDK ドキュメントの java.sql.CallableStatment
の部分を参照してください。
その他のメソッド
さらに、java.sql.Blob
インタフェースの以下のメソッドが、WebLogic Server JDBC 2.0 ドライバに実装されています。詳細については、JDK ドキュメントを参照してください。
position()
メソッドは実装されていません。
CLOB
Oracle バージョン 8 で使用可能になった CLOB データ型は、Oracle テーブル内に大きな文字列を格納できます。JDBC 2.0 の仕様には CLOB カラムを直接更新する機能は含まれていないので、CLOB を挿入したり更新したりするために、BEA では getAsciiOutputStream()
メソッド(ASCII データ用)と getCharacterOutputStream()
メソッド(Unicode データ用)を実装しました。
コードセットのサポート
使用する Oracle Server およびクライアントのバージョンによっては、以下のプロパティのいずれかを設定する必要があります。設定するには、DBMS 接続を確立したときにそのプロパティを Connection オブジェクトに渡すように、Java クライアントのコード中に記述します。
weblogic.codeset
NLS_LANG
に指定されたコードセットの値をオーバーライドします。
weblogic.oci.ncodeset
NLS_NCHAR
に指定されたコードセットの値をオーバーライドします。
weblogic.oci.codeset_width
0
(可変幅のコードセットを使用する場合)
1
(固定幅のコードセットを使用する場合。1
はデフォルト値)
2
または 3
(コードセットの幅をバイト単位で指定する場合)
weblogic.oci.ncodeset_width
0
(可変幅のコードセットを使用する場合)
1
(固定幅のコードセットを使用する場合。1 はデフォルト値)
2
または 3
(コードセットの幅をバイト単位で指定する場合)
CLOB フィールドの初期化
CLOB データ型が入った行を最初に挿入するときには、実際のデータを使ってそのフィールドを更新する前に、「空の」CLOB を持つ行を挿入する必要があります。空の CLOB を挿入するには、Oracle EMPTY_CLOB() 関数を使用します。
CLOB カラムを初期化する手順は以下のとおりです。
EMPTY_CLOB()
関数を使用して、空の CLOB カラムを 1 つ持つ行を 1 つ挿入します。
stmt.execute("INSERT into myTable VALUES (1,EMPTY_CLOB()");
java.sql.Clob myClob = null;
Statement stmt2 = conn.createStatement();
stmt2.execute("SELECT myClobColumn from myTable
where pk = 1 for update");
ResultSet rs = stmt2.getResultSet();
while (rs.next) {
myClob = rs.getClob("myClobColumn");
}
CLOB への ASCII データの書き込み
CLOB
カラムに ASCII 文字データを書き込む手順は以下のとおりです。
String s = // ASCII データ
weblogic.jdbc.common.OracleClob
にキャストしなければなりません。
java.io.OutputStream os =
((weblogic.jdbc.common.OracleClob) myclob).getAsciiOutputStream();
OutputStream
オブジェクトの flush()
メソッドを呼び出したときに終了します。
byte[] b = s.getBytes("ASCII");
os.write(b);
os.flush();
os.close();
pstmt.close();
conn.close();
CLOB への Unicode データの書き込み
CLOB
カラムに Unicode 文字データを書き込む手順は以下のとおりです。
String s = // Unicode 文字データ
weblogic.jdbc.common.OracleClob
にキャストしなければなりません。
java.io.Writer wr =
((weblogic.jdbc.common.OracleClob) myclob).getCharacterOutputStream();
OutputStream
オブジェクトの flush()
メソッドを呼び出したときに終了します。
char[] b = s.toCharArray(); // 「s」 を文字配列に変換
wr.write(b);
wr.flush();
wr.close();
pstmt.close();
conn.close();
CLOB オブジェクトの書き込み
CLOB オブジェクトをテーブルに書き込むには、Prepared Statements を使用します。たとえば、myClob
オブジェクトをテーブル myOtherTable
に書き込むコードは以下のとおりです。
PreparedStatement pstmt = conn.preparedStatement(
"UPDATE myOtherTable SET myOtherClobColumn = ? WHERE id = 12");
pstmt.setClob(1, myClob);
CLOB データの読み取り
SQL SELECT 文の実行結果を使用して CLOB カラムを取り出した場合は、CLOB データへのポインタだけが返されます。実際のデータはクライアントに転送されていません。getAsciiStream()
メソッドが呼び出されて初めて、その文字データがストリームに読み込まれます。
Oracle テーブルから CLOB データを読み取る手順は以下のとおりです。
java.sql.Clob myClob = null;
Statement stmt2 = conn.createStatement();
stmt2.execute("SELECT myClobColumn from myTable");
ResultSet rs = stmt2.getResultSet();
while (rs.next) {
myClob = rs.getClob("myClobColumn");
java.io.InputStream readClobis =
myReadClob.getAsciiStream();
char[] c = new char[26];
for (int i=0 ; i < 26 ; i++) {
c[i] = (char) readClobis.read();
System.out.println("output [" + i + "] = " + c[i]);
}
}
rs.close();
stmt2.close();
注意: また、CallableStatement
を使用して、ResultSet
を生成することもできます。この ResultSet
は、上記と同じように使用できます。詳細については、JDK ドキュメントの java.sql.CallableStatment
の部分を参照してください。
その他のメソッド
さらに、java.sql.Clob
インタフェースの以下のメソッドが、WebLogic Server(JDBC 2.0 ドライバ)に実装されています。
これらのメソッドの詳細については、JDK ドキュメントを参照してください。
注意: position()
メソッドは実装されていません。
文字と ASCII ストリーム
JDBC 2.0 仕様の新しいメソッドの一部では、文字と ASCII ストリームを、以前のバージョンで実装されていたようにバイト列として扱うのではなく、文字列として扱うことができます。文字と ASCII ストリームを扱うための以下のメソッドが WebLogic Server で実装されています。
Unicode 文字ストリーム
getCharacterStream()
java.sql.ResultSet
インタフェースは、Unicode ストリームを Java の java.io.Reader
型として読み込むために、このメソッドを使用します。このメソッドは、非推奨になった getUnicodeStream()
メソッドに代わって採用されました。
setCharacterStream()
java.sql.PreparedStatement
インタフェースは、java.io.Reader
オブジェクトを書き込むためにこのメソッドを使用します。このメソッドは、非推奨になった setUnicodeStream()
メソッドに代わって採用されました。
ASCII 文字ストリーム
getAsciiStream()
java.sql.ResultSet
インタフェースは、ASCII ストリームを Java の java.io.InputStream
型として読み込むためにこのメソッドを使用します。
setAsciiStream()
java.sql.PreparedStatement
インタフェースは、java.io.InputStream
オブジェクトを書き込むためにこのメソッドを使用します。
これらのメソッドの使い方の詳細については、JDK ドキュメントを参照してください。
バッチ更新
バッチ更新は JDBC 2.0 の新しい機能で、この機能を使用すると、複数の SQL 更新文を 1 単位として DBMS に送ることができます。アプリケーションによっては、複数の更新文を個々に送るよりも性能が向上することがあります。バッチ更新機能は、Statement
インタフェースで使用可能ですが、更新件数を返して結果セットを返さない SQL 文を使用することが必要となります。callableStatement
または preparedStatement
を使用したバッチ更新はサポートされていません。
バッチ更新で使用できる SQL 文は以下のとおりです。
バッチ更新の使い方
バッチ更新の使い方の基本的な手順を以下に示します。
conn
です。
createStatement()
メソッドを使用して、statement オブジェクトを作成します。次に例を示します。
Statement stmt = conn.createStatement();
addBatch()
メソッドを使用して、SQL 文をバッチに追加します。これらの文は、executeBatch()
メソッドが呼び出されるまで、DBMS に送られません。次に例を示します。
stmt.addBatch("INSERT INTO batchTest VALUES ('JOE', 20,35)");
stmt.addBatch("INSERT INTO batchTest VALUES ('Bob', 30,44)");
stmt.addBatch("INSERT INTO batchTest VALUES ('Ed', 34,22)");
executeBatch()
メソッドを使用して、処理のためバッチを DBMS に送ります。次に例を示します。
stmt.executeBatch();
文が失敗して例外が発生した場合、文は 1 行も実行されません。
バッチ処理文の消去
clearBatch()
メソッドを使用すると、addBatch()
メソッドを使用して作成した文の集合を消去できます。次に例を示します。
stmt.clearBatch();
更新件数
JDBC 2.0 仕様によると、executeBatch()
メソッドは、各 Statement で更新された行の数が入った整数の配列を返すことになっています。しかし、Oracle DBMS はこの情報をドライバに提供していません。代わりに、Oracle DBMS は、すべての更新に対して -2
を返します。
新しい日付関連メソッド
以下のメソッドは、新しい署名を使用して、java.util.Calendar
オブジェクトをパラメータとして取ります。java.util.Calendar
を使用すると、日付の変換に使われるタイム ゾーンやロケーションの情報を指定できます。java.util.Calendar
クラスの使い方の詳細については、JDK API ガイドを参照してください。
java.sql.ResultSet.getDate(int columnIndex, Calendar cal)
java.sql.Date
オブジェクトを返す)
java.sql.PreparedStatement.setDate
(int parameterIndex, Date x, Calendar cal)
java.sql.CallableStatement.getDate
(int parameterIndex, Calendar cal)
java.sql.Date
オブジェクトを返す)
![]() |
![]() |