前言
看来看去,网络上关于COBOL的资料实在是少得可怜。可是在现今的中国,对日软件开发已经越来越多,而COBOL语言的使用也变得开始多了起来,于是各种各样的问题也浮出水面。
我已经使用COBOL开发了三年,从中也发现汲取了许多经验和教训。希望可以帮助大家少走些弯路。
COBOL就是公用面向商用语言(Common Business-Oriented Language)。 在我看来,COBOL对于数据库的驾驭能力,是当今那些流行语言望尘莫及的。 语言简单、明了是COBOL最大的特点。 八股文的流程使任何一个人都能在短时间内掌握。 COBOL程序分为四个部(DIVISION): 1。标识部(IDENTIFICAION DIVISION) 2。环境部(ENVIRONMENT DIVISION) 3。数据部(DATA DIVISION) 4。过程部(PROCEDURE DIVISION) 其中,标识部主要定义了程序的ID(不可少)、程序员姓名、计算机设置场所、编写日期、编译日期、保密程度等。 环境部主要是定义机器的信息和输入文件、输出文件的路径。 数据部则是为程序中所要用到的变量、常量定义和赋值,当然也包括对外部调用、数据库调用的定义。 过程部是程序的重点,所有的算法都将在这里实现。 所以,COBOL的学习就是格式的学习,当你学会了COBOL的格式之后,你就可以发现COBOL是多么的好,VB、VC对数据库操作的代码是多么的浪费资源。 |
上面这段话是我多年前在网上找到的唯一的关于COBOL的中文介绍,作者精确地描述了COBOL的特性,一点也没有夸大的成分。我也使用VB和VC进行过数据库编程,别的语言不敢妄论,但至少COBOL对VB和VC是相当有优势的,那是一种从诞生开始就具有的先天优势。
记得当年进入公司面试的时候,考官问:“你对COBOL这种古老的语言有什么看法?”我回答:“就好像C++之于VC++一样。”任何一种语言能够生存发展到现在,都是有自身独特的优势的。
注意要点
#参考书:对于COBOL的语法,我相信是没有必要多说的了。这个现在只有两本书,一本是谭浩强的《COBOL语言》,另一本是《COBOL从入门到精通》。窃以为前者适合初学者,但基本上在平时使用的只到上半册,而后者可谓翻译得极烂,排版混乱,但是问题的解决之道往往就在其中。
#观念:不要觉得COBOL语言死板,不符合现代语言灵活多变的标准。要知道COBOL开发的系统往往是银行和证券系统,姑且不论运行效率,严谨的语法有助于提高数据运算的准确性。不灵活的语言特性,使之无法访问系统底层,却提高了最为重要的安全性。再来看运行效率,COBOL往往是运行在UNIX、LINUX或者大小型机上的,在这些机种上COBOL的运行效率比C要高。在对日软件开发中,时常就会遇到“只有在万不得已的情况下才使用C”的情况。
#现代的发展:和别的高级语言一样,COBOL也是在不停发展的,现在用的较多的是85和2000的标准,但由于厂商的关系,各个版本之间的COBOL并不完全兼容。与大多数人想象的不一样的是,COBOL也是有开发面向对象程序的能力的,如MicroFocus的NetExpress就是非常优秀的集成开发环境。更加重要的是,现在的COBOL已经加入了对Microsoft .NET Framework的支持。下面的代码看上去是不是很神奇呢?
|
|
</tr> </table> </font> </form> </body> </html> |
#变量定义:用过COBOL的人一定接触过COPY句,当然可能名字不那么叫。我认为COPY句尽可能不要嵌套,这样可以减少项目维护时的遗漏。COBOL是不区分大小写的,于是定变量时不仅要定为简洁易懂,更加要在一定程度上避免重名,不得已的情况下一定要用限定符。关于层号,个人认为以5或10为一个单位递进,诸如“01、05、10、15……”,这样的话即便发生追加变量的情况时也不至于伤筋动骨了。我也不推荐在不必要的情况下使用象“66、77、88”这样的特殊层号。
#活用Corresponding和Redefines:这其实是个尺度的问题。滥用Corresponding会导致毁灭性的错误,比如“把总经理的工资发给了门房的老大爷”。但Corresponding也的确可以为我们带来效率,把一万个变量赋值给另一万个同名变量,不用Corresponding也将是毁灭性的。要注意的是层号要相同。Redefines也能帮上大忙,一般来说和前台通信的9型变量往往往都应该Redefines一个X型,这样就可以判断空值了。又比方下面的例子。这是相当常用的一个办法,还可以用于分割9型的变量。
01 work-area. 05 work-client-info pic x(30). 05 work-client-info-r redefines work-client-info. 10 work-client-ip pic x(15). 10 work-tmp pic x(15). |
#数据库:这个是重点。其实我并不很擅长数据库的操作,但是只要是开发证券和银行的软件就必须和数据库打交道。COBOL相对于ORACLE的开发叫做PROCOBOL,这个是现今比较常用的组合。有了这样的宿主关系之后,COBOL对数据库的开发就变得非常简单和直观。
1. 首先,对于数据库操作的变量,一定要声明为HOST变量。
2. 要注意初始化。看起来像废话,其实在循环取得数据时,如果没有初始化HOST变量,则有可能把上次取得的结果保留下来。这绝不会是一件好事。
3. 要随时把提高SQL语句效率的观念放在首位,不要贪图简便而忽略效率。
4. 不要滥用CURSOR。更要注意的是不能打开了CURSOR却不关闭。
5. 没必要时,不要使用动态SQL,这可能会使你陷在寻找BUG的泥潭里。
下面看一点小小的例子:
exec sql select xxx1 into :h-xxxxxxx from tbl001 where xxx1 = ??? end-exec.
evaluate sqlcode when zero ????????? when other move sqlerrmc to ????? end-evaluate. |
data division. working-storage section. exec sql include sqlca end-exec. exec sql begin declare section end-exec. 01 ora-working-area. 05 h-xxxxxxx pic x(01). exec sql end declare section end-exec. |
01 ora-working-items. exec sql begin declare section end-exec. 01 h-sqlstmt pic x(4096) varying. exec sql end declare section end-exec. 01 wk-area. 05 wk-sqlstmt. 10 wk-sqlstmt-select pic x(100). 10 wk-sqlstmt-from pic x(100). 10 wk-sqlstmt-where. 20 wk-sqlstmt-where-1 pic x(50). 20 wk-sqlstmt-where-2 pic x(50). ………….. string wk-sqlstmt-select delimited by size wk-sqlstmt-from delimited by size wk-sqlstmt-where delimited by size into h-sqlstmt-arr. move 4096 to h-sqlstmt-len.
exec sql prepare s01 from :h-sqlstmt end-exec. |
exec sql declare cr01 cursor for s01 end-exec.
exec sql open cr01 end-exec.
perform until flg <> zero initialize h-tbl exec sql fetch cr01 into :h-xxxxx end-exec
evaluate sqlcode when zero ???????????? when 1403 ???????????? when other ???????????? end-evaluate end-perform.
exec sql close cr01 end-exec. |
#活用字符型变量:一般来说,在证券和银行系统中,主要做的还是数据处理,但是绝对不可以小看了字符型的变量,往往救命的就是它。我认为最为重要的是就是下面的这种形式。
01 work-area. 05 work-data pic 9(09)v9(09). 05 work-data-r redefines work-client-info. 10 work-high pic x(09). 10 work-low pic x(09). 05 work-middle pic 9(04)v(05). 05 work-middle-r redefines work-middle pic x(09). ..... move work-high(6:4) to work-middle-r(1:4). move work-low(1:5) to work-middle-r(5:5). |
当然其实这样的方法也可以对数字类型进行操作,但是我并不推荐那样的做法。还要注意的是要小心带有符号的数字型。
#数组:其实在COBOL中这个叫做表。首先要引起注意的是COBOL的数组是从1开始计数的,这一点和大多数别的语言不一样。另外还有个小技巧可以应用的数据库操作上,比方从一个数据库中取得的数据条数是固定不变而且很有限的话,可以将HOST变量定义为数组,可以避开定义CURSOR直接取得数据。但这个技巧不能滥用,数据量较多的话,还是不用为好。
#要使用END-XXX:我遇到很多错误都是这个家伙搞出来的。虽然书上说很多的END-XXX都是可省略的,但是建议还是都要一一加上,有时候少句话结果却是不一样的。
perform until rec-f-end = 1 read inr-dt-in at end move 1 to rec-f-end end-read ...... end-perform.
perform until rec-f-end = 1 read inr-dt-in at end move 1 to rec-f-end ...... end-perform. |
#良好的习惯:COBOL本身的语言规范十分严谨,但是也需要编写程序的人有严谨的作风和良好的习惯。格式的整洁和项目的成功完成是分不开的,更加有利于后期的维护。谁也不愿意去读天书,那么“己所不欲勿施于人”,就不要将这种如此接近自然语言的程序语言写成天书了吧。
结语
唠唠叨叨写了一点,其实COBOL入门并不难,只要抱有正确的态度和良好的作风就完全不会有问题。
原本我的水平也不怎么样,只是看看有机可趁,就出来秀一下罢了,希望真正有水平的高人不吝赐教,或分享一点经验,那就感激不尽了。