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

エラー条件が同じ場合、TimesTenでは、TimesTenが戻すエラー・メッセージとOracle Databaseが戻すメッセージが同じになることは保証されませんが、SQLコードは同じになります。 そのため、SQLERRMファンクションによって戻される情報は異なる場合がありますが、SQLCODEファンクションによって戻される情報は同じになります。

さらに情報を得るには、次を参照してください:

PL/SQLで表示されない警告

Oracle Databaseには実行時警告の概念がないため、Oracle Database PL/SQLでは警告はサポートされていません。TimesTenには警告の概念がありますが、TimesTen PL/SQLの実装はOracle Database PL/SQLの実装に基づいているため、TimesTen PL/SQLでは警告はサポートされていません。

その結果、TimesTenではSQL文を実行してその結果発生する警告を表示できますが、同じ文をPL/SQLから実行した場合には、警告は表示されません。

サポートされていない事前定義済エラー

「事前定義済TimesTenエラーのトラップ」では、TimesTenでサポートされている事前定義済例外、関連するORAエラー番号とSQLCODE値、および例外の説明が示されています。

表4-2に、TimesTenでサポートされていない事前定義例外を示します。

表4-2 TimesTenでサポートされていない事前定義済例外

例外名 Oracle Databaseエラー番号 SQLCODE 説明

LOGIN_DENIED

ORA-01017

-1017

ユーザー名およびパスワードが無効です。

NOT_LOGGED_ON

ORA-01012

-1012

プログラムがデータベースに接続せずにデータベース・コールを発行しました。

SELF_IS_NULL

ORA-30625

-30625

プログラムがMEMBERメソッドを起動しようとしましたが、オブジェクトが初期化されていませんでした。

TIMEOUT_ON_RESOURCE

ORA-00051

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