8 エラー処理および診断
アプリケーション・プログラムでは、ランタイム・エラーを予想し、そのエラーをリカバリするように対処する必要があります。この章では、エラー・レポートおよびリカバリを詳しく説明します。具体的には、状態変数SQLCODE、SQLSTATE、SQLCA(SQLコミュニケーション領域)およびWHENEVER
文を使用して警告およびエラーを処理する方法を説明します。さらに状態変数ORACA(Oracle通信領域)による問題点の診断方法も紹介します。次の内容について説明します。
8.1 エラー処理の必要性
どのようなアプリケーション・プログラムでも、その大部分をエラー処理に充てる必要があります。エラー処理の主な利点は、エラーが発生しても、プログラムの処理を続行できることです。エラーは、設計ミス、コーディングの誤り、ハードウェアの障害、無効なユーザー入力、その他様々な原因で発生します。
潜在的なエラーをすべて予測するのは無理ですが、プログラムにとって意味のある特定の種類のエラーについてアクションを考えることはできます。Oracleプリコンパイラにとって、エラー処理とはSQL文の実行エラーの検出およびリカバリのことです。
値が切り捨てられたことを示す警告やデータの終わりなどの状態の変更も処理できます。INSERT
文、UPDATE
文またはDELETE
文は、表内の処理対象行すべてを処理する前に失敗することがあるため、データ操作文を実行するたびにエラー状態および警告状態がないか調べることが特に重要です。
8.2 エラー処理の代替手段
Oracleプリコンパイラには、エラー処理の手段として役立つ4種類の状態変数が用意されています。
MODEオプションは、ANSI/ISOの準拠を制御します。SQLCODE変数、SQLSTATE変数およびSQLCA変数の可用性は、MODE設定によって異なります。ORACA変数は、MODE設定に関係なく宣言して使用できます。詳細は、Oracle通信領域の使用についてを参照してください。
MODE={ORACLE|ANSI13}
の場合、SQLCA状態変数を宣言する必要があります。SQLCODE宣言およびSQLSTATE宣言も指定できますが(お薦めはできません)、状態変数としては認識されません。詳細は、SQL通信領域の使用についてを参照してください。
MODE={ANSI|ANSI14}
の場合、SQLCODE変数、SQLSTATE変数およびSQLCA変数のうちの任意の1つ、2つあるいは3つすべてを使用できます。アプリケーションに最適な変数(または変数の組合せ)を確認するには、MODE={ANSI|ANSI14}の場合の状態変数の使用についてを参照してください。
8.2.1 SQLCODEおよびSQLSTATE
Oracleプリコンパイラのリリース1.5では、SQLCODE状態変数が、SQL89標準ANSI/ISOエラー・レポート・メカニズムとして導入されました。SQL92標準では、SQLCODEが非推奨機能としてあげられ、新しい状態変数SQLSTATE(Oracleプリコンパイラのリリース1.6で導入)が推奨ANSI/ISOエラー・レポート・メカニズムとして定義されました。
SQLCODEには、エラー・コードおよび見つからない状態が格納されています。これは、SQL89との互換性のためのみに保持されており、標準の将来のバージョンからは削除される見込みです。
SQLCODEとは異なり、SQLSTATEにはエラーおよび警告のコードが格納され、標準化されたコード体系を使用します。SQL文を実行すると、Oracleサーバーからは、現在有効範囲内にあるSQLSTATE変数にステータス・コードが戻されます。ステータス・コードは、SQL文が正常に実行されたか、あるいは例外(エラーまたは警戒の状態)が発生したかを示します。相互運用性(システムが情報を容易に交換する能力)を高めるために、SQL92では、すべての一般的なSQL例外が事前に定義されています。
8.2.2 SQLCA
SQLCAは、レコードに似たホスト言語データ構造体です。Oracleでは、すべての実行SQL文の後でSQLCAが更新されます。(宣言部の後では、SQLCAの値は未定義になります。)SQLCAに格納されているOracleリターン・コードをチェックすることで、プログラムはSQL文の結果を判断できます。これには2通りの方法があります。
-
WHENEVER文による暗黙的なチェック
-
SQLCA変数の明示的なチェック
WHENEVER
文、SQLCA変数に対するコードの明示的チェックを使用するか、あるいは両方を使用できます。一般的に、WHENEVER
文を使用する方が簡単で、移植性も高く、ANSI準拠であるためお薦めします。
8.2.3 ORACA
ランタイム・エラーについてSQLCAから得られる情報が十分でない場合、カーソル統計、SQL文データ、オプション設定およびシステム統計が格納されているORACAを使用できます。
ORACAはオプションであり、MODEの設定に関係なく宣言できます。ORACA状態変数の詳細は、Oracle通信領域の使用についてを参照してください。
8.3 MODE={ANSI|ANSI14}の場合の状態変数の使用について
MODE={ANSI|ANSI14}
の場合、次の状態変数の少なくとも1つを宣言する必要があります(2つあるいは3つ全部を宣言してもかまいません)。
Pro*COBOLでは、SQLCAが宣言されていれば、SQLCODEは宣言できません。同様に、SQLCODEが宣言されていれば、SQLCAは宣言できません。SQLCAデータ構造のフィールドにはPro*COBOL用のエラー・コードが格納されており、SQLCODEとも呼ばれ、そのためこれら2つの状態変数を宣言するとエラーが発生します。
プログラムでは、実行SQL文およびPL/SQL文の後で、独自のコードを使用して明示的にSQLCODEおよびSQLSTATE、SQLCODEまたはSQLSTATEをチェックすることで、最新の実行SQL文の結果を取得できます。また、SQLCAを暗黙的にチェックすることも(WHENEVER
SQLERROR文およびWHENEVER
SQLWARNING文を使用)、SQLCA変数を明示的にチェックすることもできます。
ノート:
MODE={ORACLE|ANSI13}
の場合、SQLCA状態変数を宣言する必要があります。詳細は、SQL通信領域の使用についてを参照してください。
8.3.2 リリース1.5
Oracle Precompilerのリリース1.5では、宣言部で宣言されたかどうかに関係なく、ステータス変数SQLCODEが存在すると想定していました。実際、プリコンパイラは、SQLCODEのための宣言があるかどうかをチェックせず、ただ宣言が存在すると想定していました。SQLCAが状態変数として使用されるのは、SQLCAのINCLUDE
が存在する場合のみでした。
8.3.3 リリース1.6
Oracleプリコンパイラ・リリース1.6から、プリコンパイラでは、SQLCODE状態変数があると仮定しなくなり、SQLCODE状態変数は必須ではありません。SQLCA、SQLCODEまたはSQLSTATEのうち少なくとも1つを宣言する必要があります。
SQLCODEは、少なくとも次の基準の1つが満たされたときにかぎり、状態変数として認識されます。
-
宣言部で完全に正しいデータ型で宣言されている場合。
-
プリコンパイラで他の状態変数が見つからない場合。
プリコンパイラが宣言部で(完全に正しい型の)SQLSTATE宣言を検出した場合、またはSQLCAのINCLUDE
を検出した場合には、SQLCODEが宣言されているとはみなしません。
8.3.4 リリース1.7
Oracleプリコンパイラのリリース1.5では、SQLCODE変数を宣言部の外部で宣言できたのに対し、リリース1.6以降のプリコンパイラでは、同時にSQLCAを宣言すると、互換性の問題が生じます。これを修正するために、リリース1.6.7では新しいオプションASSUME_SQLCODE={YES|NO}
(デフォルトはNO)が追加され、リリース1.7で新機能として文書化されました。
ASSUME_SQLCODE=YES
と指定した場合、SQLSTATEまたはSQLCA(Pro*FORTRANのみ)が状態変数として宣言されると、宣言部で宣言されているかどうか、あるいは正しい型かどうかに関係なく、プリコンパイラではSQLCODEが宣言されているものとみなします。このため、リリース1.6.7以降は、この点でリリース1.5と同様の動作をします。プリコンパイラ・オプションASSUME_SQLCODEの詳細は、「ASSUME_SQLCODE」を参照してください。
8.3.6 SQLCODEの宣言
SQLCODE(Pro*FORTRANではSQLCOD)は、表8-1に示すように、宣言部の内側または外側のいずれかで、4バイト整数変数として宣言する必要があります。
表8-1 SQLCODEの宣言
言語 | SQLCODEの宣言 |
---|---|
COBOL |
SQLCODE PIC S9(9) COMP. |
FORTRAN |
INTEGER*4 SQLCOD |
宣言部の外部で宣言すると、SQLCODEは、ASSUME_SQLCODE=YESの場合にのみ状態変数として認識されます。MODE={ORACLE|ANSI13}
の場合、SQLCODEの宣言は無視されます。
警告:
Pro*COBOLソース・ファイルでは、SQLCAが宣言されている場合は、SQLCODEを宣言しないでください。同様に、SQLCODEが宣言されている場合は、SQLCAを宣言しないでください。SQLCA構造体によって宣言される状態変数もSQLCODEという名前なので、両方のエラー・レポート・メカニズムを使用するとエラーが発生します。
ローカルとグローバルの両方の宣言が可能なホスト言語を使用することにより、複数のSQLCODE変数を宣言できます。ローカルSQLCODEへのアクセスは、プログラム内の有効範囲により制限されます。SQLの動作が終わるたびに、Oracleから現在有効範囲にあるSQLCODEにステータス・コードが戻されます。したがって、プログラムでは、SQLCODEを明示的にチェックするか、WHENEVER
文で暗黙的にチェックして、最近のSQL動作の結果を確認できます。
特定のコンパイル・ユニットのSQLCAのかわりにSQLCODEを宣言すると、プリコンパイラでは、そのユニット用に内部SQLCAを1つ割り当てます。ホスト・プログラムでは、その内部SQLCAにアクセスできません。SQLCAとSQLCODE(Pro*COBOLでは非対応)を宣言すると、OracleからはSQLの動作が終わるたびに、両方に同じステータス・コードが戻されます。
8.3.7 SQLSTATEの宣言
SQLSTATE(Pro*FORTRANではSQLSTA)は、表8-2に示すように、宣言部内5文字の英数字文字列として宣言する必要があります。SQLCAの宣言はオプションです。
表8-2 SQLSTATEの宣言
言語 | SQLSTATEの宣言 |
---|---|
COBOL |
SQLSTATE PIC X(5). |
FORTRAN |
CHARACTER*5 SQLSTA |
8.3.8 状態変数の組合せ
MODE={ANSI|ANSI14}
の場合、状態変数の動作は、次の条件によって決まります。
-
宣言されている変数
-
宣言の配置(宣言部の内側か外側か)
-
ASSUME_SQLCODE設定
表8-3および表8-4では、ASSUME_SQLCODE=NOおよびASSUME_SQLCODE=YESのそれぞれの場合、各状態変数の組合せがどのような動作になるかを説明しています。
表8-3 状態変数の組合せ - SQLCODE = NO
宣言部(内/外/ --) | 動作 | ||
---|---|---|---|
SQLCODE |
SQLSTATE |
SQLCA |
|
外 |
-- |
-- |
SQLCODEが宣言され、状態変数であるとみなされます。 |
外 |
-- |
外 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、SQLCAが状態変数として宣言され、SQLCODEは宣言されますが、状態変数とは認識されません。 |
外 |
-- |
内 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、この状態変数の構成はサポートされていません。 |
外 |
外 |
-- |
SQLCODEが宣言され、状態変数とみなされます。SQLSTATEは宣言されますが、状態変数とは認識されません。 |
外 |
外 |
外 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、SQLCAが状態変数として宣言され、SQLCODEおよびSQLSTATEは宣言されますが、状態変数とは認識されません。 |
外 |
外 |
内 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、この状態変数の構成はサポートされていません。 |
外 |
内 |
-- |
SQLSTATEが状態変数として宣言されます。SQLCODEは宣言されますが、状態変数とは認識されません。 |
外 |
内 |
外 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、SQLSTATEおよびSQLCAが状態変数として宣言され、SQLCODEは宣言されますが、状態変数とは認識されません。 |
外 |
内 |
内 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、この状態変数の構成はサポートされていません。 |
内 |
-- |
-- |
SQLCODEが状態変数として宣言されます。 |
内 |
-- |
外 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、SQLCODEおよびSQLCAが状態変数として宣言されます。 |
内 |
-- |
内 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、この状態変数の構成はサポートされていません。 |
内 |
外 |
-- |
SQLCODEが状態変数として宣言されます。SQLSTATEは宣言されますが、状態変数とは認識されません。 |
内 |
外 |
外 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、SQLCODEおよびSQLCAが状態変数として宣言され、SQLSTATEは宣言されますが、状態変数とは認識されません。 |
内 |
外 |
内 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、この状態変数の構成はサポートされていません。 |
内 |
内 |
-- |
SQLCODEおよびSQLSTATEが状態変数として宣言されます。 |
内 |
内 |
外 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、SQLCODE、SQLSTATEおよびSQLCAが状態変数として宣言されます。 |
内 |
内 |
内 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、この状態変数の構成はサポートされていません。 |
-- |
-- |
-- |
この状態変数の構成はサポートされていません。 |
-- |
-- |
外 |
SQLCAが状態変数として宣言されます。 |
-- |
-- |
内 |
Pro*COBOLでは、SQLCAが状態ホスト変数として宣言されます。Pro*FORTRANでは、この状態変数の構成はサポートされていません。 |
-- |
外 |
-- |
この状態変数の構成はサポートされていません。 |
-- |
外 |
外 |
SQLCAが状態変数として宣言されます。SQLSTATEは宣言されますが、状態変数とは認識されません。 |
-- |
外 |
内 |
Pro*COBOLでは、SQLCAが状態ホスト変数として宣言され、SQLSTATEは宣言されますが、状態変数とは認識されません。Pro*FORTRANでは、この状態変数の構成はサポートされていません。 |
-- |
内 |
-- |
SQLSTATEが状態変数として宣言されます。 |
-- |
内 |
外 |
SQLSTATEおよびSQLCAが状態変数として宣言されます。 |
-- |
内 |
内 |
Pro*COBOLでは、SQLSTATEおよびSQLCAが状態ホスト変数として宣言されます。Pro*FORTRANでは、この状態変数の構成はサポートされていません。 |
表8-4 状態変数の組合せ - SQLCODE = YES
宣言部(内/外/ --) | 動作 | ||
---|---|---|---|
SQLCODE |
SQLSTATE |
SQLCA |
|
外 |
-- |
-- |
SQLCODEが宣言され、状態変数であるとみなされます。 |
外 |
-- |
外 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、SQLCAが状態変数として宣言され、SQLCODEは宣言されますが、状態変数とはみなされません。 |
外 |
-- |
内 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、この状態変数の構成はサポートされていません。 |
外 |
外 |
-- |
SQLCODEが宣言され、状態変数とみなされます。SQLSTATEは宣言されますが、状態変数とは認識されません。 |
外 |
外 |
外 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、SQLCAが状態変数として宣言され、SQLCODEは宣言されて状態変数とみなされ、SQLSTATEは宣言されますが、状態変数とは認識されません。 |
外 |
外 |
内 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、この状態変数の構成はサポートされていません。 |
外 |
内 |
-- |
SQLSTATEが状態変数として宣言されます。SQLCODEは宣言されますが、状態変数とはみなされません。 |
外 |
内 |
外 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、SQLSTATEおよびSQLCAが状態変数として宣言され、SQLCODEは宣言されて状態変数とみなされます。 |
外 |
内 |
内 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、この状態変数の構成はサポートされていません。 |
内 |
-- |
-- |
SQLCODEが状態変数として宣言されます。 |
内 |
-- |
外 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、SQLCODEおよびSQLCAが状態変数として宣言されます。 |
内 |
-- |
内 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、この状態変数の構成はサポートされていません。 |
内 |
外 |
-- |
SQLCODEが状態変数として宣言されます。SQLSTATEは宣言されますが、状態変数とは認識されません。 |
内 |
外 |
外 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、SQLCODEおよびSQLCAが状態変数として宣言され、SQLSTATEは宣言されますが、状態変数とは認識されません。 |
内 |
外 |
内 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、この状態変数の構成はサポートされていません。 |
内 |
内 |
-- |
SQLCODEおよびSQLSTATEが状態変数として宣言されます。 |
内 |
内 |
外 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、SQLCODE、SQLSTATEおよびSQLCAが状態変数として宣言されます。 |
内 |
内 |
内 |
Pro*COBOLでは、この状態変数の構成はサポートされていません。Pro*FORTRANでは、この状態変数の構成はサポートされていません。 |
-- -- -- -- -- -- -- -- -- |
-- -- -- 外 外 外 内 内 内 |
-- 外 内 -- 外 内 -- 外 内 |
これらの状態変数の構成はサポートされていません。SQLCODEは、ASSUME_SQLCODE=YESの場合、宣言部の内側または外側のいずれかで宣言する必要があります。 |
8.3.9 状態変数の値
この項では、SQLCODE状態変数およびSQLSTATE状態変数の値について説明します。SQLCA状態変数については、エラー・レポートの主要コンポーネントを参照してください。
8.3.10 SQLCODE値
SQLの動作が終わるたびに、Oracleから現在有効範囲にあるSQLCODE変数にステータス・コードが戻されます。SQLの動作の結果を示すステータス・コードは、次のいずれかの数値です。
0
OracleではSQL文が実行され、エラーも例外も検出されませんでした。
> 0
Oracleは文を実行しましたが、例外を検出しました。これは、WHERE
句の条件を満たす行が見つからなかった場合、あるいはSELECT
INTO
またはFETCH
で行が戻されなかった場合に発生します。
MODE={ANSI|ANSI14|ANSI13}
の場合、行のINSERT
がなかったときに+100がSQLCODEに戻されます。副問合せで処理に行が戻されなかったときにこの状態が発生します。
< 0
データベース、システム、ネットワークまたはアプリケーションのいずれかにエラーが発生したため、Oracleは文を実行しませんでした。このようなエラーはリカバリ不能です。このようなエラーが発生すると、ほとんどの場合はカレント・トランザクションがロールバックされます。負のリターン・コードは、『Oracle Databaseエラー・メッセージ』に記載されているエラー・コードに対応しています。
最近のSQLの動作の結果は、SQLCODEを独自のコードで明示的にチェックするか、WHENEVER
文で暗黙的にチェックすることで確認できます。
特定のプリコンパイル・ユニットのSQLCAのかわりにSQLCODEを宣言すると、プリコンパイラでは、そのユニット用に内部SQLCAを1つ割り当てます。ホスト・プログラムでは、その内部SQLCAにアクセスできません。SQLCAとSQLCODE(Pro*FORTRANのみ)を宣言すると、OracleからはSQLの動作が終わるたびに、両方に同じステータス・コードが戻されます。
ノート:
MODE={ORACLE|ANSI13}
の場合、SQLCODEの宣言は無視されます。
8.3.11 SQLSTATE値
SQLSTATE状態コードは、2文字のクラス・コードおよびその後に続く3文字のサブクラス・コードで構成されます。クラス・コード00は正常終了を示し、それ以外のクラス・コードは例外のカテゴリを示します。サブクラス・コード000は特定の例外を示しませんが、それ以外のサブクラス・コードはそのカテゴリの中の特定の例外を示します。たとえば、SQLSTATE値22012は、クラス・コード22(データ例外)とサブクラス・コード012(ゼロ除算)で構成されています。
SQLSTATE値の5文字はそれぞれ、数字(0から9)または大文字の英字(AからZ)です。0から4の数字、あるいはAからHの文字で始まるクラス・コードは、事前定義の条件(SQL92で定義されている条件)用に予約されています。他のすべてのクラス・コードは実装定義の状態用に確保されています。事前定義クラスのうち、0から4の数字またはAからHの文字で始まるサブクラス・コードは、事前定義の副条件用に予約されています。他のすべてのサブクラス・コードは、実装時に定義される副条件用に予約されています。図8-1は、コード体系を示しています。
表8-5は、SQL92で事前に定義されているクラスを示しています。
表8-5 事前に定義されたSQL92のクラス
クラス | 状態 |
---|---|
00 |
正常終了 |
01 |
警告 |
02 |
データなし |
07 |
動的SQLエラー |
08 |
接続の例外 |
0A |
機能がサポートされていない |
21 |
カーディナリティ違反 |
22 |
データの例外 |
23 |
整合性制約違反 |
24 |
カーソル状態が無効 |
25 |
トランザクション状態が無効 |
26 |
SQL文名が無効 |
27 |
トリガー・データの変更違反 |
28 |
認証の指定が無効 |
2A |
直接SQL構文エラーまたはアクセス規則違反 |
2B |
依存権限記述子がまだ存在しています。 |
2C |
文字セット名が無効 |
2D |
トランザクションの終了が無効 |
2E |
接続名が無効 |
33 |
SQL記述子名が無効 |
34 |
カーソル名が無効 |
35 |
状態番号が無効 |
37 |
動的SQL構文エラーまたはアクセス規則違反 |
3C |
カーソル名があいまい |
3D |
カタログ名が無効 |
3F |
スキーマ名が無効 |
40 |
トランザクション・ロールバック |
42 |
構文エラーまたはアクセス規則違反 |
44 |
WITH_CHECK_OPTION指定違反 |
HZ |
リモート・データベース・アクセス |
ノート:
クラス・コードHZは、国際標準規格ISO/IEC DIS 9579-2で定義された条件であるリモート・データベース・アクセス用に確保されています。
表8-6 は、OracleのエラーとSQLSTATEステータス・コードの対応を示しています。1つのステータス・コードに複数のOracleエラーが対応する場合もあります。その他の場合、ステータス・コードに対応するOracleエラーはありません(したがって、最後の列は空)。60000から99999の範囲のステータス・コードは、実装定義です。
表8-6 OracleエラーとSQLSTATEステータス・コードの対応
コード | 状態 | Oracleエラー |
---|---|---|
00000 |
正常終了 |
ORA-00000 |
01000 |
警告 |
|
01001 |
カーソル操作の競合 |
|
01002 |
切断エラー |
|
01003 |
集合関数でのNULL値が排除 |
|
01004 |
文字列データの右側切捨て |
|
01005 |
項目記述子領域が不十分 |
SQL-02142 |
01006 |
権限が取り消されていない |
|
01007 |
権限が付与されていない |
|
01008 |
暗黙的なゼロビットの埋込み |
|
01009 |
情報スキーマの検索条件が長すぎます。 |
|
0100A |
情報スキーマの問合せ式が長すぎます。 |
|
02000 |
データなし |
ORA-01095 ORA-01403 ORA-0100 |
07000 |
動的SQLエラー |
SQL-02137 SQL-02139 |
07001 |
USING句がパラメータ指定と一致しません。 |
|
07002 |
USING句が相手指定と一致しません。 |
|
07003 |
カーソル仕様を実行できません。 |
|
07004 |
動的パラメータにはUSING句が必要です。 |
|
07005 |
プリコンパイルされたSQL文がカーソル仕様ではありません。 |
|
07006 |
制限付きのデータ型属性違反 |
|
07007 |
結果フィールドにはUSING句が必要です。 |
|
07008 |
記述子の数が無効 |
SQL-02126 SQL-02141 |
07009 |
記述子の索引が無効 |
SQL-02140 |
08000 |
接続の例外 |
|
08001 |
SQLのクライアントがSQL接続を確立できません。 |
|
08002 |
接続名の重複 |
|
08003 |
接続が存在しません。 |
SQL-02121 |
08004 |
SQLサーバーによるSQL接続の拒絶 |
|
08006 |
接続の失敗 |
|
08007 |
トランザクションの結果が不明 |
|
0A000 |
機能がサポートされていない |
ORA-03000~03099 |
0A001 |
複数のサーバー・トランザクション |
|
21000 |
カーディナリティ違反 |
ORA-01427 SQL-02112 ORA-01422 |
22000 |
データの例外 |
|
22001 |
文字列データの右側切捨て |
ORA-01401 ORA-01406 ORA-12899 |
22002 |
NULL値(インジケータ・パラメータなし) |
ORA-01405 SQL-02124 |
22003 |
数値が範囲外 |
ORA-01426 ORA-01438 ORA-01455 ORA-01457 |
22005 |
割当てのエラー |
|
22007 |
日時書式が無効 |
|
22008 |
日時フィールドのオーバーフロー |
ORA-01800~01899 |
22009 |
タイム・ゾーンによる時差が無効 |
|
22011 |
部分文字列のエラー |
|
22012 |
ゼロによる除算 |
ORA-01476 |
22015 |
間隔フィールドのオーバーフロー |
|
22018 |
キャストの文字値が無効 |
|
22019 |
エスケープ文字が無効 |
ORA-00911 ORA-01425 |
22021 |
レパートリに文字がありません。 |
|
22022 |
インジケータのオーバーフロー |
ORA-01411 |
22023 |
パラメータ値が無効 |
ORA-01025 ORA-01488 ORA-04000~04019 |
22024 |
C文字列が未終了 |
ORA-01479~01480 |
22025 |
エスケープ・シーケンスが無効 |
ORA-01424 |
22026 |
文字列データの長さ不一致 |
|
22027 |
切捨てエラー |
|
23000 |
整合性制約違反 |
ORA-00001 ORA-01400 ORA-02290~02299 |
24000 |
カーソル状態が無効 |
ORA-01001から01003 ORA-01410 ORA-06511 ORA-08006 SQL-02114 SQL-02117 SQL-02118 SQL-02122 |
25000 |
トランザクション状態が無効 |
|
26000 |
SQL文名が無効 |
|
27000 |
トリガー・データの変更違反 |
|
28000 |
認証の指定が無効 |
|
2A000 |
直接SQL構文エラーまたはアクセス規則違反 |
|
2B000 |
依存権限記述子がまだ存在しています。 |
|
2C000 |
文字セット名が無効 |
|
2D000 |
トランザクションの終了が無効 |
|
2E000 |
接続名が無効 |
|
33000 |
SQL記述子名が無効 |
SQL-02138 |
34000 |
カーソル名が無効 |
|
35000 |
状態番号が無効 |
|
37000 |
動的SQL構文エラーまたはアクセス規則違反 |
|
3C000 |
カーソル名があいまい |
|
3D000 |
カタログ名が無効 |
|
3F000 |
スキーマ名が無効 |
|
40000 |
トランザクション・ロールバック |
ORA-02091~02092 |
40001 |
シリアライズの失敗 |
|
40002 |
整合性制約違反 |
|
40003 |
文の完了が不明 |
|
42000 |
構文エラーまたはアクセス規則違反 |
ORA-00022 ORA-00251 ORA-00900から00999 ORA-01031 ORA-01490から01493 ORA-01700から01799 ORA-01900から02099 ORA-02140から02289 ORA-02420から02424 ORA-02450から02499 ORA-03276から03299 ORA-04040から04059 ORA-04070から04099 |
44000 |
WITH_CHECK_OPTION指定違反 |
ORA-01402 |
60000 |
システム・エラー |
ORA-00370から00429 ORA-00600から00899 ORA-06430から06449 ORA-07200から07999 ORA-09700から09999 |
61000 |
リソース・エラー |
ORA-00018から00035 ORA-00050から00068 ORA-02376から02399 ORA-04020から04039 |
62000 |
共有サーバーおよび分離プロセスのエラー |
ORA-00101~00120 ORA-00440~00569 |
63000 |
Oracle*XAおよび2タスク・インタフェースのエラー |
ORA-00150から00159 SQL-02128 ORA-02700から02899 ORA-03100から03199 ORA-06200から06249 SQL-02128 |
64000 |
制御ファイル、データベース・ファイルおよびREDOファイルのエラー、アーカイブおよびメディア・リカバリのエラー |
ORA-00200~00369 ORA-01100~01250 |
65000 |
PL/SQLのエラー |
ORA-06500~06599 |
66000 |
SQL*Netドライバのエラー |
ORA-06000から06149 ORA-06250から06429 ORA-06600から06999 ORA-12100から12299 ORA-12500から12599 |
67000 |
ライセンス許可のエラー |
ORA-00430~00439 |
69000 |
SQL*Connectのエラー |
ORA-00570~00599 ORA-07000~07199 |
72000 |
SQL実行フェーズのエラー |
ORA-01000から01099 ORA-01400から01489 ORA-01495から01499 ORA-01500から01699 ORA-02400から02419 ORA-02425から02449 ORA-04060から04069 ORA-08000から08190 ORA-12000から12019 ORA-12300から12499 ORA-12700から21999 |
82100 |
メモリー不足のためメモリーが割り当てられません。 |
SQL-02100 |
82101 |
無効なカーソル・キャッシュです。ユニット・カーソル/グローバル・カーソルが一致しません。 |
SQL-02101 |
82102 |
無効なカーソル・キャッシュです。グローバル・カーソル・エントリがありません。 |
SQL-02102 |
82103 |
無効なカーソル・キャッシュです。カーソル・キャッシュ参照の範囲を超えています。 |
SQL-02103 |
82104 |
無効なホスト・キャッシュです。使用可能なカーソル・キャッシュがありません。 |
SQL-02104 |
82105 |
無効なカーソル・キャッシュです。グローバル・カーソルがありません。 |
SQL-02105 |
82106 |
無効なカーソル・キャッシュ(無効なOracleカーソル番号) |
SQL-02106 |
82107 |
ランタイム・ライブラリに対して古すぎるプログラム |
SQL-02107 |
82108 |
ランタイム・ライブラリに渡された無効な記述子 |
SQL-02108 |
82109 |
無効なホスト・キャッシュです。ホスト参照が範囲外です。 |
SQL-02109 |
82110 |
無効なホスト・キャッシュです。ホスト・キャッシュ・エントリの型が無効です。 |
SQL-02110 |
82111 |
ヒープ一貫性エラー |
SQL-02111 |
82112 |
メッセージ・ファイルをオープンできません。 |
SQL-02113 |
82113 |
コード生成の内部整合性の障害 |
SQL-02115 |
82114 |
リエントラント・コード・ジェネレータが無効なコンテキストを与えました。 |
SQL-02116 |
82115 |
hstdef引数が無効 |
SQL-02119 |
82116 |
sqlrcnの第1引数および第2引数が両方ともNULLです。 |
SQL-02120 |
82117 |
データベースへの接続でのOPENまたはPREPAREが無効です。 |
|
82118 |
アプリケーション・コンテキストが見つかりません。 |
SQL-02123 |
82119 |
接続エラーでメッセージを取り出せません。 |
SQL-02125 |
82120 |
プリコンパイラとSQLLIBのバージョンが一致しません。 |
SQL-02127 |
82121 |
FETCHされたバイト数が奇数です。 |
SQL-02129 |
82122 |
EXEC TOOLSインタフェースが使用できません。 |
SQL-02130 |
82123 |
使用中のランタイム・コンテキスト |
SQL-02131 |
82124 |
ランタイム・コンテキストの割当て不能 |
ORA-01422 SQL-02132 |
82125 |
スレッドで使用するプロセスを初期化できません。 |
SQL-02133 |
82126 |
ランタイム・コンテキストが無効 |
SQL-02134 |
90000 |
デバッグ・イベント |
ORA-10000~10999 |
99999 |
すべて捕捉 |
その他すべて |
HZ000 |
リモート・データベース・アクセス |
8.4 SQL通信領域の使用について
SQL通信領域(SQLCA)は、レコードに似たデータ構造体です。そのフィールドには、SQL文を実行するたびにOracleによって更新されるエラー、警告およびステータス情報が格納されます。したがって、SQLCAには常に最新のSQLの動作結果が反映されます。結果を確認するには、SQLCA内の変数をチェックします。
ローカルおよびグローバルの両方の宣言ができるホスト言語では、プログラムで複数のローカルSQLCAを使用できます。たとえば、1つのグローバルSQLCAと複数のローカルSQLCAを設定できます。ローカルSQLCAへのアクセスは、プログラム内の有効範囲により制限されます。Oracleからは、アクティブなSQLCAにのみ情報が戻されます。
また、アプリケーションでSQL*Netを使用してローカルとリモートのデータベースに同時にアクセスしている場合、すべてのデータベースが1つのSQLCAに書込みを行います。つまり、データベースごとに異なるSQLCAがあるわけではありません。詳細は、「同時接続」を参照してください。
MODE={ORACLE|ANSI13}
の場合、SQLCAは必須です。SQLCAが宣言されないと、コンパイル時エラーが発生します。SQLCAはMODE={ANSI|ANSI14}
のときにはオプションですが、WHENEVER
SQLWARNING文はSQLCAの宣言がなければ使用できません。したがって、WHENEVER
SQLWARNING文を使用する場合は、SQLCAを宣言する必要があります。
特定のコンパイル・ユニットでSQLCAのかわりにSQLCODEを宣言すると、プリコンパイラでは、そのユニット用に内部SQLCAを1つ割り当てます。ホスト・プログラムでは、その内部SQLCAにアクセスできません。SQLCAとSQLCODE(Pro*FORTRANのみ)を宣言すると、OracleからはSQLの動作が終わるたびに、両方に同じステータス・コードが戻されます。
MODE={ANSI|ANSI14}
の場合、いずれかのSQLSTATEを宣言する必要があります(「SQLCODEおよびSQLSTATE」を参照)。SQLSTATE状態変数は、SQL92標準で指定されたSQLSTATE状態変数をサポートします。SQLSTATE状態変数は、SQLCODEの有無に関係なく使用できます。詳細は、表8-3と表8-4を参照してください。
8.4.2 Pro*COBOLでのSQLCAの宣言について
Pro*COBOLでは、INCLUDE
が宣言部の内側であろうが外側であろうが違いはありません。Pro*COBOLでのSQLCAの宣言の詳細は、「SQL通信領域の使用方法」を参照してください。
8.4.3 Pro*FORTRANでのSQLCAの宣言について
Pro*FORTRANでは、SQLCAはCOMMONブロックなので宣言部の外側で宣言する必要があります。さらに、SQLCAはCONNECT
文と最初の実行可能なFORTRAN文の前に置く必要があります。
SQLCAは、SQL文を含むサブルーチンやファンクションごとに宣言します。サブルーチンやファンクションの1つでSQL文が実行されるたびに、OracleによりCOMMONブロック内に保存されているSQLCAが更新されます。
通常、重要なのはCOMMONリストにある変数の順序とデータ型のみで、名前ではありません。ただし、プリコンパイラではそれらの名前を参照するコードが生成されるため、SQLCA変数の名前を変更することはできません。したがって、SQLCAの宣言はすべて同一であることが必要です。Pro*FORTRANでのSQLCAの宣言の詳細は、「SQL通信領域の使用方法」を参照してください。
8.4.4 SQLCAの内容
SQLCAにはSQL文の実行結果に関する次のランタイム情報が格納されます。
-
Oracleエラー・コード
-
警告フラグ
-
イベント情報
-
処理済行数
-
診断情報
図8-2に、SQLCA内のすべての変数を示します。特定のホスト言語におけるSQLCA構造体および変数の名前を調べるには、このマニュアルに対するその言語用の補足資料を参照してください。
8.4.6 ステータス・コード
すべての実行SQL文は、SQLCA変数のSQLCODEにステータス・コードを戻し、このステータス・コードは、WHENEVER
文によって暗黙的にチェックすることも、独自のコードによって明示的にチェックすることもできます。
ステータス・コードは、ゼロ、負数、正数のいずれかです。SQLCODEの詳細は、「SQLCODEの宣言」を参照してください。
8.4.9 解析エラー・オフセット
SQL文は実行前に必ず解析され、構文規則に従っているか、有効なデータベース・オブジェクトを参照しているかが検証されます。エラーが検出されると、SQLCA変数のSQLERRD(5)にオフセットが格納され、これは明示的にチェックできます。このオフセットには、解析エラーの始まりを示すSQL文中の文字位置が示されています。先頭の文字位置は0 (ゼロ)です。たとえば、オフセットが9のとき、解析エラーは10番目の文字から始まっています。
デフォルトでは、静的SQL文は、プリコンパイル時に構文エラーがないかチェックされます。そのため、SQLERRD(5)は、プログラムの実行時に受け入れたり作成したりする動的SQL文のデバッグには最も便利です。
解析エラーは、キーワードの欠落、位置指定の誤りまたはスペルミス、無効なオプション、存在しない表などが原因で発生します。たとえば、次のような動的SQL文があるとします。
UPDATE EMP SET JIB = :job_title WHERE EMPNO = :emp_number
これは解析エラーになります。
ORA-00904: invalid column name
原因は、列名JOBのスペルミスです。SQLERRD(5)の値は15になりますが、これは誤った列名JIBが16番目の文字で始まっているためです。
SQL文に解析エラーがない場合、SQLERRD(5)は0 (ゼロ)に設定されます。解析エラーが先頭の文字(文字位置0 (ゼロ))から始まっている場合にも、SQLERRD(5)は0 (ゼロ)に設定されます。このため、SQLERRD(5)のチェックは、SQLCODEが負の値(エラーが発生したことを示す)の場合にのみ行ってください。
8.4.10 エラー・メッセージ・テキスト
Oracleエラーのエラー・コードおよびメッセージは、SQLCA変数のSQLERRMCに格納されています。テキストの最初の最大70文字が格納されます。70文字を超えるメッセージの全文を取得するには、SQLGLMファンクションを使用します。エラー・メッセージの全文の取得を参照してください。
8.4.14 SQLCODE
この整数フィールドには、最後に実行されたSQL文のステータス・コードが入ります。SQLの動作の結果を示すステータス・コードは、次のいずれかの数値です。
0
Oracleは文を実行し、エラーも例外も検出しませんでした。
> 0
Oracleは文を実行しましたが、例外を検出しました。これは、WHERE
句の検索条件を満たす行が見つからなかった場合、あるいはSELECT
INTO
またはFETCH
で行が戻されなかった場合に発生します。
< 0
MODE={ANSI|ANSI14|ANSI13}
の場合、行のINSERTがなかったときに+100がSQLCODEに戻されます。副問合せで処理に行が戻されなかったときにこの状態が発生します。
データベース、システム、ネットワークまたはアプリケーションのいずれかにエラーが発生したため、Oracleは文を実行しませんでした。このようなエラーはリカバリ不能です。このようなエラーが発生すると、ほとんどの場合はカレント・トランザクションがロールバックされます。
負のリターン・コードは、『Oracle Databaseエラー・メッセージ』に記載されているエラー・コードに対応しています。
8.4.15 SQLERRM
このサブレコードには、次の2つのフィールドがあります。
この整数フィールドには、SQLERRMCに格納されるメッセージ・テキストの長さが入ります。
この文字列フィールドには、SQLCODEに格納されたエラー・コードのメッセージテキストが保持され、最大70文字を格納できます。70文字を超えるメッセージの全文を取得するには、SQLGLMファンクションを使用します。
SQLCODEが負数であることを確認します
(SQLERRMCを参照する前に)。SQLCODEが0 (ゼロ)の場合は、SQLERRMCを参照するとそれ以前のSQL文に関連するメッセージ・テキストが戻されます。
8.4.17 SQLERRD
この2進整数の配列には6つの要素があります。SQLERRD(FORTRANではSQLERDと呼ぶ)内のフィールドの説明は、次のとおりです。
SQLERRD(1)
このフィールドは、将来の使用に備えて確保されています。
SQLERRD(2)
このフィールドは、将来の使用に備えて確保されています。
SQLERRD(3)
このフィールドには、最後に実行したSQL文によって処理された行数が入ります。ただし、SQL文が失敗すると、1つの例外を除き、SQLERRD(3)の値は未定義となります。配列の動作中にエラーが発生すると、エラーの原因となった行で処理が停止し、SQLERRD(3)は正常に処理された行数を示します。
処理済行数はOPEN
文の後にゼロに設定され、FETCH
文の後で増加します。EXECUTE
、INSERT
、UPDATE
、DELETE
およびSELECT
INTO
の各文では、数は正常に処理された行数が反映されます。この数には、UPDATEやDELETE_CASCADEで処理された行は含まれません。たとえばWHERE句の条件を満たす20行が削除された後で、列制約条件に違反する5行が削除されたときの処理済行数は、25ではなく20となります。
SQLERRD(4)
このフィールドは、将来の使用に備えて確保されています。
このフィールドには、一番最後に実行されたSQL文中の、解析エラーが始まる文字位置を示すオフセットが格納されます。先頭の文字位置は0 (ゼロ)です。
SQLERRD(6)
このフィールドは、将来の使用に備えて確保されています。
8.4.18 SQLWARN
この1文字の配列には8つの要素があります。これらの要素は警告フラグとして使用されます。Oracleではそれに文字値W(警告)を割り当てることでフラグを設定します。フラグは例外状態の発生を警告します。
たとえば、切り捨てられた列値が出力ホスト変数に割り当てられると、警告フラグが設定されます。
また、図8-2ではSQLWARNを配列として示していますが、Pro*COBOLでは、SQLWARN0からSQLWARN7までの基本のPIC X項目を持つグループ・アイテムとして実装されることにも注意してください。Pro*FORTRANの実装は、SQLWN0からSQLWN7までのLOGICAL変数で構成されます。
SQLWARN(0)
このフラグは別の警告フラグが設定されていることを示します。
SQLWARN(1)
このフラグは、切り捨てられた列値が出力ホスト変数に代入されたときに設定されます。これは文字データにのみ適用されます。Oracleが一部の数値データを切り捨てるときには、警告の設定も負のSQLCODE値の戻しもありません。
列値が切り捨てられたかどうか、またどれだけ切り捨てられたかを調べるには、出力ホスト変数に対応する標識変数をチェックします。標識変数によって戻された値が正の整数のときは、その値は列値の元の長さを示します。その値に応じてホスト変数の長さを増やすことができます。
SQLWARN(2)
このフラグは、AVG、COUNTまたはMAXなどのSQLグループ関数の評価で、1つ以上のNULLが無視された場合に設定されます。COUNT(*)を除き、すべてのグループ関数ではNULLが無視されるため、この動作になります。必要な場合は、SQL関数のNVLを使用して、NULLの列エントリに一時的に値(たとえばゼロ)を割り当てることができます。
SQLWARN(3)
このフラグは、問合せ選択リスト内の列数が、SELECT
文またはFETCH
文のINTO
句内のホスト変数の数と一致しない場合に設定されます。戻される項目の数は、両者のうち少ない方です。
SQLWARN(4)
このフラグは、表内のすべての行がWHERE句のないUPDATE
文またはDELETE
文で処理された場合に設定されます。処理される行数を制限する検索条件がない場合、更新または削除は無条件と呼ばれます。このような更新や削除は例外的であるため、この警告フラグが設定されます。必要に応じて、トランザクションはロールバックできます。
SQLWARN(5)
このフラグは、EXEC SQL CREATE {PROCEDURE|FUNCTION|PACKAGE|PACKAGE BODY}文が、PL/SQLコンパイル・エラーのために失敗したときに設定されます。
SQLWARN(6)
このフラグは現在使用されていません。
SQLWARN(7)
このフラグは現在使用されていません。
8.4.20 PL/SQLの考慮事項
プリコンパイラ・プログラムで埋込みPL/SQLブロックを実行するときに、SQLCAのフィールドがすべて設定されるわけではありません。たとえば、ブロックで複数の行がフェッチされた場合、処理済行数SQLERRD(3)は、実際にフェッチされた行数ではなく、1に設定されます。したがって、PL/SQLブロックを実行した後は、信頼できるSQLCAのフィールドはSQLCODEフィールドおよびSQLERRMフィールドのみになります。
8.4.21 エラー・メッセージのテキスト全体の取得
SQLCAには70文字までのエラー・メッセージを格納できます。それより長い(またはネストされた)エラー・メッセージの全文を取得するには、SQLGLMファンクションが必要です。Oracleに接続している場合、次の構文を使用してSQLGLMをコールできます。
SQLGLM(message_buffer, buffer_size, message_length);
説明:
message_buffer
エラー・メッセージを格納するためのテキスト・バッファです(Oracleではこのバッファの最後まで空白文字で埋め込みます)。
buffer_size
バッファの最大サイズをバイト単位で示した整数変数です。
エラー・メッセージの実際の長さが格納される整数変数です。
Oracleエラー・メッセージの最大長は、エラー・コード、ネストされたメッセージ、表や列の名前など、メッセージの挿入部分を含めて512文字です。SQLGLMによって戻されるエラー・メッセージの最大長は、buffer_sizeに指定した値によって決まります。
次の例では、SQLGLMをコールして、100文字以内の長さのエラー・メッセージを取得します。
-- declare variables for function call msg_buffer CHARACTER(100); buf_size INTEGER; msg_length INTEGER; set buf_size = 100; EXEC SQL WHENEVER SQLERROR DO sql_error; -- other statements ROUTINE sql_error BEGIN -- get full text of error message SQLGLM(msg_buffer, buf_size, msg_length); display contents of msg_buffer; exit program with an error END sql_error;
SQLGLMは、SQLエラーが発生した場合にのみコールされます。SQLGLMをコールする前に、SQLCODEが負の値であることを必ず確認してください。SQLCODEが0 (ゼロ)のときにSQLGLMをコールすると、前のSQL文に対応するメッセージ・テキストが戻されます。
8.4.22 WHENEVER文の使用方法
8.4.23 SQLWARNING
Oracleから警告が戻されたか(同時にSQLWARN(1)からSQLWARN(7)の警告フラグのうちの1つが設定されます)、またはSQLCODEの値が+1403以外の正の値になっていたために、SQLWARN(0)が設定されている状態です。たとえば、SQLWARN(1)は、Oracleにより切り捨てられた列値が出力ホスト変数に割り当てられた場合に設定されます。
MODE={ANSI|ANSI14}の場合、SQLCAの宣言はオプションです。ただし、WHENEVER SQLWARNINGを使用するには、必ずSQLCAを宣言してください。
8.4.25 NOT FOUND
OracleでWHERE
句の検索条件を満たす行を検出できなかったか、SELECT INTO
またはFETCH
で行が戻されなかったため、SQLCODEには+1403が設定されています(MODE={ANSI|ANSI14| ANSI13}
のときは+100)。MODE={ANSI|ANSI14|ANSI13}
の場合、行がINSERT
されなければ、+100がSQLCODEに戻されます。
Oracleで前述の状態のいずれかが検出されたときは、プログラムに次のいずれかのアクションを実行させることができます。
8.4.27 DO
プログラムでは、制御を内部ルーチンに移します。ルーチンの最後に達すると、制御は失敗したSQL文の次の文に移ります。
ルーチンとは、COBOLパラグラフまたはFORTRAN
サブルーチンなど、起動可能な関数プログラム・ユニットです。ここでは、COBOL
のサブルーチンなど、別にコンパイルされたプログラムは、ルーチンではありません。
ルーチンの開始と終了の通常の規則が適用されます。ただし、ルーチンにパラーメータを渡すことはできません。さらに、ルーチンでは値を戻すことはできません。
パラーメータroutine_callは、次の例のように、ホスト言語を起動します。
EXEC SQL -- COBOL WHENEVER <condition> DO PERFORM <paragraph_name> -- COBOL END-EXEC. -- COBOL
または
EXEC SQL -- FORTRAN WHENEVER <condition> DO CALL <subroutine_name> -- FORTRAN
8.4.29 STOP
プログラムは実行を停止し、コミットされていない作業がロールバックされます。
ここでは注意が必要です。STOP
アクションでは、Oracleとの接続を切断する前に何もメッセージが表示されません。Pascalでは、同等のコマンドがないため、STOP
アクションは無効です。
8.4.30 例
たとえば、プログラムで次のアクションが必要だとします。
-
「データが見つかりません」という状態が発生した場合、close_cursorに進みます。
-
警告が発生した場合、次の文の処理を続行します。
-
エラーが発生した場合、error_handlerに進みます。
最初の実行SQL文の前に、次のWHENEVER
文を記述します。
EXEC SQL WHENEVER NOT FOUND GOTO close_cursor; EXEC SQL WHENEVER SQLWARNING CONTINUE; EXEC SQL WHENEVER SQLERROR GOTO error_handler;
次のPro*Cの例では、WHENEVER
...DO
文を使用して特定のエラーを処理します。
EXEC SQL WHENEVER SQLERROR DO handle_insert_error; EXEC SQL INSERT INTO EMP (EMPNO, ENAME, DEPTNO) VALUES (:emp_number, :emp_name, :dept_number); EXEC SQL WHENEVER SQLERROR DO handle_delete_error; EXEC SQL DELETE FROM DEPT WHERE DEPTNO = :dept_number; ... ROUTINE handle_insert_error; BEGIN IF sqlca.sqlcode = -1 THEN -- duplicate key value ... ELSEIF sqlca.sqlcode = -1401 THEN -- value too large ... ENDIF; ... END; ROUTINE handle_delete_error; BEGIN IF sqlca.sqlerrd(3) = 0 THEN -- no rows deleted ... ELSE ... ENDIF; ... END; ...
SQLCAの変数をチェックしてアクションの過程を決定する手順に注意してください。
8.4.31 有効範囲
WHENEVER
は宣言文であるため、その有効範囲は論理的なものではなく、位置的なものになります。テストするのは、ソース・ファイルの中でその文より後に記述されているすべての実行SQL文であり、プログラム・ロジックの流れの中でその文より後にくる実行SQL文ではありません。したがって、WHENEVER
文は、テストする最初の実行SQL文の前に記述する必要があります。
WHENEVER
文は、同じ条件をチェックする別のWHENEVER
文に置き換えられるまで有効です。
次の例では、最初のWHENEVER
SQLERROR文は2番目の文に置き換えられるため、CONNECT
文に対してのみ適用されます。2番目のWHENEVER
SQLERROR文は、step1からstep3への制御の流れに関係なく、UPDATE文とDROP文の両方に適用されます。
step1: EXEC SQL WHENEVER SQLERROR STOP; EXEC SQL CONNECT :username IDENTIFIED BY :password; ... GOTO step3; step2: EXEC SQL WHENEVER SQLERROR CONTINUE; EXEC SQL UPDATE EMP SET SAL = SAL * 1.10; ... step3: EXEC SQL DROP INDEX EMP_INDEX; ...
8.4.32 ガイドライン
次のガイドラインは、一般的な問題を回避するために役立ちます。
文の位置。通常、WHENEVER
文はプログラムの最初の実行SQL文の前に記述してください。そうすればWHENEVER文はファイルの最後まで有効なので、発生するすべてのエラーを確実に捕捉できます。
データの終了条件の処理。カーソルを使用して行をフェッチするときは、プログラムでデータの終了条件を処理できるようにしておく必要があります。FETCH
によりデータが戻されない場合、プログラムでは次のようにCLOSE
コマンドが発行されるコードのラベル付きセクションに分岐します。
SQL WHENEVER NOT FOUND GOTO no_more; ... no_more: ... EXEC SQL CLOSE my_cursor; ...
無限ループの回避。WHENEVER
SQLERROR GOTO
文が、実行SQL文を含むエラー処理ルーチンに分岐する場合、そのSQL文にエラーが発生すると、プログラムは無限ループに陥る恐れがあります。これを回避するには、次の例のように、そのSQL文の前にWHENEVER
SQLERROR CONTINUE
を記述します。
EXEC SQL WHENEVER SQLERROR GOTO sql_error; ... sql_error: EXEC SQL WHENEVER SQLERROR CONTINUE; EXEC SQL ROLLBACK WORK RELEASE; ...
WHENEVER
SQLERROR CONTINUE
文を指定しなければ、ROLLBACK
エラーが発生したときにこのルーチンが再び起動され、無限ルーチンに陥ります。
WHENEVER
を不注意に使用すると、問題が発生する可能性があります。たとえば、DELETE
文で検索条件を満たす行がないためNOT
FOUND
を設定すると、次のコードは無限ループに陥ります。
-- improper use of WHENEVER ... EXEC SQL WHENEVER NOT FOUND GOTO no_more; LOOP EXEC SQL FETCH emp_cursor INTO :emp_name, :salary; ... ENDLOOP; no_more: EXEC SQL DELETE FROM EMP WHERE EMPNO = :emp_number; ...
次の例では、GOTO
のターゲットを再設定することで、NOT FOUND
の状態を適切に処理します。
-- proper use of WHENEVER ... EXEC SQL WHENEVER NOT FOUND GOTO no_more; LOOP EXEC SQL FETCH emp_cursor INTO :emp_name, :salary; ... ENDLOOP; no_more: EXEC SQL WHENEVER NOT FOUND GOTO no_match; EXEC SQL DELETE FROM EMP WHERE EMPNO = :emp_number; ... no_match: ...
アドレス指定能力の維持。ローカルおよびグローバルの識別子を使用できるホスト言語により、WHENEVER
GOTO
文に支配されるすべてのSQL文が必ずGOTO
ラベルに分岐できるようにします。次のコードでは、FUNC1内のlabelAがFUNC2内のINSERT文の有効範囲内にないため、コンパイル時エラーが発生します。
FUNC1 BEGIN EXEC SQL WHENEVER SQLERROR GOTO labelA; EXEC SQL DELETE FROM EMP WHERE DEPTNO = :dept_number; ... labelA: ... END; FUNC2 BEGIN EXEC SQL INSERT INTO EMP (JOB) VALUES (:job_title); ... END;
WHENEVER GOTO
文の分岐先のラベルは、この文と同じプリコンパイル・ファイル内にする必要があります。
エラー後の戻り。エラーの処理後にプログラムに戻る必要がある場合、DO
routine_callアクションを使用します。または、次の例のように、SQLCODEの値をテストしてもかまいません。
EXEC SQL UPDATE EMP SET SAL = SAL * 1.10; IF sqlca.sqlcode < 0 THEN -- handle error EXEC SQL DROP INDEX EMP_INDEX; ...
アクティブなWHENEVER
GOTO
文またはWHENEVER
STOP
文がないことを確認してください。
8.4.33 SQL文のテキストの取得
多くのプリコンパイラ・アプリケーションでは、処理中のテキスト文、その長さ、そこで指定されているSQLコマンド(INSERT
またはSELECT
など)を把握すると便利です。これは、動的SQLを使用するアプリケーションについて特に当てはまります。
-
最後に解析されたSQL文のテキスト
-
文の長さ
-
文で使用されているSQLコマンドの機能コード(表8-8を参照)
SQLGLSは、静的SQL文の発行後にコールできます。動的SQL方法1では、SQL文の実行後にSQLGLSをコールできます。動的SQL方法2、3または4では、SQL文の作成後にSQLGLSをコールできます。
SQLGLS(SQLSTM, STMLEN, SQLFC)
表8-7は、SQLGLS引数リストでパラメータに使用可能なホスト言語のデータ型を示しています。
表8-7 SQLGLSパラメータのデータ型
パラメータ | 言語 | データ型 |
---|---|---|
COBOL |
PIC X(n) |
|
SQLSTM |
FORTRAN |
CHARACTER*n |
STMLEN、SQLFC |
COBOL |
PIC S9(9) COMP |
STMLEN、SQLFC |
FORTRAN |
INTEGER*4 |
パラメータはすべて、参照によって渡す必要があります。通常、デフォルトでパラメータ引渡し規則は参照によって引渡されるため、特別な処置は必要ありません。
SQLSTMパラメータは、空白埋込み(NULLで終了しない)文字バッファで、SQL文の戻されたテキストが格納されます。プログラムでは、静的にバッファを宣言するか、動的にバッファのメモリーを割り当てる必要があります。
長さパラメータSTMLENは4バイトの整数です。SQLGLSをコールする前に、このパラメータをSQLSTMバッファの実際のサイズ(単位はバイト)に設定します。SQLGLSが戻すときに、SQLSTMバッファには、SQL文のテキストにバッファの長さまで空白を足したものが含まれます。STMLENは戻された文テキストの実際のバイト数を戻します。足されている空白は数えません。ただし、エラーが発生した場合、STMLENはゼロを戻します。
次のエラーが考えられます。
-
SQL文が1つも解析されませんでした。
-
無効なパラメータを渡しました(たとえば、長さとして負の値を渡した場合)。
-
SQLLIBで内部例外が発生しました。
SQLFCパラメータは、文のSQLコマンドのSQL機能コードを戻す4バイトの整数です。表8-8は、各SQLコマンドの機能コードを示しています。
-
CONNECT
-
COMMIT
-
ROLLBACK
-
RELEASE
-
FETCH
これらの文にはSQLファンクション・コードがありません。
表8-8 SQLコマンドの機能コード
コード | SQL機能 | コード | SQL機能 |
---|---|---|---|
01 |
CREATE TABLE |
39 |
AUDIT |
02 |
SET ROLE |
40 |
NOAUDIT |
03 |
INSERT |
41 |
ALTER INDEX |
04 |
SELECT |
42 |
CREATE EXTERNAL DATABASE |
05 |
UPDATE |
43 |
DROP EXTERNAL DATABASE |
06 |
DROP ROLE |
44 |
CREATE DATABASE |
07 |
DROP VIEW |
45 |
ALTER DATABASE |
08 |
DROP TABLE |
46 |
CREATE ROLLBACK SEGMENT |
09 |
DELETE |
47 |
ALTER ROLLBACK SEGMENT |
10 |
CREATE VIEW |
48 |
DROP ROLLBACK SEGMENT |
11 |
DROP USER |
49 |
CREATE TABLESPACE |
12 |
CREATE ROLE |
50 |
ALTER TABLESPACE |
13 |
CREATE SEQUENCE |
51 |
DROP TABLESPACE |
14 |
ALTER SEQUENCE |
52 |
ALTER SESSION |
15 |
(未使用) |
53 |
ALTER USER |
16 |
DROP SEQUENCE |
54 |
COMMIT |
17 |
CREATE SCHEMA |
55 |
ROLLBACK |
18 |
CREATE CLUSTER |
56 |
SAVEPOINT |
19 |
CREATE USER |
57 |
CREATE CONTROL FILE |
20 |
CREATE INDEX |
58 |
ALTER TRACING |
21 |
DROP INDEX |
59 |
CREATE TRIGGER |
22 |
DROP CLUSTER |
60 |
ALTER TRIGGER |
23 |
VALIDATE INDEX |
61 |
DROP TRIGGER |
24 |
CREATE PROCEDURE |
62 |
ANALYZE TABLE |
25 |
ALTER PROCEDURE |
63 |
ANALYZE INDEX |
26 |
ALTER TABLE |
64 |
ANALYZE CLUSTER |
27 |
EXPLAIN |
65 |
CREATE PROFILE |
28 |
GRANT |
66 |
DROP PROFILE |
29 |
REVOKE |
67 |
ALTER PROFILE |
30 |
CREATE SYNONYM |
68 |
DROP PROCEDURE |
31 |
DROP SYNONYM |
69 |
(未使用) |
32 |
ALTER SYSTEM SWITCH LOG |
70 |
ALTER RESOURCE COST |
33 |
SET TRANSACTION |
71 |
CREATE SNAPSHOT LOG |
34 |
PL/SQL EXECUTE |
72 |
ALTER SNAPSHOT LOG |
35 |
LOCK TABLE |
73 |
DROP SNAPSHOT LOG |
36 |
(未使用) |
74 |
CREATE SNAPSHOT |
37 |
RENAME |
75 |
ALTER SNAPSHOT |
38 |
COMMENT |
76 |
DROP SNAPSHOT |
8.5 Oracle通信領域の使用について
SQLCAで標準的なSQL通信が処理されるのと同様に、Oracle通信領域(ORACA)ではOracle通信が処理されます。ランタイム・エラーおよび状態の変化について、SQLCAで提供されるより詳しい情報が必要な場合は、ORACAを使用してください。これには、豊富な診断ツールが用意されています。ただし、ORACAの使用はランタイム・オーバーヘッドを増加させるため、あくまでもオプションです。
ORACAは問題の診断に役立つ上に、プログラムによるOracleリソース(SQL文エグゼキュータやカーソル・キャッシュなど)の利用を監視できます。
ローカルおよびグローバルな宣言が可能なホスト言語では、プログラムで複数のORACAを使用できます。たとえば、1つのグローバルORACAと複数のローカルORACAを設定できます。ローカルORACAへのアクセスは、プログラム内のその有効範囲によって制限されます。Oracleでは、アクティブなORACAに対してのみ情報が戻されます。情報はコミットまたはロールバック後でなければ使用できません。
8.5.2 ORACAの有効化
ORACAを有効にするには、コマンドラインに次のようにORACAオプションを指定する必要があります。
ORACA=YES
またはインラインで次のように指定します
EXEC ORACLE OPTION (ORACA=YES);
その後、ORACA内にフラグを設定することで、適切なランタイム・オプションを選択する必要があります。
8.5.3 ORACAの内容
ORACAには、次のように、オプションの設定、システムの統計および高度な診断情報が保存されています。
-
SQL文のテキスト(テキストの保存時に指定できます)
-
エラーが発生したファイルの名前
-
ファイル内のエラーの位置
-
カーソル・キャッシュのエラーおよび統計情報
図8-3は、ORACA内のすべての変数を示しています。特定のホスト言語におけるORACA構造体および変数の名前を調べるには、このマニュアルのその言語用の補足資料を参照してください。
8.5.8 ORACCHF
マスターDEBUGフラグ(ORADBGF)が設定されている場合、このフラグによって、各カーソルの動作の前にカーソ・キャッシュの一貫性をチェックできます。
Oracleランタイム・ライブラリでは一貫性チェックが行われ、エラー・メッセージが発行されることがあります(エラー・メッセージについては、『Oracle Databaseエラー・メッセージ』を参照してください)。これらは、Oracleエラー・メッセージと同様にSQLCAに戻されます。
このフラグは次のいずれかを設定します。
-
0: キャッシュ一貫性チェックを無効にします(デフォルト)。
-
1: キャッシュ一貫性チェックを有効にします。
8.5.9 ORADBGF
このマスター・フラグを使用すると、DEBUGオプションをすべて選択できます。これには次の設定があります。
-
0: すべてのDEBUG処理を無効にします(デフォルト)。
-
1: すべてのDEBUG処理を有効にします。
8.5.10 ORAHCHF
マスターDEBUGフラグ(ORADBGF)が設定されている場合、プリコンパイラにより動的にメモリーが割り当てられたり解放されたりするたびに、このフラグがOracleランタイム・ライブラリにヒープの一貫性チェックを指示します。これはメモリー障害を起こすプログラムの不具合を検出するのに役立ちます。
このフラグはCONNECT
コマンドを発行する前に設定する必要があります。また、このフラグは一度設定するとクリアできなくなります。つまり、設定後にこのフラグの変更要求があっても無視されます。これには次の設定があります。
-
0: ヒープ一貫性チェックを無効にします(デフォルト)。
-
1: ヒープ一貫性チェックを有効にします。
8.5.11 ORASTXTF
このフラグを使用すると、現行のSQL文のテキストを保存するタイミングを指定できます。これには次の設定があります。
-
0: SQL文のテキストを保存しません(デフォルト)。
-
1: SQLERRORのSQL文のテキストのみ保存します。
-
2: SQLERRORまたはSQLWARNINGのSQL文のテキストのみ保存します。
-
3: 常にSQL文のテキストを保存します。
SQL文のテキストは、ORASTXTという名前のORACAサブレコードに保存されます。
8.5.18 ORAMOC
この整数フィールドには、プログラムの要求によってオープンされたOracleカーソルの最大数が記録されます。MAXOPENCURSORS
に設定されている値が小さすぎて、その結果プリコンパイラによってカーソル・キャッシュが拡張されると、この数はORAHOCより大きくなることがあります。
8.5.20 ORANOR
この整数フィールドには、プログラムの要求によって再度割り当てられたカーソル・キャッシュの数が記録されます。この数値は、カーソル・キャッシュのスラッシングの程度を示すもので、できるだけ小さく保つ必要があります。
8.5.22 ORANEX
この整数フィールドには、プログラムの要求によって実行されたSQL文の数が記録されます。この数値のORANPR
の数値に対する割合は、できるかぎり大きく保つ必要があります。つまり、不要な再解析は回避します。詳細は、パフォーマンス・チューニングを参照してください。
8.5.23 例
次のプログラムでは、部門番号の入力を要求し、その部門内の各従業員の名前および給与を2つの表のいずれかに挿入してから、ORACAからの診断情報を表示します。
EXEC SQL BEGIN DECLARE SECTION; username CHARACTER(20); password CHARACTER(20); emp_name INTEGER; dept_number INTEGER; salary REAL; EXEC SQL END DECLARE SECTION; EXEC SQL INCLUDE SQLCA; EXEC SQL INCLUDE ORACA; display 'Username? '; read username; display 'Password? '; read password; EXEC SQL WHENEVER SQLERROR DO sql_error; EXEC SQL CONNECT :username IDENTIFIED BY :password; display 'Connected to Oracle'; EXEC ORACLE OPTION (ORACA=YES); -- set flags in the ORACA set oraca.oradbgf = 1; -- enable debug operations set oraca.oracchf = 1; -- enable cursor cache consistency check set oraca.orastxtf = 3; -- always save the SQL statement display 'Department number? '; read dept_number; EXEC SQL DECLARE emp_cursor CURSOR FOR SELECT ENAME, SAL + NVL(COMM,0) FROM EMP WHERE DEPTNO = :dept_number; EXEC SQL OPEN emp_cursor; EXEC SQL WHENEVER NOT FOUND DO no_more; rLOOP EXEC SQL FETCH emp_cursor INTO :emp_name, :salary; IF salary < 2500 THEN EXEC SQL INSERT INTO PAY1 VALUES (:emp_name, :salary); ELSE EXEC SQL INSERT INTO PAY2 VALUES (:emp_name, :salary); ENDIF; ENDLOOP; ROUTINE no_more BEGIN EXEC SQL CLOSE emp_cursor; EXEC SQL WHENEVER SQLERROR CONTINUE; EXEC SQL COMMIT WORK RELEASE; display 'Last SQL statement: ', oraca.orastxt.orastxtc; display '... at or near line number: ', oraca.oraslnr; display display ' Cursor Cache Statistics'; display '-------------------------------------------'; display 'Maximum value of MAXOPENCURSORS ', oraca.orahoc; display 'Maximum open cursors required: ', oraca.oramoc; display 'Current number of open cursors: ', oraca.oracoc; display 'Number of cache reassignments: ', oraca.oranor; display 'Number of SQL statement parses: ', oraca.oranpr; display 'Number of SQL statement executions: ', oraca.oranex; exit program; END no_more; ROUTINE sql_error BEGIN EXEC SQL WHENEVER SQLERROR CONTINUE; EXEC SQL ROLLBACK WORK RELEASE; display 'Last SQL statement: ', oraca.orastxt.orastxtc; display '... at or near line number: ', oraca.oraslnr; display display ' Cursor Cache Statistics'; display '-------------------------------------------'; display 'Maximum value of MAXOPENCURSORS ', oraca.orahoc; display 'Maximum open cursors required: ', oraca.oramoc; display 'Current number of open cursors: ', oraca.oracoc; display 'Number of cache reassignments: ', oraca.oranor; display 'Number of SQL statement parses: ', oraca.oranpr; display 'Number of SQL statement executions: ', oraca.oranex; exit program with an error; END sql_error;