2010年7月31日(土) 19:36 JST

HOME > i am BEST > RPG でも埋め込みSQL!! のすすめ

RPG でも埋め込みSQL!! のすすめ

  • 2010年2月11日(木) 04:46 JST
  • 投稿者:
    hidehi

今まで紹介してきた埋め込み SQL はバッチ系の処理が中心でしたが、もちろん対話型アプリケーションでも OK です。



今回は EOL の「対話型プログラム(1)」の中の例題「品目登録」を埋め込み SQLで書き換えてみました。
(こちらはかなり機械的な書き換えなので元のプログラムの全文は省略しています。
 EXEC SQL のすぐ上のコメントアウトされている RPG 命令コードを見ればどう書きかえたかはわかると思います。
 F 仕様書は自明なのでもう削除ずみですが、一行対一行ですべて置き換えてあります。つまり行数は SQL の字下げの分だけしか増えていません)

ごくカンタンにかいつまんで説明すると、

  • 画面から入力された品目コードをもって品目マスターを検索
  • 存在している場合はエラー表示し、存在していない場合は品目登録画面(PANEL02)を出力
  • 品目登録画面で品目マスターに登録

という流れになっています。

こちらがコード全文になります。表示装置ファイルはほぼ EOL のままなので掲載は省略します。

     H OPTION(*SRCSTMT:*NODEBUGIO)                                                                  
     H DATFMT(*JIS) DATEDIT(*YMD)                                                                  
      * HIN020 品目登録                                                                                 
     FHIN020S1  CF   E             WORKSTN INDDS(Indicators)                                       
      *
     D HINDS         E DS                  EXTNAME(HINMSP)                                         
     D Indicators      DS                                                                          
     D  exit                           n   overlay(Indicators:3)                                   
     D  alreadyin                      n   overlay(Indicators:32)                                  
      /free                                                                                        
                                                                                                   
               dow not exit ;                                                                      
                  exfmt PANEL01 ;                                                                  
                     if exit ;                                                                     
                        leave ;                                                                    
                     endif ;                                                                       
                                                                                                   
                  alreadyin = *off ;                                                               
              //  chain    HNBANG  HINMSP ;                                                        
                  exec SQL SELECT  hnbang, hnnakj, hngsur, hngkin                                  
                             INTO :HNBANG,:HNNAKJ,:HNGSUR,:HNGKIN                                  
                             FROM  Hinmsp                                                          
                            WHERE  hnbang = :HNBANG ;                                               
              //  if not %found ;                                                                  
                  if SQLSTATE = '02000' ;                                                          
                     write  PANEL01 ;                                                              
                     exfmt  PANEL02 ;                                                              
                     HNGSUR = 0 ;                                                                  
                     HNNSUR = 0 ;                                                                  
                     HNGKIN = 0 ;                                                                  
                     HNNKIN = 0 ;                                                                  
               //    write  HINMSR ;                                                               
                     exec SQL INSERT INTO Hinmsp (                                                 
                                hnbang,  hnnakn,  hnnakj,  hnvend,  hnteik,                        
                                hngenk,  hngsur,  hnnsur,  hngkin,  hnnkin  )                      
                              VALUES (                                                             
                               :HNBANG, :HNNAKN, :HNNAKJ, :HNVEND, :HNTEIK,                        
                               :HNGENK, :HNGSUR, :HNNSUR, :HNGKIN, :HNNKIN ) ;                     
                  else ;                                                                           
                      alreadyin = *on ;                                                            
                  endif ;                                                                          
               enddo ;                                                                             
                                                                                                   
               *inLR = *on ;                                                                       
               return ;                                                                            
                                                                                                   
      /end-free

例によって、元の RPG とパフォーマンスを比較してみましたが、今までの記事どおりほとんど同じか速いくらいだったので今回はわざわざ載せるのはやめました。
(RPG/400 がかなり遅く、フリー・フォーマットの ILE RPG が SQLRPG と同じくらいかやや遅いくらい、と前回とまったく同じような結果でした)

 

SQL も RPG も、ジョブがはじまったところで ODP (Open Data Path) というものを作成して(WRKJOB の 14 で見れますね)、
その ODP に対して CHAIN(= SELECT) したり、WRITE(= INSERT) したりするわけで、構造的にはまったく同じことをやっているんですね。

SQL では(以前ふれたように)実際にデータを取得する手順はデータの内容によって適切なものを選択するようになっています。
たとえば、選択範囲が大半になってしまうのであれば全件読み込み(テーブルスキャン)を行い、選択範囲が少ないのであればインデックスを使う、といったようなことを行うわけです。

SQL の場合はこのやり方にいろんなバリエーションがあるのですが、
RPG の場合はこのやり方が限られている上に固定である、ということです。

さらに言うと、RPG では SQL では使えるたとえばハッシュによるグルーピングとかビットマップインデックスの使用なども利用できません。
SQL にはマルチ・プロセスによる並行処理を行わせることが可能ですが、RPG の並行処理には pthreads を使ってコーディングする必要があります。

つまり、RPG と SQL を比較すると OS で実行される仕組みはほぼ同じで、SQL の方がそのうえで使える武器も多い、というわけです。
原則、パフォーマンス的には埋め込み SQL の方が有利、といっていいでしょう。
(もちろんケースバイケースで RPG ネイティブの方が速いことはありえます)

 

他の言語ではデータベースアクセスと言えば埋め込み SQL が普通です。
RPG のネイティブ命令と言っても以前述べたように「論理ファイル」と同様の"歴史的"なもので、特別にパフォーマンスよく設計されている、といったことはありません。

現在の CPU の速さや積んでいるメモリの大きさを考えると、
システム的には RPG より SQL、
SQL の中でも新しい SQE というエンジンでの処理、
と効率がよくなっていっているのは間違いのないところです。
できるだけその方向に沿うことでシステム資源が有効活用できるわけですね。

プログラマのスキルにとっての将来性といった意味でもやはり SQL の方が有利です。

データベース処理を SQL で行ったからといって RPG の価値は下がりません。
RPG はとても初心者にもわかりやすい言語で、プログラミングの基本を学ぶにはとてもよくできたものです。
特に、ILE であれば C の関数や Java のメソッドを利用することだってできます。
得た知識を元に他の言語の学習もラクになるでしょう。

 

SQL でデータベースアクセスを行い、その他の処理(たとえばループや画面、印刷など)の制御を RPG で行う、というのはとても相性のよい組み合わせだと思います。
埋め込み SQL はその RPG と SQL の両方の利点をあわせもっている、というわけですね。

ぜひトライしてみてください!!

トラックバック

このエントリのトラックバックURL:
http://www.iforum.ne.jp/trackback.php/20100124044645607
表示形式
コメント投稿

コメントは投稿者の責任においてなされるものであり,サイト管理者は責任を負いません。

iForumサポーター

      iFourmの趣旨にご賛同いただき、ご支援いただける企業または個人を募集しています。詳しくは、info@iforum.ne.jp へお願いします。