RPG多文件讀取轉換為SQL多表查詢
對於400上的應用,還大多停留在RPG,C,COBOL,或者Java操作文件的階段。
IBM的戰略是將這些對物理或者邏輯文件的操作,向SQL過渡並遷移;通過SQL對數據集進行操作,而非訪問文件記錄;
傳統的應用是對記錄進行訪問和操作,程序員決定了數據訪問的方法,這樣就致使應用性能的好壞取決於程序員的編程技巧和經驗;
而SQL方式操作以數據為中心,DB2提供更多的數據訪問方法,DB2可以選擇最優的訪問方法組合,讓DB2為我們做復雜的數據訪問優化。
下面是一段RPG程序片段,主要完成對2個視圖和1個表函數返回值的處理,然後取到數據:
以變量P_SYSID所帶的值為查詢條件,遍歷PMFM202視圖(PMRM202為PMFM202邏輯文件的記錄名);
對於讀取到的每一條記錄,都進行如下操作:
1.字段P20PCOD未出現在PMFM203視圖裡面。
2.調用函數GETATRVAL(可視為SQL表函數,返回PMFM20和PMFM21表中的相關數據),取每一個P20PCOD對應的數據。
3.將從表函數返回的數據與程序入口結構(DPM1000:P_SYSID,P_CCY,P_CPFLG)中數據進行比較。
[sql]
......
C P_SYSID SETLL PMRM202
C DOW 1=1
C P_SYSID READE PMRM202
C IF %EOF
C LEAVE
C ENDIF
*無效
C IF P20EFCT = '0'
C ITER www.2cto.com
C ENDIF
*非末級產品
C P20PCOD CHAIN PMRM203
C IF %FOUND
C ITER
C ENDIF
C
*取產品屬性
C EXSR @PRDATR
C*開辦日期
C IF VYCMIDTE < K_OPNDAT
C ITER
C ENDIF
C*停辦日期
C IF VYCMIDTE > K_ENDDAT
C ITER
C ENDIF
C*有效狀態
C IF K_VLDSTS <> '1'
C ITER
C ENDIF
C*單位個人標志
C IF P_CPFLG <> '' AND P_CPFLG <> K_CORPPSNFLG
C ITER
C ENDIF www.2cto.com
C
C EVAL O01_PCOD = P20PCOD
C EVAL O01_DESP = K_PRDNAM
C
C IF O01_DESP = ''
C EVAL O01_DESP = P20DESP
C ENDIF
C
C ADD 1 V_CNT
C*生成下傳信息
C MOVEL(P) PM1000C01O MSGTXT
C*控制前台應答響應
C EVAL FORMAT=VYCMTCDE+'01'
C EXSR #SNDQRY
C
C ENDDO
......
C @PRDATR BEGSR
C*函數GETATRVAL的作用是用過參數P20PCOD,
C*讀取PMFM20表,和PMFM21表,然後取出相關數據,這裡可以看作:
C*表函數getatrval從通過傳入參數,取PMFM20表和PMFM21表裡面的相關數據。
/FREE
K_CORPPSNFLG = %TRIM(GETATRVAL(P20PCOD:'CORPPSNFLG'));
K_PRDNAM = GETATRVAL(P20PCOD:'PRDNAM');
K_VLDSTS = GETATRVAL(P20PCOD:'VLDSTS');
K_OPNDAT = %DATE(GETATRVAL(P20PCOD:'OPNDAT'));
K_ENDDAT = %DATE(GETATRVAL(P20PCOD:'ENDDAT'));
K_OPNORGLVL= GETATRVAL(P20PCOD:'OPNORGLVL');
K_OPNORGTYP= GETATRVAL(P20PCOD:'OPNORGTYP');
K_OPNTLRLVL= GETATRVAL(P20PCOD:'OPNTLRLVL');
K_OPNTLRTYP= GETATRVAL(P20PCOD:'OPNTLRTYP'); www.2cto.com
/END-FREE
C ENDSR
......
從上面這段RPG代碼,就可以應證這一點:
“對於傳統的數據記錄的訪問,程序員決定數據訪問方法,應用的性能取決於程序員的編程技巧與經驗”。
程序員必須清楚:
文件的遍歷順序?
用什麼方式遍歷?READE還是CHAIN?
沒有豐富的經驗和對RPG讀取文件的操作碼的足夠認識,很可能就會遺漏掉文件中的部分數據,或者造成根本沒有讀取文件。
如果轉換為SQL去訪問表,我們就不用關心數據庫中表的訪問方式,只需要寫出邏輯正確的SQL語句。 www.2cto.com
上面的這段代碼轉換為DB2 SQL查詢語句,可以書寫如下:
[sql]
select a.p20pcod O01_PCOD
,IFNULL(c.P21DESP,b.P20DESP) O01_DESP
from pmfm202 a,pmfm203 b,TABLE(GETATRVAL(b.p20pcod)) c
where b.p20biz = a.p20biz
and b.p20pcod = c.p21pcod
and a.P20BIZ = P_SYSID
and a.P20EFCT <> '0'
and c.P21STRD <= CURRENT DATE
and c.P21ENDD >= CURRENT DATE
and TRIM(c.P21VAL) = P_CPFLG