CL

118. CLPでデータ・ベースを更新するには?

CLPでデータ・ベースを更新する方法があるだろうか?
CLPでデータ・ベースは DCLFで定義しておけば
RCVFコマンドでレコード単位で読取ることができることは
よく知られている。
しかし SNDFコマンドでレコードをCLPで出力することはできない。
SNDFが使える対象は画面ファイル(DSPF)だけである。

しかしCLPでもデータ・ベースを更新できる方法はひとつだけある。
それはVer7.1で利用可能になったRUNSQLコマンドを使うことである。

RUNSQLコマンドとはVer7.1で追加されたSQL命令を実行する
コマンドであり SELECT文は実行できないが UPDATE/INSERT/DELETE
実行することができる。

それでは RUNSQLによってレコードを更新するサンブルCLPを紹介しよう。

[商品マスターのレコードをSQLで更新するサンプル: TESTSQLC1 ]

ソースはこちらで

001.00              PGM                                                          
002.00 /*-------------------------------------------------------------------*/   
003.00 /*   TESTSQLC1 :  SQL レコード更新                                   */   
004.00 /*                                                                   */   
005.00 /*   2020/02/29  作成                                                */   
006.00 /*-------------------------------------------------------------------*/   
007.00              DCL        VAR(&MSG) TYPE(*CHAR) LEN(132)                    
008.00              DCL        VAR(&MSGID) TYPE(*CHAR) LEN(7)                    
009.00              DCL        VAR(&MSGF) TYPE(*CHAR) LEN(10)                    
010.00              DCL        VAR(&MSGFLIB) TYPE(*CHAR) LEN(10)                 
011.00              DCL        VAR(&MSGDTA) TYPE(*CHAR) LEN(132)                 
012.00              DCL        VAR(&TYPE) TYPE(*CHAR) LEN(1)                     
013.00              DCL        VAR(&TOPGMQ) TYPE(*CHAR) LEN(10)                  
014.00              DCL        VAR(&MSGTYPE) TYPE(*CHAR) LEN(10) +               
015.00                           VALUE('*ESCAPE   ')                             
016.00              DCL        VAR(&APIERR) TYPE(*CHAR) LEN(116) +               
017.00                           VALUE(X'000074') /* 2 進数  */                  
018.00              DCL        VAR(&NULL4) TYPE(*CHAR) LEN(4) +                  
019.00                           VALUE(X'00000000')                              
020.00              /*( SQL レコード更新用の変数 )*/                             
021.00              DCL        VAR(&STR) TYPE(*CHAR) LEN(1024)                   
022.00              MONMSG     MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))           
023.00                                                                           
0024.00 /*( 環境の取得 )*/                                                    
0025.00              RTVJOBA    TYPE(&TYPE)                                   
0026.00              IF         COND(&TYPE *EQ '0') THEN(DO) /*  バッチ  */   
0027.00              CHGVAR     VAR(&TOPGMQ) VALUE('*SYSOPR   ')              
0028.00              ENDDO      /*  バッチ  */                                
0029.00              ELSE       CMD(DO) /*  対話式  */                        
0030.00              CHGVAR     VAR(&TOPGMQ) VALUE('*TOPGMQ   ')              
0031.00              ENDDO      /*  対話式  */                                
0032.00                                                                       
0033.00 /*( SQL によるレコード更新 )*/                                        
0034.00              CHGVAR     VAR(&STR) VALUE('UPDATE QTRFIL/SHOHIN SET +   
0035.00                           SHTANK = 28000 WHERE SHCODE = ''SF-SDCD''') 
0036.00              RUNSQL     SQL(&STR) COMMIT(*NONE)                       
0037.00              CHGVAR     VAR(&MSG) VALUE('1 レコードを更新しました。 ')
0038.00              GOTO       SNDMSG                                        
0039.00              RETURN                                                   
0040.00                                                                       
0041.00  APIERR:                                                              
0042.00              CHGVAR     VAR(&MSGID) VALUE(%SST(&APIERR 9 7))          
0043.00              CHGVAR     VAR(&MSGDTA) VALUE(%SST(&APIERR 17 100))      
0044.00              CHGVAR     VAR(&MSGF) VALUE('QCPFMSG   ')                
0045.00              CHGVAR     VAR(&MSGFLIB) VALUE('QSYS      ')             
0046.00              GOTO       SNDMSG                                        
0047.00                                                                       
0048.00  ERROR:      RCVMSG     MSGTYPE(*LAST) RMV(*NO) MSG(&MSG) +          
0049.00                           MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) +
0050.00                           MSGFLIB(&MSGFLIB)                          
0051.00  SNDMSG:     IF         COND(&MSGID *EQ ' ') THEN(DO)                
0052.00              SNDPGMMSG  MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&MSG) +  
0053.00                           TOMSGQ(&TOPGMQ) MSGTYPE(&MSGTYPE)          
0054.00              MONMSG     MSGID(CPF2400) EXEC(RETURN)                  
0055.00              ENDDO                                                   
0056.00              ELSE       CMD(DO)                                      
0057.00              SNDPGMMSG  MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +         
0058.00                           MSGDTA(&MSGDTA) TOMSGQ(&TOPGMQ) +          
0059.00                           MSGTYPE(&MSGTYPE)                          
0060.00              MONMSG     MSGID(CPF2400) EXEC(RETURN)                  
0061.00              ENDDO                                                   
0062.00              ENDPGM   


                                              

[解説]

SQL文の文字ストリング &STR に次のように値をセットしている。

0034.00              CHGVAR     VAR(&STR) VALUE('UPDATE QTRFIL/SHOHIN SET +   
0035.00                           SHTANK = 28000 WHERE SHCODE = ''SF-SDCD''')

つまりこれは

  UPDATE QTRFIL/SHOHIN SET HSTANK = 28000 WHERE SHCODE = 'SF-SDCD'

を実行することであり商品コード SF-SDCDのレコードの単価: SHTANK
28000円に更新することを意味している。
このプログラムを実行すると


 > call test.com/testsqlc1   
   1 レコードを更新しました。

のようになり結果をQUERYで確認すると

                                 報告書の表示                       
                                              報告書の幅  . . . . . 
 行の位置指定 . . . . . . .               桁移動  . . . . . . . . . 
 行    ....+....1....+....2....+....3....+....4....+....5....+....  
        商品 コード   商品名                       単価    品種 コード  
000001 NV-BS30S     目次ビデオ                 165,000     0002     
000002 NV-BS50S     ビデオ画王                 200,000     0002     
000003 NV-CF2       薄型テレビ                  98,000     0003     
000004 NV-CF81      更新テスト                  58,000     0004     
000005 NV-CF9       漢字テスト                  19,000     0002     
000006 NV-F850      音声録画ビデオ             140,000     0002     
000007 NV-HK1       歌えるビデオ                90,000     0002     
000008 NV-H1T-S     みんなのビデオ              69,800     0002     
000009 NV-SX10      ビデオ画王                 115,000     0002     
000010 NV-W1        世界放送方式ビデオ         350,000     0002     
000011 RX-DT75      CDラジオカセット          53,800     0003     
000012 SC-CH150     超ミニ・コンポ              70,000     0003     
000013 SC-CH505     パーソナル・ミニコンポ     100,000     0003     
000014 SC-CH655     ロングプレイ・コンポ       129,000     0003     
000015 SC-CH950     ドルビー・ミニコンポ       162,000     0003     
000016 SF-SDCD     FFFFF                        28,000     0009     

のようにして見事 SF-SDCDの単価は 28000円に更新されている。
( 更新前は 19000円であった)

SQL : UPDATE QTRFIL/SHOHIN SET HSTANK = 28000 WHERE SHCODE = 'SF-SDCD'

を更新したのは次のたった一行のRUNSQLコマンドであった。

 RUNSQL     SQL(&STR) COMMIT(*NONE)

このようにRUNSQLを使えば SQLUPDATE/INSERT/DELETE による更新を行うことが
できる。
ただし RUNSQLが使えるのは OS Ver7.1からである。