日本語PDF

8 エラー処理および診断

アプリケーション・プログラムでは、ランタイム・エラーを予想し、そのエラーをリカバリするように対処する必要があります。この章では、エラー・レポートおよびリカバリを詳しく説明します。具体的には、状態変数SQLCODE、SQLSTATE、SQLCA(SQLコミュニケーション領域)およびWHENEVER文を使用して警告およびエラーを処理する方法を説明します。さらに状態変数ORACA(Oracle通信領域)による問題点の診断方法も紹介します。次の内容について説明します。

8.1 エラー処理の必要性

どのようなアプリケーション・プログラムでも、その大部分をエラー処理に充てる必要があります。エラー処理の主な利点は、エラーが発生しても、プログラムの処理を続行できることです。エラーは、設計ミス、コーディングの誤り、ハードウェアの障害、無効なユーザー入力、その他様々な原因で発生します。

潜在的なエラーをすべて予測するのは無理ですが、プログラムにとって意味のある特定の種類のエラーについてアクションを考えることはできます。Oracleプリコンパイラにとって、エラー処理とはSQL文の実行エラーの検出およびリカバリのことです。

値が切り捨てられたことを示す警告やデータの終わりなどの状態の変更も処理できます。INSERT文、UPDATE文またはDELETE文は、表内の処理対象行すべてを処理する前に失敗することがあるため、データ操作文を実行するたびにエラー状態および警告状態がないか調べることが特に重要です。

8.2 エラー処理の代替手段

Oracleプリコンパイラには、エラー処理の手段として役立つ4種類の状態変数が用意されています。

  • SQLCODE(Pro*FORTRANではSQLCOD)

  • SQLSTATE(Pro*FORTRANではSQLSTA)

  • SQLCA(WHENEVER文を使用)

  • ORACA

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つ全部を宣言してもかまいません)。

  • SQLCODE

  • SQLSTATE

  • SQLCA

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.1 履歴情報

Oracleプリコンパイラによる状態変数および変数の組合せの処理は、リリース1.5から進化してきました。

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.5 状態変数の宣言について

この項では、SQLCODEおよびSQLSTATEの宣言方法について説明します。SQLCA状態変数の宣言の詳細は、SQLCAの宣言を参照してください。

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にアクセスできません。SQLCASQLCODE(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

MODE={ORACLE|ANSI13}の場合、SQLSTATE変数の宣言は無視されます。

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にアクセスできません。SQLCASQLCODE(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-1 SQLSTATEコード体系

図8-1の説明が続きます
「図8-1 SQLSTATEコード体系」の説明

表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にアクセスできません。SQLCASQLCODE(Pro*FORTRANのみ)を宣言すると、OracleからはSQLの動作が終わるたびに、両方に同じステータス・コードが戻されます。

MODE={ANSI|ANSI14}の場合、いずれかのSQLSTATEを宣言する必要があります(「SQLCODEおよびSQLSTATE」を参照)。SQLSTATE状態変数は、SQL92標準で指定されたSQLSTATE状態変数をサポートします。SQLSTATE状態変数は、SQLCODEの有無に関係なく使用できます。詳細は、表8-3表8-4を参照してください。

8.4.1 SQLCAの宣言

SQLCAを宣言するには、次のようにホスト言語のソース・ファイルにEXEC SQL INCLUDEを使用してSQLCAを含めます。

* Include the Oracle Communications Area (ORACA).
 EXEC SQL INCLUDE ORACA
EXEC SQL INCLUDE SQLCA;

SQLCAは、SQLCAのINCLUDEがある場合にかぎり使用されます。

プログラムをプリコンパイルすると、INCLUDE SQLCA文は複数の変数宣言に置換されます。この変数宣言により、Oracleはそのプログラムと通信できます。

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.5 エラー・レポートの基本コンポーネント

エラー・レポートは、SQLCA内の変数によって異なります。この項では、エラー・レポートの主要コンポーネントについて説明します。次の項では、SQLCAについて詳しく説明します。

8.4.6 ステータス・コード

すべての実行SQL文は、SQLCA変数のSQLCODEにステータス・コードを戻し、このステータス・コードは、WHENEVER文によって暗黙的にチェックすることも、独自のコードによって明示的にチェックすることもできます。

ステータス・コードは、ゼロ、負数、正数のいずれかです。SQLCODEの詳細は、「SQLCODEの宣言」を参照してください。

8.4.7 警告フラグ

警告フラグは、SQLCA変数のSQLWARN(0)からSQLWARN(7)に戻され、これらは暗黙的にも明示的にもチェックできます。警告フラグは、Oracleでエラーとみなされない実行時の状態のチェックに便利です。

8.4.8 処理済行数

最後に実行したSQL文で処理された行数は、SQLCA変数のSQLERRD(3)に戻され、これは明示的にチェックできます。

厳密には、この変数はエラー・レポート用ではなく、誤りの防止に役立ちます。たとえば、表から約10行を削除するとします。削除後に、SQLERRD(3)をチェックすると、75行が処理されたことが判明します。念のために、削除処理をロールバックしてWHERE句の検索条件を確認します。

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.11 SQLCA構造体

この項では、SQLCAの構造体、そのフィールドおよびそこに格納可能な値について説明します。

8.4.12 SQLCAID

この文字列フィールドは、SQLCAに初期化され、SQL通信領域を識別します。

8.4.13 SQLCABC

この整数フィールドには、SQLCA構造体の長さがバイト単位で入ります。

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つのフィールドがあります。

SQLERRML

この整数フィールドには、SQLERRMCに格納されるメッセージ・テキストの長さが入ります。

SQLERRMC

この文字列フィールドには、SQLCODEに格納されたエラー・コードのメッセージテキストが保持され、最大70文字を格納できます。70文字を超えるメッセージの全文を取得するには、SQLGLMファンクションを使用します。

SQLCODEが負数であることを確認します

(SQLERRMCを参照するに)。SQLCODEが0 (ゼロ)の場合は、SQLERRMCを参照するとそれ以前のSQL文に関連するメッセージ・テキストが戻されます。

8.4.16 SQLERRP

この文字列フィールドは、将来の使用に備えて確保されています。

8.4.17 SQLERRD

この2進整数の配列には6つの要素があります。SQLERRD(FORTRANではSQLERDと呼ぶ)内のフィールドの説明は、次のとおりです。

SQLERRD(1)

このフィールドは、将来の使用に備えて確保されています。

SQLERRD(2)

このフィールドは、将来の使用に備えて確保されています。

SQLERRD(3)

このフィールドには、最後に実行したSQL文によって処理された行数が入ります。ただし、SQL文が失敗すると、1つの例外を除き、SQLERRD(3)の値は未定義となります。配列の動作中にエラーが発生すると、エラーの原因となった行で処理が停止し、SQLERRD(3)は正常に処理された行数を示します。

処理済行数はOPEN文の後にゼロに設定され、FETCH文の後で増加します。EXECUTEINSERTUPDATEDELETEおよびSELECT INTOの各文では、数は正常に処理された行数が反映されます。この数には、UPDATEやDELETE_CASCADEで処理された行は含まれません。たとえばWHERE句の条件を満たす20行が削除された後で、列制約条件に違反する5行が削除されたときの処理済行数は、25ではなく20となります。

SQLERRD(4)

このフィールドは、将来の使用に備えて確保されています。

SQLERRD(5)

このフィールドには、一番最後に実行された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のフィールドの説明は次のとおりです。

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.19 SQLEXT

この文字列フィールドは、将来の使用に備えて確保されています。

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

バッファの最大サイズをバイト単位で示した整数変数です。

message_length

エラー・メッセージの実際の長さが格納される整数変数です。

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文の使用方法

デフォルトでは、プリコンパイルされたプログラムはOracleエラーおよび警告の状態を無視し、可能であれば処理を続行します。自動状態チェックおよびエラー処理を実行するには、WHENEVER文を使用します。

WHENEVER文を使用すると、Oracleでエラー、警告または「見つかりません」の状態が検出されたときのアクションを指定できます。これらのアクションには、次の文の継続実行、ルーチンのコール、ラベル付きの文への分岐、停止などがあります。

WHENEVER文は次の構文を使用して記述します。

EXEC SQL WHENEVER <condition> <action>;

次の状態がないか、Oracleに自動的にSQLCAをチェックさせることができます。

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.24 SQLERROR

Oracleからエラーが戻されたので、SQLCODEには負の値が設定されています。

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.26 CONTINUE

可能であれば、プログラムは次の文から実行を継続します。これはデフォルトの動作で、WHENEVER文を使用しない場合と同じです。これを使用すると、状態チェックを終了できます。

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.28 GOTO

プログラムはラベル付きの文に分岐します。

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を使用するアプリケーションについて特に当てはまります。

ルーチンSQLGLSは、SQLLIBランタイム・ライブラリの一部で、次の情報を戻します。

  • 最後に解析されたSQL文のテキスト

  • 文の長さ

  • 文で使用されているSQLコマンドの機能コード(表8-8を参照)

SQLGLSは、静的SQL文の発行後にコールできます。動的SQL方法1では、SQL文の実行後にSQLGLSをコールできます。動的SQL方法2、3または4では、SQL文の作成後にSQLGLSをコールできます。

SQLGLSをコールするには、次の構文を使用します。

SQLGLS(SQLSTM, STMLEN, SQLFC)

表8-7は、SQLGLS引数リストでパラメータに使用可能なホスト言語のデータ型を示しています。

表8-7 SQLGLSパラメータのデータ型

パラメータ 言語 データ型

SQLSTM

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コマンドの機能コードを示しています。

SQLGLSでは、次のコマンドを含む文は戻されません。

  • 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.1 ORACAの宣言

ORACAを宣言するには、次のようにホスト言語のソース・ファイルにEXEC SQL INCLUDE文を使用してORACA含めます。

* Include the Oracle Communications Area (ORACA).
 EXEC SQL INCLUDE ORACA

ORACAは宣言部の外側で宣言する必要があります。

プログラムをプリコンパイルすると、INCLUDE ORACA文は複数の変数宣言に置換されます。この変数宣言により、Oracleはそのプログラムと通信できます。

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.4 ランタイム・オプションの選択

ORACAにはいくつかのオプション・フラグがあります。これらのフラグにゼロ以外の値を割り当てて設定すると、次のことが可能になります。

  • SQL文のテキストの保存

  • DEBUG処理の有効化

  • カーソル・キャッシュの一貫性チェック(カーソル・キャッシュとは、カーソル管理に使用されるメモリーで継続的に更新される領域)

  • ヒープの一貫性チェック(ヒープとは、動的変数用に予約されているメモリー領域です)

  • カーソルの統計情報の収集

次の説明は、必要なオプションを選択するときの参考になります。

8.5.5 ORACA構造体

この項では、ORACAの構造体、そのフィールドおよびそこに格納可能な値について説明します。

8.5.6 ORACAID

この文字列フィールドは、ORACAに初期化され、Oracle通信領域を識別します。

8.5.7 ORACABC

この整数フィールドには、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.12 診断情報

ORACAは高度な診断情報を提供します。次の変数によってエラーの位置をすばやく特定できます。

8.5.13 ORASTXT

このサブレコードは、問題のあるSQL文を見つけるのに役立ちます。Oracleで解析された最後のSQL文のテキストを保存できます。このサブレコードには、次の2つのフィールドがあります。

ORASTXTL

この整数フィールドには、現行SQL文の長さが入ります。

ORASTXTC

この文字列フィールドには、現行のSQL文のテキストが格納されます。先頭から最大70文字までのテキストが保存されます。

プリコンパイラによって解析された文(CONNECTFETCHおよびCOMMITなど)は、ORACAには保存されません

8.5.14 ORASFNM

このサブレコードは、現行SQL文を含むファイルを識別し、1つのアプリケーションのために複数のファイルがプリコンパイルされるときのエラー検出に役立ちます。このサブレコードには、次の2つのフィールドがあります。

ORASFNML

この整数フィールドには、ORASFNMCに格納されているファイル名の長さが入ります。

ORASFNMC

この文字列フィールドには、ファイル名が格納されます。先頭から最大70文字が格納されます。

8.5.15 ORASLNR

この整数フィールドは、現行SQL文がある行またはその付近の行を識別します。

8.5.16 カーソル・キャッシュ統計情報

次の変数により、カーソル・キャッシュ統計情報を収集できます。これらは、プログラムでCOMMIT文またはROLLBACK文が発行されるたびに自動的に設定されます。内部的には、CONNECTされたデータベースごとにこれらの変数のセットがあります。ORACA内の現行値は、最後にコミットまたはロールバックが実行されたデータベースに関するものです。

8.5.17 ORAHOC

この整数フィールドには、プログラムの実行時にMAXOPENCURSORSに設定された最大値が記録されます。

8.5.18 ORAMOC

この整数フィールドには、プログラムの要求によってオープンされたOracleカーソルの最大数が記録されます。MAXOPENCURSORSに設定されている値が小さすぎて、その結果プリコンパイラによってカーソル・キャッシュが拡張されると、この数はORAHOCより大きくなることがあります。

8.5.19 ORACOC

この整数フィールドには、プログラムの要求によってオープンされているOracleカーソルの現在の数が記録されます。

8.5.20 ORANOR

この整数フィールドには、プログラムの要求によって再度割り当てられたカーソル・キャッシュの数が記録されます。この数値は、カーソル・キャッシュのスラッシングの程度を示すもので、できるだけ小さく保つ必要があります。

8.5.21 ORANPR

この整数フィールドには、プログラムの要求によって解析されたSQL文の数が記録されます。

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;