*交易和组件写法
Firebird核心系统的整体结构,是由主控--交易--组件这几个层次组成的。联机交易主控由C程序编写,异步交易主控和日终批量主控由CL和RPGLE程序编写。主控通过交易码调用相应的交易RPGLE程序,交易程序又通过CALLP调用不同模块的组件RPGLE程序,完成整个处理逻辑。交易程序和组件程序都总结了一套模版样例,下面就介绍样例程序的写法。
在介绍交易和组件程序写法之前,先介绍统一由/COPY引入的通用程序,这部分程序放在DSCPPGM中。注意/COPY不宜滥用,一定要结合命名规范,否则极易导致程序可读性差。
首先是HEAD。这个文件定义了copyright和几个日期fmt规则。
-
**BEGIN***************************************************************
-
**程序名称:程序公共控制头 *
-
**功能描述:程序公共控制头 *
-
** *
-
**版本:2014-10-21_1 *
-
** *
-
**设计人员:PACMAN 开发人员:AUTOGEN *
-
**设计日期:2011-08-30 开发日期:2011-08-30 *
-
** *
-
**END*****************************************************************
-
**
-
HCOPYRIGHT(‘Firebird V2.1 corebanking system, CSW SHANGHAI‘)
-
HDATFMT(*ISO) TIMFMT(*ISO) DATEDIT(*YMD)
然后是ENUM,这个文件是引入枚举常量定义,在数据字典和枚举值部分已经有了介绍,这里就不重复了。
接下来是PGDS,这个文件定义了每个程序都会引入的PSDS和INFDS结构定义,错误结构定义,错误信息数组,接口数组条数,以及特殊用途变量等。
最后是通用处理过程PGCM,这个程序定义了错误捕获程序以及检查,退出等通用过程,并以#开头的过程名,与交易中普通@开头过程名以示区分。
-
**BEGIN***************************************************************
-
**程序名称:程序公共子程序 *
-
**功能描述:程序公共子程序 *
-
** *
-
**版本:2014-10-21_1 *
-
** *
-
**设计人员:PACMAN 开发人员:AUTOGEN *
-
**设计日期:2011-08-30 开发日期:2011-08-30 *
-
** *
-
**END*****************************************************************
-
**
-
**********************************************************************
-
** #EXIT返回
-
**********************************************************************
-
C #EXIT BEGSR
-
**
-
C EVAL PG_FRYNFG = YNFG_NO
-
C/IF DEFINED(USELR)
-
C EVAL *INLR = *ON
-
C/ENDIF
-
C RETURN
-
**
-
C ENDSR
-
**********************************************************************
-
** #ERR 取错误信息
-
**********************************************************************
-
C #ERR BEGSR
-
**
-
C EVAL PMG.MSFLNM = PG_SRCMBR
-
C IF PMG.BKMSDS = *BLANKS
-
C CALL ‘SCNCMMG‘
-
C PARM PMG
-
C PARM A_MSDS
-
C ENDIF
-
C EXSR #EXIT
-
**
-
C ENDSR
-
**********************************************************************
-
** #CHKMSG检查程序返回信息
-
**********************************************************************
-
C #CHKMSG BEGSR
-
**
-
C IF PMG.BKMSID <> *BLANKS
-
C EXSR #EXIT
-
C ENDIF
-
**
-
C ENDSR
-
**********************************************************************
-
** *PSSR程序异常处理
-
**********************************************************************
-
C *PSSR BEGSR
-
**
-
C IF PG_ERYNFG = YNFG_NO
-
C EVAL PG_ERYNFG = YNFG_YES
-
C EVAL PMG.MSFLNM = PG_SRCMBR
-
C EVAL PMG.MSCDLN = PG_SRCLINE
-
C EVAL PMG.BKMSID = ‘F‘ + PG_MSID
-
C EVAL PMG.BKMSDS = PG_EXCPDT
-
C EVAL PMG.OTMSDS = PG_STATUS+‘ ‘+PG_PGMLIB+‘ ‘+
-
C PG_PGMNAME
-
C EXSR #EXIT
-
C ENDIF
-
**
-
C ENDSR
-
**********************************************************************
-
** #FLEX文件异常处理
-
**********************************************************************
-
C #FLEX BEGSR
-
**
-
C EVAL PMG.MSFLNM = PG_SRCMBR
-
C EVAL PMG.MSCDLN = FL_SRCLINE
-
C EVAL PMG.BKMSID = ‘F‘ + FL_MSID
-
C IF FL_STATUS = 1218
-
C CALL ‘GETOBJTXT‘
-
C PARM FL_LIBRARY V_FLEXLIB 10
-
C PARM FL_FILENAME V_FLEXOBJ 10
-
C PARM ‘*FILE‘ V_FLEXTYP 7
-
C PARM *BLANKS V_FLEXTEXT 50
-
C EVAL PMG.BKMSDS = %TRIM(V_FLEXTEXT) +
-
C %TRIM(FL_FILENAME) + ‘.‘ +
-
C %TRIM(FL_MEMBER) + C_MGLOCK +
-
C ‘,‘ + PG_EXCPDT
-
C ELSE
-
C EVAL PMG.BKMSDS = PG_EXCPDT
-
C ENDIF
-
C EVAL PMG.OTMSDS = PG_FLINFO
-
C EXSR #EXIT
-
**
-
C ENDSR
交易程序样例以6位交易码000000为例,交易程序名为T000000A,有两个输入T000000I1,T000000I2,两个输出T000000O1,T00000O2。其中I2和O2是数组。
T000000I1程序如下。
-
A REF(DICT)
-
A R RT000000I1
-
A BKBRNO R REFFLD(@@BRNO)
-
A COLHDG(‘机构‘)
-
A TEXT(‘机构‘)
T000000I2程序如下。
-
A REF(DICT)
-
A R RT000000I2
-
A BKTLNO R REFFLD(@@TLNO)
-
A COLHDG(‘柜员‘)
-
A TEXT(‘柜员‘)
T000000O1程序如下。
-
A REF(DICT)
-
A R RT000000O1
-
A BKTRWB R REFFLD(@@TRWB)
-
A COLHDG(‘交易流水号‘)
-
A TEXT(‘交易流水号‘)
T000000O1程序如下。
-
A REF(DICT)
-
A R RT000000O2
-
A BKACNO R REFFLD(@@ACNO)
-
A COLHDG(‘账号‘)
-
A TEXT(‘账号‘)
交易程序T000000A程序如下。
在交易程序中,如果需要调用模块组件,那么会用/COPY引入组件的PROTOTYPE声明和组件参数结构定义,这部分在组件样例中介绍。
交易的参数统一为3个。先是PMG,错误信息结构,用于将出错信息返回主控,判断交易是否成功,组织出错报文。再是PIN,输入复合结构,依次由INHD输入应用头,INFE输入费用数组,INCS输入券面数组,I1,I2等交易自身结构组成。最后是POT,输出复合结构,依次由OTHD输出应用头,OTVC输出记账传票数组,O1,O2等交易自身结构组成。这部分可以参见报文格式一节内容。
程序中将所有临时变量都定义在D_VARS结构下,这样方便一开始的初始化,可以用CLEAR D_VARS直接清值。
交易程序中调用了组件程序模版SCETPSV,同样第一个参数要是PMG,这样结合#CHKMSG,可以让出错信息层层传递返回。接着是组件自己的参数。如果是记账组件,那么最后一个参数必须是传票数组POT.OTVC层层传递,以实现将交易所有产生的记账传票流水按套顺序重组,返回前端打印。现有的很多系统,只能体现交易所有借贷传票,无法体现传票先后顺序,也不能按会计原理进行最小成套归类,并保证每套不会出现多借多贷,而Firebird则做到了这一点。
在返回处理过程中,特别注意如果是输出有数组,需要在这段中调用SCNCMTA设置输出数组实际有值的条数,主控会根据实际条数去简化返回报文。
组件程序样例SCETPSV,除了固定的PMG参数外,有F1,F2两个自有参数。组件由SCETPSVP组件声明,SCETPSVF1,SCETPSVF2两个参数结构定义,SCETPSV组件程序这几个部分组成。
SCETPSVF1参数文件如下。
-
A REF(DICT)
-
A R RSCETPSVF1
-
A BKBRNO R REFFLD(@@BRNO)
-
A COLHDG(‘机构号‘)
-
A TEXT(‘机构号‘)
SCETPSVF2参数文件如下。
-
A REF(DICT)
-
A R RSCETPSVF2
-
A MTTLNO R REFFLD(@@TLNO)
-
A COLHDG(‘柜员号‘)
-
A TEXT(‘柜员号‘)
SCETPSVP组件声明文件如下。
-
**BEGIN***************************************************************
-
**程序名称:服务程序模板原型 *
-
**功能描述:服务程序模版原型及参数接口定义 *
-
** *
-
**版本:2014-10-21_1 *
-
** *
-
**设计人员:CSWWM 开发人员:CSWWM *
-
**设计日期:2011-08-30 开发日期:2011-08-30 *
-
**-------------------------------------------------------------------*
-
**维护人员:CSWYJ *
-
**维护日期:2014-10-17 *
-
**维护内容:按新规范改写 *
-
** *
-
**END*****************************************************************
-
**常量定义
-
DC_NBTPSVF2 C CONST(50)
-
*************************
-
**参数接口定义
-
DTPSVF1 E DS EXTNAME(SCETPSVF1) QUALIFIED
-
DT_TPSVF2 E DS EXTNAME(SCETPSVF2) QUALIFIED TEMPLATE
-
DTPSVF2 DS QUALIFIED
-
D RECD LIKE(DICT.@@RECD)
-
D ARR DIM(C_NBTPSVF2) LIKEDS(T_TPSVF2)
-
*************************
-
**程序原型定义
-
DSCETPSV PR EXTPGM(‘SCETPSV‘)
-
D PMG LIKEDS(PMG)
-
D TPSVF1 LIKEDS(TPSVF1)
-
D TPSVF2 LIKEDS(TPSVF2)
这里要注意的是,组件的数组与交易接口数组不同,全部是带上RECD实际记录条数的复合结构。这样才能知道最大容量的数组,实际存放了多少条有效记录。
组件程序SCETPSV文件如下。
这里值得注意的是,组件程序本身也要/COPY引入组件声明,以为声明包含了原型定义,以及参数结构定义。另外,由于引入了异常处理程序,现在应用程序编写起来就清晰多了,无需考虑各种文件操作的异常报错处理,是不是很方便呢。
至此,组件和交易模版介绍完了,按照这个模版,就可以编写实际使用的各个模块程序,挂在交易主控中执行了。
AS400银行核心系统开发中的技术总结--交易和组件写法
原文:http://blog.chinaunix.net/uid-283313-id-5700780.html