DL/I 固有のタスク

ここでは、 以下の DL/I タスクを実行する具体的な方法を説明します。 これらの手順の例はすべて、『DL/I データベース・サンプル』を使用しています。

パス呼び出しを使用した複数セグメントへのアクセス

従属セグメント・レコード・オブジェクトで EGL I/O 文を呼び出す場合、 ルートからオブジェクトまでのパス上のどのセグメントでも同時に読み取ることができます。 パス呼び出しのレコードを文に追加することによって、簡単にこれを行うことができます。 例えば、サンプルの顧客データベースから注文セグメントを検索する場合、 顧客セグメントとロケーション・セグメントを同じ呼び出しで読み取ることができます。
get myCustomer, myLocation;
この文は、次の DL/I 疑似コードを生成します。
GU STSCCST*D (STQCCNO = :myCustomer.customerNo)
   STSCLOC (STQCLNO = :myLocation.locationNo)
get...forUpdate 文で D コマンド・コードを使用すると、後続の replace 文は、取り出されるすべてのセグメントに影響します。 次の例のように、replace キーワードの SSA に明示的 N コマンド・コードを指定することによって、選択されたセグメントが置換されることを防ぎます。
get myCustomer, myLocation forUpdate;
replace myLocation with #dli{
	REPL STSCCST*N
	     STSCLOC };
D コマンド・コード付きの get forUpdate 文に続く delete 関数のデフォルトの DL/I 呼び出し EGL ビルドでは、取り出された各セグメントを削除しません。 I/O オブジェクト・セグメントのみを削除します。

単一の呼び出しによるすべてのセグメントの読み取り

単一の関数を使用して、データベース内のすべてのセグメントを読み取ることができます。SSA なしで DL/I get next 呼び出しを実行すると、DL/I はデータベース内の次のセグメントをそのタイプに関係なく戻します。 この手法を使用するには以下のステップを実行してください。
  1. データベース内の最も大きいセグメントを表すレコードのために get next 文を書き込む。 これによって、読み取るセグメントが、割り振られているメモリーを超えることがなくなります。
  2. 文のデフォルト DL/I 呼び出しを編集して、単一の SSA を削除する。
  3. データベース内の他のセグメントと一致するレコードを作成する。ステップ 1 のレコードに再定義されたレコードとして、それらを宣言する。
  4. 取り出されたセグメントのタイプを識別するため、get next 文の後の DLIVar.segmentName を確認する。
  5. 再定義されたレコード構造から、取り出されたセグメントにアクセスするか、 または再定義構造を同じタイプの別のレコードに割り当てる。
顧客データベース内にあるものすべてを印刷するコードの例をここに挙げます。 この例では、HistoryRecordPart が最も大きい DLISegment レコードです。
redefCustomer CustomerRecordPart {redefines=HistoryRecordPart};
redefLocation LocationRecordPart {redefines=HistoryRecordPart};
...


//read next segment, whatever type it is, into history record
while (myHistory not EOF)
	get next myHistory with #dli{
		GN };

	//so what type was it?
	case (DLIVar.segmentName)
		when "STSCCST"                   // it was a customer
 			myCustomer = redefCustomer;
			printCustomer();               // myCustomer is global
		when "STSCLOC"                   // it was a location
 			myLocation = redefLocation;
			printLocation();
		...
	end
end

2 次索引による検索

データベースに 2 次索引を追加する方法はいくつかあります。 最も単純な方法は、ご使用の PSB レコードにある DB_PCBRecord 変数に対する @PCB プロパティーに secondaryIndex フィールドを追加することです。 これが PSB レコード内の最初の DB_PCBRecord である場合、EGL はデフォルトでこの 2 次索引を使用します。 例えば、注文セグメントの orderReference フィールド (STFCORF) に基づいて顧客を検索したい場合は、 このデータベース・サンプルでは、以下のように customerPCB に 2 次索引を追加することができます。
// database PCB 	
customerPCB DB_PCBRecord { @PCB {
	pcbType = DB,
	pcbName = "STDCDBL",
	secondaryIndex = "STFCORF", //use DL/I name
	hierarchy = [
		@Relationship { segmentRecord = "CustomerRecordPart"},
	 	@Relationship {
			segmentRecord = "LocationRecord",
			parentRecord = "CustomerRecordPart" }, 			
		@Relationship {
 			segmentRecord = "OrderRecord",
			parentRecord = "LocationRecordPart" },
		...
以下の例のように、顧客を見つけるために get 操作を実行します。
get myCustomer;
EGL はデフォルトで以下のコードを生成します。
	GU STSCCST (STFCORF = :myOrder.orderReference)
顧客へのアクセスを、orderReference 別と customerNo 別とで選択できるようにしたい場合は、2 次索引のために 2 番目の PCB を作成します。 以下の例では、2 次 PCB は orderReferencePCB という名前です。
 // データベース PCB--顧客番号別のアクセス
customerPCB DB_PCBRecord { @PCB {
	pcbType = DB,
	pcbName = "STDCDBL",
	hierarchy = [
		@Relationship { segmentRecord = "CustomerRecordPart"},
	 	@Relationship {
			segmentRecord = "LocationRecord",
			parentRecord = "CustomerRecordPart" }, 			
		@Relationship {
 			segmentRecord = "OrderRecord",
			parentRecord = "LocationRecordPart" },
		...

// database PCB--access by order reference	
orderReferencePCB DB_PCBRecord { @PCB {
	pcbType = DB,
	pcbName = "STDXDBL",
	secondaryIndex = "STFCORF", //use DL/I name
	hierarchy = [
		@Relationship { segmentRecord = "CustomerRecordPart"},
	 	@Relationship {
			segmentRecord = "LocationRecord",
			parentRecord = "CustomerRecordPart" }, 			
		@Relationship {
 			segmentRecord = "OrderRecord",
			parentRecord = "LocationRecordPart" },
		...
pcbName は実際の DL/I PCB と一致する必要があります。ここで、EGL のデフォルトの振る舞いは、customerNo フィールドを使用してもう一度、顧客レコードにアクセスすることになります。 Alt キーを使用してアクセスするには、ご使用の EGL I/O 文で、以下の例のように usingPCB キーワードで orderReferencePCB を指定する必要があります。
get myCustomer usingPCB orderReferencePCB;
また、 ご使用のプログラムから見られるデータベース全体の構造を変更したい場合など、 さらに複雑なケースもあります。 (繰り返しますが、EGL プログラムの PCB 構造は既存の DL/I PCB と一致している必要があることに留意してください。) 顧客データベースを、ご使用のプログラムにとっては、注文セグメントに対するキーとして固有の参照番号を持つ 注文データベースのように見せたいとします。 以下の構造の PCB を持つことができます。
// 顧客データベースの注文ビュー
ordersPCB DB_PCBRecord { @PCB {
	pcbType = DB,
	pcbName = "STDCDBL",
	secondaryIndex = "STFCORF", //use DL/I name
	hierarchy = [
		@Relationship { segmentRecord = "OrderRecordPart" },
		@Relationship {
			segmentRecord = "LocationRecordPart",
			parentRecord = "OrderRecordPart" },
		@Relationship {
			segmentRecord = "CustomerRecordPart",
			parentRecord = "LocationRecordPart" },
		@Relationship {
			segmentRecord = "CreditRecordPart",
			parentRecord = "CustomerRecordPart" },
		@Relationship {
			segmentRecord = "HistoryRecordPart",
			parentRecord = "CustomerRecordPart" },
		@Relationship {
			segmentRecord = "ItemRecordPart",
			parentRecord = "OrderRecordPart" }]}};
end
注文参照番号が各顧客および注文ごとに固有であり、ordersPCB が現在のデフォルト PCB であるとすると、ロケーションおよび顧客の修飾を除去する変更されたパス呼び出しを行うことで、 注文をした顧客を見つけることができます。
get myOrder, myCustomer with #dli{
	GU STPCORD (STQCODN = :myOrder.orderReference)
	   STSCLOC
	   STSCCST };

別の非キー・フィールドによる検索

呼び出しの検索引数 (SSA) を変更することによって、DL/I 呼び出しの検索引数としてセグメントのどのフィールドも使用することができます。 例えば、顧客データベースを読み通し、クレジット・バランスが特定の金額より多い顧客ごとの 顧客セグメントとクレジット・セグメントを検索したい場合、 以下のように DL/I 呼び出し検索引数を定義します。
  1. クレジット・セグメント (STSCSTA) の creditBalance フィールド (STFCSBL) で検索する。 これを行うには、検索したい特定の金額を含むタイプ MONEY の変数 (例えば、「targetBalance」) を定義します。
  2. myCrStatus レコードの get 文を書き込む。
  3. その行に #dli ディレクティブを追加し、デフォルト・コードを変更する。 creditBalance フィールドの金額が targetBalance より大きいセグメントを検索する修飾 SSA を追加します。
  4. パス・コマンド・コード (*D) を組み込み、クレジット・セグメントに対応する顧客セグメント (STSCCST) を検索する。
以下のサンプル・コードは、このプロセスを表しています。
	targetBalance MONEY;
	targetBalance = 10,000.00;

	get myCrStatus with #dli{
		GU STSCCST*D STSCSTA (STFCSBL >= :targetBalance) };
また、別のレコードの情報に基づいて検索したい場合もあります。 例えば、基本レコードであって、データベースの一部ではないタイプ (InvoiceRecordPart) である送り状レコード (myInvoice) で、顧客番号 (invCustNo) に基づいて顧客を検索したい場合です。 そのコードは、以下のようなものになります。
get myCustomer with #dli{
	GU STSCCST (STQCCNO = :myInvoice.invCustNo) };

関連概念:
DL/I データベース・サポート
IMS ランタイム・ サポート

関連リファレンス:
DLIVar
DL/I データベース・サンプル

フィードバック
(C) Copyright IBM Corporation 2000, 2005. All Rights Reserved.