10 トランスレータとランタイムの検証
この章では、Oracle SQLJのトランスレータおよびランタイムの内部操作と機能について説明します。
内容は次のとおりです。
10.1 トランスレータの内部操作
ここでは、変換時にSQLJトランスレータによって実行される主な操作について説明します。
10.1.1 JavaとSQLJのコード解析と構文チェック
SQLJ変換の最初の段階では、SQLJパーサーとJavaのパーサーによってすべてのソース・コードが処理され、構文チェックが行われます。SQLJトランスレータは、.sqlj
ファイルの解析時に、Java文の構文チェックのためにJavaパーサーを起動し、SQLJコンストラクト(先頭に#sql
が付くもの)の構文チェックのためにSQLJパーサーを起動します。また、SQLJパーサーは、Javaパーサーを起動して、SQLJ実行文に含まれるJavaホスト変数と式の構文をチェックします。
SQLJパーサーは、SQLJ言語の仕様に基づいてSQLJコンストラクトの文法をチェックします。ただし、埋込みSQL操作の文法はチェックしません。SQL構文は、セマンティクス・チェックまたはオフライン解析でチェックされます。
この構文チェックでは、セミコロンの抜け、中カッコの対の抜け、明らかな型の不一致(乗算する値の一方が文字列になっている)などのエラーが検索されます。このチェックで構文エラーまたは型の不一致が検出されると、変換が中止されてエラーが出力されます。
10.1.2 SQLのセマンティクス・チェックとオフライン解析
SQLJおよびJavaアプリケーションのソース・コードに構文の誤りがないことが確認されると、次のセマンティクス・チェックに進みます。このチェックでは、SQLJのオプション設定に基づいて、SQLセマンティクス・チェッカまたはSQLオフライン・パーサー(あるいはその両方)が起動します。
-user
オプションを設定するとオンライン・チェックが有効になり、-user
オプションでパスワードとURLが指定されていない場合に、-password
および-url
オプションを設定するとデータベース接続が指定されます。-offline
オプションまたは-online
オプションで、使用するチェッカを指定します。デフォルトでは(通常はこの設定で十分)、OracleChecker
と呼ばれるチェッカ・フロントエンドが指定され、オンライン・チェックが有効かどうか、および使用されるJava Database Connectivity (JDBC)に応じて、最も適切なチェッカが選択されます。
-parse
はオフライン・パーサーを有効にするオプションであり、デフォルトはtrue
です。オフライン・パーサーでは、変換時にデータベース接続なしでSQLおよびPL/SQL構文を検証する手段が提供されます(データベース列に対するデータ型の検証は行われません)。-parse
オプションの設定によっては、-user
オプションがオーバーライドされ、オンライン・チェックが無効になります。
注意:
ISOコード生成の場合は、SQLJトランスレータを前回実行した際に生成されたプロファイルに対しても、セマンティクス・チェックを実行できます。「プロファイルのセマンティクス・チェック用のSQLCheckerCustomizer」を参照してください。
セマンティクス・チェックでは、オンライン・チェックまたはオフライン解析のステータスに関係なく、次のタスクが常に実行されます。
-
SQLJによって、SQLJ実行文で使用されているJava式の型が解析されます。
変換されるSQLJソース・ファイルの他に、コマンドラインで指定した
.java
ファイル、インポート済のJavaクラスの.class
ファイルまたは.java
ファイルのうちCLASSPATHで検出可能なファイルも解析の対象になります。解析では、SELECT
文またはCAST
文でのストリーム型が使用されているかどうか、使用されている場合はその使用方法がチェックされます。また、イテレータ列またはINTO
リストで使用されているJava型、入力ホスト変数として使用されているJava型、出力ホスト変数として使用されているJava型もチェックされます。また、SQLJでは、
FETCH
、CAST
、CALL
、SET TRANSACTION
、VALUES
およびSET
の各文が構文に基づいて処理されます。SQLJ実行文内のJava式には、それぞれの状況と用途に適したJava型を指定する必要があります。たとえば、次の文を考えてみます。
#sql [myCtx] { UPDATE ... };
myCtx
は、この文に対する接続コンテキスト・インスタンスまたは実行コンテキスト・インスタンスを指定する変数です。この変数は、実際にSQLJの接続コンテキスト型または実行コンテキスト型に解決できることが必要です。ここで、次の例について考えてみます。
#sql { UPDATE employees SET salary = :newSal };
newSal
がフィールドではなく変数の場合、newSal
があらかじめ宣言されていないときは、エラーが生成されます。また、この変数を有効なJava型に代入できない場合や、この変数のJava型をSQL文(java.util.Vector
など)で使用できない場合も、エラーが生成されます。注意:
Java型のセマンティクス・チェックは、SQLJ実行文内のJava式に対してのみ行われます。標準のJava文でのエラーは、Javaコンパイラでコンパイルされるまで検出されません。
-
SQLJで、埋込みSQL操作の分類が試みられます。このため、操作の種類を識別するために、操作ごとに
SELECT
やINSERT
などの認識可能なキーワードが必要です。たとえば、次の文ではエラーが生成されます。#sql { foo };
-
オンライン・チェックまたはオフライン解析(あるいはその両方)が有効な場合は、SQLJによって、SQLとPL/SQLの埋込み操作の構文が分析および検証されます。
-
オンライン・チェックまたはオフライン解析(あるいはその両方)が有効な場合は、SQLJによって、SQLJ実行文で使用されているJava式の型が、データベースの列のSQL型、ストアド・プロシージャおよびストアド・ファンクションの引数と戻り値のSQL型に対してチェックされます。
このチェック中に、SQLJ実行文で使用されるSQLエンティティ(表、ビュー、ストアド・プロシージャなど)が実際にデータベースに存在するかどうかが、SQLJによって検証されます。また、データベース列からデータを選択してJava基本型のイテレータ列に入力する場合、基本型のイテレータ列ではNULLデータを処理できないため、SQLJは選択元のデータベース列でNULL値が許容されているかどうかもチェックします。ただし、ストアド・プロシージャやストアド・ファンクションの出力パラメータと戻り値に対しては、NULL値が許容されているかどうかはチェックされません。
10.1.3 コードの生成
ISO標準SQLJコード生成の場合、SQLJトランスレータは、1つの.sqlj
アプリケーション・ソース・ファイルに対して、1つの.java
ファイルと、1つ以上のプロファイル(.ser
ファイルまたは.class
ファイル)を生成します。.java
ファイルには、変換済のアプリケーション・ソース・コード、宣言したprivateイテレータと接続コンテキスト用のクラス定義、および、ISOコードの場合は、SQLJによって生成されて内部的に使用されるプロファイルキーのクラス定義が含まれています。
注意:
デフォルトのOracle固有コード生成モードを使用している場合、プロファイルやプロファイルキー・クラスは生成されません。
ISOコード生成では、SQLJ実行文をコードで使用しない場合、プロファイルやプロファイルキー・クラスはありません。
.javaファイル内に生成されたアプリケーション・コード
デフォルトのOracle固有コード生成の場合、アプリケーション用に生成された.java
ファイルには、元のSQLJ実行文のかわりにOracle JDBCドライバへの直接コールが含まれます。Oracle固有のSQLJランタイムへのコールもあります。ISO標準SQLJコード生成の場合、SQLJ実行文はSQLJランタイムへのコールに置き換えられ、このSQLJランタイムにはJDBCドライバへのコールが含まれます。
便宜上、生成された.java
ファイルには、各#sql
文に関するコメントも含まれ、参照用にその文全体も含まれます。生成された.java
ファイルには、入力.sqlj
ファイルと同じベース名が使用されます。通常は、.sqlj
ファイルに定義されているPublicクラスの名前が使用され、Publicクラスが存在しない場合は最初に定義されているクラスの名前が使用されます。たとえば、Foo.sqlj
でFoo
クラスが定義されているとします。トランスレータで生成されるソース・ファイル名はFoo.java
となります。
生成された.java
ファイルの格納場所は、SQLJの-dir
オプション設定の有無および設定方法によって決まります。デフォルトでは、生成された.java
ファイルは、.sqlj
入力ファイルと同じディレクトリに格納されます。
.javaファイル内に生成されるプロファイルキー・クラス(ISOコード生成の場合)
ISO標準SQLJコード生成を使用した場合、SQLJはプロファイルキー・クラスを生成します。これは、シリアライズされたプロファイルのロードおよびアクセスを実行するために、実行時に内部的に使用されます。このクラスには、変換済アプリケーション内のSQLJランタイム・コールと、シリアライズ・プロファイル内に挿入されたSQL操作間のマッピング情報が含まれています。また、シリアライズ・プロファイルにアクセスするためのメソッドも含まれています。
注意:
デフォルトのOracle固有コード生成を使用している場合、プロファイルやプロファイルキー・クラスは生成されません。
このプロファイルキー・クラスは、変換されたアプリケーション・ソース・コードが出力された.java
ファイル内に定義され、次のように、.sqlj
ソース・ファイルのベース名を使用した名前が付けられます。
Basename_SJProfileKeys
たとえば、Foo.sqlj
を変換すると、生成された.java
ファイルには、次のプロファイルキー・クラスが定義されます。
Foo_SJProfileKeys
これは、パッケージに含まれるアプリケーションの場合も同じです。たとえば、a.b
というパッケージに含まれるFoo.sqlj
を変換すると、次のクラスが定義されます。
a.b.Foo_SJProfileKeys
.serファイルまたは.classファイル内に生成されるプロファイル(ISOコード生成の場合)
ISO標準SQLJコード生成を使用した場合、SQLJは、入力ファイル内のSQL操作に関する情報を格納するためのプロファイルを生成します。プロファイルは、アプリケーションで使用する接続コンテキスト・クラスごとに1つ生成されます。プロファイルには、関連付けられた接続コンテキスト・クラスのインスタンスを使用して実行される操作が記述されています。つまり、実行するSQL操作、アクセスする表、コールするストアド・プロシージャとストアド・ファンクションなどが記述されています。
注意:
デフォルトのOracle固有コード生成を使用する場合、SQL操作に関する情報はOracle JDBCドライバを直接コールする生成コードに埋め込まれます。この場合、SQLJではプロファイルが生成されません。
プロファイルは、.ser
シリアライズ・リソース・ファイル内に生成されます。ただし、SQLJの-ser2class
オプションが有効になっている場合は、変換時にプロファイルが.class
ファイルに自動的に変換されます。この場合、これ以降のプロファイルのカスタマイズはできなくなります。.class
ファイルを削除し、SQLJトランスレータを再度実行してプロファイルを再作成する必要があります。
プロファイルのベース名は、プロファイルキー・クラス名の場合と同じように生成されます。このベース名には、パッケージ名の後に.sqlj
ファイルのベース名が続き、最後に次の文字列が付きます。
_SJProfilen
n
は0 (ゼロ)から始まる一意の番号で、特定の.sqlj
入力ファイルに対して生成された各プロファイルに付けられます。
再び、Foo.sqlj
という入力ファイルを例として使用します。この入力ファイルがパッケージに含まれていない場合、生成される2つのプロファイルのベース名は、次のようになります。
Foo_SJProfile0 Foo_SJProfile1
Foo.sqlj
がa.b
というパッケージに含まれる場合、プロファイルのベース名は、次のようになります。
a.b.Foo_SJProfile0 a.b.Foo_SJProfile1
実際には、プロファイルは、リソース・ファイル内のシリアライズされたJavaオブジェクトとして存在します。プロファイルを含むリソース・ファイルには、プロファイルのベース名(パッケージ名は除く)に従って名前が付けられ、拡張子として.ser
が付きます。前述の例の2つのプロファイルを含むリソース・ファイルには、それぞれ次のように名前が付けられます。
Foo_SJProfile0.ser Foo_SJProfile1.ser
ただし、-ser2class
オプションが有効になっている場合は、Foo_SJProfile0.class
およびFoo_SJProfile1.class
となります。このオプションを選択した場合は、カスタマイズ手順の後に、.class
への変換が行われます。
これらのファイルは、SQLJの-d
オプションで設定されているディレクトリに置かれます。生成されたすべての.ser
ファイルおよび.class
ファイルの格納先は、このオプションで指定されます。
SQLJランタイムに対して生成されたコールについて
#sql
文がJDBCドライバ(Oracle固有コード生成の場合)またはSQLJランタイム(ISO標準SQLJコード生成の場合)へのコールに置き換えられている場合、これらのコールは表10-1に示す動作を行います。
表10-1 生成されたコールの動作、ISO標準とOracle固有の比較
ISO標準コード生成の場合 | Oracle固有コード生成の場合 |
---|---|
関連付けされているプロファイル・エントリ中に格納されている情報を使用して、SQLJ文オブジェクトを取得します。 |
Oracle JDBC文オブジェクトを取得します。 |
文オブジェクトの |
Oracle JDBC文メソッドを使用して入力をバインドして、必要な場合は、出力パラメータを登録します。 |
文オブジェクトの |
Oracle文を実行します。 |
可能な場合は、イテレータ・インスタンスを生成します。 |
可能な場合は、イテレータ・インスタンスを生成します。 |
文オブジェクトの |
JDBC取得メソッドを使用して、文から出力を取り出します。 |
SQLJ文オブジェクトを終了します(デフォルトで、SQLJ文キャッシュによって再使用されます)。 |
JDBC文オブジェクトを終了します(デフォルトで、JDBC文キャッシュによって再使用されます)。 |
SQLJランタイムでは、JDBC文オブジェクトに似たSQLJ文オブジェクトが使用されますが、SQLJの具体的な実装状態によっては、JDBC文クラスを直接使用できる場合とできない場合があります。SQLJ文クラスを使用すると、SQLJ固有の機能が追加されます。次に例を示します。
-
標準SQLJ文オブジェクトは、データベースから取り出したNULL値が、NULL値を使用できない
int
やfloat
などのJava基本型に出力されると、SQL例外を生成します。 -
Oracle SQLJ文オブジェクトでは、ユーザー定義のオブジェクト型やコレクション型をOracle Databaseに渡したり、Oracle Databaseから取り出したりできます。
10.1.4 Javaコンパイル
コードが生成されると、SQLJではJavaコンパイラが起動され、生成済.java
ファイルがコンパイルされます。これにより、アプリケーションで定義されているクラスごとに、.class
ファイルが生成されます(イテレータ宣言および接続コンテキスト宣言を含む)。また、ISOコード生成を使用する場合(およびアプリケーションでSQLJ実行文を使用しているとして)、生成されたプロファイルキー・クラスに対しても.class
ファイルが生成されます。SQLJコマンドラインで型解決などのために直接指定した.java
ファイルも、この時点でコンパイルされます。
「コードの生成」で示した例では、ソース・コードにパッケージ情報が指定されている場合、次の.class
ファイルが適切なディレクトリに生成されます。
-
Foo.class
-
Foo_SJProfileKeys.class
(ISOコード生成の場合のみ) -
Foo.sqlj
に定義した追加クラスに対する.class
ファイル -
Foo.sqlj
で宣言した各イテレータ・クラスおよび接続コンテキスト・クラス(publicおよびprivate)に対する.class
ファイル
.class
ファイルとプロファイル(ある場合は、.ser
または.class
のいずれか)が、同じディレクトリに格納されるようにするために、SQLJで設定された-d
オプションがJavaコンパイラに渡されます。-d
オプションが設定されていない場合、.class
ファイルとプロファイルは、生成された.java
ファイルと同じディレクトリ(-dir
オプションで指定されたディレクトリ)に格納されます。
また、SQLJとJavaコンパイラで同じエンコーディングが使用されるように、SQLJはその-encoding
オプションをJavaコンパイラに渡します。ただし、SQLJの-compiler-encoding-flag
が無効になっている場合を除きます。-encoding
オプションが設定されていない場合、SQLJとコンパイラでは、Java Virtual Machine (JVM)のfile.encoding
プロパティの設定が使用されます。
デフォルトでは、標準のSun社のJava Development Kit(JDK)のjavac
コンパイラが使用されますが、他のコンパイラを使用することも可能です。他のJavaコンパイラを使用するには、SQLJの-compiler-executable
オプションを設定します。
注意:
SQLJの-encoding
オプションを使用しているが、コンパイラに-encoding
オプションがない場合は、SQLJの-compiler-encoding-flag
を無効にします。無効にしないと、SQLJはコンパイラに-encoding
オプションを渡そうとします。
10.1.5 プロファイルのカスタマイズ(ISOコード生成の場合)
ISO標準コード生成を使用している場合は、Javaコンパイルが終了すると、生成されたプロファイルのカスタマイズが行われます。プロファイルには、埋込みのSQL命令に関する情報が含まれています。カスタマイズを行うと、使用しているデータベースでのアプリケーションの処理効率が向上し、ベンダー固有の拡張機能を利用できるようになります。
注意:
デフォルトのOracle固有コード生成を使用する場合、SQLJではプロファイルが生成されず、カスタマイズも行われません。コードでは、Oracle JDBC Application Programming Interface(API)を直接コールすることによって、Oracle固有の機能をサポートします。
次のコマンドを使用して、カスタマイザで設定済のオプションを確認できます。
% sqlj -P-print *.ser
プロファイル出力オプションの詳細は、「専用カスタマイザ: プロファイル出力オプション(print)」を参照してください。
カスタマイズ時に、SQLJはカスタマイザ・ハーネスと呼ばれるフロントエンドが起動します(これはコマンドライン・ユーティリティとして機能するJavaクラスです)。このカスタマイザ・ハーネスは、特定のカスタマイザ、つまりデフォルトのOracleカスタマイザ、またはSQLJオプション設定で指定されたカスタマイザを起動します。
プロファイルのカスタマイズには、次の目的があります。
-
可能な場合は、ベンダー固有のデータベース型や機能をアプリケーションで使用できるようにします。
-
データベース環境にあわせて、アプリケーションが最も効率的に機能するプロファイルを生成します。
カスタマイズを行わなかった場合、アクセスして使用できるのは標準のJDBC型のみです。
たとえば、Oracleカスタマイザを使用すると、独自に定義したSQL PERSON
型をサポートするように、プロファイルを更新できます。これにより、サポートされている他のデータ型と同じようにPERSON
型も使用できるようになります。
oracle.sql
の拡張型を使用する場合も、Oracleカスタマイザを使用してカスタマイズする必要があります。
注意:
プロファイルのカスタマイズについて、次の点に注意してください。
-
Oracle SQLJランタイムとOracle JDBCドライバは、変換時にOracleカスタマイザを使用するたびにアプリケーションで必要となるものであり、Oracle拡張型をコード中に使用しない場合にもこのことが当てはまります。
-
アプリケーションでカスタマイズ(接続のための処理)を行わない場合には、汎用SQLJランタイムが使用されます。
-
.ser
ファイル、または.ser
ファイルを含む.jar
ファイルをコマンドラインで指定すると、以前に生成されたプロファイルをカスタマイズできます。ただし、これは、変換が行われるSQLJ実行とは別の実行で行う必要があります。指定できるのは、カスタマイズする.ser
/.jar
ファイル、または変換、コンパイルおよびカスタマイズする.sqlj
/.java
ファイルのうち、どちらか一方のみです。.jar
ファイルの使用方法の詳細は、「プロファイルのJARファイル」を参照してください。
10.2 トランスレータのエラー、メッセージおよび終了コード
ここでは、SQLJトランスレータのメッセージと終了コードの概要を示します。内容は次のとおりです。
10.2.1 トランスレータのエラー、警告および情報メッセージ
変換時に出力されるSQLJメッセージは、エラー、警告および情報の3レベルに区分されています。警告メッセージは、さらに非表示にできない警告と非表示にできる警告の2つのレベルに区分されています。次は、メッセージの4つのレベル(重要度の順)です。
-
エラー
-
非表示にできない警告
-
非表示にできる警告
-
情報
非表示にできる警告と情報は、SQLJの-warn
オプションを使用して制御します。
エラー・メッセージは「Error:
」で開始され、次のいずれかの状態が発生した場合に表示されます。
-
コンパイルを実行できない(たとえば、ファイルのベース名とは別の名前のPublicクラスがソース・ファイルに含まれている)場合。
-
コードを実行すると、実行時エラーが発生する(たとえば、Oracle JDBCドライバを使用して、
VARCHAR
をjava.util.Vector
にフェッチしようとするコードが含まれている)場合。
SQLJ変換時にエラーが発生すると、出力は生成されず、コンパイルとカスタマイズは実行されません。
非表示にできない警告メッセージは「Warning:
」で開始され、次のいずれかの状態が発生した場合に表示されます。
-
コードを実行したときに、実行時エラーが発生する可能性のある(たとえば、
SELECT
文の出力先が指定されていない)場合。 -
SQLJの機能で、ソース・コードの実行時の状況が検証できない(たとえば、オンライン・チェック用に指定したデータベースに接続できない)場合。
-
コーディングの誤りや見落としが原因でエラーが発生した場合。
SQLJ変換は、非表示にできない警告が発生した場合でも最後まで実行されますが、アプリケーションを実行する前に、その問題を分析して、修復の必要があるかどうかを確認してください。オンライン・チェックが指定されている場合に、オンライン・チェックを完了できなかったときは、かわりにオフライン・チェックが実行されます。
注意:
処理上の理由で、SQLJトランスレータによるSQL操作の解析には、実行時に使用されるSQLパーサーよりも精度の低い解析プログラムが使用されます。このため、変換時にエラーが検出されても、実際にはアプリケーションの実行時には問題にならない場合があります。そのようなエラーは、致命的なエラーと区別して、非表示にできない警告として出力されます。
非表示にできる警告も「Warning:
」で開始され、移植性などアプリケーション固有の問題に関する情報が表示されます。たとえば、oracle.sql.NUMBER
などのOracle固有の型を使用してOracle Database 12c リリース1 (12.1)に対して読込みと書込みを行った場合に、警告が出力されます。
情報メッセージやステータス・メッセージはInfo:
で始まりますが、エラーの状態に関する情報は出力されません。これらのエラーには、変換時に発生した事柄に関する追加情報が表示されます。
非表示にできる警告メッセージやステータス・メッセージを非表示にするには、-warn
オプションの次のフラグを使用します。
-
cast/nocast
:nocast
を設定すると、オブジェクト型インスタンスをサブタイプのインスタンスにキャストしようとするときに発生する実行時エラーに関する警告が非表示になります。 -
precision/noprecision
:noprecision
に設定すると、変換時にデータの精度が低下することを示す警告が非表示になります。 -
nulls/nonulls
:nonulls
に設定すると、NULL値が許されている列や型が原因で発生する実行時エラーに関する警告が非表示になります。 -
portable/noportable
:noportable
に設定すると、Oracle固有または非標準の機能を使用しているために、他の環境に移植できないSQLJコードに関する警告が非表示になります。 -
strict/nostrict
:nostrict
に設定すると、名前付きイテレータの列数が、そこに取り込むために選択したデータの列数よりも少ない場合に出力される警告が非表示になります。 -
verbose/noverbose
:noverbose
に設定すると、エラーや警告の状態ではなく情報のみを表示するステータス・メッセージが非表示になります。
SQLJ変換時に警告が表示された場合は、-warn=none
オプションを設定して、トランスレータを再実行し、その警告が重要度の高いもの(非表示にできない警告)であるかどうかを確認します。
次の表は、SQLJトランスレータで生成されるエラー・メッセージおよびステータス・メッセージの分類です。
表10-2 SQLJトランスレータのエラー・メッセージの分類
メッセージの分類 | 接頭辞 | 内容 | 非表示に設定する方法 |
---|---|---|---|
エラー |
|
コンパイル時または実行時に発生する障害の原因となる致命的なエラー(変換は異常終了します) |
該当なし |
非表示にできない警告 |
|
変換が正常に実行されない原因、または実行時に発生する障害の原因となる状態(変換は最後まで実行されます) |
該当なし |
非表示にできる警告 |
|
アプリケーション固有の問題(変換は最後まで実行されます) |
|
情報/ステータス・メッセージ |
|
変換プロセスに関する情報 |
|
10.2.2 トランスレータのステータス・メッセージ
エラー、警告、情報の各メッセージ以外にも、SQLJでは変換、コンパイル、カスタマイズの全段階のSQLJ操作でステータス・メッセージを生成できます。ステータス・メッセージは、各ファイルの処理時に、SQLJ操作の各段階で生成されます。
SQLJの-status
オプションを使用して、ステータス・メッセージを制御できます。
10.2.3 トランスレータの終了コード
SQLJトランスレータでは、変換終了時に次の終了コードがオペレーティング・システムに戻されます。
-
0
: 実行時にエラーなし -
1
: SQLJ実行時にエラー -
2
: Javaコンパイル時にエラー -
3
: プロファイルのカスタマイズ時にエラー -
4
: クラスのインストルメントのエラー(.sqlj
ソース・ファイルから、生成される.class
ファイルへの行番号のマッピング(任意)時のエラー) -
5
:ser2class
変換時のエラー(.ser
ファイルから.class
ファイルへのプロファイル・ファイルの変換(任意)時のエラー)
注意:
-
-help
オプションまたは-version
オプションが指定されている場合は、SQLJ終了コードは0
(ゼロ)です。 -
処理対象のファイルを指定せずにSQLJを実行すると、SQLJによってヘルプ情報が出力され、終了コード
1
が戻されます。
10.3 SQLJランタイム
ここでは、Oracle SQLJランタイムについて説明します。SQLJランタイムは、Pure JavaコードのThinレイヤーで、JDBCドライバよりも上のレイヤーで実行されます。
デフォルトのOracle固有コード生成を使用する場合は、Oracle JDBCドライバとともに使用されるランタイム・サブセットによって、SQLJランタイム・レイヤーがより軽量になります。大部分のランタイム機能は、Oracle JDBCコールに直接コンパイルされます。Oracle以外のJDBCドライバは使用できません。
ISO標準コード生成を使用して、SQLJトランスレータでSQLJソース・コードを変換すると、Javaアプリケーション内の埋込みSQLコマンドはSQLJランタイムへのコールに置き換えられます。ランタイム・クラスは、それに相当するJDBCクラスのラッパーとして機能し、SQLJの特別な機能を提供します。エンド・ユーザーがアプリケーションを実行すると、SQLJランタイムが仲介役となり、プロファイルからSQL操作に関する情報を読み込んでJDBCドライバに命令を渡します。
ただし、一般的にSQLJランタイムは、あらゆるJDBCドライバおよびベンダー固有のデータベース・アクセス手段に対応しています。Oracle SQLJランタイムにはJDBCドライバが必要ですが、どの標準JDBCドライバでも使用できます。ただし、Oracle固有のデータ型や機能を使用する場合は、必ずOracle JDBCドライバを使用してください。このマニュアルでは、Oracle DatabaseとOracle JDBCドライバの1つを使用していることを前提としています。
注意:
ISO標準SQLJコード生成の場合、Oracle SQLJランタイムとOracle JDBCドライバは、変換時にOracleカスタマイザを使用するたびにアプリケーションで必要となるものであり、Oracle拡張型をコード中に使用しない場合にもこのことが当てはまります。アプリケーションでカスタマイズ(接続のための処理)を行わない場合には、汎用SQLJランタイムが使用されます。
10.3.1 SQLJランタイム・パッケージ
Oracle SQLJランタイムのパッケージは、インポートして直接使用できるものもあれば、間接的にしか使用できないものもあります。
注意:
これらのパッケージはランタイム・ライブラリであるruntime12
、runtime12ee
およびruntime
に含まれています。
直接的に使用可能なパッケージ
アプリケーションに直接インポートして使用できるクラスを含むパッケージを次に示します。
-
sqlj.runtime
このパッケージには、
ExecutionContext
クラス、ConnectionContext
インタフェース、ConnectionContextFactory
インタフェース、ResultSetIterator
インタフェース、ScrollableResultSetIterator
インタフェースが含まれ、さらに、ストリーム(BinaryStream
やCharacterStream
、および非推奨のAsciiStream
やUnicodeStream
)に対するラッパー・クラスも含まれています。このパッケージに含まれるインタフェースおよび抽象クラスは、
sqlj.runtime.ref
パッケージやoracle.sqlj.runtime
パッケージ内のクラス、またはSQLJトランスレータによって生成されるクラスによって実装されます。 -
sqlj.runtime.ref
このパッケージのクラスには、
sqlj.runtime
パッケージのインタフェースおよび抽象クラスが実装されます。sqlj.runtime.ref.DefaultContext
クラスを使用して、デフォルト接続を指定し、デフォルト接続コンテキスト・インスタンスを作成できます。このパッケージに含まれるその他のクラスは、コード生成時のクラス定義の際にSQLJで内部的に使用されます。たとえば、SQLJコード中でイテレータ・クラスや接続コンテキスト・クラスなどを宣言するときに使用されます。 -
oracle.sqlj.runtime
このパッケージには、
DefaultContext
クラスのインスタンス化やデフォルト接続の確立に使用するOracle
クラスが含まれています。また、Oracle SQLJで使用されるOracle固有のランタイム・クラスもこのパッケージに含まれ、Oracleの拡張型と他の型との相互変換などが可能となっています。
注意:
名前がoracle
で始まるパッケージには、Oracle固有のSQLJ機能が実装されています。
間接的に使用可能なパッケージ
SQLJで内部的に使用されるクラスを含むパッケージを次に示します。
-
sqlj.runtime.profile
このパッケージには、SQLJプロファイルを定義するインタフェースおよび抽象クラスが含まれています(適用対象はISO標準コード生成のみ)。たとえば、
EntryInfo
クラスやTypeInfo
クラスなどが含まれています。プロファイル内の各エントリは、EntryInfo
オブジェクトで記述されます(このオブジェクトでは、プロファイルのエントリと、アプリケーション内のSQL操作が対応付けられます)。プロファイルのエントリ内の各パラメータは、TypeInfo
オブジェクトで記述されます。このパッケージのインタフェースおよびクラスは、
sqlj.runtime.profile.ref
パッケージ内のクラスによって実装されます。 -
sqlj.runtime.profile.ref
このパッケージには、
sqlj.runtime.profile
パッケージのインタフェースおよび抽象クラスを実装するクラスが含まれており、これらのクラスは、プロファイル定義時にSQLJトランスレータによって内部的に使用されます(ISO標準コード生成の場合のみ)。また、デフォルトのJDBCベースのランタイムの実装にも使用されます。 -
sqlj.runtime.error
このパッケージは、SQLJ内部で使用されます。このパッケージには、SQLJトランスレータによって生成される一般的な(Oracle固有ではない)エラー・メッセージのリソース・ファイルが含まれています。
-
oracle.sqlj.runtime.error
このパッケージは、SQLJ内部で使用されます。このパッケージには、SQLJトランスレータによって生成されるOracle固有のエラー・メッセージのリソース・ファイルが含まれています。
10.3.2 ランタイム・エラーの分類
ランタイム・エラーは、次のいずれかによって生成されます。
-
SQLJランタイム
-
JDBCドライバ
-
RDBMS
いずれの場合も、SQL例外が、java.sql.SQLException
クラスまたはsqlj.runtime.SQLNullException
などのサブクラスのインスタンスとして生成されます。
エラーの発生元によっては、getSQLState()
、getErrorCode()
およびgetMessage()
の各メソッドを使用して、例外から有用な情報を取得できることがあります。たとえば、SQLJエラーには、有用なSQLの状態とメッセージが含まれています。
実行時にOracle JDBCドライバまたはRDBMSでエラーが発生した場合は、メッセージの接頭辞を確認して、次の各マニュアルを参照してください。
-
JDBCエラーについては、『Oracle Database JDBC開発者ガイド』を参照してください
-
RDBMSエラーについては、Oracleエラー・メッセージのドキュメント(「関連ドキュメント」を参照)を参照してください
10.4 トランスレータおよびランタイムでのグローバリゼーション・サポート
Oracle SQLJ実装では、グローバリゼーション・サポートのためにJavaの組込み機能が使用されます。この項では、次の内容について説明します。
-
SQLJにおけるグローバリゼーション・サポートとネイティブ文字エンコーディングの基本事項。文字エンコーディングおよび言語サポートが、Oracle実装でどのように実装されているかを説明します。
-
SQLJコマンドラインでOracleのグローバリゼーション・サポート構成の調整に使用できるオプション。
-
拡張Oracleグローバリゼーション・サポート。
-
グローバリゼーション・サポートのためのSQLJ外部での関連操作。
注意:
ここでは、Oracleのグローバリゼーション・サポートについての知識があることを前提としています。特に、文字エンコーディングおよびロケールについての知識が必要です。詳細は、次を参照してください。:
Oracle Databaseグローバリゼーション・サポート・ガイドこの項の内容は次のとおりです。
10.4.1 文字エンコーディングと言語サポート
SQLJのグローバリゼーション・サポートは、次の2つに大別できます。
-
文字エンコーディング
文字エンコーディングは、3つに分類できます。
-
SQLJ変換時のソース・ファイルの読取りおよび生成のための文字エンコーディング。
-
SQLJ変換時のエラーおよびステータス・メッセージ生成のための文字エンコーディング。
-
アプリケーション実行時のエラーおよびステータス・メッセージ生成のための文字エンコーディング。
-
-
言語サポート
SQLJ変換時またはSQLJ実行時に、SQLJからエラー・メッセージおよびステータス・メッセージが出力される場合に、どの言語のメッセージ・リストを使用するのかを指定します。
実行時のグローバリゼーション・サポートの機能は、データベース・キャラクタ・セットにある文字のみをSQLJソース・コードおよびSQL文字データに使用していることを想定しており、ユーザーは特に意識する必要がありません。SQL文字データとUnicodeとのマッピングは、透過的に行われます。
多言語対応のアプリケーションでは、次のいずれかを使用することをお薦めします。
-
キャラクタ・セットでUnicodeをサポートしているデータベースの使用。
-
データベース・キャラクタ・セットでUnicodeがサポートされていない場合でも、Unicodeをサポートする各国語キャラクタ・セットを指定します。(『Oracle Databaseグローバリゼーション・サポート・ガイド』を参照。)通常、この場合は、SQLJ Unicode文字型を使用します(「SQLJ拡張グローバリゼーション・サポート」を参照)。
注意:
-
SQLJトランスレータでは、Unicode 2.0およびJava Unicodeのエスケープ・シーケンスが完全にサポートされています。これに対しSQLJコマンドライン・ユーティリティでは、Unicodeエスケープ・シーケンスはサポートされていません。そのため、オペレーティング・システムでサポートされているネイティブの文字しか使用できません。コマンドライン・オプションにUnicodeエスケープ・シーケンスの入力が必要な場合は、かわりにSQLJプロパティ・ファイルに入力してください。プロパティ・ファイルではUnicodeエスケープ・シーケンスがサポートされています。
-
埋込みSQL操作で使用される文字と、データベースから読み書きする文字のエンコーディングおよび変換は、JDBCで直接処理されます。SQLJは、これらの処理に介在しません。ただし、変換時にオンラインのセマンティクス・チェックが有効になっていると、データベース・キャラクタ・セットと互換性のない文字がSQLデータ操作言語(DML)操作のテキストに含まれている場合は、警告メッセージが表示されます。
-
JDBCのグローバリゼーション・サポート機能の詳細は、『Oracle Database JDBC開発者ガイド』を参照してください。
文字エンコーディングの概要
SQLJでは、ソース・ファイルの文字エンコーディング設定に従って、次の2つが決定されます。
-
.sqlj
および.java
の入力ファイル内のソース・コードの記述方法。これらのファイルは、SQLJトランスレータが解読できる必要があります。 -
SQLJによって生成された
.java
出力ファイル内のソース・コードの表記方法。
SQLJでは、デフォルトでJVM file.encoding
プロパティで指定されたエンコーディングを使用します。ソース・ファイルに他のエンコーディングを使用している場合は、適切に変換を行うためにSQLJにこのエンコーディングを指定する必要があります。
それには、SQLJの-encoding
オプションを使用します。この-encoding
の設定は、SQLJからコンパイラに渡され、コンパイラで.java
ファイルの読取りに使用されます。ただし、SQLJの-compiler-encoding-flag
が無効の場合を除きます。
注意:
ソース・ファイルの文字エンコーディングを指定するときに、file.encoding
システム・プロパティを変更しないでください。プラットフォームやオペレーティング・システムの環境によっては、Java操作の他の機能に影響し、一部の文字エンコーディングしか利用できなくなる場合があります。
変換時やエンド・ユーザーによるアプリケーション実行時のSQLJメッセージ出力にも、このシステム文字エンコーディング設定が使用されます。この文字エンコーディングは、SQLJの-encoding
オプションとは関係なく、file.encoding
プロパティに従って設定されます。
ソース・ファイルのエンコーディングを指定する場合は、-encoding
オプションを使用すると、Java環境でサポートされる任意の文字エンコーディングを指定できます。Sun MicrosystemsのJDKを使用している場合、これらはnative2ascii
のドキュメントにリストされており、次のWebサイトで参照できます。
https://docs.oracle.com/javase/8/docs/technotes/tools/windows/native2ascii.html
Sun社のJDKでは、数多くの文字エンコーディングがサポートされています。たとえば、8859_1
から8859_9
(ISO Latin-1からISO Latin-9)、JIS
(日本語)、SJIS
(Shift-JIS、日本語)、UTF8
などが含まれています。
文字エンコーディングでの注意事項
以下の点に注意します。
-
メッセージとソース・ファイルのいずれの場合も、使用している文字エンコーディングで表現できない文字は、Java Unicodeエスケープ・シーケンスで表現されます。その形式は、
\uHHHH
(Hは16進数)です。 -
変換時の
.sqlj
ソース・ファイルの読込みと処理で表示されるエラー・メッセージには、入力文字エンコーディング中の(バイト位置ではなく)文字位置により、ソースの位置が示されます。 -
文字エンコーディング設定は、SQLJ
-encoding
オプションまたはJavafile.encoding
のどちらで設定したかにはかかわらず、Javaプロパティ・ファイル(sqlj.properties
やconnect.properties
など)には適用されません。プロパティ・ファイルでは、常に8859_1
エンコーディングを使用します。これは、特別なSQLJの機能ということではなく、一般的なJavaの機能です。ただし、Unicodeのエスケープ・シーケンスなら、プロパティ・ファイルで使用できます。エスケープ・シーケンスを決める際は、native2ascii
ユーティリティを使用することをお薦めします。
言語サポートの概要
SQLJのエラーおよびステータス・レポートでは、変換時または実行時に、JVMのuser.language
プロパティのJavaロケール設定を使用します。通常、ユーザーはこの設定を変更する必要はありません。
言語サポートは、キー/値ペアを使用したメッセージ・リソースを使用して実装されます。たとえば、英語の「OkKey」というキーと「Okay」
という値は、ドイツ語の「OkKey」と「Gut」
に相当します。使用するメッセージ・リソースは、ロケール設定の値で決定されます。
SQLJでサポートされているロケール設定は、en
(英語)、de
(ドイツ語)、fr
(フランス語)およびja
(日本語)です。
注意:
Javaのロケール設定では、言語拡張の他にも、国拡張およびバリアント拡張がサポートされています。たとえば、ErrorMessages_de_CH_var1
について考えてみます。CH
は、ドイツ語の国拡張であるスイスを示します。var1
は追加バリアントです。ただし、現在SQLJでサポートされているのは言語拡張(この例ではde
)のみで、国拡張およびバリアント拡張は無視されます。
10.4.2 SQLJおよびJavaの文字エンコーディングと言語サポートの設定
Oracle SQLJ実装では、次の設定を行う構文が提供されています。
-
SQLJトランスレータおよびJavaコンパイラで、ソース・コードの表示に使用される文字エンコーディング
SQLJの
-encoding
オプションを使用します。 -
SQLJのトランスレータおよびランタイムで、エラー・メッセージやステータス・メッセージの表示に使用される文字エンコーディング
SQLJの接頭辞
-J
を使用して、Javaのfile.encoding
プロパティを設定します。 -
SQLJのトランスレータおよびランタイムで、エラー・メッセージやステータス・メッセージの表示に使用されるロケール
SQLJの接頭辞
-J
を使用して、Javaのuser.language
プロパティを設定します。
ソース・コードの文字エンコーディングの設定
SQLJの-encoding
オプションを使用して、トランスレータで読み込まれる.sqlj
ファイル、トランスレータで生成される.java
ファイル、コンパイラで読み込まれる.java
ファイルの表現に使用されている文字エンコーディングを指定します。オプション設定は、SQLJの-compiler-encoding-flag
がオフになっていなければ、SQLJによってコンパイラに渡されます。
このオプションは、コマンドラインで設定するか、または次の例のように環境変数SQLJ_OPTIONS
を使用して設定します。
-encoding=SJIS
次のように、SQLJプロパティ・ファイルで設定することもできます。
sqlj.encoding=SJIS
エンコーディングのオプションが設定されていない場合、トランスレータとコンパイラでは、JVMのfile.encoding
プロパティで指定されたエンコーディングが使用されます。これは、SQLJコマンドラインからも設定できます。
注意:
-encoding
オプションを常に同じ値に設定する場合は、2番目の例のようにプロパティ・ファイルで設定します。
SQLJメッセージの文字エンコーディングとロケールの設定
変換時と実行時に生成されるSQLJのエラー・メッセージおよびステータス・メッセージの文字エンコーディングおよびロケールは、Javaのfile.encoding
およびuser.language
プロパティで指定します。通常は必要ありませんが、SQLJの-J
接頭辞を使用して、これらのJVMプロパティや他のJVMプロパティをSQLJコマンドラインで設定できます。この接頭辞の付いたオプションは、JVMに渡されます。
文字エンコーディングは、次のように設定します。この例では、日本語の文字エンコーディングであるShift-JISが設定されています。
-J-Dfile.encoding=SJIS
注意:
プラットフォームやオペレーティング・システムの環境によっては、一部の文字エンコーディングしか利用できない場合があります。
ロケールは、次のように設定します。(この例では、日本語が設定されています。)
-J-Duser.language=ja
-J
接頭辞は、コマンドラインまたは環境変数SQLJ_OPTIONS
でのみ使用できます。プロパティ・ファイルでは使用できません(プロパティ・ファイルは、JVMの起動後に読み取られるためです)。
注意:
-
file.encoding
、user.language
などのJavaプロパティを常に同じ値に設定する場合は、環境変数SQLJ_OPTIONS
に-J
を設定しておきます。このように設定すると、コマンドラインで何度も同じ値を指定する必要がありません。この構文は、基本的にコマンドラインの構文と同じです。詳細は、「環境変数SQLJ_OPTIONSによるオプションの設定」を参照してください。 -
SQLJの
-encoding
オプションが設定されていない場合は、file.encoding
の設定がソース・ファイル、エラー・メッセージおよびステータス・メッセージに適用されます。 -
file.encoding
プロパティを変更すると、予測できないところでJava操作が影響される場合があります。新規に設定する場合は、オペレーティング・システムとの互換性に注意する必要があります。
SQLJコマンドラインの例: 文字エンコーディングとロケールの設定
次は、JVMのfile.encoding
およびuser.language
が設定された完全なSQLJコマンドラインの例です。
% sqlj -encoding=8859_1 -J-Dfile.encoding=SJIS -J-Duser.language=ja Foo.sqlj
この例では、SQLJの-encoding
オプションを使用して、SQLJ変換時のソース・コード表示に8859_1
(Latin-1)を指定しています。このエンコーディングは、.sqlj
入力ファイルの読取り時と.java
出力ファイルの生成時に、トランスレータによって使用されます。その後、このエンコーディング設定がJavaコンパイラに渡されて、生成された.java
ファイルの読取り時に使用されます。-encoding
オプションが指定されていると、このオプションはJavaコンパイラに渡されます(ただし、SQLJの-compiler-encoding-flag
が無効に設定されている場合を除きます)。
Foo.sqlj
の変換時にSQLJトランスレータによって出力されるエラー・メッセージおよびステータス・メッセージには、文字エンコーディングとしてSJIS
、ロケールとしてja
が使用されます。
10.4.3 SQLJ拡張グローバリゼーション・サポート
Oracle SQLJ実装には、既存の文字およびストリーム型から導出されたJava型(Unicode文字型)のサポートが含まれています。この型では、グローバリゼーション向けに期待される使用方法が伝達されます。SQLJでは、グローバリゼーション・サポートを目的とするJDBC文または結果セットのメソッドを直接使用することはできません。これらのメソッドの詳細は、『Oracle Database JDBC開発者ガイド』を参照してください
データベースがネイティブにUnicodeをサポートする場合は、次の項で説明する型は不要です。この場合、グローバリゼーション・サポートが透過的に処理されます。ネイティブにUnicodeをサポートしていないが、データベースにUnicodeをサポートする各国語キャラクタ・セットがある場合は、通常これらの型(各国語キャラクタ・セットを使用する列の型)を使用します。
グローバリゼーション・サポートのためのJava型
Oracle SQLJ実装では、グローバリゼーション・サポート用のJava型がいくつか用意されています。次の表に、これらのグローバリゼーション・サポート型と、汎用のJDBCとSQLJの文字およびストリーム型の関係を示します。NString
以外の各グローバリゼーション・サポート型は、JDBCまたはSQLJ型のサブクラスです。
表10-3 JDBC型およびSQLJ型とグローバリゼーション型
JDBC型およびSQLJ型 | グローバリゼーション・サポート型 |
---|---|
JDBC型: |
|
|
|
|
|
|
|
SQLJ型: |
|
|
|
(非推奨。 |
(非推奨。 |
(非推奨。 |
(非推奨。 |
アプリケーションで各国語文字列を処理する必要がある場合、各国語キャラクタ・セットの列との間の各国語文字列の受渡しには、対応する汎用型ではなく、グローバリゼーション・サポート型を使用します。
注意:
-
すべてのグローバリゼーション・サポート型では、
IN
およびOUT
パラメータの使用を自動的に登録する機能が追加されますが、JDBCまたはSQLJ型(コンストラクタなど)の使用方法は同じです。 -
グローバリゼーション・サポート型の使用は、イテレータ列では不要です。基になるネットワーク・プロトコルで、基になる結果セット用に各国語文字が暗黙的にサポートされているためです。
NStringクラスの使用方法と注意事項
oracle.sql.CHAR
クラスおよびそのNCHAR
サブクラスは、データベース・キャラクタ・セットに関する明示的な知識が必要なコンストラクタのみを提供します。したがって、たいていの環境ではjava.lang.String
のラッパーであるoracle.sql.NString
クラスの方が好ましい選択です。NString
クラスにはより簡単なコンストラクタがあり、各国語文字の使用形式が確実にJDBCドライバに登録されます。
次に主要なNString
メソッドを示します。
-
NString(String)
: このコンストラクタでは、既存のString
インスタンスからNString
インスタンスが作成されます。 -
String toString()
: このメソッドでは、基になるString
インスタンスが戻されます。 -
String getString()
: このメソッドでも、基になるString
インスタンスが戻されます。
toString()
メソッドによって、文字列連結式にNString
インスタンスを使用できます(たとえば、"a"+b
の場合、b
が文字列です)。CHAR
スーパークラスにあるgetString()
メソッドは、一貫性のためにもサポートされています。さらに、String
クラスのメンバー・メソッドは、NString
ラッパー・クラスに引き継がれます。これによって、より簡潔なコードを記述できます。
SQLJアプリケーションの場合、Oracle Database 11g より前のバージョンでは、NString
型のホスト変数を使用してNCHAR
型の列をバインドする必要があります。たとえば、次の表の場合を考えます。
CREATE TABLE Tbl1 ( ColA CHAR NColB NCHAR )
SQLJアプリケーションを介してこの表に行を挿入するには、次のようなコードを使用します。
... String v_a = "\uFF5E"; NString v_nb = "\uFF5E"; #sql {INSERT INTO Tbl1 (ColA, NColB) VALUES (:v_a, :v_nb)}; ...
Oracle Database 11g リリース1以降、SQLJアプリケーションはString
変数を使用してNCHAR
列をバインドします。したがって、前述の例は次のように書き換えられます。
... String v_a = "\uFF5E"; String v_nb = "\uFF5E"; #sql {INSERT INTO Tbl1 (ColA, NColB) VALUES (:v_a, :v_nb)}; ...
ただし、String
ホスト変数を使用してNCHAR
列をバインドする場合、次のように、SQLJトランスレータ・オプション-ncharconv
を使用してSQLJファイルを変換する必要があります。
sqlj -ncharconv [-options] app.sqlj
前述のコマンドでは、options
に他のSQLJオプションを指定でき、app.sqlj
はコードを含むSQLJファイルです。
このオプションを使用すると、文字型列(CHAR
列またはNCHAR
列)へのすべてのバインドに対してsetFormOfUse
メソッドが生成されます。
注意:
-ncharconv
オプションを指定してSQLJファイルをコンパイルすると、codegen=oracle
の生成コードでsetFormOfUse
メソッドが使用されます。codegen=iso
の場合、このオプション情報は、バインドの実行時にSetFormOfUse
を内部的に使用するOracle SQLJランタイムに渡されます。
SQLJアプリケーションでは、-ncharconv
オプションを使用せずに、String
ホスト変数を使用してサーバーからデータを取得できます。これは、列型に関する情報がクライアント側でフェッチされ、JDBCによって該当する列の形式が内部的に設定されるためです。
注意:
-ncharconv
オプションを使用する場合、データベース・キャラクタ・セット、各国語キャラクタ・セットおよび表内の文字型列の数によって、パフォーマンスが多少異なる場合があります。
グローバリゼーション・サポートの例
次の例では、NString
クラスの使用を説明しています。
-
IN
引数としてのNString
この例では、
NString
インスタンスをデータベースへの入力パラメータとして使用します。import oracle.sql.NString; ... NString nc_name = new NString("Name with strange characters"); #sql { update PEOPLE set city = :(new NString("\ufff2")), name = :nc_name where num= :n }; ...
-
OUT
引数としてのNString
この例では、
NString
インスタンスをデータベースからの出力パラメータとして使用します。import oracle.sql.NString; ... NString nstr; #sql { call foo(:out nstr) }; System.out.println("Result is: "+nstr); // or, explicitly: System.out.println("Result is: "+nstr.toString()); ...
-
結果セット
列としてのNString
この例では、イテレータ列に
NString
型を使用します。このような使用方法は不要ですが、基になるネットワーク・プロトコルで各国語文字を暗黙的にサポートしているため特に問題とはなりません。またこの例では、NString
に引き継がれるString
メソッドの1つであるsubstring()
の使用方法を示しています。import oracle.sql.NString; import oracle.sql.NCLOB; ... #sql iterator NIter(NString title, NCLOB article); NIter nit; #sql nit = { SELECT article, title FROM page_table }; while (nit.next()) { System.out.println("<TITLE>"+nit.title()+"</TITLE>"); ... nit.article().substring(0, 1000); ... }
注意:
前述の例でNString
型ではなくてNCHAR
型を使用するには、次のように変更する必要があります。
-
適切な
NCHAR
コンストラクタを使用します。次のように、NCHAR
コンストラクタはCHAR
コンストラクタを反映しています。NCHAR(String str, oracle.sql.CharacterSet charset)
-
NString
インスタンスからその基になるString
を取得するには、toString()
またはgetString()
のいずれかを使用できますが、NCHAR
インスタンスの場合、getString()
メソッドを使用する必要があります。NString
型を使用する場合、文字列連結にはtoString()
メソッドが自動的に使用されます。
10.4.4 SQLJ外部でのグローバリゼーション・サポート用の操作
ここでは、SQLJ外でのOracleグローバリゼーション・サポートの設定の操作方法について説明します。
アプリケーションの実行時に行う文字エンコーディングとロケールの設定
通常のJavaアプリケーションと同じように、JVMを起動してSQLJアプリケーションを実行する際に、file.encoding
やuser.language
などのJVMのプロパティを直接指定できます。これにより、アプリケーション実行時に出力されるメッセージに使用される文字エンコーディングおよびロケールが決定します。
たとえば、次のように指定します。
% java -Dfile.encoding=SJIS -Duser.language=ja Foo
この場合、文字エンコーディングにはSJIS
が使用され、ロケールには日本語が使用されます。
APIによるJavaプロパティの設定
JavaコードでJavaプロパティの値を確認するには、java.lang.System.getProperty()
メソッドを使用し、該当のプロパティを指定します。次に例を示します。
public class Settings { public static void main (String[] args) { System.out.println("Encoding: " + System.getProperty("file.encoding") + ", Language: " + System.getProperty("user.language")); } }
このコードをコンパイルすると、スタンドアロン・ユーティリティとして実行できます。
すべてのプロパティの値を戻り値とするgetProperties()
メソッドもあります。ただし、サーバー側で実行されるコード中にこのメソッドを使用すると、セキュリティの例外が生成されます。
native2asciiによるソース・ファイルの文字エンコーディングの変換
Sun社のJDKを使用している場合は、SQLJを使用せずにソース・コードの文字エンコーディングを変換できます。native2ascii
というユーティリティを使用すると、ネイティブな文字エンコーディングのソースが、Unicodeエスケープ・シーケンスを使用した7ビットASCIIに変換されます。
注意:
native2ascii
で生成されたソース・コードをSQLJで変換する場合は、SQLJを起動する側のJVMのfile.encoding
に、7ビットASCIIのスーパーセットをサポートする文字エンコーディングを設定するようにしてください。EBCDICまたはUnicodeの場合は、この設定は必要ありません。
native2ascii
を実行するには、次のように指定します。
% native2ascii <options> <inputfile> <outputfile>
入力ファイルまたは出力ファイルが指定されていない場合は、標準入力または標準出力が使用されます。このコマンドでは、次の2つのオプションを使用できます。
-
-reverse
(逆変換を行います。つまり、Latin-1またはUnicodeからネイティブ・コードに変換します。) -
-encoding <
encoding
>
次に例を示します。
% native2ascii -encoding SJIS Foo.sqlj Temp.sqlj
詳細は次のWebサイトを参照してください。
https://docs.oracle.com/javase/8/docs/technotes/tools/windows/native2ascii.html