get

EGL get 文は、単一ファイル・レコードまたはデータベース行を検索し、 コード内で後で格納されたデータを置換または削除することができるオプションを提供します。また、 この文を使用してデータベース行の集合を検索し、それぞれの後続の行を動的配列の次の SQL レコードに入れることができます。

get 文は、get by key value として識別されることがあり、get ワードで始まるその他の文とは区別されます。


get 文の構文図
record name
読み取る入出力オブジェクトの名前。DLISegment レコード、索引付きレコード、MQ レコード、相対レコード、シリアル・レコード、SQL レコードなどを指定します。SQL 処理の場合、EGL INTO 文節 (後述) を指定しない場合、 レコード名が必要です。
forUpdate
ファイルまたはデータベースから検索されたデータを置換または削除するために以降の EGL 文を使用することができるオプション。

リソースがリカバリー可能である場合 (VSAM ファイル、DL/I データベースまたは SQL データベースのケースのように)、レコードは forUpdate オプションによってロックされるため、コミットが発生するまで他のプログラムから変更することはできません。 コミット処理の詳細については『作業論理単位』を参照してください。

usingPCB pcbName
PSB レコードで定義されているように、デフォルトの PCB 名の代わりに使用される、PCB 名を指定できるようにするオプション。
with #dli{ dliStatement }
#dli ディレクティブ』で説明されているように、明示的 DL/I GU または GHU 文を許可するオプション。 #dli と左中括弧の間にスペースを入れないでください。
resultSetID
EGL replacedelete、 および execute 文、 および EGL close 文に使用するための結果セット ID。 詳細については、『resultSetID』を参照してください。
singleRow
get 文の検索条件が 1 行にのみ適用され、 行を更新または削除しない場合のようにさらに効率的な SQL を生成するためのオプション。検索条件が複数行に適用されるときにこのオプションを指定すると、ランタイム入出力エラーが発生します。追加情報については、『SQL レコード』を参照してください。
#sql{ sqlStatement }
SQL サポート』で説明されているように、明示的な SQL SELECT 文を許可するオプション。#sql と左中括弧の間にスペースを入れないでください。
into ... item
リレーショナル・データベースから値を受け取る EGL ホスト変数を識別する EGL INTO 文節。この文節は、 以下のいずれかの場合に SQL を処理するときに必要です。
  • SQL レコードが指定されていない。
  • SQL レコードと明示的な SQL SELECT 文の両方が指定されているが、SQL SELECT 文節の列がレコード項目と関連付けられていない。 (関連は、『SQL 項目プロパティー』に記載されているように SQL レコード・パーツに指定されます。)

このような文節 (#sql{ } ブロックの外側にある) では、ホスト変数名の前にセミコロンを含めないでください。

preparedStatementID
実行時に SQL SELECT 文を作成する EGL prepare 文の ID。get 文 SQL SELECT 文を動的に実行します。詳細については、『prepare』を参照してください。
using ... item
実行時に準備済み SQL SELECT 文に使用可能な EGL ホスト変数を識別する USING 文節。このような文節 (sql-and-end ブロックの外側にある) では、ホスト変数名の前にセミコロンを含めないでください。
usingKeys ... item
暗黙の SQL 文の WHERE 文節のキー値コンポーネントを作成するために使用する キー項目のリストを識別します。暗黙の SQL 文は、 明示的な SQL 文を指定しない場合に実行時に使用されます。

usingKeys 文節を指定しない場合、 暗黙の文のキー値コンポーネントは get 文で参照される SQL レコード・パーツに基づくか、get 文で参照される 動的配列の基礎になります。

動的配列の場合、usingKeys 文節の項目 (または SQL レコードのホスト変数) は、 動的配列の基礎である SQL レコードに存在しない必要があります。

明示的な SQL 文を指定する場合、usingKeys 情報は無視されます。

SQL dynamic array
SQL レコードによって構成される動的配列の名前。
以下の例はファイル・レコードを読み取り、置換する方法を示します。
  emp.empnum = 1;         // sets the key in record emp

  try
    get emp forUpdate;
  onException
    myErrorHandler(8);  // プログラムを終了する
  end

  emp.empname = emp.empname + " Smith";

  try
    replace emp;
  onException
    myErrorHandler(12);
  end
次の get 文は、 データベース行を検索するときに SQL レコード emp を使用し、以降の更新または削除を実行することはできません。
  try
    get emp singleRow into empname with
      #sql{
        select empname
        from Employee
        where empnum = :empnum
      };
  onException
    myErrorHandler(8);
  end
次の例は、同じ SQL レコードを使用して SQL 行を置換します。
  try
    get emp forUpdate into empname with
      #sql{
        select empname
        from Employee
        where empnum = :empnum
      };

  onException
    myErrorHandler(8);  // プログラムを終了する
  end

  emp.empname = emp.empname + " Smith";

  try
    replace emp;
  onException
    myErrorHandler(12);
  end

MVS/ESA™ 用 CICS® 環境では、コミットまたはロールバックが発行されたとき、またはセグメント・モードで実行中に converse 文の後にコミットまたはロールバックが続くときに、get 位置が失われます。

get 文の詳細は、レコード・タイプによって異なります。 DL/I 処理の詳細については、『DLISegment レコード』を参照してください。 SQL 処理の詳細については、『SQL レコード』を参照してください。

DLISegment レコード

get 文は DL/I GU 文を生成します。get...forUpdate 文は DL/I GHU 文を生成します。get 文の基本の使用目的は次のとおりです。
  • あるセグメントのデータで何かを行うため、例えばレポートや請求書の印刷をするためにそのセグメントを読み込む。
  • EGL キーワード、delete または replace を使ってセグメントを除去したり更新したりするために、(forUpdate オプションと組み合わせて) セグメントを保持する。 ほとんどの場合、レコードを 追加 する前に get 文を実行する必要はありません。
DL/I による get...forUpdate 文の使用例については、『delete』を参照してください。
DL/I では get 文に対するパス呼び出しの使用もサポートしています。 これは、読み取っている最も低いレベルのセグメントとルート間にあるすべてのセグメントについて、親セグメントを読み取れることを意味しています。 次の例で、DL/I は 1 つの呼び出しによって、それぞれの DLISegment レコードの 3 つのセグメントすべて (顧客、ロケーション、およびオーダー) を読み取ります。
get myCustomer, myLocation, myOrder;
EGL はこの文から次の擬似 DL/I コードを生成します。
GU STSCCST*D (STQCCNO = :myCust.customerNo) 
   STSCLOC (STQCLNO = :myLocation.locationNo) 
   STPCORD

索引付きレコード

索引付きレコードに対して get 文を発行するときは、 レコードのキー値によって、ファイルから検索されるレコードが決定されます。

索引付き (または相対) レコードを置換または削除する場合は、レコードに対して get 文を発行し、同じファイルに対する入出力操作を間に挟まずに、 ファイル変更文 (replace または delete) を 発行する必要があります。get 文を発行した後、同じファイルに対して次に入出力操作を行うと、以下のようになります。
  • 次の入出力操作が同じ EGL レコードに対する replace 文である場合は、レコードがファイル内で変更される
  • 次の入出力操作が同じ EGL レコードに対する delete 文である場合は、ファイル内のレコードが削除用にマークされる
  • 次の入出力操作が、同じファイル中のレコードに対する forUpdate オプションを含む get 文である場合は、以降の replace または delete 文は新しく読み取られるファイル・レコードに対して 有効となる
  • 次の入出力操作が、同じ EGL レコードに対する forUpdate オプションを含まない get 文、または同じファイルに対する close 文である場合は、ファイル・レコードは変更なしに解放される

ファイルが VSAM ファイルである場合、EGL get 文 (forUpdate オプション指定) の間、他のプログラムからこのレコードを変更することはできません。z/OS® バッチ・プログラムでは、コミットが発生するまでロックが続き、コミットがジョブ・ステップの終わりまで発生しないこともあります。iSeries™ COBOL プログラムでは、コミットが発生するまでロックが続き、『実行単位』で説明したとおり、コミットが実行単位の終わりまで発生しないこともあります。

MQ レコード

get キーワードによってメッセージ・キュー内の MQ レコードを読み取る場合、EGL は自動的に次のことを実行します。

  1. まだ接続していない場合、キュー・マネージャーに接続する
  2. キューがまだ開いていない場合、キューを開く
  3. キューから次のメッセージを取得し、そのメッセージ内容をメッセージ・キューのレコード構造に移動する。 IMS™ のメッセージ・ヘッダー (長さ、ZZ 制御情報フィールド、およびトランザクション・コード) は、キューから読み取られた各レコードから自動的に除去されます。

IMS では、単一セグメントのメッセージ・キューに割り当てられたシリアル・レコードに対する get 文の結果、I/O PCB への get unique (GU) 呼び出しが行われます。この GU 呼び出しにより、自動コミット点が決まります。複数セグメントのメッセージ・キューに割り当てられたシリアル・レコードに関する最初の get 文の結果、I/O PCB への GU 呼び出しが行われます。後続の get 文により、NRF (このセグメント・レベルではレコードが見付かりませんでした) 条件に達するまで GN 呼び出しが行われます。 NRF に到達してからの最初の get 文により、別の GU 呼び出しが行われ、このプロセスは EOF に達するまで継続します。 各 GU 呼び出しにより、自動コミット点が決まります。

相対レコード

相対レコードに対して get を発行するときは、レコードに関連付けられたキー項目によって、ファイルから検索されるレコードが決定されます。キー項目は、そのレコードを使用するすべての関数で使用できなければなりません。以下のいずれかをキー項目とすることができます。
  • 同じレコード内の項目
  • プログラムに対してグローバルであるか、または get 文を実行している 関数に対してローカルであるレコード内の項目
  • プログラムに対してグローバルであるか、または get 文を実行している 関数に対してローカルであるデータ項目
索引付き (または相対) レコードを置換または削除する場合は、レコードに対して get 文を発行し、同じファイルに対する入出力操作を間に挟まずに、 ファイル変更文 (replace または delete) を 発行する必要があります。get 文を発行した後、同じファイルに対して次に入出力操作を行うと、以下のようになります。
  • 次の入出力操作が同じ EGL レコードに対する replace 文である場合は、レコードがファイル内で変更される
  • 次の入出力操作が同じ EGL レコードに対する delete 文である場合は、ファイル内のレコードが削除用にマークされる
  • 次の入出力操作が、同じファイルに対する forUpdate オプションを含む get である場合は、以降の replace または delete は新しく読み取られるファイル・レコードに対して 有効となる
  • 次の入出力操作が同じ EGL レコードに対する get であり、forUpdate オプションを含まない場合、 または同じファイルに対する close である場合は、ファイル・レコードが変更されずに解放される

シリアル・レコード

get 文は、入力シーケンスの最後に読み取られたレコードに続くレコードを読み取ります。 最初のレコードはファイルの最初のスキャンで読み取られます。 前回の入出力操作においてアクセスされたレコードがファイルの最後のレコードであった場合は、get 文は EOF を戻します。

プログラムが追加から読み取りに、または読み取りから追加に変更されるときは、常にファイルがクローズされてから再オープンされます。 ファイルがクローズされると、ファイル位置が失われます。このため、add 文の後の最初の get 文は、ファイルの最初のレコードを読み取ります。 同様に、get 文または get next 文 に続く add 文は、ファイルの先頭にレコードを追加します。

zSeries® のバッチ環境では、GSAM ファイルに対して割り当てられたシリアル・レコードに対する get 文の結果、GSAM データベースへの get next (GN) 呼び出しが行われます。 GSAM と関連付けられたファイルに可変長のシリアル・レコードがあり、そのレコード長が物理ファイルよりも長い場合、DL/I は空白の状況コードを戻します。 データは切り捨てられますが、状況は検出できないのでメッセージは発行されません。

SQL レコード

EGL get 文により、生成されるコード内で SQL SELECT 文が作成されます。singleRow オプションを指定する場合、SQL SELECT 文は、 スタンドアロン文です。または、SQL SELECT 文は、 『SQL サポート』で説明するようにカーソル内の文節です。

エラー条件

以下の条件は、get 文を使用してリレーショナル・データベースからデータを読み取るときには有効ではありません。
  • SELECT 以外の型の SQL 文を指定する
  • SQL SELECT 文に直接 SQL INTO 文節を指定する
  • SQL INTO 文節以外に、SQL SELECT 文の全部ではなく一部の文節を指定する場合
  • 存在しないか、関連するホスト変数との互換性がない列に関連付けられている SQL SELECT 文を指定する (または受け入れる) 場合
以下のエラー条件は、forUpdate オプションを使用する場合に発生することがあります。
  • 複数のテーブルを更新する意図を示す SQL 文を指定する (または受け入れる) 場合
  • 入出力オブジェクトとして SQL レコードを使用し、 すべてのレコード項目が読み取り専用である場合
また、以下の状態でエラーが生じることがあります。
  • forUpdate オプションを指定して EGL get 文をカスタマイズしたが、特定の SQL テーブルの列が update で使用可能であることを示していない場合
  • get 文に関連付けられた replace 文が列を変更しようとした。
この不一致は、以下のいずれかの方法で解決できます。
  • EGL get 文をカスタマイズする際に、使用する列名を SQL SELECT 文の FOR UPDATE OF 文節に組み込む
  • EGL replace 文をカスタマイズする際に、SQL UPDATE 文の SET™ 文節内にある列への参照を除去する
  • getreplace 文の両方について、デフォルトを受け入れる

暗黙の SQL SELECT 文

get 文に SQL レコードを入出力オブジェクトとして指定するが、 明示的な SQL 文を指定しない場合、暗黙の SQL SELECT は以下の特性を持ちます。

  • 各 SQL テーブルのキー列の値が SQL レコードの対応するキー項目の値と等しい限り、選択されるテーブルの行は、レコード固有の defaultSelectCondition と呼ばれるプロパティーによって決まる。レコード・キーとデフォルトの選択条件のどちらも指定しない場合は、すべてのテーブル行が選択されます。何らかの理由で複数のテーブル行が選択された場合は、最初に検索された行がレコードに入れられます。
  • レコード定義におけるレコード項目と SQL テーブル列の関連付けの結果として、特定の項目が、関連する SQL テーブル列の内容を受け取る。
  • forUpdate オプションを指定した場合、SQL SELECT FOR UPDATE 文には、読み取り専用のレコード項目が含まれない
  • 特定のレコード用の SQL SELECT 文は、以下の文のようになります。 ただし、FOR UPDATE OF 文節は、get 文に forUpdate オプションが 含まれる場合にのみ使用します。
      SELECT column01, 
             column02, ... 
             columnNN
      FROM   tableName 
      WHERE  keyColumn01 = :keyItem01
      FOR UPDATE OF
             column01, 
             column02, ... 
             columnNN
    スタンドアロンの SQL SELECT またはカーソルに関連する FETCH 文の SQL INTO 文節は、 以下の文節のようになります。
      INTO   :recordItem01,
             :recordItem02, ...
             :recordItemNN

    EGL では、INTO 文節を指定しないと、SQL レコードが 明示的な SQL SELECT 文を伴わない場合、SQL INTO 文節が派生されます。 派生した INTO 文節の項目は、SQL 文の SELECT 文節にリストされた列と関連づけられた項目です。(項目と列の関連付けは、 『SQL 項目プロパティー』に記載されているように SQL レコード・パーツに指定されます。) 列が項目と関連付けられていない場合は、EGL INTO 文節が必要です。

get 文に SQL レコードの動的配列を入出力オブジェクトとして指定するが、 明示的な SQL 文を指定しない場合は、暗黙の SQL SELECT は単一 SQL レコードに関して説明した暗黙の SQL SELECT と類似していますが、 以下の相違があります。
  • 照会のキー値コンポーネントは、より大か等しい条件に基づく関係の集合です。
      keyColumn01 >= :keyItem01 &
      keyColumn02 >= :keyItem02 &
             .
             .
             .
      keyColumnN  >= :keyItemN
  • usingKeys 文節中の項目 (または SQL レコード中のホスト変数) は、動的配列の基礎である SQL レコードに存在してはなりません
フィードバック
(C) Copyright IBM Corporation 2000, 2005. All Rights Reserved.