Chinaunix首页 | 论坛 | 博客
  • 博客访问: 303933
  • 博文数量: 40
  • 博客积分: 1
  • 博客等级: 民兵
  • 技术积分: 670
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-31 11:19
个人简介

从事银行核心系统设计开发的程序猿

文章存档

2019年(1)

2018年(4)

2017年(11)

2016年(6)

2015年(18)

分类: 信息化

2016-02-22 00:14:14

*数据字典和枚举值


    在核心系统应用开发中,数据字典有举足轻重的作用。数据字典是对系统中所有字段的归纳抽象,需要规范同类字段的类型长度,方便定义和修改。
    但是,在过去的核心系统中,数据字典的理解往往也会有失误。常见的错误方法,是试图穷举定义所有可以出现的字段名字。可是实际上核心系统应用程序内容是不断扩充的,功能和交易程序都在不停增加,所用到的字段也是无穷无尽。如果需要列举的是所有字段,就像建巴比伦塔一样困难。而且不可避免会出现账号1到账号9这样的重复。
    在Firebird系统中,数据字典的使用方式回归了本源意义,即数据字典定义的是不重复的字段基础类型。举例来说,“日期”就是一个基础类型,归数据字典管理。而“交易日期”,“开户日期”这些字段,都只是使用基础类型定义出来的具体字段变量,不归集到数据字典管理,但命名上要求具体字段必须以数据字典基础类型结尾,体现归属关系。“日期”在数据字典里定义的是WKDT,“开户日期”起名可以叫OPWKDT,“交易日期”起名可以叫TRWKDT,不同场景中也可以起名不一样。这样的数据字典和字段命名规则,既满足应用系统字段的不断扩充,又保持数据字典的精简和稳定。


    数据字典的实现方式,是建立一个DICT的PF文件并编译,里面的内容即是所有基础类型的定义。摘录部分如下所示。

  1. A R RDICT
  2. A*长度 L
  3. A @@WKDT L TEXT('日期')
  4. A
  5. A*长度 T
  6. A @@WKTM T TEXT('时间')
  7. A
  8. A*长度 Z
  9. A @@TMSP Z TEXT('时间戳')
  10. A
  11. A*长度 1A
  12. A @@CHAR 1A TEXT('字符')
  13. A @@YNFG 1A TEXT('是否标志')
  14. A* 1 是 YES
  15. A* 0 否 NO
  16. ......
  17. A*长度 3P
  18. A @@EXSQ 3P 0 TEXT('执行序号')
  19. A*长度 4A
  20. A @@SMCD 4A TEXT('摘要代码')
  21. A @@ITCD 4A TEXT('核算代码')
  22. A @@CSCD 4A TEXT('现金项目代码')
  23. ......


    为了与实际应用程序中的字段名区分,数据字典中的基础类型字段名以@@开头。


    在表结构PF字段定义,通用结构定义,交易、组件输入输出接口PF字段定义时,就可以参照数据字典了。
    以尾箱凭证登记表ACNVCBB为例展示如下。

  1. A UNIQUE
  2. A REF(DICT)
  3. A R RACNVCBB
  4. A BKBRNO R REFFLD(@@BRNO)
  5. A TEXT('机构号')
  6. A COLHDG('机构号')
  7. A BKBXNO R REFFLD(@@BXNO)
  8. A TEXT('尾箱号')
  9. A COLHDG('尾箱号')
  10. A BKVCTP R REFFLD(@@VCTP)
  11. A TEXT('凭证种类')
  12. A COLHDG('凭证' '种类')
  13. A VBMDNU R REFFLD(@@MDNU)
  14. A TEXT('凭证张数')
  15. A COLHDG('凭证' '张数')
  16. A BKSTCD R REFFLD(@@STCD)
  17. A TEXT('记录状态')
  18. A COLHDG('记录状态')
  19. A K BKBRNO
  20. A K BKBXNO
  21. A K BKVCTP


    以尾箱主表ACNBXBX为例展示如下。

  1. A UNIQUE
  2. A REF(DICT)
  3. A R RACNBXBX
  4. A BKBRNO R REFFLD(@@BRNO)
  5. A TEXT('机构号')
  6. A COLHDG('机构号')
  7. A BKBXNO R REFFLD(@@BXNO)
  8. A TEXT('尾箱号')
  9. A COLHDG('尾箱号')
  10. A VCACNO R REFFLD(@@ACNO)
  11. A TEXT('凭证账号')
  12. A COLHDG('凭证' '账号')
  13. A BKTLNO R REFFLD(@@TLNO)
  14. A TEXT('柜员号')
  15. A COLHDG('柜员号')
  16. A EQYNFG R REFFLD(@@YNFG)
  17. A TEXT('碰平标志')
  18. A COLHDG('碰平' '标志')
  19. A OPBRNO R REFFLD(@@BRNO)
  20. A TEXT('创建机构')
  21. A COLHDG('创建' '机构')
  22. A OPDPNO R REFFLD(@@DPNO)
  23. A TEXT('创建部门')
  24. A COLHDG('创建' '部门')
  25. A OPTLNO R REFFLD(@@TLNO)
  26. A TEXT('创建柜员')
  27. A COLHDG('创建' '柜员')
  28. A OPWKDT R REFFLD(@@WKDT)
  29. A TEXT('创建日期')
  30. A COLHDG('创建' '日期')
  31. A OPWKTM R REFFLD(@@WKTM)
  32. A TEXT('创建时间')
  33. A COLHDG('创建' '时间')
  34. A MTBRNO R REFFLD(@@BRNO)
  35. A TEXT('修改机构')
  36. A COLHDG('修改' '机构')
  37. A MTDPNO R REFFLD(@@DPNO)
  38. A TEXT('修改部门')
  39. A COLHDG('修改' '部门')
  40. A MTTLNO R REFFLD(@@TLNO)
  41. A TEXT('修改柜员')
  42. A COLHDG('修改' '柜员')
  43. A MTWKDT R REFFLD(@@WKDT)
  44. A TEXT('修改日期')
  45. A COLHDG('修改' '日期')
  46. A MTWKTM R REFFLD(@@WKTM)
  47. A TEXT('修改时间')
  48. A COLHDG('修改' '时间')
  49. A BKSTCD R REFFLD(@@STCD)
  50. A TEXT('记录状态')
  51. A COLHDG('记录' '状态')
  52. A K BKBRNO
  53. A K BKBXNO


    从上面的例子可以看出,PF定义中首先要REF(DICT)引入数据字典,然后定义具体字段时候,REFFLD指明数据字典的基础类型字段。注意的是命名规范要求,具体字段的后4位必须和数据字典基础字段名字一致。这样在程序中可以轻松认出是哪种类型(这就是应用型匈牙利命名法,有关匈牙利命名法的误解和讨论参见《软件随想录 -- Joel on software》的第23章“让错误的代码显而易见”)。不同的PF字段名字可能会一样,因此在RPG程序中需要QUALIFIED防止重叠,这在后续“命名限定”时候再介绍。


    那么如果在RPG程序中需要参照数据字典定义变量该怎么写呢。这里就需要使用一个新的关键字TEMPLATE,它可以引入一个PF结构但并不分配存储空间。同样让例子程序说话。

  1. **********************************************************************
  2. **公共结构
  3. **引入数据字典
  4. DDICT E DS EXTNAME(DICT) QUALIFIED TEMPLATE
  5. *************************
  6. **临时变量结构
  7. DD_VARS DS
  8. **定义参照数据字典(LIKE)的变量 
  9. D V_BKBRNO LIKE(DICT.@@BRNO)
  10. D V_EQYNFG LIKE(DICT.@@YNFG)
  11. **定义无法参照的临时变量 
  12. D V_NUM 5P 0
  13. **********************************************************************


     先是D段定义了DICT,引入外部PF结构DICT,并且是QUALIFIED限定为以点访问字段,TEMPLATE指明只声明不分配空间,然后定义变量时就可以用LIKE了。


    数据字典除了定义了字段类型长度,还对枚举项列表进行了管理。比如数据字典例子中,@@YNFG就是一个枚举,1表示是,0表示否。在尾箱主表的EQYNFG碰平标志就是用了这个枚举。在程序中如果写0,1的话,既不便于阅读程序,也不方便枚举值的变化。因此,Firebird中根据DICT自动生成了ENUM这个枚举列表,这样RPG程序中就可以用YNFG_YES代表1,YNFG_NO代表0。摘录DSCPPGM/ENUM这个RPGLE源码部分如下。

  1. **BEGIN***************************************************************
  2. **程序名称:数据字典枚举值 *
  3. **功能描述:数据字典枚举值常量定义 *
  4. ** *
  5. **版本:2014-11-08_1 *
  6. ** *
  7. **设计人员:PACMAN 开发人员:AUTOGEN *
  8. **设计日期:2011-08-30 开发日期:2011-08-30 *
  9. ** *
  10. **END*****************************************************************
  11. **
  12. *是否标志:是YES
  13. D YNFG_YES C CONST('1')
  14. *是否标志:否NO
  15. D YNFG_NO C CONST('0')
  16. *
  17. *借贷标志:借方DEBIT
  18. D DCFG_DEBIT C CONST('1')
  19. *借贷标志:贷方CREDIT
  20. D DCFG_CREDT C CONST('2')
  21. *
  22. *记录状态:正常NORMAL
  23. D STCD_NORML C CONST('1')
  24. *记录状态:删除ABNORMAL
  25. D STCD_ABNML C CONST('2')
  26. *


    在RPG程序中,通过D/COPY DSCPPGM,ENUM 即可引入数据字典枚举常量。之后就可以 EVAL V_EQYNFG=YNFG_YES 这么写了。


阅读(3499) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~