バージョン 8.1.3
 —  トリガとストアドプロシージャ  —

プログラミングとパフォーマンス

このドキュメントでは、効率的なプロシージャを作成するためのガイドラインとオプションについて説明します。 Natural を使用する際の特別な要件と、フォーマットバッファとレコードバッファの使用、およびレコードバッファ抽出ルーチン STPRBE についても説明します。

このドキュメントでは、次のトピックについて説明します。


プロシージャの作成

プロシージャを作成するときは、パフォーマンスについて検討することが重要です。 すべてのユーザーのすべてのコマンドを処理するために使用できるサブシステムの数は、10 までです。 著しく長い処理時間を必要とするプロシージャがあると、サブシステムはその他の要求に対応できなくなります。

すべてのサブシステムに重い負荷がかかると、トリガとストアドプロシージャ要求のキューイングが過剰に発生します。 同期のトリガとストアドプロシージャのコマンドは強制的に待機状態になり、ユーザーにとってはレスポンスタイムが悪化する可能性があります。

ストアドプロシージャ

ストアドプロシージャは、ライブラリ SYSSPT に作成することも、SYSSPT の steplib である別のライブラリに作成することもできます。

ストアドプロシージャは、通常の Natural サブプログラムで、次の特徴があります。

トリガ

トリガされるプロシージャが実行する機能は、特定のファイルに基づきます。 特定のコマンドやフィールドを使用することもあります。 プロシージャが実行する必要のある操作の数を減らすため、機能は非常に特化した内容にする必要があります。 任意のコマンドで、最大でプレコマンドトリガ 1 つとポストコマンドトリガ 1 つを起動できます。

非同期トリガ

非同期トリガは、実際にイベントが発生したかどうかを判断するときに役立ちます。

同期トリガ

同期トリガは、通常はアプリケーションに関連した依存性があります。つまり、コマンドを処理する前または後で何らかのアクションを実行する必要があります。 コマンドは、プロシージャが完了するまで続行できません。

同期プロシージャが制御を受け取ると、非同期プロシージャの場合と同様の処理を実行できます。 フィールド名が条件として指定されると、プロシージャはその値を受け取って(レコードの ISN を読み込むか、STPRBE をコール)、必要な処理を実行することができます。

マルチトリガのサポートの実装

それぞれのコマンドでは、1 つのプレコマンドトリガと 1 つのポストコマンドトリガのみを起動できます。 複数のフィールドでトリガが必要な場合は、"マルチトリガ"(複数の関連するトリガが含まれている単一のトリガ)をサポートするロジックを実装する必要があります。

特定のファイルやコマンドにマルチトリガを定義する場合は、トリガメンテナンス機能ではなく、プロシージャを使用することをお勧めします。 そのようなプロシージャには、次の特徴があります。

マルチトリガの例

トリガ条件 File 11
Command UPDATE
Field '** any field **'
Procedure PROC001
コマンド A1 Format Buffer='AA,BB,AB,CA,DF,MT,DT.'
プロシージャ サブプログラムは、AB、GA、DT、AA、LT、CA の順序でマルチトリガを処理します。 PROC001 は、制御を取得すると、シーケンス内の各フィールドを確認します。 フィールドが見つからない場合、そのフィールドのプロシージャは無視され、処理は次のフィールドに移ります。 この例では、フィールド GA と LT が見つかりません(フォーマットバッファ内にない)。 いずれかのプロシージャからゼロ以外のレスポンスコードが返されるかどうかに関係なく、処理を続行することができます。

単一トリガとマルチトリガ

トリガのリストが非常に長くなる場合、マルチトリガを 1 つ使用するのではなく、単一トリガを複数使用するほうが効率よいことがあります。

この方法は、ファイルにレコードタイプがある場合、またはアプリケーションがグループ内のファイルに対してデータを読み込んで更新する場合に意味があります。

Employees のようなアプリケーションに、2 つの独立した機能があるとします(Adabas のインストール時に提供される Employees サンプルファイルに基づく)。

Top of page

Natural 構文の制限

プロシージャをコーディングするときは、通常の Natural 構文を使用できます。 ただし、以下に説明する制限を考慮する必要があります。

エラー処理

STPPDRIV には ON ERROR 節が含まれているため、プロシージャの結果で発生するすべてのエラーは、STPPDRIV でトラップされます。

再スタート処理の一部として、STP は Adabas トリガドライバに対し、処理中のトリガ要求を終了したこと、結果がユーザーに返されることを通知します。

次の規則が適用されます。

これらの規則に従わない場合、Natural トリガドライバが制御を失う可能性があり、このときユーザーはAdabas トリガドライバからバッチ Natural サブシステムをキャンセルする必要があります。 Adabas トリガドライバがエラー処理に関わるときは、追加のリソースが必要になります。

プリンタのサポート

レポートやメッセージは、Natural サブシステムから出力できますが、サブシステムはバッチプロセッサのようには機能しません。 プリンタファイルはさまざまなサブシステムに割り当てることができますが、使用するには注意が必要です。 Natural サブシステムは、アプリケーションでどのプロシージャを実行するのか制御しません。

通常、レポートは、完全な形式で利用できます。 ニュークリアスがアクティブでも、スプールシステムがバッファをフラッシュしていないために、最新のメッセージまたはレポートの出力を利用できないことがあります。

ワークファイルのサポート

ワークファイルはサポートされていますが、実行時にどのワークファイルがサブシステムに割り当てられるのかは不明です。 そのため、プロシージャを実行するサブシステムに応じて、特定のワークファイルに対して読み書きするプロシージャを作成する必要があります。

ET ロジック

エンドトランザクション(ET)ロジックは、通常の方法で動作します。ただし、関与トリガによるに影響に注意してください。

非同期または非関与トリガが実行を完了したときは、BT を発行して、次のトリガを発行できるように、サブシステムを ET ステータスにする必要があります。

Natural のレベル

Natural プログラムレベルは、FETCH RETURN、CALLNAT、または PERFORM ステートメントが外部サブルーチンを処理するときに変更されます。 Natural トリガドライバが Natural セッションを制御し続けられるように、プログラムレベルを維持することが重要です。そのため、FETCH と STOP ステートメント(STACK TOP COMMAND が前提)は使用しないでください。 従って、実際にプロシージャやサブプログラムを呼び出す STPPDRIVは、レベル 1 である必要があります。

バッチモードに適したステートメント

プロシージャは、バッチモードで実行されます。 そのため、INPUT などのステートメントは、STACK DATA ステートメントとともに適切に使用する必要があります。 STACK コマンドは、適切ではありません。

CALLNAT パラメータ

Natural トリガドライバは、CALLNAT ステートメントでサブプログラムを呼び出します。 トリガエントリ内の定義に応じて、サブプログラムでは次のいずれかのオプションが使用されることを前提とします。

  1. パラメータは渡されません。

    非常に特化した機能を実行する非同期トリガで通常使用されます。 つまり、トリガイベント条件が、プロシージャがタスクを実行するために必要な唯一の情報です。 レスポンスコードは不要のため渡されません。コマンドはすでに完了している可能性があるため、プロシージャからゼロ以外のレスポンスコードを返すことができません。

  2. レスポンスコードフィールドだけが渡されます。

    レスポンスコードフィールドは修正可能な 4 バイトのバイナリ(B4)フィールドです。 Natural トリガドライバは、呼び出しが成功したかどうかを判断するために、4 バイトすべてを確認します。 ただし、実際のレスポンスコードが格納されているのは、下位 2 バイトだけです。 上位 2 バイトは、理由をレポートするときのサブコードとして使用される場合があります。

    Natural トリガドライバは、同期トリガの場合はレスポンスコードを返しますが、非同期トリガの場合はレスポンスコードを無視します。 非同期トリガは開始コマンドの実行完了後に実行されることがあるため、レスポンスコードは無意味です。

    レスポンスコード値は、ユーザーに返される前に、コマンドのアディション 4 フィールドの上位 2 バイトに格納されます。Adabas コントロールブロックのレスポンスコードフィールドには格納されません。 この場合のレスポンスコードは、通常 155(プレコマンドトリガを表す)または 156(ポストコマンドトリガを表す)です。

  3. レスポンスコードフィールドと制御情報が渡されます。

    レスポンスコードフィールドは、上記と同じ方法で渡されます。

    トリガに関する制御情報は、プロシージャを正常に実行するために不可欠である場合があります。 制御情報は、STPAPARM または STPXPARM パラメータデータエリア(PDA)で提供され、次の情報が含まれます。

  4. レスポンスコードフィールド、制御情報、およびグローバルユーザーエリアが渡されます。

    上記のレスポンスコードフィールドと制御情報の他に、グローバルユーザーエリアが渡されます。

    グローバルユーザーエリアは、アクティブな Natural サブシステムセッション中、保持されます。 グローバルユーザーエリアが Natural トリガドライバによって修正されることはないため、プロシージャの呼び出し間で情報を渡すために使用できます。 作業用のストレージエリアとして使用することもできます。

Top of page

フォーマットバッファとレコードバッファの使用

レコードバッファ

パラメータ

レコードバッファを設定するときは、パラメータの定義が重要です。 さまざまな長さの複数のパラメータを次のように渡すことができます。

パラメータを渡すオプションはさまざまで、柔軟性があります。環境に合わせて、最も効果的または整合性の高い方法を選択してください。

  1. パラメータは渡されません。

  2. 固定された定義

    パラメータは、ストレージ上の連続した領域に格納され、長さと定義は固定されています。 各パラメータは、構造によって変化しないため、やはり長さは固定されています。 そのため、呼び出されるプロシージャは、パラメータ用に定義された構造または DSECT を解釈できる必要があります。 サンプル STPLNK01 を参照してください。

  3. パラメータの固定リスト

    複数のパラメータがありますが、STPLNK が呼び出されるときの各パラメータの番号、順序、形式、長さはそれぞれ一定です。 STPLNK では、要求の発行前に、これらのパラメータがストレージ上で連続した領域、つまりレコードバッファに格納されていることだけが必要です。 サンプル STPLNK02 を参照してください。

  4. パラメータの可変リスト

    パラメータを渡す柔軟性の高い方法です。呼び出されるプロシージャは、レコードバッファに渡されるパラメータの形式を認識する必要があります。 このような情報(つまりプロシージャイベントフィールド DD)を渡すときにフォーマットバッファを使用すると非常に便利です。 レコードバッファ抽出ルーチン STPRBE は、フィールドのフォーマットバッファをスキャンし、同時にレコードバッファを調べて正しい値(開始位置と終了位置)を特定する必要があります。 サンプル STPLNK03 を参照してください。

いずれの場合も、RBOPT パラメータオプションを使用して、レコードバッファに対する読み込みまたは書き込みアクセスが許可される必要があります。

フォーマットバッファ

フォーマットバッファは、レコードバッファで渡されるパラメータの定義を格納するときに、任意で使用できます。

レコードバッファ抽出ルーチン(STPRBE)

STPRBE は、レコードバッファ抽出ルーチンです。 レコードバッファ情報を要求するために Adabas プロシージャで使用できます。 STPRBE をコールできるのは次のとおりです。

すべての機能で、レコードバッファ抽出ルーチンは次のように呼び出されます。

CALL 'STPRBE' FUNCTION REQUEST-PARM REC-BUFFER

FUNCTION、REQUEST-PARM、および REC-BUFFER について次に説明します。

REQUEST-PARM(A154)

REQUEST-PARM を構成するフィールドは次のとおりです。

フィールド名 長さ 説明
ERR-MESSAGE A72 受け取ったエラーのエラーメッセージテキスト
RESPONSE-CODE I4 このルーチンからのレスポンスコード(サブコードと実際のエラー)
VERSION NUMBER A4 この構造のバージョン
FIELD NAME A32 抽出されるフィールドのロングネーム
FIELD FORMAT A1 抽出されるフィールドの形式
FIELD OPTIONS A3 特殊なオプション
FIELD LENGTH I4 抽出されるフィールドの長さ
FIELD SHORT A2 フィールドの Adabas ショートネーム
未使用 A2 未使用
FIELD OCCUR I4 PE/MU フィールドのオカレンス番号
GROUP OCCUR I4 PE フィールド内の MU のオカレンス番号
FIELD OFFSET I4 抽出するレコードバッファに対するオフセット
未使用 A18 未使用

 

FUNCTION(A4)

指定しなければならない機能について次の表で説明します。

フィールド 説明
GF フォーマットバッファの内容を取得します。
GI インデックス値を取得します(MU または PE のインデックスオカレンスを取得)。
GM マルチバリューを取得します(PE 内の MU フィールドを取得)。
GR レコードバッファの範囲を取得します(呼び出しで指定された開始位置と長さに従って、レコードバッファ情報を取得)。
GV 値を取得します(レコードバッファからフラットフィールド値を取得)。
GX UBX 情報を取得します。 NR 機能とは異なり、ユーザーは ADALNK のユーザー出口 B の定義に従って、ユーザーバッファ拡張を使用して渡されたすべての情報を取得できます。
NR Natural 情報を取得します(渡されたオフセットと長さに従って、ユーザーバッファから Natural ユーザー情報を取得)。 ADALNK のユーザー出口 B でユーザーバッファ拡張が使用されている場合のみ有効です。
UI インデックス値を更新します(MU または PE のインデックスオカレンスを変更)。
UM マルチバリューを更新します(PE 内の MU フィールドを変更)。
UR レコードバッファの範囲を更新します(呼び出しで指定された開始位置と長さに従って、レコードバッファ情報を変更)。
UV 値を更新します(レコードバッファからフラットフィールド値を変更)。

各機能で必須の値について次の表に示します。

フィールド GF GI GM GR GV GX NR UI UM UR UV
ERR-MESSAGE _/U _/U _/U _/U _/U _/U _/U _/U _/U _/U _/U
RESPONSE-CODE _/U _/U _/U _/U _/U _/U _/U _/U _/U _/U _/U
FIELD NAME   F/A F/A   F/A     F/A F/A   F/A
FIELD FORMAT   f/U f/U   f/U     f/U f/U   f/U
FIELD OPTIONS   G     C/G     G     G
FIELD LENGTH F f/U f/U   f/U F   f/U f/U   f/U
FIELD SHORT   f/U f/U   f/U     f/U f/U   f/U
FIELD OCCUR   F/A F/A         F/A F/A    
GROUP OCCUR   f/A F/A         f/A F/A    
FIELD OFFSET F   F/A     F/A   F/A      

 

記号 説明
_ 未使用
A コール後も未変更のまま
F コール前に設定
f コール前にオプションで設定
C フィールドカウント。カウントフィールドの値が必要なとき MU または PE フィールドでのみ有効
G グループオプション。グループフィールド内のエレメンタリフィールドを抽出/更新
U 明示しない限り、コール後に更新(例えば長さ)

 

REC-BUFFER

REC-BUFFER は、可変長のフィールドで、次のいずれかが格納されます。

レスポンスコード
コード 説明
0 コールは完全に成功しました。
1 内部エラーが発生しました。名前マッピングの取得に失敗しました。
2 名前マッピングでロングネームが見つかりません。ファイル - フィールドテーブル定義に名前が存在しませんでした。
3 予約済みです。
4 フォーマットバッファにフィールドが見つかりません。ユーザーは、フォーマットバッファに存在しないフィールドの値を要求しました。
5 フィールドは、レコードバッファの非常に深いところにあります。 レコードバッファの長さは、Adabas コントロールブロック(ACB)のレコードバッファ長(RBL)で判断されました。 フィールドが存在する場合は、定義されている上限を超えています。
6 要求されたオカレンスがフォーマットバッファに存在しません。 MU または PE の特定のオカレンスがフォーマットバッファに見つからなかったことをユーザーに通知します。
7 機能タイプが無効です。FUNCTION に有効な値が設定されていません。
8 レコードバッファにアクセスできません。レコードバッファオプションフィールドが none に設定されているため、アクセスが許可されません。 そのため、このプロシージャで利用できるレコードバッファ抽出機能はありません。
9 レコードバッファの修正が拒否されました。レコードバッファへのアクセスは許可されていますが、書き込みアクセスは許可されていません。 そのため、GET 機能のみを要求できます。
10 レコードバッファ長(RBL)が ACB で可能な最大値を超えています。指定された長さは、RBL の合計長を超過しています。 オプション NI にも適用されます。 拡張バッファの 232 バイトのみを取り出すことができます。
11 レコードバッファ長が不適切にゼロに設定されています。レコードバッファ抽出ルーチンでは、ユーザーがこの関数コールで RBL の長さを指定する必要がありましたが、ゼロに設定されています (例えば RAngeReq)。
12 フォーマットバッファの構文が正しくありません。 コマンドで有効な構文が、レコードバッファ抽出ルーチンで解決されていない可能性があります。 通常は、n 構文(例えば AB1-n、ABn)が使用されたときに適用されます。 ただし、トリガがプレコマンドトリガである場合は、フォーマットバッファ自体が無効である可能性があります。
13 無効なパラメータが指定されました。関数コールで設定されるはずのパラメータのいずれかが設定されていませんでした。 例えば、フィールド名関数コールが設定されていませんでした。
14 PE グループオカレンスが指定されていませんでした。特定の PE または MU オカレンスにアクセス/更新する関数コールが指定されましたが、パラメータでオカレンス番号が渡されませんでした。
15 無効な編集マスクがフォーマットバッファで指定されました。 有効な編集マスクだけを指定できます。
16 予約済みです。
17 ユーザー情報は利用できません。リンク B がありません。つまり、ユーザーはユーザーバッファ抽出情報にアクセスしようとしましたが、利用できる情報がありません。
18 現在のファイルのグループ定義レコードが見つかりませんでした。
19 現在のファイルのグループ定義レコードで、フィールドが見つかりませんでした。
60 フォーマットバッファの構文エラーです。ニュークリアスと同様に、レコードバッファ抽出ルーチンでは、フォーマットバッファが一般的な定義規則に準拠する必要がありますが、現在のフォーマットバッファは無効です。 エラーメッセージでサブコードを確認してください(『Adabas メッセージおよびコードマニュアル』を参照)。
3xxx ゼロ以外の Adabas レスポンスコードが返されました。xxx は実際の Adabas レスポンスコードです。 レコードバッファ抽出ルーチンがトリガテーブルにアクセスして詳細情報を取得しようとしているときに、このような状態が発生することがあります。
9999 GDA が正しくないか、破損しているか、または存在しません。 これは内部エラーであることを示します。 Natural サブシステムからのメッセージに何らかのエラーを示しているものがないか確認するか、Software AG 技術サポートに連絡してください。 ダンプが必要になります。

 

オフセットによる値の取得
フィールド値の取得

この要求では、Adabas フィールド名が指定される必要があります。

処理時に RBE は、レコードバッファとフォーマットバッファを調べる必要があります。 目的のフィールドを特定する前に、フォーマットバッファで見つかった各フィールドで、RBE はレコードバッファを調べ、実際の移動に備えて正しい位置を探します。

MU フィールドと PE フィールドを調べるには、次のように配列内の要素の合計数を計算する必要があります。

注意:
ユーザーがフォーマットバッファ内のオカレンス番号を指定しなかった MU の場合、ユーザーは最初のオカレンスを受け取ります。つまり要求は、"エレメンタリ" フィールドの要求のように扱われます。

RBE は、ユーザーが MU フィールドまたは PE フィールドだけを指定したのか、それとも PE フィールド内の MU を指定したのかを判断します。 フォーマットバッファでサポートされる PE フィールドや使用方法の例を次に示します(m と n は、実際のオカレンス値)。

レコードバッファから MU 数または PE 数を取得するには、フィールド名かショートネームを指定する必要があります。返される値の長さの指定は任意です。

Top of page