このステップでは、論理ビュー PSLMST1 (部門ごとの人事) を使用して社員リストを取得するための選択 (SELECT) を行い、その後、ファイル PSLSKL (人事スキル) で社員のスキル・リストを取得するための選択 (SELECT) を実行する RDMLX を作成します。サーバー側の設定 (SET) を行う RDMLX は、この内部ロジック中でインラインで行われます。これは、内部ロジックとSETコマンドが順に分けられていた以前の演習とは異なります。

 この演習では、内部ロジックの終了後、各コマンドを順番に実行しません。代わりに、アウトバウンドBINDとルート・フラグメントSETが、インバウンドBINDコマンドとGETコマンドの直後に来ます(データベース・アクセスの前)。さらに2つのSETコマンドが、外部のSELECTステートメントに入ります。最後に、WRITEコマンドとSENDコマンドが最後のENDSELECTの後に続きます。

 iiiFN06 ファンクションの全体の構造は次のようになります。

1.  JSMX_OPEN
2.    SERVICE_LOAD (HTTPInboundXMLBindService)
3.     BIND (インバウンド)
4.     GET (部門コードのフラグメント)
5.     BIND (アウトバウンド)
6.     SET (社員リストのフラグメント)
7.     PSLMST1 に対する SELECT

        a.  PSLSKL に対する SELECT
        b.  SKLTAB から FETCH
        c.  ENDSELECT
        d.  SET (社員フラグメント)
        e.  SET (社員スキルリスト)

8.     ENDSELECT
9.     WRITE
10.   SEND
11.  JSMX_CLOSE


  1. ファンクション iiiFN06 で、以下のコードを探して削除します。
     * サービスをバインドして HTTP 応答コンテンツを作成
    CHANGE FIELD(#JSMXCMD) TO('BIND SERVICE( <<<outbound.class>>> ) TYPE(*OUTBOUND)')
    USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMXSTS #JSMXMSG)
    EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS #JSMXMSG)

  2. プロジェクト iii 研修 がスタジオで開かれている状態で、サーバー XML 社員要求/Samples/RDMLX フォルダの SAMPLE_RDMLX_OUTBOUND_HTTP.txt ファイルをテキスト・エディターで開きます。以下に示されているコードを探します。

    赤で示されているコードをコピーしてファンクションに貼り付け、削除したコード・ブロックと置き換えます。

  3. EMPWORK という作業リスト定義を、フィールド SKILDESC を含むファンクションの上部に追加します。これは、返される各社員のスキル・リストです。コードは以下のようになります。 
    DEF_LIST NAME(#EMPWORK) FIELDS(#SKILDESC) TYPE(*WORKING) ENTRYS(*MAX)
  4. アウトバウンドの BIND と SET のロジックを追加したら、以下の操作を行う RDMLX コードを作成します。
    1. キー・フィールド DEPTMENT を使用して、論理ファイル PSLMST1 から社員番号と名前を選択 (SELECT) します。
    2. この SELECT 処理内で、名と姓からフルネームのフィールドを設定します。
    3. さらにこの SELECT ループ内で、CLR_LIST EMPWOR を行った後、KPSLSKL に対して、SELECT を実行し、社員番号を使って各社員のスキル・コードのリストを取得します。
    4. 内部の (ネストされた) SELECT 内で、各スキル・コードについて SKLTAB からスキルの説明を取得 (FETCH) します。
    5. 社員のスキル作業リスト EMPWORK にエントリーを追加 (ADD) します。
    6. 両方の SELECT を終了 (END) します。
      RDMLX コードは以下のようになります。

      SELECT FIELDS(#EMPNO #SURNAME #GIVENAME) FROM_FILE(PSLMST1) WITH_KEY(#DEPTMENT)
      #FULLNAME := #GIVENAME  ' '  #SURNAME
      CLR_LIST NAMED(#EMPWORK)
      SELECT FIELDS(#SKILCODE) FROM_FILE(PSLSKL) WITH_KEY(#EMPNO)
      FETCH FIELDS(#SKILDESC) FROM_FILE(SKLTAB) WITH_KEY(#SKILCODE)
      ADD_ENTRY TO_LIST(#EMPWORK)
      ENDSELECT
       * 社員フラグメント設定
       * 社員スキルリスト設定
      ENDSELECT

      注意:次のステップで分かりやすいように、このコードにはコメントが付けられています。

  5. 前回と同様、SAMPLE_RDMLX_OUTBOUND_HTTP.txt ファイルのこの演習用に生成されたコードを使って、ファンクションを完成させます。以下に示されているコードを探します。

  6. 上に示されたコピーしてコードに貼り付け、ステップ 4f で以下のコメント部分を置き換えます。
    * 社員フラグメント設定
    * 社員スキルリスト設定

  7. リスト #EMPWORK を参照するように、TO_GET() キーワードの作業リスト名を変更します。  コードは以下のようになります。
    * リストの設定 - EMPLOYEESKILL
    CHANGE FIELD(#JSMXCMD) TO('SET LIST(EMPLOYEESKILL)')
    USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMXSTS #JSMXMSG #EMPWORK)
  8. ファンクションの RDMLX コードと、その後に続く最後の ENDSELECT を確認します。最初にコピーした生成済みコードに、必要なWRITE、SEND、CLOSEロジックが含まれています。

  9. CHECK サブルーチンで、エラーが発生した場合はプログラムが終了するように .ENDIF ステートメントに ABORT コマンドを追加します。

  10. ファンクション iiiFN06 を保存してコンパイルします。IBM i の JSM サーバーを使用している場合は、ファンクションを IBM iにチェックインしてコンパイルします。
    完了した RDMLX コードは以下のようになります。

    FUNCTION OPTIONS(*DIRECT)
    *以下のフィールドは xml バインド・マップで使用
    *#DEPTMENT
    *以下のフラグメントは xml バインド・マップで使用
    GROUP_BY NAME(#DEPTREQ) FIELDS(#DEPTMENT)
    *
    DEF_LIST NAME(#empwork) FIELDS(#skildesc) TYPE(*WORKING) ENTRYS(*MAX)
    *サービスを開く
    USE BUILTIN(JSMX_OPEN) TO_GET(#JSMXSTS #JSMXMSG #JSMXHDLE1)
    EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS #JSMXMSG)
    *サービスのロード
    CHANGE FIELD(#JSMXCMD) TO('SERVICE_LOAD SERVICE(HTTPInboundXMLBindService) SERVICE_CONTENT(*HTTP) TRACE(*YES)')
    USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMXSTS #JSMXMSG)
    EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS #JSMXMSG)
    *サービスをバインドして、HTTP 要求コンテンツを読み込む
    CHANGE FIELD(#JSMXCMD) TO('BIND SERVICE(IIIPRO06_REQUEST) TYPE(*INBOUND) BINDTRACE(*YES)')
    USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMXSTS #JSMXMSG)
    EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS #JSMXMSG)
    *フラグメント取得 - DEPARTMENTREQUEST
    CHANGE FIELD(#JSMXCMD) TO('GET FRAGMENT(DEPARTMENTREQUEST) SERVICE_EXCHANGE(*FIELD)')
    USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMXSTS #JSMXMSG)
    EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS #JSMXMSG)
    *サービスをバインドして、HTTP 要求コンテンツを作成
    CHANGE FIELD(#JSMXCMD) TO('BIND SERVICE(IIIPRO06_RESPONSE) TYPE(*OUTBOUND)')
    USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMXSTS #JSMXMSG)
    EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS #JSMXMSG)
    *フラグメント設定 - EMPLOYEELIST
    CHANGE FIELD(#JSMXCMD) TO('SET FRAGMENT(EMPLOYEELIST) SERVICE_EXCHANGE(*FIELD)')
    USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMXSTS #JSMXMSG)
    EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS #JSMXMSG)
    SELECT FIELDS(#EMPNO #SURNAME #GIVENAME) FROM_FILE(PSLMST1) WITH_KEY(#DEPTMENT)
    #FULLNAME := #GIVENAME + ' ' + #SURNAME
    CLR_LIST NAMED(#EMPWORK)
    SELECT FIELDS(#SKILCODE) FROM_FILE(PSLSKL) WITH_KEY(#EMPNO)
    FETCH FIELDS(#SKILDESC) FROM_FILE(SKLTAB) WITH_KEY(#SKILCODE)
    ADD_ENTRY TO_LIST(#EMPWORK)
    ENDSELECT
    *フラグメント設定 - EMPLOYEE
    CHANGE FIELD(#JSMXCMD) TO('SET FRAGMENT(EMPLOYEE) SERVICE_EXCHANGE(*FIELD)')
    USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMXSTS #JSMXMSG)
    EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS #JSMXMSG)
    *リスト設定 - EMPLOYEESKILL
    CHANGE FIELD(#JSMXCMD) TO('SET LIST(EMPLOYEESKILL)')
    USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMXSTS #JSMXMSG #EMPWORK)
    EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS #JSMXMSG)
    ENDSELECT
    *コンテンツの書き込み
    CHANGE FIELD(#JSMXCMD) TO('WRITE INDENT(*YES) BINDTRACE(*YES)')
    USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMXSTS #JSMXMSG)
    EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS #JSMXMSG)
    *HTTP 応答コンテンツの送信
    CHANGE FIELD(#JSMXCMD) TO('SEND')
    USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMXSTS #JSMXMSG)
    EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS #JSMXMSG)
    *サービスを閉じる
    USE BUILTIN(JSMX_CLOSE) WITH_ARGS(#JSMXHDLE1) TO_GET(#JSMXSTS #JSMXMSG)
    EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS #JSMXMSG)
    *Check ルーチン
    SUBROUTINE NAME(CHECK) PARMS((#JSMXSTS *RECEIVED) (#JSMXMSG *RECEIVED))
    IF COND('#JSMXSTS *NE OK')
    USE BUILTIN(JSMX_CLOSE) WITH_ARGS(#JSMXHDLE1) TO_GET(#JSMXSTS #JSMXMSG)
    ENDIF
    ENDROUTINE


ファンクション iiiFN06 のコーディングのおさらい

事前に作成されていたコードを使ってサーバー・ファンクションを作成して、XML 要求に対するインバウンド・ロジックをすべて処理し、ファイル処理に関する独自のコーディングを追加して要求されたデータを生成するロジックを作成して、応答 XML ドキュメントを作成するアウトバウンド・ロジックを作成しました。