組込みSQLというのはRPGプログラムなどにSQL文を組み込んだRPGのことであり
過去にいくつか利用方法を紹介してきた。
このサイトではこのようにすると良くなる、つまりパフォーマンスが良くなるとか
保守が容易になるとか高品質になるとか良くなる例を紹介してきた。
これは当たり前のことであるがここで紹介するのは悪くなる例である。
製品をお客さまに提供していると当然いろいろなお客さまのソースを
見る機会が増える。
あるユーザーのソースを見る機会があったのだが
そのお客さまでは協力会社のSEが代行して開発していたのだが
組込みSQLを使ったRPGでCGIを開発していた。
そのような例を見るのは筆者も初めてでなるほど高度な知識を
持っている開発者であると感心していた。
ところが他のRPGソースを見るとどれもが組込みSQLのRPGである。
初めは契約データを検索照会するためにSQLを使っているものと
思っていたのだが、見てみるとどれも組込みSQLである。
よく見るとデータ・ベースを使うすべてのプログラムが組込みSQLによる
RPGである。
それで筆者は気が付いた。
この開発者はレコード・レベルのアクセスを知らないのではなかいと
考えた。
別の有名な経理システムのパッケージを開発販売している会社でも
パフォーマンスが悪いと客からクレームが多いので相談に乗って欲しい
ということであったが肝心のRPGソースを女性の担当が嫌がって
ほんのチラッとししか見せてくれない。
しかし何度がほんのわずか見てすぐにわかったことは
この経理パッケージも他のプラットフォームからIBM iに
PORTINGしてきたものであって組込みSQLを多用しているというか
組込みSQLしか使用していないのである。
IBM iはSQLが使えるとはいうものの本来の使用はレコード・レベルの
アクセスであるが他のプラットフォームからやってきた開発者は
IBM iのレコード・レベルのアクセス(CHAINヤREAD命令など)が
理解できないのだ。
SQLしか知らない開発者は何でもSQLの世界で済まそうとしてしまう。
そこで無理やり組込みSQLによるRPGの開発を行ってしまう。
これはIBM i本来の機能を生かしていないので
パフォーマンスは著しく低下してしまう。
次は全く同じ担当者マスターを印刷出力する例である。
RPGサイクルを使った本来のRPG : TANPRINT は実行すると瞬間に終わってしまうが
組込みSQLを使った: SQLPRINT ではゆっくりと時間がかかってしまう。
組込みSQLはあくまでSQLを必要とするときにのみ使用すべきであって
不要なときや何でもかんでもSQL組込みにしてしまうとそのプログラムの
実行だけでなく社内全体のパフォーマンスを定価させてしまう。
SQLはデータ・ベースをすべてCPUメモリの中に読み込んでしまうので
CPU消費量も大きくなって社内の他のユーザーの実行も一斉に遅くなってしまうことを
覚悟しておいたほうが良い。
当然、プロフェッショナルであればSQLの使用は最小限に留めるべきである。
[ SQLPRINT : 組込みSQLによる RPGのサンプル・ソース ]
ソースはこちらから
0001.00 H DEBUG DFTNAME(SQLPRINT) DATEDIT(*YMD/) 0002.00 F********** SQL 担当者マスター一覧表 ***************************** 0003.00 FQPRINT O F 132 PRINTER OFLIND(*INOF) 0004.00 F FORMLEN(66) 0005.00 F FORMOFL(62) 0006.00 F***************************************************************** 0007.00 *[ COMPILE ] 0008.00 * CRTSQLRPGI QTEMP/SQLPRINT SRCFILE(QTRSRC/QRPGLESRC) COMMIT(*NONE) 0009.00 * OBJTYPE(*MODULE) OUTPUT(*PRINT) 0010.00 * CRTPGM QTROBJ/SQLPRINT MODULE(QTEMP/SQLPRINT) ACTGRP(*NEW) AUT(*ALL) 0011.00 * 0012.00 *[ 実行 ] 0013.00 * CALL QTROBJ/SQLPRINT 0014.00 0015.00 D HDR S 32 DIM(1) CTDATA PERRCD(1) 見出し 0016.00 D LIN S 1 DIM(132) 0017.00 D KENSU S 4S 0 0018.00 D TBCODE_B S 2A 0019.00 D*( データ・ベース外部データ構造 ) 0020.00 D FMT001 E DS EXTNAME(TANTOM) 0021.00 D FMT002 E DS EXTNAME(BUKAM) 0022.00 D RCDDTA DS OCCURS(9999) 0023.00 D VAR1 1 1024 0024.00 D N S 4B 0 0025.00 C****************************************************** 0026.00 C* SQL 文のカーソルの前準備 0027.00 C****************************************************** 0028.00 C* SELECT 文によってカーソル C1 を用意 0029.00 C/EXEC SQL DECLARE C1 CURSOR FOR 0030.00 C+ SELECT TACODE, TTNAMJ, TBCODE, TTNAM, BKNAME 0031.00 C+ FROM QTRFIL/TANTOM, QTRFIL/BUKAM 0032.00 C+ WHERE TBCODE = BKCODE 0033.00 C+ ORDER BY TBCODE, TACODE 0034.00 C/END-EXEC 0035.00 C* カーソルをオープン 0036.00 C/EXEC SQL OPEN C1 0037.00 C/END-EXEC 0038.00 C****************************************************** 0039.00 C* 明 細 演 算 0040.00 C****************************************************** 0041.00 C/EXEC SQL WHENEVER NOT FOUND GOTO EOF 0042.00 C/END-EXEC 0043.00 C 1 DO *HIVAL N 0044.00 C N OCCUR RCDDTA 0045.00 C/EXEC SQL 0046.00 C+ FETCH C1 INTO :TACODE, :TTNAMJ, :TBCODE, :TTNAM, :BKNAME 0047.00 C/END-EXEC 0048.00 C*( 明細印刷 ) 0049.00 C* TACODE CAT(P) TTNAMJ:0 RCDDTA 0050.00 C MOVEL(P) TACODE RCDDTA 0051.00 C CAT TTNAMJ:0 RCDDTA 0052.00 C/EXEC SQL SET RESULT SETS ARRAY :RCDDTA FOR :N ROWS 0053.00 C/END-EXEC 0054.00 C*------------------------------------------------------------------ 0055.00 C SETON 42 0056.00 C EXSR OUTPUT 0057.00 C*------------------------------------------------------------------ 0058.00 C ADD 1 KENSU 0059.00 C ENDDO 0060.00 C EOF TAG 0061.00 C* カーソルをクローズ 0062.00 C/EXEC SQL CLOSE C1 0063.00 C/END-EXEC 0064.00 C END TAG 0065.00 C*------------------------------------------------------------------ 0066.00 C SETON 49 0067.00 C EXSR OUTPUT 0068.00 C*------------------------------------------------------------------ 0069.00 C SETON LR 0070.00 C****************************************************** 0071.00 C *INZSR BEGSR 0072.00 C****************************************************** 0073.00 C* 初期のみの実行 0074.00 C CLEAR FMT001 0075.00 C MOVEA *ALL'-' LIN 0076.00 C INZEND ENDSR 0077.00 C****************************************************** 0078.00 C OUTPUT BEGSR 0079.00 C****************************************************** 0080.00 C TBCODE IFNE TBCODE_B 0081.00 C SETOFF 40 0082.00 C ENDIF 0083.00 C N40 SETON 4041 0084.00 C EXCEPT 0085.00 C OF SETOFF 40OF 0086.00 C SETOFF 414243 0087.00 C SETOFF 444546 0088.00 C SETOFF 474849 0089.00 C MOVE TBCODE TBCODE_B 0090.00 C ENDSR 0091.00 OQPRINT E 41 2 06 0092.00 O UDATE Y 8 0093.00 O 14 ' 作成 ' 0094.00 O HDR(1) 82 0095.00 O 128 'PAGE.' 0096.00 O PAGE Z 131 0097.00 O E 41 1 0098.00 O 12 ' 部課コード ' 0099.00 O TBCODE 18 0100.00 O 24 ' 部課名 ' 0101.00 O BKNAME 36 0102.00 O E 41 1 0103.00 O LIN 132 0104.00 O E 41 1 0105.00 O 14 ' 担当者コード ' 0106.00 O 24 ' 担当者名 ' 0107.00 O 44 ' 略名 ' 0108.00 O E 41 1 0109.00 O LIN 132 0110.00 O E 42 2 0111.00 O TACODE 5 0112.00 O TTNAMJ 36 0113.00 O TTNAM 46 0114.00 O E 49 1 0115.00 O 40 ' 処理件数 ' 0116.00 O 57 '. . . . . . . . .' 0117.00 O KENSU 2 65 0118.00 DR 0118.00 ** HDR 0119.00 担当者一覧表
[コンパイル]
CRTSQLRPGI QTEMP/SQLPRINT SRCFILE(QTRSRC/QRPGLESRC) COMMIT(*NONE)
OBJTYPE(*MODULE) OUTPUT(*PRINT)
CRTPGM QTROBJ/SQLPRINT MODULE(QTEMP/SQLPRINT) ACTGRP(*NEW) AUT(*ALL)
[ TANPRINT: RPGサイクルによる通常の印刷 ]
ソースはこちらから
0001.00 H DFTNAME(TANPRT) DATEDIT(*YMD/) 0002.00 F********** 担当者マスター一覧表 ************************************* 0003.00 FTANTOM IP E K DISK 0004.00 FBUKAM IF E K DISK 0005.00 FQPRINT O F 132 PRINTER OFLIND(*INOF) 0006.00 F FORMLEN(66) 0007.00 F FORMOFL(62) 0008.00 F********************************************************************** 0009.00 0010.00 *[ COMPILE ] 0011.00 * CRTRPGMOD OBJ(QTEMP/TANPRINT) SRCFILE(QTRSRC/QRPGLESRC) 0012.00 * DBGVIEW(*SOURCE) AUT(*ALL) 0013.00 * CRTPGM PGM(QTROBJ/TANPRINT) MODULE(QTEMP/TANPRINT) ACTGRP(*NEW) 0014.00 * AUT(*ALL) 0015.00 0016.00 *-------------------------------------------------------------------* 0017.00 * 2020/04/04 : 作成 0018.00 *-------------------------------------------------------------------* 0019.00 *( 作業変数 ) 0020.00 D HDR S 32 DIM(1) CTDATA PERRCD(1) 見出し 0021.00 D LIN S 1 DIM(132) 0022.00 D KENSU S 4S 0 0023.00 0024.00 I@TANTOM 01 0025.00 I TBCODE L1 0026.00 0027.00 C****************************************************** 0028.00 C *INL1 IFEQ *ON *INL1 0029.00 C****************************************************** 0030.00 C SETOFF 99 0031.00 C TBCODE CHAIN BUKAM 99 0032.00 C ENDIF *INL1 0033.00 C****************************************************** 0034.00 C* 明 細 演 算 0035.00 C****************************************************** 0036.00 C*( 明細印刷 ) 0037.00 C*-------------------------------------------------------------------------+ 0038.00 C SETON 42 | 0039.00 C EXSR OUTPUT | 0040.00 C*-------------------------------------------------------------------------+ 0041.00 C ADD 1 KENSU 件数 0042.00 * 0043.00 C*-------------------------------------------------------------------------+ 0044.00 CL1 SETON LR49 | 0045.00 CL1 EXSR OUTPUT | 0046.00 C*-------------------------------------------------------------------------+ 0047.00 C****************************************************** 0048.00 C *INZSR BEGSR 0049.00 C****************************************************** 0050.00 C MOVEA *ALL'-' LIN 0051.00 C ENDSR 0052.00 C****************************************************** 0053.00 C OUTPUT BEGSR 0054.00 C****************************************************** 0055.00 C N40 SETON 4041 0056.00 C EXCEPT 0057.00 C OF SETOFF 40OF 0058.00 C SETOFF 414243 0059.00 C SETOFF 444546 0060.00 C SETOFF 474849 0061.00 C ENDSR 0062.00 OQPRINT E 41 2 06 0063.00 O UDATE Y 8 0064.00 O 14 ' 作成 ' 0065.00 O HDR(1) 82 0066.00 O 128 'PAGE.' 0067.00 O PAGE Z 131 0068.00 O E 41 1 0069.00 O 12 ' 部課コード ' 0070.00 O TBCODE 18 0071.00 O 24 ' 部課名 ' 0072.00 O BKNAME 36 0073.00 O E 41 1 0074.00 O LIN 132 0075.00 O E 41 1 0076.00 O 14 ' 担当者コード ' 0077.00 O 24 ' 担当者名 ' 0078.00 O 44 ' 略名 ' 0079.00 O E 41 1 0080.00 O LIN 132 0081.00 O E 42 2 0082.00 O TACODE 5 0083.00 O TTNAMJ 36 0084.00 O TTNAM 46 0085.00 O E 49 1 0086.00 O 40 ' 処理件数 ' 0087.00 O 57 '. . . . . . . . .' 0088.00 O KENSU 2 65 0089.00 ** HDR 0090.00 担当者一覧表
[コンパイル]
CRTBNDRPG PGM(QTROBJ/TANPRINT) SRCFILE(QTRSRC/QRPGLESRC) DFTACTGRP(*NO) ACTGRP(*NEW) DBGVIEW(*SOURCE) AUT(*ALL)
[解説]
119ステップのSQL-RPGと 90ステップのRPGと比べてみても構造が通常のTANPRINTのほうがシンプルで
実行速度も圧倒的に速いし保守も容易である。
SQL-RPGは難しく書いて実行速度も低下している。
IBM iはどんに書き方をしても動いてしまうので気づかないかも知れないが
あなたの経理パッケージの実行が遅いと感じたらSQLが原因であるかもしれない。