久しぶりの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;