TimesTenにおける相違点: 例外処理およびエラー動作
TimesTenでのPL/SQLとOracle DatabaseでのPL/SQLとでは、エラー関連の一部の動作が異なることに注意する必要があります。
例外が処理されない場合のTimesTen PL/SQLトランザクションおよびロールバック動作
トランザクションの途中でPL/SQLが実行され、PL/SQLの実行中に未処理例外が発生した場合、TimesTen PL/SQLの処理は、Oracle Database PL/SQLでの処理と異なります。Oracle Databaseは無名ブロックの先頭までロールバックします。TimesTenはロールバックしません。
次の例に示すとおり、PL/SQLブロックの実行の結果発生した例外を常にアプリケーションで処理し、自動コミットを無効にしてアプリケーションを実行する必要があります。
create table mytable (num int not null primary key);
set serveroutput on
insert into mytable values(1);
begin
insert into mytable values(2);
insert into mytable values(1);
exception
when dup_val_on_index then
dbms_output.put_line('oops:' || sqlerrm);
rollback;
end;
select * from mytable;
commit;
2番目のINSERT
は、値が一意である必要があるため失敗し、これにより、例外が発生して、プログラムはロールバックを実行します。TimesTenでは、これを実行するとこのような結果になります。
oops:TT0907: Unique constraint (MYTABLE) violated at Rowid <BMUFVUAAABQAAAADjq>
select * from mytable;
0 rows found.
結果はOracle Databaseの場合と同様で、SELECT
の結果に行は表示されません。
ここで、例外が処理されないTimesTenの例を考えてみます。自動コミットを無効にし、この例を再実行します。
create table mytable (num int not null primary key);
set serveroutput on
insert into mytable values(1);
begin
insert into mytable values(2);
insert into mytable values(1);
end;
select * from mytable;
commit;
TimesTenでは、SELECT
問合せは最初の2つの挿入の実行を指示します。
907: Unique constraint (MYTABLE) violated at Rowid <BMUFVUAAABQAAAADjq>
8507: ORA-06512: at line 3
The command failed.
select * from mytable;
< 1 >
< 2 >
2 rows found.
これをOracle Databaseで実行すると、PL/SQLブロックの先頭にロールバックされるため、SELECT
の結果は最初の挿入のみの実行を示します。
ORA-00001: unique constraint (SYSTEM.SYS_C004423) violated
ORA-06512: at line 3
NUM
----------
1
ノート:
-
PL/SQLブロックに未処理例外がある場合、TimesTenではトランザクションがオープンのままになるため、アプリケーションでその状態を評価して適切なアクションを判断する必要があります。
-
TimesTenのアプリケーションでは、現在のトランザクションでコミットされていない変更内容がある間はPL/SQLブロックを実行しないでください(ただし、変更内容とPL/SQL操作によって単一の論理作業ユニットが構成され、そのアプリケーションが適切なアクションを決定できる場合を除きます)。このようなアクションには、たとえば、トランザクションの先頭へのロールバックなどがあります。
-
自動コミットが有効になっているときにTimesTenで未処理例外が発生した場合は、トランザクション全体がロールバックされます。
TimesTenのエラー・メッセージおよびSQLコード
SQLERRM
ファンクションによって戻される情報は異なる場合がありますが、SQLCODE
ファンクションによって戻される情報は同じになります。
さらに情報を得るには、次を参照してください:
-
「RAISE文の使用」内の例では、
SQLERRM
およびSQLCODE
を使用します。 -
特定のTimesTenエラー・メッセージについては、『Oracle TimesTen In-Memory Databaseエラー・メッセージおよびSNMPトラップ』のエラーおよび警告を参照してください。
-
一般的な情報は、『Oracle Database PL/SQL言語リファレンス』のSQLERRMファンクションおよびSQLCODEファンクションを参照してください。
PL/SQLで表示されない警告
その結果、TimesTenではSQL文を実行してその結果発生する警告を表示できますが、同じ文をPL/SQLから実行した場合には、警告は表示されません。
サポートされていない事前定義済エラー
「事前定義済TimesTenエラーのトラップ」では、TimesTenでサポートされている事前定義済例外、関連するORA
エラー番号とSQLCODE
値、および例外の説明が示されています。
表4-2に、TimesTenでサポートされていない事前定義例外を示します。
表4-2 TimesTenでサポートされていない事前定義済例外
例外名 | Oracle Databaseエラー番号 | SQLCODE | 説明 |
---|---|---|---|
|
|
-1017 |
ユーザー名およびパスワードが無効です。 |
|
|
-1012 |
プログラムがデータベースに接続せずにデータベース・コールを発行しました。 |
|
|
-30625 |
プログラムが |
|
|
-51 |
データベースでリソースを待機している間に、タイムアウトが発生しました。 |
クリーン・コンパイル後の実行時エラーの可能性(Oracle Database SQLパーサーの使用)
TimesTen PL/SQLの実装では、PL/SQLプログラムのコンパイル時に、Oracle Database SQLパーサーが使用されます。
これは、「TimesTenでのPL/SQLとOracle DatabaseでのPL/SQL」で説明されています。
そのため、TimesTenでサポートされていないOracle Databaseの構文または組込みプロシージャをプログラムで使用しても、コンパイル中は問題が検出されません。ただし、プログラムの実行中に実行時エラーが発生します。
実行時のTimesTen式の使用
TimesTen SQLには、Oracle Database SQLにはない構造がいくつか含まれています。PL/SQL言語には、これらの構造は含まれていません。PL/SQLからTimesTen固有のSQLを実行するには、EXECUTE IMMEDIATE
文を使用してSQL文を実行します。これによりコンパイル・エラーを回避します。
TimesTen固有のSQLおよび式のリストは、『Oracle TimesTen In-Memory Databaseキャッシュ・ガイド』のTimesTenとOracle Databasesとの互換性を参照してください。
EXECUTE IMMEDIATE
の詳細は、「PL/SQLでの動的SQL (EXECUTE IMMEDIATE文)」を参照してください。