プライマリ・コンテンツに移動
Oracle® Database Oracleプリコンパイラのためのプログラマーズ・ガイド
12c リリース1 (12.1)
B71398-03
目次へ移動
目次
索引へ移動
索引

前
次

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

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構造体および変数の名前を調べるには、このマニュアルに対するその言語用の補足資料を参照してください。

エラー・レポートの基本コンポーネント

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

ステータス・コード

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

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

警告フラグ

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

処理済行数

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

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

解析エラー・オフセット

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が負の値(エラーが発生したことを示す)の場合にのみ行ってください。

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

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

SQLCA構造体

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

SQLCAID

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

SQLCABC

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

SQLCODE

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

0

Oracleは文を実行し、エラーも例外も検出しませんでした。

> 0

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

< 0

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

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

負のリターン・コードは、『Oracle Databaseエラー・メッセージ』に記載されているエラー・コードに対応しています。

SQLERRM

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

SQLERRML

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

SQLERRMC

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

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

(SQLERRMCを参照するに)。SQLCODEが0 (ゼロ)の場合は、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文中の、解析エラーが始まる文字位置を示すオフセットが格納されます。先頭の文字位置は0 (ゼロ)です。

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が0 (ゼロ)のときにSQLGLMをコールすると、前のSQL文に対応するメッセージ・テキストが戻されます。

WHENEVER文の使用方法

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

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

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

EXEC SQL WHENEVER <condition> <action>;

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

SQLWARNING

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

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文であり、プログラム・ロジックの流れの中でその文より後にくる実行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を参照)

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

(not used)

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

(not used)

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

(not used)

74

CREATE SNAPSHOT

37

RENAME

75

ALTER SNAPSHOT

38

COMMENT

76

DROP SNAPSHOT