ヘッダーをスキップ
Oracle® Database Oracleプリコンパイラのためのプログラマーズ・ガイド
11g リリース2(11.2)
B61344-01
  目次
目次
索引へ
索引

前へ
前へ
 
次へ
次へ
 

8 エラーの処理および診断

アプリケーション・プログラムでは、ランタイム・エラーを予想し、エラーからのリカバリを試みる必要があります。この章では、エラーのレポートおよびリカバリについて詳しく説明します。状態変数のSQLCODEl、SQLSTATE、SQLCA(SQL通信領域)およびWHENEVER文を使用して、警告およびエラーを処理する方法を学習します。内容は次のとおりです。

エラー処理の必要性

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

潜在的なエラーをすべて予想することは無理ですが、プログラムにとって重要なある種のエラーについては、処理方法を計画することはできます。Oracleプリコンパイラにとって、エラー処理とはSQL文の実行エラーの検出およびリカバリのことです。

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

エラー処理の代替方法

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}の場合の状態変数の使用方法」を参照してください。

SQLCODEおよびSQLSTATE

Oracleプリコンパイラのリリース1.5では、SQLCODE状態変数が、SQL89標準ANSI/ISOエラー・レポート・メカニズムとして導入されました。SQL92標準では、SQLCODEが非推奨機能として挙げられ、新しい状態変数SQLSTATE(Oracleプリコンパイラのリリース1.6で導入)が推奨ANSI/ISOエラー・レポート・メカニズムとして定義されました。

SQLCODEには、エラー・コードおよび見つからない状態が格納されています。SQLCODEは、SQL89との互換性のためのみに保持されており、標準の将来のバージョンからは削除される見込みです。

SQLCODEとは異なり、SQLSTATEにはエラーおよび警告のコードが格納され、標準化されたコード体系を使用します。SQL文を実行すると、Oracleサーバーからは、現在有効範囲内にあるSQLSTATE変数にステータス・コードが戻されます。ステータス・コードは、SQL文が正常に実行されたか、あるいは例外(エラーまたは警戒の状態)が発生したかを示します。相互運用性(システムが情報を容易に交換する能力)を高めるために、SQL92では、すべての一般的なSQL例外が事前に定義されています。

SQLCA

SQLCAは、レコードに似たホスト言語データ構造です。Oracleでは、実行SQL文が実行されるたびに、SQLCAが更新されます(宣言部の後ではSQLCA値は未定義になります)。プログラムは、SQLCAに格納されているOracleリターン・コードをチェックして、SQL文の結果を確認できます。これには次の2つの方法があります。

  • WHENEVER文による暗黙的チェック

  • SQLCA変数の明示的チェック

WHENEVER文、SQLCA変数に対するコードの明示的チェックを使用するか、あるいは両方を使用できます。一般的に、WHENEVER文を使用する方が簡単で、移植性も高く、ANSI準拠であるためお薦めします。

ORACA

ランタイム・エラーについてSQLCAから得られる情報が十分でない場合、カーソル統計、SQL文データ、オプション設定およびシステム統計が格納されているORACAを使用できます。

ORACAはオプションであり、MODE設定に関係なく宣言できます。ORACA状態変数の詳細は、「Oracle通信領域の使用方法」を参照してください。

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通信領域の使用方法」を参照してください。

履歴情報

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

リリース1.5

Oracleプリコンパイラ・リリース1.5では、宣言部で宣言されているかどうかに関係なく、状態変数SQLCODEはあると仮定しました。実際、プリコンパイラでは、SQLCODEの宣言があるかどうかをわざわざ通知することはなく、単に宣言は存在すると仮定しました。SQLCAのINCLUDEがある場合にのみ、SQLCAが状態変数として使用されました。

リリース1.6

Oracleプリコンパイラ・リリース1.6から、プリコンパイラでは、SQLCODE状態変数があると仮定しなくなり、SQLCODE状態変数は必須ではありません。SQLCA、SQLCODEまたはSQLSTATEのうち少なくとも1つを宣言する必要があります。

SQLCODEは、少なくとも次の基準の1つが満たされたときにかぎり、状態変数として認識されます。

  • 宣言部で完全に正しいデータ型で宣言されている場合。

  • プリコンパイラで他の状態変数が見つからない場合。

プリコンパイラが宣言部で(完全に正しい型の)SQLSTATE宣言を検出した場合、またはSQLCAのINCLUDEを検出した場合には、SQLCODEが宣言されているとはみなしません

リリース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」を参照してください。

状態変数の宣言

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

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の動作が終わるごとに、両方に同じステータス・コードが戻されます。

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変数の宣言は無視されます。

状態変数の組合せ

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の場合、宣言部の内側または外側のいずれかで宣言する必要があります。


状態変数の値

この項では、SQLCODE状態変数およびSQLSTATE状態変数の値について説明します。SQLCA状態変数については、「エラー・レポートの主要コンポーネント」を参照してください。

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の宣言は無視されます。

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コード体系

SQLSTATEコード体系
「図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オプション違反

HZ

リモート・データベース・アクセス



注意:

クラス・コードHZは、国際標準規格ISO/IEC DIS 9579-2で定義された条件であるリモート・データベース・アクセス用に予約されています。

表8-6は、SQLSTATEステータス・コードとOracleエラーの対応を示しています。一部の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

カーソル仕様ではないプリコンパイル文


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オプション違反

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

フェッチされたバイト数が奇数

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

リモート・データベース・アクセス



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が宣言されていないと、コンパイル時のエラーが発生します。MODE={ANSI|ANSI14}の場合、SQLCAはオプションですが、SQLCAを宣言しないと、WHENEVER SQLWARNING文を使用できません。そのため、WHENEVER SQLWARNING文を使用する場合は、SQLCAを宣言する必要があります。

特定のコンパイル・ユニットでSQLCAのかわりにSQLCODEを宣言すると、プリコンパイラでは、そのユニット用に内部SQLCAを1つ割り当てます。ホスト・プログラムでは、その内部SQLCAにアクセスできません。SQLCASQLCODE(Pro*FORTRANのみ)を宣言すると、OracleからはSQLの動作が終わるたびに、両方に同じステータス・コードが戻されます。

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

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はそのプログラムと通信できます。

Pro*COBOLでのSQLCAの宣言

Pro*COBOLでは、INCLUDEが宣言部の内側であろうが外側であろうが違いはありません。Pro*COBOLでのSQLCAの宣言の詳細は、『Pro*COBOLプログラマーズ・ガイド』を参照してください。

Pro*FORTRANでのSQLCAの宣言

Pro*FORTRANでは、SQLCAはCOMMONブロックなので宣言部の外側で宣言する必要があります。さらに、SQLCAはCONNECT文と最初の実行可能なFORTRAN文の前に置く必要があります。

SQLCAは、SQL文を含むサブルーチンやファンクションごとに宣言します。サブルーチンやファンクションの1つでSQL文が実行されるたびに、OracleによりCOMMONブロック内に保存されているSQLCAが更新されます。

通常、重要なのはCOMMONリストにある変数の順序とデータ型のみで、名前ではありません。ただし、プリコンパイラではそれらの名前を参照するコードが生成されるため、SQLCA変数の名前を変更することはできません。したがって、SQLCAの宣言はすべて同一であることが必要です。Pro*FORTRANでのSQLCAの宣言の詳細は、Oracleプリコンパイラ・ガイドのPro*FORTRAN用補足資料を参照してください。

SQLCAの内容

SQLCAにはSQL文の実行結果に関する次のランタイム情報が格納されます。

  • Oracleエラー・コード

  • 警告フラグ

  • イベント情報

  • 処理済行数

  • 診断情報

図8-2は、SQLCA内のすべての変数を示しています。特定のホスト言語におけるSQLCA構造体および変数の名前を調べるには、このマニュアルに対するその言語用の補足資料を参照してください。

図8-2 SQLCAの変数

SQLCAの変数
「図8-2 SQLCAの変数」の説明

エラー・レポートの主要コンポーネント

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

ステータス・コード

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

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

警告フラグ

警告フラグは、SQLCA変数のSQLWARN(0)からSQLWARN(7)に戻され、これらは暗黙的にも明示的にもチェックできます。警告フラグは、Oracleでエラーとみなされない実行時の状態のチェックに便利です。たとえば、DBMS=V6のとき、インジケータ変数が使用可能な場合、Oracleでは切り捨てた列値をホスト変数に割り当てると警告を通知します。(インジケータ変数が使用できない場合は、エラー・メッセージが発行されます。)

処理済行

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

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

解析エラー・オフセット

SQL文は実行前に必ず解析され、構文規則に従っているか、有効なデータベース・オブジェクトを参照しているかが検証されます。エラーが検出されると、SQLCA変数のSQLERRD(5)にオフセットが格納され、これは明示的にチェックできます。このオフセットには、解析エラーの始まりを示すSQL文中の文字位置が示されています。先頭の文字の位置はゼロです。たとえば、オフセットが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文に解析エラーがなければ、OracleではSQLERRD(5)がゼロに設定されます。解析エラーが先頭の文字(文字位置はゼロ)で始まっているときも、SQLERRD(5)はゼロに設定されます。したがって、SQLCODEがエラーの発生したことを意味する負数の場合のみ、SQLERRD(5)をチェックしてください。

エラー・メッセージ・テキスト

Oracleエラーのエラー・コードおよびメッセージは、SQLCA変数のSQLERRMCに格納されています。テキストの最初の最大70文字が格納されます。70文字を超えるメッセージの全文を取得するには、SQLGLMファンクションを使用します。「エラー・メッセージの全文の取得」を参照してください。

SQLCA 構造体

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

SQLCAID

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

SQLCABC

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

SQLCODE

この整数フィールドには、最後に実行されたSQL文のステータス・コードが入ります。SQLの動作結果を示すステータス・コードは、次のいずれかの数になります。

0

文が実行され、エラーも例外も検出されませんでした。

> 0

文は実行されましたが、例外が検出されました。これは、WHERE句の検索条件を満たす行が見つからなかった場合、あるいはSELECT INTOまたはFETCHで行が戻されなかった場合に発生します。

< 0

MODE={ANSI|ANSI14|ANSI13}の場合、行のINSERTがなかったときに+100がSQLCODEに戻されます。これは、副問合せで処理する行が戻されなかった場合に発生します。

データベース、システム、ネットワークまたはアプリケーションのエラーのため、Oracleでは文が実行されませんでした。このようなエラーはリカバリ不能です。これらが発生した場合、現行のトランザクションは、ほとんどの場合、ロールバックする必要があります。

負のリターン・コードに対応するエラー・コードについては、『Oracle Databaseエラー・メッセージ』を参照してください。

SQLERRM*

このサブレコードには、次の2つのフィールドがあります。

SQLERRML

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

SQLERRMC

この文字列フィールドには、SQLCODEに格納されているエラー・コードのメッセージ・テキストが入ります。70文字まで格納できます。70文字を超えるメッセージの全文は、SQLGLM関数を使用して取得します。

SQLERRMCを参照する前に、

SQLCODEが負数であることを確認します。SQLCODEがゼロのときにSQLERRMCを参照すると、前のSQL文に関連付けられたメッセージ・テキストを取得することになります。

SQLERRP

この文字列フィールドは、将来使用するために予約されています。

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文で解析エラーが始まった文字位置を示すオフセットが入ります。先頭の文字の位置はゼロです。

SQLERRD(6)

このフィールドは、将来使用するために予約されています。

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)

このフラグは現在使用されていません。

SQLEXT

この文字列フィールドは、将来使用するために予約されています。

PL/SQLの考慮事項

プリコンパイラ・プログラムで埋込みPL/SQLブロックを実行するときに、SQLCAのフィールドがすべて設定されるわけではありません。たとえば、ブロックで複数の行がフェッチされる場合、処理済行数SQLERRD(3)は1に設定され、実際のフェッチ行数には設定されません。したがって、PL/SQLブロックの実行後は、SQLCAのSQLCODEフィールドおよびSQLERRMフィールドのみを信頼してください。

エラー・メッセージの全文の取得

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がゼロのときにSQLGLMをコールすると、前の文に関連付けられたメッセージ・テキストを取得することになります。

WHENEVER文の使用方法

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

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

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

EXEC SQL WHENEVER <condition> <action>;

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

SQLWARNING

SQLWARN(0)は、Oracleから警告(SQLWARN(1)からSQLWARN(7)までのいずれか1つも設定されます)が戻されたか、SQLCODEが+1403以外の正の値になっているために設定されます。たとえば、SQLWARN(1)は、Oraclにより切り捨てられた列値が出力ホスト変数に割り当てられた場合に設定されます。

MODE={ANSI|ANSI14}の場合、SQLCAの宣言はオプションです。ただし、WHENEVER SQLWARNINGを使用するには、SQLCAを宣言する必要があります

SQLERROR

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

NOT FOUND

OracleでWHERE句の検索条件を満たす行を検出できなかったか、SELECT INTOまたはFETCHで行が戻されなかったため、SQLCODEには+1403が設定されています(MODE={ANSI|ANSI14| ANSI13}のときは+100)。MODE={ANSI|ANSI14|ANSI13}の場合、行がINSERTされなければ、+100がSQLCODEに戻されます。

Oracleで前述の状態のいずれかが検出されたときは、プログラムに次のいずれかのアクションを実行させることができます。

CONTINUE

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

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

GOTO

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

STOP

プログラムは実行を停止し、コミットされていない作業がロールバックされます。

ここでは注意が必要です。STOPアクションでは、Oracleとの接続を切断する前に何もメッセージが表示されません。Pascalでは、同等のコマンドがないため、STOPアクションは無効です。

たとえば、プログラムで次のアクションが必要だとします。

  • 「データが見つかりません」という状態が発生した場合、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の変数をチェックしてアクションの過程を決定する手順に注意してください。

有効範囲

WHENEVERは宣言文であるため、その有効範囲は論理的なものではなく、位置的なものになります。それは、プログラム・ロジックの流れではなく、ソース・ファイル内で後に続くすべての実行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;
 ...

ガイドライン

次のガイドラインは、一般的な問題を回避するために役立ちます。

文の位置。通常、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文がないことを確認してください。

SQL文のテキストの取得

多くのプリコンパイラ・アプリケーションでは、処理中のテキスト文、その長さ、そこで指定されているSQLコマンド(INSERTまたはSELECTなど)を把握すると便利です。これは、動的SQLを使用するアプリケーションについて特に当てはまります。

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

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

  • 文の長さ

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

静的SQL文の発行後にSQLGLSをコールできます。動的SQL方法1の場合は、SQL文の実行後にSQLGLSをコールできます。動的SQL方法2、3または4の場合は、文の準備がてきたらSQLGLSをコールできます。

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

SQLGLS(SQLSTM, STMLEN, SQLFC)

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

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

パラメータ Language データ型

SQLSTM

COBOL

PIC X(n)


FORTRAN

CHARACTER*n

STMLEN、SQLFC

COBOL

PIC S9(9) COMP


FORTRAN

INTEGER*4


パラメータはすべて、参照により渡す必要があります。通常はデフォルトのパラメータを渡すのが便利です。特別なアクションは不要です。

SQLSTMパラメータは、空白埋込み(NULLで終了しない)文字バッファで、SQL文の戻されたテキストが格納されます。プログラムでは、静的にバッファを宣言するか、動的にバッファのメモリーを割り当てる必要があります。

長さのパラメータSTMLENは、4バイトの整数です。SQLGLSをコールする前に、このパラメータをSQLSTMバッファの実際のサイズ(バイト単位)に設定してください。SQLGLSが戻ると、SQLSTMバッファにはバッファ長まで空白文字が埋められたSQL文テキストが入ります。STMLENは、戻された文のテキストの実際のバイト数を戻します。これには埋め込まれた空白文字のバイト数は含まれません。ただし、STMLENは、エラーが発生した場合にはゼロを1つ戻します。

次のエラーが考えられます。

  • SQL文が解析されませんでした。

  • 無効なパラメータを渡しました(たとえば、負の長さの値)。

  • 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


Oracle通信領域の使用方法

SQLCAで標準的なSQL通信が処理されるのと同様に、Oracle通信領域(ORACA)ではOracle通信が処理されます。ランタイム・エラーおよび状態の変化について、SQLCAで提供されるより詳しい情報が必要な場合は、ORACAを使用してください。これには、豊富な診断ツールが用意されています。ただし、ORACAの使用はランタイム・オーバーヘッドを増加させるため、あくまでもオプションです。

ORACAは問題の診断に役立つ上に、プログラムによるOracleリソース(SQL文エグゼキュータやカーソル・キャッシュなど)の利用を監視できます。

ローカルおよびグローバルな宣言が可能なホスト言語では、プログラムで複数のORACAを使用できます。たとえば、1つのグローバルORACAと複数のローカルORACAを設定できます。ローカルORACAへのアクセスは、プログラム内のその有効範囲によって制限されます。Oracleでは、アクティブなORACAに対してのみ情報が戻されます。情報はコミットまたはロールバック後でなければ使用できません。

ORACAの宣言

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

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

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

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

ORACAの有効化

ORACAを有効にするには、コマンドラインに次のようにORACAオプションをを指定する必要があります。

ORACA=YES

またはインラインで次のように指定します。

EXEC ORACLE OPTION (ORACA=YES);

その後、ORACA内にフラグを設定することで、適切なランタイム・オプションを選択する必要があります。

ORACAの内容

ORACAには、次のように、オプションの設定、システムの統計および高度な診断情報が保存されています。

  • SQL文のテキスト(テキストの保存時に指定できます)

  • エラーが発生したファイルの名前

  • ファイル内のエラーの位置

  • カーソル・キャッシュのエラーおよび統計情報

図8-3は、ORACA内のすべての変数を示しています。特定のホスト言語におけるORACA構造体および変数の名前を調べるには、このマニュアルのその言語用の補足資料を参照してください。

図8-3 ORACAの変数

ORACAの変数
「図8-3 ORACAの変数」の説明

ランタイム・オプションの選択

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

  • SQL文のテキストの保存

  • DEBUG処理の有効化

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

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

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

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

ORACAの構造体

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

ORACAID

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

ORACABC

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

ORACCHF

マスターDEBUGフラグ(ORADBGF)が設定されている場合、このフラグによって、各カーソルの動作の前にカーソ・キャッシュの一貫性をチェックできます。

Oracleランタイム・ライブラリでは一貫性チェックが行われ、エラー・メッセージが発行されることがあります(エラー・メッセージについては、『Oracle Databaseエラー・メッセージ』を参照してください)。これらは、Oracleエラー・メッセージと同様にSQLCAに戻されます。

このフラグは次のいずれかの設定になります。

0

キャッシュ一貫性チェックを無効にします(デフォルト)。

1

キャッシュ一貫性チェックを有効にします。

ORADBGF

このマスター・フラグを使用すると、DEBUGオプションをすべて選択できます。これには次の設定があります。

0

すべてのDEBUG処理を無効にします(デフォルト)。

1

すべてのDEBUG処理を有効にします。

ORAHCHF

マスターDEBUGフラグ(ORADBGF)が設定されている場合、プリコンパイラにより動的にメモリーが割り当てられたり解放されたりするたびに、このフラグがOracleランタイム・ライブラリにヒープの一貫性チェックを指示します。これは、メモリーを混乱させるプログラムの不具合を検出するのに役立ちます。

このフラグは、CONNECTコマンドが発行される前に設定する必要があります。一度設定すると解除できなくなります。つまり、設定後の変更要求は無視されます。これには、次の設定があります。

0

ヒープ一貫性チェックを無効にします(デフォルト)。

1

ヒープ一貫性チェックを有効にします。

ORASTXTF

このフラグを使用すると、現行のSQL文のテキストをいつ保存するかを指定できます。これには、次の設定があります。

0

SQL文のテキストを保存しません(デフォルト)。

1

SQLERRORのSQL文のテキストのみを保存します。

2

SQLERRORまたはSQLWARNINGのSQL文のテキストのみを保存します。

3

常にSQL文のテキストを保存します。

SQL文のテキストは、ORASTXTという名前のORACAサブレコードに保存されます。

診断情報

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

ORASTXT

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

ORASTXTL

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

ORASTXTC

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

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

ORASFNM

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

ORASFNML

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

ORASFNMC

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

ORASLNR

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

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

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

ORAHOC

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

ORAMOC

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

ORACOC

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

ORANOR

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

ORANPR

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

ORANEX

この整数フィールドには、プログラムの要求によって実行されたSQL文の数が記録されます。この数値のORANPRの数値に対する割合は、できるかぎり大きく保つ必要があります。つまり、不要な再解析は回避します。詳細は、付録C「パフォーマンス・チューニング」を参照してください。

次のプログラムでは、部門番号の入力を要求し、その部門内の各従業員の名前および給与を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;