タイガー!タイガー!じれったいぞー!(SE編)

AS400, Java, JavaEE, JSF等の開発、習慣など。日々の気づきをまとめたブログ(備忘録)

【AS400】SQLRPGLE-ワークファイルを使った照合プログラム例

久しぶりのAS400のネタです。

業務上で、テーブル1とテーブル2の集計結果を照合して「金額などが合致しているか?」を確認したいケースがたまにあります。

シンプルなテーブル構成であれば、SQL文1本で照合できるのですが、複数のテーブルを参照したり、計算式を複雑にしたりすると、スパゲティ・クエリになりがちです。

今回、ワークファイルを準備して、SQLRPGLEで照合を行うサンプルプログラムを作成してみました。

実際の集計は、SQL文のところが複雑になりますが、サンプルなので、シンプルなSQL文になっています。

  • プログラムでは、集計結果を格納する処理のみを担当します。不一致かどうかの判定は、PGMで作成されたワークファイルをSQL等で参照します(手作業)。
  • ワークファイルをクリアするために、CLから実行する必要があります。
  • 直接SQLRPGLEをCALLしてしまうと、重複キーの書き出しになったり、前回の残高に加算されたりしてうまく照合できませんので注意です。

SAMPWORK(PF)

A                                      UNIQUE
A          R RECWK00                   TEXT('照合用ワーク')
A            WKKEY         10A         COLHDG('キー')
A            WKKIN1        11S 0       COLHDG('TABLE1の集計結果')
A            WKKIN2        11S 0       COLHDG('TABLE2の集計結果')
A          K WKKEY

SAMPCOMP1(CLLE)

PGM000: PGM
/* ワーククリア */
    CLRPFM  FILE(*LIBL/SAMPWORK)
/* 照合処理 */
    CALL  SAMPCOMP2   

PGM999: ENDPGM

SAMPCOMP2(SQLRPGLE)

     H DATEDIT(*YMD/)
     H*
     F*照合用ワーク
     FSAMPWORK  UF A E           K DISK
     F*
     D MAIN            PR                  EXTPGM('SAMPCOMP2')
     D MAIN            PI
     D*
     D DATADS          DS
     D C@KEY                         10A
     D C@KIN                         11S 0
     D*
     D W@LOOP          S              1A
     D W@OPEN          S              1A
     D*
       //**************************************************
       //*  MAIN
       //**************************************************
      /FREE
          // INITIALIZE
           EXSR  #SRINZ;

          //集計処理1
           EXSR  #CALC1;

          //集計処理2
           EXSR  #CALC2;

          // FINALIZE
           EXSR  #SRFIN;

       //**************************************************
       //*  INITIALIZE
       //**************************************************
       BEGSR #SRINZ;
          // SQL OPTIONS
           EXEC SQL
               SET OPTION COMMIT = *NONE;

          //※実際には、複雑なSQL文を想定しています。
           EXEC SQL
               DECLARE CS1 CURSOR FOR
                    SELECT FIELD1, SUM(FIELD2)
                      FROM TABLE1
                     GROUP BY FIELD1;
           EXEC SQL
               DECLARE CS2 CURSOR FOR
                    SELECT FIELD1, SUM(FIELD2)
                      FROM TABLE2
                     GROUP BY FIELD1;
       ENDSR;
       //**************************************************
       //*  FINALIZE
       //**************************************************
       BEGSR #SRFIN;
           *INLR = *ON;
           RETURN;
       ENDSR;
       //**************************************************
       //* 集計処理1
       //**************************************************
       BEGSR #CALC1;
           W@OPEN = *OFF;
           EXEC SQL
               OPEN CS1;

           IF SQLCODE <> *ZERO;
               //例外処理
           ELSE;
               W@OPEN = *ON;
           ENDIF;

           W@LOOP = *OFF;
           DOU W@LOOP = *ON;
               EXEC SQL
                   FETCH CS1 INTO :DATADS;
               SELECT;
                   WHEN SQLCODE = 100;  // NO DATA
                       W@LOOP = *ON;
                   WHEN SQLCODE <> 0;   // ERROR
                       //例外処理
                   WHEN SQLCODE = *ZERO;
                       CLEAR RECWK00;
                       WKKEY  = C@KEY;
                       WKKIN1 = C@KIN;
                       WKKIN2 = *ZERO;
                       WRITE RECWK00;
               ENDSL;
           ENDDO;
           IF W@OPEN = *ON;
               EXEC SQL
                 CLOSE CS1;
           ENDIF;
       ENDSR;
       //**************************************************
       //* 集計処理2
       //**************************************************
       BEGSR #CALC2;
           W@OPEN = *OFF;
           EXEC SQL
               OPEN CS2;

           IF SQLCODE <> *ZERO;
               //例外処理
           ELSE;
               W@OPEN = *ON;
           ENDIF;

           W@LOOP = *OFF;
           DOU W@LOOP = *ON;
               EXEC SQL
                   FETCH CS2 INTO :DATADS;
               SELECT;
                   WHEN SQLCODE = 100;  // NO DATA
                       W@LOOP = *ON;
                   WHEN SQLCODE <> 0;   // ERROR
                       //例外処理
                   WHEN SQLCODE = *ZERO;
                       CHAIN C@KEY RECWK00;  
                       IF %FOUND();
                           WKKIN2 = C@KIN;
                           UPDATE RECWK00;
                       ELSE;
                           CLEAR RECWK00;
                           WKKEY  = C@KEY;
                           WKKIN1 = *ZERO;
                           WKKIN2 = C@KIN;
                           WRITE RECWK00;
                       ENDIF;
               ENDSL;
           ENDDO;
           IF W@OPEN = *ON;
               EXEC SQL
                 CLOSE CS2;
           ENDIF;
       ENDSR;

照合処理実行

CALL SAMPCOMP1

照合結果確認

SELECT * 
  FROM SAMPWORK
 WHERE WKKIN1 <> WKKIN2;