3.8. 手順
Data Virtualization の手順言語を使用して外部手順を呼び出し、仮想手順とトリガーを定義できます。
3.8.1. 手順言語 リンクのコピーリンクがクリップボードにコピーされました!
Data Virtualization で手順言語を使用して、仮想手順を定義することができます。これは、リレーショナルデータベース管理システムに保存された手順と類似しています。この言語を使用して、ビューに対して INSERT、UPDATE、DELETE コマンドを置く変換ロジックを定義できます。これらは更新手順として知られています。詳細は、「 仮想手順および 更新手順 (Triggers) 」を参照してください。
3.8.1.1. コマンドステートメント リンクのコピーリンクがクリップボードにコピーされました!
コマンドステートメントは、1 つ以上のデータソースに対して DML コマンド、DDL コマンド、または動的 SQL を実行します。詳細は、「 DML コマンド および DDL コマンド」を参照してください。
用途
command [(WITH|WITHOUT) RETURN];
command [(WITH|WITHOUT) RETURN];
コマンドステートメントの例
SELECT * FROM MySchema.MyTable WHERE ColA > 100 WITHOUT RETURN; INSERT INTO MySchema.MyTable (ColA,ColB) VALUES (50, 'hi');
SELECT * FROM MySchema.MyTable WHERE ColA > 100 WITHOUT RETURN;
INSERT INTO MySchema.MyTable (ColA,ColB) VALUES (50, 'hi');
構文ルール
-
EXECUTE コマンドステートメントは、IN/OUT、OUT、および RETURN パラメーターにアクセスできます。戻り値にアクセスするには、ステートメントの形式は
var = EXEC proc…になります。パラメーター構文の名前が OUT または IN/OUT の値にアクセスするには、使用する必要があります。たとえば、EXEC proc(in_paramgitops'1', out_paramgitopsvar)は out パラメーターの値を変数 var に割り当てます。パラメーターのデータタイプは、暗黙的に変数のデータ型に変換できることが予想されます。EXECUTE コマンドステートメントの詳細は、「 EXECUTE コマンド 」を参照してください。 - RETURN 句は、コマンドの結果が手順から返すことができるかどうかを判断します。WITH RETURN がデフォルトです。コマンドが結果セットを返さないか、手順が結果セットを返さないと、RETURN 句は無視されます。WITH RETURN が指定されている場合は、コマンドの結果セットは、予想される手順の結果セットと一致する必要があります。手順結果セットとして、WITH RETURN を実行して成功した最後のステートメントのみが返されます。戻り可能な結果セットがなく、この手順で結果セットが返されることを宣言すると、空の結果セットが返されます。
INTO 句はテーブルへの挿入にのみ使用されます。'SELECT … INTO table … は、'INSERT INTO table SELECT … 変数を割り当てる必要がある場合は、以下のいずれかの方法を使用できます。
- scalar サブクエリーで割り当てステートメントを使用します。
DECLARE string var = (SELECT col ...);
DECLARE string var = (SELECT col ...);
- 一時テーブルの使用
INSERT INTO #temp SELECT col1, col2 ...; DECLARE string VARIABLES.RESULT = (SELECT x FROM #temp);
INSERT INTO #temp SELECT col1, col2 ...;
DECLARE string VARIABLES.RESULT = (SELECT x FROM #temp);
- アレイの使用
DECLARE string[] var = (SELECT (col1, col2) ...); DECLARE string col1val = var[1];
DECLARE string[] var = (SELECT (col1, col2) ...);
DECLARE string col1val = var[1];
3.8.1.2. 動的 SQL コマンド リンクのコピーリンクがクリップボードにコピーされました!
動的 SQL では、仮想手順で任意の SQL コマンドの実行が可能になります。動的 SQL は、正確なコマンド形式が実行前に認識されない状況で有用です。
用途
EXECUTE IMMEDIATE <sql expression> AS <variable> <type> [, <variable> <type>]* [INTO <variable>] [USING <variable>=<expression> [,<variable>=<expression>]*] [UPDATE <literal>]
EXECUTE IMMEDIATE <sql expression> AS <variable> <type> [, <variable> <type>]* [INTO <variable>] [USING <variable>=<expression> [,<variable>=<expression>]*] [UPDATE <literal>]
構文ルール
- SQL 式は、262144 文字未満の CLOB または文字列の値である必要があります。
-
AS句は、実行された SQL 文字列によって返される Projected シンボル名とタイプを定義するために使用されます。AS句シンボルは、実行された SQL 文字列によって返されるシンボルと位置的に一致します。変換できないタイプや、実行された SQL 文字列によって返された列が多すぎると、エラーが発生します。 -
INTO句は動的 SQL を指定された temp テーブルにプロジェクトします。INTO句を指定すると、Dynamic コマンドは実際に QUERY EXPRESSION を持つ INSERT のように動作するステートメントを実行します。dynamic SQL コマンドがINTO句で一時テーブルを作成する場合は、テーブルのメタデータを定義するためにAS句が必要になります。 -
USING句を使用すると、動的な SQL 文字列に、実行時に指定された値にバインドされる変数参照を含めることができます。これにより、周りの手順の変数名および入力名から SQL 文字列を独立させることができます。動的コマンドUSING句では、各変数は短縮名でのみ指定されます。ただし、動的な SQL では、USING変数はDVARに対して完全修飾する必要があります。USING句は、動的 SQL で有効な式として使用される値のみに使用されます。USING句を使用してテーブル名、キーワードなどを置き換えることはできません。これにより、準備済みステートメントで通常のバインド(?)式と同等のシンボルが使用されます。USING句は、必要な文字列操作の量を減らすのに役立ちます。USING 句の値にバインドされていない SQL 文字列のUSING記号に参照が行われると、例外が発生します。 -
UPDATE句は、更新モデル数を指定するために使用されます。許可される値は(0,1,*)です。0 は、句が指定されていない場合のデフォルト値です。詳細は、「 モデル数の更新」を 参照してください。
例: 動的 SQL
以下は、動的な SQL 文字列の条件を構築するより複雑な方法の例になります。つまり、仮想手順の AccountAccess.GetAccounts には入力 ID、LastName、および bday があります。ID に値を指定すると、動的な SQL 条件で使用される唯一の値になります。または、LastName に値を指定すると、値が検索文字列であるかどうかを検出します。LastName に加えて bday を指定すると、LastName で複合基準を形成するために使用されます。
例: USING 句を使用した動的 SQL と動的に構築された基準文字列
動的 SQL の制限および回避策
dynamic SQL コマンドを使用すると、一時的なテーブルの使用を必要とする割り当てステートメントが生成されます。
割り当ての例
EXECUTE IMMEDIATE <expression> AS x string INTO #temp; DECLARE string VARIABLES.RESULT = (SELECT x FROM #temp);
EXECUTE IMMEDIATE <expression> AS x string INTO #temp;
DECLARE string VARIABLES.RESULT = (SELECT x FROM #temp);
条件の一部が存在しない場合、適切な基準の構築は複雑になります。たとえば、基準 がすでに NULL であった場合、以下の例では 条件 に NULL が残されます。
例: 危険な NULL 処理
...
criteria = '(' || criteria || ' and (Customer.Accounts.Birthdate = DVARS.BirthDay))';
...
criteria = '(' || criteria || ' and (Customer.Accounts.Birthdate = DVARS.BirthDay))';
条件が使用前に NULL ではないことを確認することが推奨されます。これができない場合は、以下の例のようにデフォルトを指定できます。
例: NULL 処理
...
criteria = '(' || nvl(criteria, '(1 = 1)') || ' and (Customer.Accounts.Birthdate = DVARS.BirthDay))';
...
criteria = '(' || nvl(criteria, '(1 = 1)') || ' and (Customer.Accounts.Birthdate = DVARS.BirthDay))';
dynamic SQL が UPDATE コマンド、DELETE コマンド、または INSERT コマンドである場合、ステートメントの行数は rowcount 変数から取得できます。
例: AS および INTO 句
/* Execute an update */ EXECUTE IMMEDIATE <expression>;
/* Execute an update */
EXECUTE IMMEDIATE <expression>;
3.8.1.3. 宣言ステートメント リンクのコピーリンクがクリップボードにコピーされました!
宣言ステートメントは、変数とそのタイプを宣言します。変数を宣言すると、手順内のそのブロックとサブブロックで使用できます。変数はデフォルトで null に初期化されますが、宣言ステートメントの一部として式の値を割り当てることもできます。
用途
DECLARE <type> [VARIABLES.]<name> [= <expression>];
DECLARE <type> [VARIABLES.]<name> [= <expression>];
構文の例
declare integer x; declare string VARIABLES.myvar = 'value';
declare integer x;
declare string VARIABLES.myvar = 'value';
構文ルール
- サブブロックでは、重複する名前の変数をリダクションできません。
- VARIABLES グループが指定されていない場合でも常に暗示されます。
- 割り当て値は、Assignments ステートメントと同じルールに従います。
- 標準タイプに加えて、例外変数を宣言する場合は EXCEPTION を指定できます。
3.8.1.4. 割り当てステートメント リンクのコピーリンクがクリップボードにコピーされました!
割り当てステートメントは、式を評価することで値を変数に割り当てます。
用途
<variable reference> = <expression>;
<variable reference> = <expression>;
構文の例
myString = 'Thank you'; VARIABLES.x = (SELECT Column1 FROM MySchema.MyTable);
myString = 'Thank you';
VARIABLES.x = (SELECT Column1 FROM MySchema.MyTable);
割り当ての有効な変数には、宣言ステートメントで宣言された in-scope 変数、または in_out および out パラメーターが含まれます。In_out パラメーターおよび out パラメーターは、完全修飾名でアクセスできます。
例: Out パラメーター
CREATE VIRTUAL PROCEDURE proc (OUT STRING x, INOUT STRING y) AS BEGIN proc.x = 'some value ' || proc.y; y = 'some new value'; END
CREATE VIRTUAL PROCEDURE proc (OUT STRING x, INOUT STRING y) AS
BEGIN
proc.x = 'some value ' || proc.y;
y = 'some new value';
END
3.8.1.5. 特別な変数 リンクのコピーリンクがクリップボードにコピーされました!
VARIABLES.ROWCOUNT 整数変数には、最後に実行した INSERT、UPDATE、または DELETE コマンドステートメントの影響を受ける行の数が含まれます。into 句で動的 SQL に より処理される挿入により、ROWCOUNT も更新されます。
サンプル使用例
... UPDATE FOO SET X = 1 WHERE Y = 2; DECLARE INTEGER UPDATED = VARIABLES.ROWCOUNT; ...
...
UPDATE FOO SET X = 1 WHERE Y = 2;
DECLARE INTEGER UPDATED = VARIABLES.ROWCOUNT;
...
更新以外のコマンドステートメント(WITH または WITHOUT RETURN)は ROWCOUNT を 0 にリセットします。
適切な ROWCOUNT 値を取得するには、コマンド文の直後に ROWCOUNT を変数に保存します。
3.8.1.6. 複合ステートメント リンクのコピーリンクがクリップボードにコピーされました!
複合ステートメントまたはブロックは、一連のステートメントを論理的にグループ化します。複合ステートメントで作成される一時的なテーブルおよび変数は、そのブロックにのみローカルであり、ブロックを終了すると破棄されます。
用途
IF、LOOP、WHILE などによってブロックが予想されると、パーサーによって単一のステートメントも使用できます。ブロック BEGIN または END は想定されていませんが、BEGIN と END のペアでラップされているかのようにステートメントが実行されます。
構文ルール
-
NOT ATOMICまたはATOMIC句が指定されていない場合、ブロックはアトミックに実行されます。 -
ATOMIC句が指定されている場合は、ブロックをアトミックに実行する必要があります。トランザクションがすでにスレッドに関連付けられている場合は、追加のアクションは実行されません。保存ポイントまたはサブトランザクションは現在使用されていません。より高いレベルのトランザクションが使用され、ブロックによって例外処理の一部がない状態では、トランザクションはロールバックのみとしてマークされます。そうでない場合は、トランザクションがブロックの実行に関連付けられます。ブロックが正常に完了すると、トランザクションはコミットされます。 - ラベルは、このラベルを含むステートメントで使用されるラベルと同じにすることはできません。
- 変数の割り当てと、暗黙的な結果のカーソルはロールバックによる影響を受けません。ブロックが正常に完了しない場合は、割り当ては引き続き影響を受けます。
例外処理
EXCEPTION 句が複合ステートメント内で使用されている場合、ステートメントから出力された処理例外は、EXCEPTION ステートメントに転送される実行フローと共に取得されます。このブロックによって開始されるブロックレベルのトランザクションは、例外ハンドラーが正常に完了するとコミットされます。例外ハンドラーまたは元の例外が例外ハンドラーから出力された場合、トランザクションはロールバックされます。例外ハンドラーステートメントでは、BLOCK に固有の一時テーブルまたは変数は使用できなくなります。
例外を処理するだけで、通常ソースで発信されたエラーや関数実行で発生します。低レベルの内部 Data Virtualization エラーまたは Java RuntimeException はキャッチされません。
キャッチされた例外の処理を支援するために、EXCEPTION 句は例外の重要なフィールドを公開するグループ名を指定します。以下の表には、例外グループに含まれる変数をまとめています。
| 変数 | タイプ | 説明 |
|---|---|---|
| 状態 | string | SQL 状態 |
| ERRORCODE | integer | エラーまたはベンダーコード。Data Virtualization の内部例外の場合は、TEIIDxxxx コードの整数サフィックスになります。 |
| TEIIDCODE | string | 完全な Data Virtualization イベントコード。通常は TEIIDxxxx です。 |
| EXCEPTION | object |
キャッチされる例外は |
| CHAIN | object | 現在の例外をチェーンされた例外または原因。 |
Data Virtualization は、SQL 状態の使用における ANSI SQL 仕様に完全に準拠していません。基礎となる SQLException 原因のない Data Virtualization エラーの場合は、Data Virtualization コードを使用することが推奨されます。
例外グループ名は、より高いレベルの例外グループまたはループのカーソル名と同じではない場合があります。
例外グループ処理の例
3.8.1.7. IF ステートメント リンクのコピーリンクがクリップボードにコピーされました!
IF ステートメントは条件を評価し、結果に応じて 2 つのステートメントのいずれかを実行します。IF ステートメントをネストすると、複雑な分岐ロジックを作成できます。依存の ELSE ステートメントは、IF ステートメントが false に評価される場合にのみステートメントを実行します。
用途
IF (criteria) block [ELSE block] END
IF (criteria)
block
[ELSE
block]
END
IF ステートメントの例
この基準には、行値を参照する有効なブール式または IS DISTINCT FROM 述語を使用できます。IS DISTINCT FROM 拡張機能は、以下の構文を使用します。
rowVal IS [NOT] DISTINCT FROM rowValOther
rowVal IS [NOT] DISTINCT FROM rowValOther
rowVal および rowValOther は、行値グループへの参照です。これは通常、行の値が変更されているかどうかを迅速に判断するために、ビューの更新トリガーではなく使用されます。
例: IS DISTINCT FROM IF ステートメント
IF ( "new" IS DISTINCT FROM "old") BEGIN ...statement... END
IF ( "new" IS DISTINCT FROM "old")
BEGIN
...statement...
END
IS DISTINCT FROM は、同等の null 値を考慮し、UNKNOWN 値を生成しません。
Null 値は IF ステートメントの条件で考慮される必要があります。IS NULL 基準を使用して、null 値の存在を検出することができます。
3.8.1.8. ループステートメント リンクのコピーリンクがクリップボードにコピーされました!
LOOP ステートメントは、結果セットを経由したカーソルに使用される反復制御コンストラクトです。
用途
[label :] LOOP ON <select statement> AS <cursorname>
statement
[label :] LOOP ON <select statement> AS <cursorname>
statement
構文ルール
- ラベルは、このラベルを含むステートメントで使用されるラベルと同じにすることはできません。
3.8.1.9. 一方で、ステートメント リンクのコピーリンクがクリップボードにコピーされました!
WHILE ステートメントは、指定した条件が満たされるたびにステートメントを繰り返し実行するために使用される反復制御コンストラクトです。
用途
[label :] WHILE <criteria>
statement
[label :] WHILE <criteria>
statement
構文ルール
- ラベルは、このラベルを含むステートメントで使用されるラベルと同じにすることはできません。
3.8.1.10. 継続ステートメント リンクのコピーリンクがクリップボードにコピーされました!
CONTINUE ステートメントは、LOOP または WHILE コンストラクト内で使用され、ループの残りのステートメントをスキップして次のループを続行します。これは LOOP または WHILE ステートメント内で使用する必要があります。
用途
CONTINUE [label];
CONTINUE [label];
構文ルール
-
ラベルが指定されている場合は、
LOOPまたはWHILEステートメントが含まれる必要があります。 -
ラベルが指定されていない場合、ステートメントは
LOOPまたはWHILEステートメントを含む最も近い値に影響します。
3.8.1.11. break ステートメント リンクのコピーリンクがクリップボードにコピーされました!
BREAK ステートメントは、LOOP または WHILE コンストラクト内で使用され、ループから分離します。これは LOOP または WHILE ステートメント内で使用する必要があります。
用途
BREAK [label];
BREAK [label];
構文ルール
-
ラベルが指定されている場合は、
LOOPまたはWHILEステートメントが含まれる必要があります。 -
ラベルが指定されていない場合、ステートメントは
LOOPまたはWHILEステートメントを含む最も近い値に影響します。
3.8.1.12. leave ステートメント リンクのコピーリンクがクリップボードにコピーされました!
LEAVE ステートメントは、複合、LOOP、または WHILE コンストラクト内で使用され、指定されたレベルに残します。
用途
LEAVE label;
LEAVE label;
構文ルール
-
ラベルは、複合ステートメント、
LOOP、またはWHILEステートメントが含まれる必要があります。
3.8.1.13. 戻り値のステートメント リンクのコピーリンクがクリップボードにコピーされました!
RETURN ステートメントは適切に手順を終了し、オプションで値を返します。
用途
RETURN [expression];
RETURN [expression];
構文ルール
- 式が指定されている場合、手順には return パラメーターが必要で、値は想定されるタイプに暗黙的に変換する必要があります。
-
手順に return パラメーターがある場合でも、
RETURNステートメントで戻り値を指定する必要はありません。戻り値のパラメーターは割り当てで設定することも、null として残すこともできます。
サンプル使用例
CREATE VIRTUAL FUNCTION times_two(val integer)
RETURNS integer AS
BEGIN
RETURN val*2;
END
CREATE VIRTUAL FUNCTION times_two(val integer)
RETURNS integer AS
BEGIN
RETURN val*2;
END
3.8.1.14. エラーステートメント リンクのコピーリンクがクリップボードにコピーされました!
ERROR ステートメントは、手順がエラー状態を入力したことを宣言します。このステートメントは、現在のトランザクションが存在する場合は、そのトランザクションもロールバックします。任意の有効な式は ERROR キーワードの後に指定できます。
用途
ERROR message;
ERROR message;
例: エラーステートメント
ERROR 'Invalid input value: ' || nvl(Acct.GetBalance.AcctID, 'null');
ERROR 'Invalid input value: ' || nvl(Acct.GetBalance.AcctID, 'null');
ERROR ステートメントは以下に相当します。
RAISE SQLEXCEPTION message;
RAISE SQLEXCEPTION message;
3.8.1.15. ステートメントを引き上げます。 リンクのコピーリンクがクリップボードにコピーされました!
RAISE ステートメントは、例外または警告を発生させるために使用されます。例外を発生させると、このステートメントは、現在のトランザクションが存在する場合は、現在のトランザクションもロールバックします。
用途
RAISE [SQLWARNING] exception;
RAISE [SQLWARNING] exception;
例外は、例外または例外式への変数参照になります。
構文ルール
-
SQLWARNINGが指定されている場合は、例外が警告としてクライアントに送信され、手順の実行が続行されます。 - null の警告は無視されます。警告以外の例外は、必ずしも例外が発生します。
raise ステートメントの例
RAISE SQLWARNING SQLEXCEPTION 'invalid' SQLSTATE '05000';
RAISE SQLWARNING SQLEXCEPTION 'invalid' SQLSTATE '05000';
3.8.1.16. 例外式 リンクのコピーリンクがクリップボードにコピーされました!
例外式は、発生または警告として使用できる例外を作成します。
用途
SQLEXCEPTION message [SQLSTATE state [, code]] CHAIN exception
SQLEXCEPTION message [SQLSTATE state [, code]] CHAIN exception
構文ルール
- いずれの値も null にすることができます。
-
メッセージと状態は、例外メッセージと SQL 状態を指定する文字列式です。Data Virtualization は、SQL 状態の使用時に ANSI SQL 仕様に完全に準拠しませんが、選択する SQL 状態を設定できます。 -
codeは、ベンダーコードを指定する整数の式です。 -
例外は、例外または例外式の変数参照であり、結果として得られる例外を親としてチェーンします。