[ |../../index.htm#lansa/ov_indexed_space.htm]
現在地:
OV_INDEXED_SPACE
注:組み込み関数の規則
索引付きスペースを定義、操作できます。
警告:このファンクションでは、RDMLXフィールドはサポートされません。
この組み込み関数は、アプリケーションへの影響を考慮した上でユーザーの責任において使用してください。明示的か暗黙的かを問わず、いかなる保証もありません。「免責事項 」全文を参照してください。
ファンクション番号: |
989 |
必要なDLL: |
U_BIF989.DLL |
各製品の対応
Visual LANSA for Windows |
使用可 |
Visual LANSA for Linux |
使用不可 |
LANSA/AD |
使用不可 |
引数
番号 |
タイプ |
必須/任意 |
説明 |
最小長 |
最大長 |
最小小数桁数 |
最大小数桁数 |
1 |
A |
必須 |
索引付きスペースに対して実行する操作のタイプ |
1 |
50 |
|
|
2 |
A |
必須 |
定義文字列または索引付きスペースの識別子(またはハンドル)。識別子(またはハンドル)は、新しい索引付きスペースを作成したときに引数2で返される、索引付きスペースを一意に識別する値です。 |
1 |
256 |
|
|
3 |
A |
任意 |
定義文字列の続き |
1 |
256 |
|
|
4 |
A |
任意 |
定義文字列の続き |
1 |
256 |
|
|
5 |
A |
任意 |
定義文字列の続き |
1 |
256 |
|
|
6 |
A |
任意 |
定義文字列の続き |
1 |
256 |
|
|
7 |
A |
任意 |
定義文字列の続き |
1 |
256 |
|
|
8 |
A |
任意 |
定義文字列の続き |
1 |
256 |
|
|
9 |
A |
任意 |
定義文字列の続き |
1 |
256 |
|
|
10 |
A |
任意 |
定義文字列の続き |
1 |
256 |
|
|
11 |
A |
任意 |
定義文字列の続き |
1 |
256 |
|
|
戻り値
番号 |
タイプ |
必須/任意 |
説明 |
最小長 |
最大長 |
最小小数桁数 |
最大小数桁数 |
1 |
A |
必須 |
標準戻りコード OK = 正常に完了した NR = レコードが見つからなかった ER = エラーが発生した |
2 |
2 |
|
|
2 |
A |
任意 |
返された索引付きスペースの識別子またはハンドル この戻り値は、引数1として、作成された索引付きスペースの識別子(またはハンドル)を返すCREATEを渡した場合は必須です。 |
10 |
10 |
|
|
技術ノート
索引付きスペースと索引付きスペース定義文字列
索引付きスペースを作成する(すなわち、引数1としてCREATEを指定する)場合、引数2~11で、索引付きスペースの定義文字列を指定する必要があります。
引数2~11は連結され(各引数の末尾ブランクは無視される)、以下のような形式の単一の定義文字列になります。
name keyword(value), name keyword(value), name keyword(value), ....... name keyword(value)
表記の説明:
- "name"は、リストを作成するRDMLファンクション内に定義されているか、そのRDMLファンクションによって参照される有効なRDMLフィールドの名前です。
- "keyword"は、"name"で指定されたフィールドの用途を指定し、KEY、DATA、AVG、MAX、MIN、COUNT、およびSUMのいずれかです。キーワードが指定されていない場合、デフォルト・キーワードのDATAが使用されます。
- "value"は、リストを定義するRDMLファンクション内に定義されているか、そのRDMLファンクションによって参照される有効なRDMLフィールドの名前を指定します。特定のキーワード値についてのみ、そのキーワード操作を実行するフィールドを指定するために使用します。すなわち、".., A SUM(B), .."は、索引付きスペース・フィールドAにフィールドBのSUM (すなわち合計)を保管するよう定義します。同様に、文字列".., X AVG(Y), .."は、索引付きスペース・フィールドXにフィールドYの平均を保管するよう定義します。
「キーワード」AVG、MAX、MIN、およびSUMには、それに関連付ける"value"が必要です。すなわち、AVG(value)、MAX(value)、MIN(value)、およびSUM(value)という形式で指定する必要があります。ここで、valueは、呼び出し元RDMLファンクションで定義されているフィールドの名前です。
「キーワード」KEY、DATA、およびCOUNTには、それに関連付ける"value"は必要ないため、必ずKEY()、DATA()、およびCOUNT()として指定する必要があります。
索引付きスペースは、表またはグリッド形式での表示に最適です。
定義文字列では、索引付きスペース内の列とその使用方法を定義します。以下の例は、この概念を示しています。
定義文字列: deptment key(), deptdes
この場合、以下のように表示できます。
Department (DEPTMENT) |
Department Description (DEPTDESC) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ここで、DEPTMENTは、テーブルまたはグリッドの各項目に対する単一のキーです。この例では、"deptdesc"でデフォルト・キーワードである"data()"が使用されることに注意してください。
定義文字列:deptment key(), section key(), secdesc
この場合、以下のように表示できます。
Department (DEPTMENT) |
Section (SECTION) |
Section Description (SECDESC) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ここで、DEPTMENTとSECTIONにより、テーブルまたはグリッドの各項目ごとに1つの集合が作成されます。この例では、"secdesc"でデフォルト・キーワードである"data()"が使用されることに注意してください。
定義文字列: deptment key(), empasal avg(salary), empxsal max(salary), empmsal min(salary)
この場合、以下のように表示できます。
Department (DEPTMENT) |
Average Salary (EMPASAL) |
Maximum Salary (EMPXSAL) |
Minimum Salary (EMPMSAL) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ここで、DEPTMENTは、テーブルまたはグリッドの各項目に対する単一のキーです。
OV_INDEXED_SPACEの使用に関する注意事項/規則/ガイドライン
- 索引付きスペースは、大量の情報を処理する「バッチ」形式のファンクションをサポートすることを主な目的として、以下の機能を提供するよう設計されています。
- 複数レベルの要約情報を累計する最適な方法
- データベース行へのアクセスに伴うオーバーヘッドを負うことなく、情報の大規模なリストにランダムに繰り返しアクセスする最適な方法(すなわち、ファンクションの開始時に必要な情報を索引付きスペースにロードし、DBMSに直接アクセスするより効率的に索引付きスペースに繰り返し(再)アクセスできる)
これらのタイプの使用例については、後の例を参照してください。
- 索引付きスペースには、少なくとも1つのキー・フィールド/列が定義されている必要があります。
- 索引付きスペースには、最大20個のキー・フィールド/列を定義できます。
- 索引付きスペースには、少なくとも1つの非キー・フィールド/列が定義されている必要があります。
- 索引付きスペースには、最大100個の非キー・フィールド/列を定義できます。
- 索引付きスペース定義内のすべてのキー・フィールド/列の合計バイト長は16Kを超えることはできません。この制限に近づきつつある場合は、アプリケーションの設計について製品ベンダーに相談してください。
- 索引付きスペース定義項目内のすべての非キー・フィールド/列の合計バイト長は16Kを超えることはできません。この制限に近づきつつある場合は、アプリケーションの設計について製品ベンダーに相談してください。
- 定義されたキーの重要性は、それが定義される順序に伴って低くなります。すなわち、定義文字列が"aaa key(), bbb key(), ccc key(), xxx data(), yyy data()"の場合、"aaa"が最も重要なキーとして定義され、"ccc"が最も重要性の低いキーとして定義されます。
- キー定義は、定義文字列内の任意の位置に配置できますが、最初に配置するのが慣例です。
- 事実上、索引付きスペースに配置できる項目数に制限はありませんが、索引付きスペースにより、割り当てられたシステム・メモリーが使用されることを常に念頭に置いておいてください。索引付きスペース内の項目数が増えるほど、システム・リソースの消費に対するオーバーヘッドは大きくなります。ここで言う「事実上制限がない」とは、実際には、事実上、システムが割り当てたり使用したりできるメモリー容量に制約されることを意味します。
- 操作FIRSTおよびNEXTでは、順次キー順アクセスがサポートされますが、これらの操作を索引付きスペースで使用できるのは、索引付きスペース内の項目が63KB/6項目(Windows 3.1の場合)または32MB/6項目(その他の環境)未満の場合のみです。これは、(キー・フィールドの実際の合計長に関係なく)索引付き項目のキーを保管するために常に6バイトを要するためです。 FIRST/NEXT順次処理がサポートされる容量を超える索引付きスペースに対してこの処理を実行しようとすると、特定のエラー・メッセージが表示され、アプリケーションが異常終了します。GET、PUT、およびINSERT操作はこの制限を受けないため、事実上、その使用に関して索引付きスペース内の項目数に関する制限はありません。
- 索引付きスペースを使用できるのは、それを作成したファンクションのみです。索引付きスペースの識別子(またはハンドル)は、簡単に他のファンクションに渡すことができますが、他のファンクションがその索引付きスペースにアクセスしようとすると、アプリケーション・エラーが発生するか予期しない結果になる可能性があります。このような操作は行わないでください。これは、索引付きスペースを作成(CREATE)するときに、作成元ファンクションに保管されたデータ・フィールドに対する固有のアクセス計画が作成されるためです。このアクセス計画は、作成元ファンクションに固有で、事実上、他のRDMLが使用することはできません。
- ファンクション内でDESTROY操作を使用してください。ただし、特定のRDMLファンクションが作成したすべての索引付きスペースは、そのファンクションの終了時に自動的に破棄されます。
- CREATE操作で複数の定義文字列を使用する場合は、末尾ブランクが無視されることを覚えておいてください。したがって、以下のようになります。
USE OV_INDEXED_SPACE (CREATE 'A KEY(), B KEY(), C ' 'KEY(), D DATA(), E DATA()')
上記のように指定した場合、文字列が連結されて定義文字列が作成されるため、実行時にシンタックス・エラーが発生します。
A KEY(), B KEY(), CKEY(), D DATA(), E DATA()
- 索引付きスペースのキー・フィールドは、純粋なバイナリー・データとして扱われます(また、ソートされます)。索引付きスペースには、Alpha、Packed、Signed、DBCSなどとしてのフィールド定義の概念がないため、どの操作でもこのことが考慮されません。
- PUT操作とINSERT操作はまったく異なる操作です。PUT操作は、索引付きスペース内に指定のキーを持つ項目が存在しているかどうかを検査します。存在する場合、その項目が集約され、適宜更新されます。存在しない場合は、新しい項目が作成されます。一方、INSERT操作は検査を実行せず、無条件に新しい項目を作成します。 すなわち、作成する項目が固有であることがわかった上で、DBMSテーブルから索引付きスペースにデータをロードする場合は、PUTよりINSERTを使用する方が大幅に効率的です。
- INSERT操作を使用して、1つの索引付きスペースに重複したキー(すなわち、キー値がまったく同じ複数の項目)を追加することができます。ただし、それによる影響や重複したキーの処理順序は未確定で、プラットフォームによって異なる可能性があります。
- 集約操作AVG()、MAX()、MIN()、SUM()、およびCOUNT()はすべて、最大有効桁数15桁の精度で実行されます。
索引付きスペースでは、配列または配列索引を使用しないでください。
例
以下のRDMLファンクションの例(L4Wの自由形式のファンクション・エディターにコピー/貼り付け可能)は、ランダム・アクセスにおける索引付きスペースの相対的効率を示すために設計されています。このファンクションを使用すると、最大100,000個の項目で構成される単純な索引付きスペースを作成し、各項目を個別に検索することができます。
FUNCTION OPTIONS(*LIGHTUSAGE *DIRECT);
********* COMMENT(Define the index space columns); DEFINE FIELD(#OV_KEY01) TYPE(*DEC) LENGTH(7) DECIMALS(0) EDIT_CODE(4); DEFINE FIELD(#OV_KEY02) TYPE(*DEC) LENGTH(7) DECIMALS(0) EDIT_CODE(4); DEFINE FIELD(#OV_KEY03) TYPE(*DEC) LENGTH(7) DECIMALS(0) EDIT_CODE(4); DEFINE FIELD(#OV_DATA01) TYPE(*DEC) LENGTH(7) DECIMALS(0); DEFINE FIELD(#OV_DATA02) TYPE(*DEC) LENGTH(7) DECIMALS(0); DEFINE FIELD(#OV_DATA03) TYPE(*DEC) LENGTH(7) DECIMALS(0); DEFINE FIELD(#OV_TOTAL) TYPE(*DEC) LENGTH(7) DECIMALS(0) EDIT_CODE(4); ********** COMMENT(Define the loop test limits); DEFINE FIELD(#OV_MKEY01) TYPE(*DEC) LENGTH(7) DECIMALS(0) LABEL('Outer Loop') EDIT_CODE(4); DEFINE FIELD(#OV_MKEY02) TYPE(*DEC) LENGTH(7) DECIMALS(0) LABEL('Middle Loop') EDIT_CODE(4); DEFINE FIELD(#OV_MKEY03) TYPE(*DEC) LENGTH(7) DECIMALS(0) LABEL('Inner Loop') EDIT_CODE(4); ********** COMMENT(Define other variables); DEFINE FIELD(#OV_RC) TYPE(*CHAR) LENGTH(2); DEFINE FIELD(#OV_HANDLE) TYPE(*CHAR) LENGTH(10); ********** COMMENT(Create the indexed space); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(CREATE 'ov_key01 key(), ov_key02 key(), ov_key03 key(),' 'ov_data01,ov_data02,ov_data03') TO_GET(#OV_RC #OV_HANDLE); ********** COMMENT(Request details of how the list is to be initialized); REQUEST FIELDS(#OV_MKEY01 #OV_MKEY02 #OV_MKEY03); BEGINCHECK; CONDCHECK FIELD(#OV_MKEY01) COND('((#OV_MKEY01 #OV_MKEY02 * #OV_MKEY03) *LE 100000)') MSGTXT('Loop values multiply to more than 100000 iterations'); ENDCHECK; ********** COMMENT(Initialize the indexed space ); CHANGE FIELD(#OV_TOTAL) TO(0); BEGIN_LOOP USING(#OV_KEY01) TO(#OV_MKEY01); CHANGE FIELD(#OV_DATA01) TO(#OV_KEY01); BEGIN_LOOP USING(#OV_KEY02) TO(#OV_MKEY02); CHANGE FIELD(#OV_DATA02) TO(#OV_KEY02); BEGIN_LOOP USING(#OV_KEY03) TO(#OV_MKEY03); CHANGE FIELD(#OV_DATA03) TO(#OV_KEY03); CHANGE FIELD(#OV_TOTAL) TO('#OV_TOTAL 1'); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(INSERT #OV_HANDLE) TO_GET(#OV_RC); END_LOOP; END_LOOP; END_LOOP; **********; MESSAGE MSGTXT('Index area initialized. Total entry's is shown. Click OK to do lookup speed test'); DISPLAY FIELDS(#OV_TOTAL); **********; CHANGE FIELD(#OV_TOTAL) TO(0); BEGIN_LOOP USING(#OV_KEY01) TO(#OV_MKEY01); BEGIN_LOOP USING(#OV_KEY02) TO(#OV_MKEY02); BEGIN_LOOP USING(#OV_KEY03) TO(#OV_MKEY03); CHANGE FIELD(#OV_TOTAL) TO('#OV_TOTAL 1'); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(GET #OV_HANDLE) TO_GET(#OV_RC); IF COND('(#OV_RC *ne OK) *or (#OV_DATA01 *ne #OV_key01) *or (#OV_data02 *ne #OV_key02) *or (#OV_data03 *ne #OV_key03)'); MESSAGE MSGTXT('Lookup was error was detected for key values shown'); REQUEST FIELDS(#OV_KEY01 #OV_KEY02 #OV_KEY03 #OV_RC); ENDIF; END_LOOP; END_LOOP; END_LOOP; MESSAGE MSGTXT('Test completed. Total number of lookup tests is shown'); DISPLAY FIELDS(#OV_TOTAL);
以下のRDMLファンクションの例は、索引付きスペースを使用して、従業員給与情報の詳細を集約します。従業員給与情報の基礎として、LANSA標準のデモンストレーション・ファイルPSLMSTを使用しています。
FUNCTION OPTIONS(*LIGHTUSAGE *DIRECT); ********** COMMENT(Departmental Summary definitions); DEFINE FIELD(#OVTDEPSAL) TYPE(*DEC) LENGTH(15) DECIMALS(2) COLHDG('Total' 'Salary' 'Expenditure') EDIT_CODE(3); DEFINE FIELD(#OVXDEPSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Maximum' 'Salary') EDIT_CODE(3); DEFINE FIELD(#OVNDEPSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Minimum' 'Salary') EDIT_CODE(3); DEFINE FIELD(#OVADEPSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Average' 'Salary') EDIT_CODE(3); DEFINE FIELD(#OVCDEPSAL) TYPE(*DEC) LENGTH(7) DECIMALS(0) COLHDG('Total' 'Employees') EDIT_CODE(3); DEFINE FIELD(#OVFDEPSAL) TYPE(*CHAR) LENGTH(256) DECIMALS(0) COLHDG('Indexed' 'Space' 'Definition'); CHANGE FIELD(#OVFDEPSAL) TO('deptment key(), ovtdepsal sum(salary), ovxdepsal max(salary), ovndepsal min(salary), ovadepsal avg(salary), ovcdepsal count()'); DEFINE FIELD(#OVHDEPSAL) TYPE(*CHAR) LENGTH(10) LABEL('Space Handle'); DEF_LIST NAME(#OVSDEPSAL) FIELDS(#DEPTMENT #OVTDEPSAL #OVCDEPSAL #OVXDEPSAL #OVNDEPSAL #OVADEPSAL); **********; DEFINE FIELD(#OV_RC) TYPE(*CHAR) LENGTH(2) LABEL('Return Code'); ********** COMMENT(Create the indexed space); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(CREATE #OVFDEPSAL) TO_GET(#OV_RC #OVHDEPSAL); ********** COMMENT((Pass over the data and update the summary details'); SELECT FIELDS(#DEPTMENT #SALARY) FROM_FILE(PSLMST); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(PUT #OVHDEPSAL) TO_GET(#OV_RC); ENDSELECT; ********** COMMENT(Now load/show a browse list with the results); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(FIRST #OVHDEPSAL) TO_GET(#OV_RC); DOWHILE COND('#OV_RC = OK'); ADD_ENTRY TO_LIST(#OVSDEPSAL); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(NEXT #OVHDEPSAL) TO_GET(#OV_RC); ENDWHILE; DISPLAY BROWSELIST(#OVSDEPSAL); ********** COMMENT(Destroy the indexed space); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(DESTROY #OVHDEPSAL) TO_GET(#OV_RC);
以下のRDMLファンクションの例は、2つ目の索引付きスペースを使用して全部門の情報を集約し、ユーザーに表示される集約リストの最後に「総」計を追加することを除き、上記の例とまったく同じです。この例は、複数の索引付きスペースを使用して、複数レベルの集約を実行する方法を示しています。
FUNCTION OPTIONS(*LIGHTUSAGE *DIRECT); ********** COMMENT(Departmental Summary definitions); DEFINE FIELD(#OVTDEPSAL) TYPE(*DEC) LENGTH(15) DECIMALS(2) COLHDG('Total' 'Salary' 'Expenditure') EDIT_CODE(3); DEFINE FIELD(#OVXDEPSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Maximum' 'Salary') EDIT_CODE(3); DEFINE FIELD(#OVNDEPSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Minimum' 'Salary') EDIT_CODE(3); DEFINE FIELD(#OVADEPSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Average' 'Salary') EDIT_CODE(3); DEFINE FIELD(#OVCDEPSAL) TYPE(*DEC) LENGTH(7) DECIMALS(0) COLHDG('Total' 'Employees') EDIT_CODE(3); DEFINE FIELD(#OVFDEPSAL) TYPE(*CHAR) LENGTH(256) DECIMALS(0) COLHDG('Indexed' 'Space' 'Definition'); CHANGE FIELD(#OVFDEPSAL) TO('deptment key(), ovtdepsal sum(salary), ovxdepsal max(salary), ovndepsal min(salary), ovadepsal avg(salary), ovcdepsal count()'); DEFINE FIELD(#OVHDEPSAL) TYPE(*CHAR) LENGTH(10) LABEL('Space Handle'); DEF_LIST NAME(#OVSDEPSAL) FIELDS(#DEPTMENT #OVTDEPSAL #OVCDEPSAL #OVXDEPSAL #OVNDEPSAL #OVADEPSAL); **********; DEFINE FIELD(#OVFGRAND) TYPE(*CHAR) LENGTH(256) DECIMALS(0) COLHDG('Indexed' 'Space' 'Definition'); CHANGE FIELD(#OVFGRAND) TO('ovkgrand key(), ovtdepsal sum(salary), ovxdepsal max(salary), ovndepsal min(salary), ovadepsal avg(salary), ovcdepsal count()'); DEFINE FIELD(#OVHGRAND) TYPE(*CHAR) LENGTH(10) LABEL('Space Handle'); DEFINE FIELD(#OVKGRAND) REFFLD(#DEPTMENT) LABEL('Invariant Key') DEFAULT('''*ALL'''); **********; DEFINE FIELD(#OV_RC) TYPE(*CHAR) LENGTH(2) LABEL('Return Code'); ********** COMMENT(Create the indexed spaces); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(CREATE #OVFDEPSAL) TO_GET(#OV_RC #OVHDEPSAL); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(CREATE #OVFGRAND) TO_GET(#OV_RC #OVHGRAND); ********** COMMENT((Pass over the data and create the summary indexes'); SELECT FIELDS(#DEPTMENT #SALARY) FROM_FILE(PSLMST); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(PUT #OVHDEPSAL) TO_GET(#OV_RC); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(PUT #OVHGRAND) TO_GET(#OV_RC); ENDSELECT; ********** COMMENT(Now load/show a browse list with the results); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(FIRST #OVHDEPSAL) TO_GET(#OV_RC); DOWHILE COND('#OV_RC = OK'); ADD_ENTRY TO_LIST(#OVSDEPSAL); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(NEXT #OVHDEPSAL) TO_GET(#OV_RC); ENDWHILE; USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(GET #OVHGRAND) TO_GET(#OV_RC); CHANGE FIELD(#DEPTMENT) TO(#OVKGRAND); ADD_ENTRY TO_LIST(#OVSDEPSAL); ********** COMMENT(Display the results); DISPLAY BROWSELIST(#OVSDEPSAL); ********** COMMENT(Destroy the indexed space); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(DESTROY #OVHDEPSAL) TO_GET(#OV_RC); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(DESTROY #OVHGRAND) TO_GET(#OV_RC);
以下のRDMLファンクションの例も、上記の2つの例によく似ていますが、さらに2つの索引付きスペースを使用して、さらに2つの集約リストを生成します。2番目の集約リストは部門/部課別、3番目のリストは給与別(すなわち、特定の給与額を得ている従業員数の分布)です。
FUNCTION OPTIONS(*LIGHTUSAGE *DIRECT); ********** COMMENT(Departmental Summary definitions); DEFINE FIELD(#OVTDEPSAL) TYPE(*DEC) LENGTH(15) DECIMALS(2) COLHDG('Total' 'Salary' 'Expenditure') EDIT_CODE(3); DEFINE FIELD(#OVXDEPSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Maximum' 'Salary') EDIT_CODE(3); DEFINE FIELD(#OVNDEPSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Minimum' 'Salary') EDIT_CODE(3); DEFINE FIELD(#OVADEPSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Average' 'Salary') EDIT_CODE(3); DEFINE FIELD(#OVCDEPSAL) TYPE(*DEC) LENGTH(7) DECIMALS(0) COLHDG('Total' 'Employees') EDIT_CODE(3); DEFINE FIELD(#OVFDEPSAL) TYPE(*CHAR) LENGTH(256) DECIMALS(0) COLHDG('Indexed' 'Space' 'Definition'); CHANGE FIELD(#OVFDEPSAL) TO('deptment key(), ovtdepsal sum(salary), ovxdepsal max(salary), ovndepsal min(salary), ovadepsal avg(salary), ovcdepsal count()'); DEFINE FIELD(#OVHDEPSAL) TYPE(*CHAR) LENGTH(10) LABEL('Space Handle'); DEF_LIST NAME(#OVSDEPSAL) FIELDS(#DEPTMENT #OVTDEPSAL #OVCDEPSAL #OVXDEPSAL #OVNDEPSAL #OVADEPSAL); ********** COMMENT(Section Summary definitions); DEFINE FIELD(#OVTSECSAL) TYPE(*DEC) LENGTH(15) DECIMALS(2) COLHDG('Total' 'Salary' 'Expenditure') EDIT_CODE(3); DEFINE FIELD(#OVXSECSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Maximum' 'Salary') EDIT_CODE(3); DEFINE FIELD(#OVNSECSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Minimum' 'Salary') EDIT_CODE(3); DEFINE FIELD(#OVASECSAL) TYPE(*DEC) LENGTH(11) DECIMALS(2) COLHDG('Average' 'Salary') EDIT_CODE(3); DEFINE FIELD(#OVCSECSAL) TYPE(*DEC) LENGTH(7) DECIMALS(0) COLHDG('Total' 'Employees') EDIT_CODE(3); DEFINE FIELD(#OVFSECSAL) TYPE(*CHAR) LENGTH(256) DECIMALS(0) COLHDG('Indexed' 'Space' 'Definition'); CHANGE FIELD(#OVFSECSAL) TO('deptment key(), section key(), ovtdepsal sum(salary), ovxdepsal max(salary), ovndepsal min(salary), ovadepsal avg(salary), ovcdepsal count()'); DEFINE FIELD(#OVHSECSAL) TYPE(*CHAR) LENGTH(10) LABEL('Space Handle'); DEF_LIST NAME(#OVSSECSAL) FIELDS(#DEPTMENT #SECTION #OVTDEPSAL #OVCDEPSAL #OVXDEPSAL #OVNDEPSAL #OVADEPSAL); ********** COMMENT(Salary Distribution Definitions); DEFINE FIELD(#OVCSALSAL) TYPE(*DEC) LENGTH(7) DECIMALS(0) COLHDG('Total' 'Employees') EDIT_CODE(3); DEFINE FIELD(#OVFSALSAL) TYPE(*CHAR) LENGTH(256) DECIMALS(0) COLHDG('Indexed' 'Space' 'Definition'); CHANGE FIELD(#OVFSALSAL) TO('salary key(), ovcsalsal count()'); DEFINE FIELD(#OVHSALSAL) TYPE(*CHAR) LENGTH(10) LABEL('Space Handle'); DEF_LIST NAME(#OVSSALSAL) FIELDS(#SALARY #OVCSALSAL); **********; DEFINE FIELD(#OV_RC) TYPE(*CHAR) LENGTH(2) LABEL('Return Code'); ********** COMMENT(Create the indexed space); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(CREATE #OVFDEPSAL) TO_GET(#OV_RC #OVHDEPSAL); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(CREATE #OVFSECSAL) TO_GET(#OV_RC #OVHSECSAL); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(CREATE #OVFSALSAL) TO_GET(#OV_RC #OVHSALSAL); ********** COMMENT((Pass over the data and create the summary indexes'); SELECT FIELDS(#DEPTMENT #SECTION #SALARY) FROM_FILE(PSLMST); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(PUT #OVHDEPSAL) TO_GET(#OV_RC); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(PUT #OVHSECSAL) TO_GET(#OV_RC); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(PUT #OVHSALSAL) TO_GET(#OV_RC); ENDSELECT; ********** COMMENT(Now load/show a browse list with the results); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(FIRST #OVHDEPSAL) TO_GET(#OV_RC); DOWHILE COND('#OV_RC = OK'); ADD_ENTRY TO_LIST(#OVSDEPSAL); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(NEXT #OVHDEPSAL) TO_GET(#OV_RC); ENDWHILE; DISPLAY BROWSELIST(#OVSDEPSAL); ********** COMMENT(Now load/show a browse list with the results); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(FIRST #OVHSECSAL) TO_GET(#OV_RC); DOWHILE COND('#OV_RC = OK'); ADD_ENTRY TO_LIST(#OVSSECSAL); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(NEXT #OVHSECSAL) TO_GET(#OV_RC); ENDWHILE; DISPLAY BROWSELIST(#OVSSECSAL); ********** COMMENT(Now load/show a browse list with the results); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(FIRST #OVHSALSAL) TO_GET(#OV_RC); DOWHILE COND('#OV_RC = OK'); ADD_ENTRY TO_LIST(#OVSSALSAL); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(NEXT #OVHSALSAL) TO_GET(#OV_RC); ENDWHILE; DISPLAY BROWSELIST(#OVSSALSAL); ********** COMMENT(Destroy the indexed spaces); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(DESTROY #OVHDEPSAL) TO_GET(#OV_RC); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(DESTROY #OVHSECSAL) TO_GET(#OV_RC); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(DESTROY #OVHSALSAL) TO_GET(#OV_RC);
以下のRDMLファンクションの例は、索引付きリストを使用して、大量の情報を処理する「バッチ」形式のジョブにおけるアプリケーションのパフォーマンスを向上させる方法を示すよう設計されています。
論理的には、このファンクションの「エンジン」ループは以下のとおりです。
BEGIN_LOOP TO(#OV_ITER); SELECT FIELDS(#EMPNO #SURNAME #GIVENAME #DEPTMENT #SECTION) FROM_FILE(PSLMST); FETCH FIELDS(#DEPTDESC) FROM_FILE(DEPTAB) WITH_KEY(#DEPTMENT); FETCH FIELDS(#SECDESC) FROM_FILE(SECTAB) WITH_KEY(#DEPTMENT #SECTION); ENDSELECT; END_LOOP;
このループでは、付属の標準デモンストレーション・テーブルPSLMSTに含まれるすべての従業員を選択します(指定の回数だけ繰り返します)。これは、「バッチ」ジョブに典型的な多数のレコードの処理をエミュレートするための処理です。
選択された各行について、DEPATBおよびSECTABテーブルから、関連付けられた部門および部署の記述を取得します。
ただし、実際には「エンジン」ループは以下のようにコーディングされています。
BEGIN_LOOP TO(#OV_ITER); SELECT FIELDS(#EMPNO #SURNAME #GIVENAME #DEPTMENT #SECTION) FROM_FILE(PSLMST); IF COND(*USEINDEX); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(GET #OV_DEPTAB) TO_GET(#OV_RC); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(GET #OV_SECTAB) TO_GET(#OV_RC); ELSE; FETCH FIELDS(#DEPTDESC) FROM_FILE(DEPTAB) WITH_KEY(#DEPTMENT); FETCH FIELDS(#SECDESC) FROM_FILE(SECTAB) WITH_KEY(#DEPTMENT #SECTION); ENDIF; ENDSELECT; END_LOOP;
これにより、DBMS (すなわち、FETCHコマンド)または索引付きスペース(すなわち、USE OV_INDEXED_SPACEコマンド)を使用してエンジン・ループを実行し、部門および部署の記述を取得することができます。これを行うことで、情報を検索する際に索引付きスペースによって得られる、完全なDBMSアクセスを超える速度という利点を確認できます。
完全なRDMLファンクション例は以下のとおりです。
部門および部署の記述の詳細を取得するために、DBMS (Dを指定)または索引付きスペース(Iを指定)を使用して、「エンジン」ループを1~20回反復することができます。ファンクションの開始時には、すべての部門および部署の記述が、それに関連付けられた索引付きスペースにロードされています。
FUNCTION OPTIONS(*LIGHTUSAGE *DIRECT); ********** COMMENT(Define and load the department indexed space); DEFINE FIELD(#OV_DEPDEF) TYPE(*CHAR) LENGTH(50) LABEL('Dept Index'); CHANGE FIELD(#OV_DEPDEF) TO('deptment key(), deptdesc'); DEFINE FIELD(#OV_DEPTAB) TYPE(*CHAR) LENGTH(10) LABEL('Index Handle'); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(CREATE #OV_DEPDEF) TO_GET(#OV_RC #OV_DEPTAB); SELECT FIELDS(#DEPTMENT #DEPTDESC) FROM_FILE(DEPTAB); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(INSERT #OV_DEPTAB) TO_GET(#OV_RC); ENDSELECT; ********** COMMENT(Define and load the section indexed space); DEFINE FIELD(#OV_SECDEF) TYPE(*CHAR) LENGTH(50) LABEL(' Section Index'); CHANGE FIELD(#OV_SECDEF) TO('deptment key(), section key(), secdesc'); DEFINE FIELD(#OV_SECTAB) TYPE(*CHAR) LENGTH(10) LABEL('Index Handle'); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(CREATE #OV_SECDEF) TO_GET(#OV_RC #OV_SECTAB); SELECT FIELDS(#DEPTMENT #SECTION #SECDESC) FROM_FILE(SECTAB); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(INSERT #OV_SECTAB) TO_GET(#OV_RC); ENDSELECT; ********** COMMENT(Define other variables); OVERRIDE FIELD(#GIVENAME) LENGTH(10); DEFINE FIELD(#OV_RC) TYPE(*CHAR) LENGTH(2) LABEL('Return Code'); DEFINE FIELD(#OV_MODE) TYPE(*CHAR) LENGTH(1) LABEL('Mode (D/I)') DEFAULT(D); DEFINE FIELD(#OV_ITER) TYPE(*DEC) LENGTH(3) DECIMALS(0) LABEL('Iterations') EDIT_CODE(3) DEFAULT(5); DEFINE FIELD(#OV_TOTAL) TYPE(*DEC) LENGTH(7) DECIMALS(0) LABEL('PSLMST Accesses') EDIT_CODE(3); DEF_COND NAME(*USEINDEX) COND('#OV_MODE = I'); DEF_LIST NAME(#OV_LIST) FIELDS(#SURNAME #GIVENAME #DEPTDESC #SECDESC) COUNTER(#OV_TOTAL); ********** COMMENT(Repeat testing until cancelled); BEGIN_LOOP; ********** COMMENT(Request and validate testing details); POP_UP FIELDS((#OV_MODE *IN) (#OV_ITER *IN)) EXIT_KEY(*NO) PROMPT_KEY(*NO); BEGINCHECK; VALUECHECK FIELD(#OV_MODE) WITH_LIST(D I) MSGTXT('Mode must be D (use DBMS) or I (use indexed space)'); RANGECHECK FIELD(#OV_ITER) RANGE((1 20)) MSGTXT(('Number of iterations must be in range 1 to 20')); ENDCHECK; ********** COMMENT(Repeat the test for the number of iterations); CLR_LIST NAMED(#OV_LIST); BEGIN_LOOP TO(#OV_ITER); SELECT FIELDS(#EMPNO #SURNAME #GIVENAME #DEPTMENT #SECTION) FROM_FILE(PSLMST); IF COND(*USEINDEX); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(GET #OV_DEPTAB) TO_GET(#OV_RC); USE BUILTIN(OV_INDEXED_SPACE) WITH_ARGS(GET #OV_SECTAB) TO_GET(#OV_RC); ELSE; FETCH FIELDS(#DEPTDESC) FROM_FILE(DEPTAB) WITH_KEY(#DEPTMENT); FETCH FIELDS(#SECDESC) FROM_FILE(SECTAB) WITH_KEY(#DEPTMENT #SECTION); ENDIF; ADD_ENTRY TO_LIST(#OV_LIST); ENDSELECT; END_LOOP; ********** COMMENT(display the results); DISPLAY FIELDS(#OV_TOTAL) BROWSELIST(#OV_LIST) EXIT_KEY(*NO) MENU_KEY(*NO) PROMPT_KEY(*NO); END_LOOP;
[ |../../index.htm#lansa/ov_indexed_space.htm]