点击这里下载 - 同济大学软件学院

Download Report

Transcript 点击这里下载 - 同济大学软件学院

大型主机应用上的开放系统和中间件
2011年度教育部-IBM精品课程
同济大学软件学院
唐剑锋
[email protected]
第6章 COBOL+CICS+VSAM和COBOL+CICS+DB2程序开发
6.1 COBOL+CICS程序编写规范



本章总结了一些COBOL内嵌CICS语言,也是我们编写Online程序的一些
规范。
1. 程序开头说明:
***************************************************
*
TONGJI MAINFRAME TESTING
*
*
EMPLOYEE EXERCISE
*
*
USAGE : BROWSE RECORDS IN EMPLOYEE FILE
*
*
FILE USAGE : EMPLOYEE
*
*
BMS USAGE : EMPMBR
*
***************************************************
首先我们必须在程序的起始部分注明一些必要的信息,要有程序所属
的项目名、程序的解释、程序的用途、程序的使用说明(如果有的
话)、程序所需要的文件(一般是VSAM文件)或数据库、程序所使用
的BMS Map名。



2. 前两个DIVISIONS
IDENTIFICATION DIVISION.
PROGRAM-ID.
EMPOBR.
ENVIRONMENT DIVISION.
IDENTIFICATION DIVISION中至少要申明PROGRAM-ID,它必须与我们这
个程序的文件名是一致的。ENVIRONMENT DIVISION一般来说我们是不
用指定的,因为所有的环境都是由CICS帮我们设定好的,不需要我们
来定义。
3. DATA DIVISION部分
DATA DIVISION中主要包含三个部分:
(1)WORKING-STORAGE SECTION
在WORKING-STORAGE SECTION中设定所有要使用的变量。我们约定在所
有的变量名之前都加上“WS-”(WS是WORKING-STORAGE的首字母)。在第
一层我们建议写“01 WS-VARIABLE”,以后各层以05开始,每层加5。
这样我们可以留出一定的层数以备不时之需,同时也使层次显得更为
清晰。

WS中的前面部分,建议使用如下写法:
05 WS-INFO.
10 WS-TSQ-NAME.
15 WS-APPLID
PIC
15 WS-TRANID
PIC
15 WS-PROGSUF
PIC
15 WS-SEQ
PIC
15 WS-TERMID
PIC
10 DSTX-ID
PIC
88 DSTX-ID-VALID
10 WS-TSQ-CONTENT.
15 WS-TSQ-LEVEL
PIC
15 WS-TSQ-TRANID
PIC
10 WS-TSQ-CURR-ITEM
PIC
10 WS-LEVEL
PIC
X(2) VALUE 'TJ'.
X(4) VALUE 'FX01'.
X(3) VALUE '001'.
X(3) VALUE '001'.
X(4) VALUE SPACES.
X(4) VALUE 'FX01'.
VALUE 'FX01'.
9(4).
X(4) VALUE SPACES.
S9(4) COMP.
9(4) VALUE 0.





TSQ-NAME分为项目名(APPLID)、交易名(TRANID)、程序后缀
(PROGSUF)、序列号(SEQ)、终端号(TERMID)。这样可以确保程
序所使用的TSQ是唯一的,不会与其他人冲突。
DSTX-ID标示了该程序的TRANSID,用于比较TSQ中的TRANSID,抽出来
便于修改。
WS-TSQ-CONTENT表示了TSQ中所要保存的内容,在里面至少应包括两个
部分:WS-TSQ-LEVEL和WS-TSQ-TRANID。前者表示我们希望下次任务所
处的层数或上次任务希望这次所在的层数。然后,希望在TSQ中存什么
信息就加在该层后面,比如想要保存的Map中域的值。
WS-TSQ-CURR-ITEM在TSQ中要用到,一般都会设定其为1。
WS-LEVEL指定现在这个任务所处的层。
(2)COPY 部分
COPY EMPMBR.
COPY EMPLOYEE
REPLACING ==EMPLOYEE:== BY
==EMPLOYEE-==.

可以使用COPY命令将需要的其他文件中的COPYBOOK给拷贝过来。
一般来说,如果是BMS Map的COPYBOOK,则直接拷贝进来即可。
如果是VSAM文件的定义,拷贝进来之后,一般都要用REPLACING
来将原本“:”改为“-”。这是一种规范,在我们写VSAM文件
的定义时,一般要在变量名之前加上文件名和“:”,这样便
于将文件前缀与变量名区别开来。
(3)LINKAGE SECTION
01 DFHCOMMAREA
PIC X(200).
 如果这个程序是要被调用的,那么在LINKAGE SECTION中是必须指定的。
这与LINK或XCTL中COMMAREA的参数相关。如果这个程序不需要被调用,
则不需指定。




4. PROCEDURE DIVISION部分
首先要先明确一些层的作用和规范。
我们约定000-MAIN作为程序的开始段,Z000-RETURN作为程序的结束段。
除了000-MAIN 和 Z000-RETURN之外,其他的代码段都要有一个对应的
EXIT。
例如:A100-GETLV.
……
A100-EXIT. EXIT.
特别提示:程序是看XXXX-EXIT来结束这个代码段的。A100-GETLV是一
个标签(所有从A区开始的,我们叫做标签LABEL),程序会从一个标
签执行到另一个标签。虽然我们可以不写A100-EXIT而仅靠下一个标签
结束,但是为了程序的规范性,建议以A100-EXIT来与A100-GETLV对应,
同时加上EXIT作为A100-EXIT的DUMMY语句,这样可以把A100-EXIT这个
标签与下一个标签区分开来(如果不写EXIT,程序会报错)。





000-MAIN. 所有程序的开始。
第一句必须是EXEC CICS HANDLE ABEND LABEL(Z000-RETURN) ENDEXEC.
这将接受后面所有产生的无其他异常处理的错误。此后应尽量避免使
用 HANDLE 语句进行出错处理,而是根据可能出现的错误情况分别处
理,例如使用DFHRESP判断CICS语句执行的错误。
然后进行程序变量的初始化:PERFORM 010-PROG-INIT THRU 010-EXIT.
得到该次的层数:PERFORM A100-GETLV THRU A100-EXIT.
得到LEVEL之后我们就可以通过不同层次来处理具体的操作:
IF WS-LEVEL = 0
……
ELSE IF WS-LEVEL = 1
……
ELSE PERFORM Z000-RETURN
END-IF.





010-PROG-INIT.
MOVE EIBTRMID TO WS-TERMID.
初始化TSQ-NAME,补充完整TSQ-NAME,正是这句能保证每个TSQ的唯一
性。
PERFORM B101-INIT-MAP THRU B101-EXIT.
初始化Map,能够保证Map的初始值是正确的。
PERFORM B102-INIT-ATTR THRU B102-EXIT.
初始化Map域的属性,能够保证Map的域的属性是正确的。
A层用于最基本的TSQ的处理代码段。
A100-GETLV.
从READQ开始, 从TSQ中得到WS-TSQ-LEVEL的信息,然后通过MOVE语句
送给WS-LEVEL,从而得到当前层的信息.


A200-SETLV.
设置LEVEL。在伪对话程序中,为了在程序两次执行中保留必要的状态
等数据信息,需要将WS-TSQ-CONTENT中的内容,包括WS-TSQ-LEVEL和
WS-TSQ-TRANID写入TSQ,使用WRITEQ或者加REWRITE选项(这将根据所
处的层数或一些特殊的条件来决定)。第一次必须是WRITEQ,以后都
将加REWRITE属性。
A300-CLEARQ.
清除TSQ。一般都是在程序都结束之前使用,使用DELETEQ。同时建议
在DELETEQ之前先将Map的所有域清空一下,用PERFORM B101-INIT-MAP
THRU B101-EXIT将该内存空间初始化。





B层用于MAP的处理代码段。
B100-SEND-MAP.
用于SEND MAP的代码段。由于SEND MAP就表示这次任务结束了,所以,
建议在SEND MAP之前使用SETLV,也就是做WRITEQ的工作。
B101-INIT-MAP.
一般一张MAP都要配备两个代码段,分别是初始化Map和初始化Map域的
属性。B101-INIT-MAP代码段用于将所有字符型的域赋值SPACES,数字
型的域赋值0。
B102-INIT-ATTR.
该代码段将所有域的属性清空,将所有的域名以A结尾的变量都赋值为
LOW-VALUE,这样可以保证每次得到的Map域的属性都是正确的。
B200-RECEIVE-MAP.
用于RECEIVE MAP 的代码段。在RECEIVE MAP之前,一般会有如下代码:
EXEC CICS HANDLE AID CLEAR (Z000-RETURN)
PF3
(Z000-RETURN)
ENTER (C100-BROWSE)
ANYKEY (C100-BROWSE)
END-EXEC.


一般来讲按F3键表示退出(有些是回到上一张MAP,有些是直接回到
CICS),其他功能键都建议使用习惯用法。
建议上述代码中包含ANYKEY,表示在键盘上按下除了清屏键、F3键和
回车键以外的其他键所执行的动作,否则如果使用没有设定过的键就
会退出任务,这往往不是我们所希望的。




如果程序中有不止一张的MAP,分别需要处理程序段,其命名规则一般
遵循以下原则:
B1@0-SEND-MAP
B1@1-INIT-MAP
B1@2-INIT-ATTR
B2@0-RECEIVE-MAP
其中@表示从1到9的数字或者从A到Z的字母,表示是第几张MAP(9之后
为A,本命名规则最多可以包含35张MAP)。
比如,第一张MAP的一些代码段就是:
B110-SEND-MAP.
B111-INIT-MAP.
B112-INIT-ATTR.
B210-RECEIVE-MAP.
即B层的后3位分别表示:第一个,1为SEND,2为RECEIVE;第二个,表
示为第几张MAP;第三个0表示SEND或RECEIVE,1以后的表示辅助的代
码段,如SEND的1为INIT-MAP,2为INIT-ATTR。



C层用于具体的代码段的处理。包括没有VSAM和DB2参与的COBOL+CICS
的代码段的处理,有VSAM参与的COBOL+CICS+VSAM的代码段的处理,有
DB2参与的COBOL+CICS+DB2的代码段的处理。
对于COBOL+CICS+VSAM的例子来说,读取VSAM数据及后续处理的核心样
例代码如下:
MOVE MYNAMEI(1:6) TO WS-STDNUM
EXEC CICS READ FILE('K211T01')
RIDFLD(WS-STDNUM)
INTO(C0S11T01-REC)
RESP(WS-FILE-RESP)
END-EXEC
IF WS-FILE-RESP = DFHRESP(NORMAL)
MOVE C0S11T01-NAME TO MYMSGO
ELSE
MOVE 'RECORD NOT FOUND' TO MYMSGO
END-IF
该代码片断实现的功能是:用EXEC CICS READ FILE命令,按VSAM的关
键字WS-STDNUM查询出非关键字C0S11T01-NAME的值,并将其传送给
COPYBOOK中的输出变量MYMSGO,以便通过SEND MAP送出到屏幕显示给
用户。


对于COBOL+CICS+DB2的例子来说,读取DB2数据及后续处理的核心样例
代码如下:
MOVE MKEYI(1:6) TO BOOKNO
EXEC SQL SELECT BOOKNAME
INTO
:BOOKNAME
FROM
TJD0211.TT01C01
WHERE BOOKNO = :BOOKNO
END-EXEC
IF SQLCODE = 0
MOVE BOOKNAME TO MCONTENO
ELSE
MOVE '**FETCH ERROR**' TO MCONTENO
END-IF
该代码片断实现的功能跟上面 COBOL+CICS+VSAM的例子的功能差不多:
用EXEC SQL SELECT语句,按DB2的主键BOOKNO查询出非主键BOOKNAME
的值,并将其传送给COPYBOOK中的输出变量MCONTENO,以便通过SEND
MAP送出到屏幕显示给用户。



Z000-RETURN.
表示所有程序的结束,样例代码如下:
MOVE 0
TO WS-TSQ-LEVEL.
MOVE SPACES TO WS-TSQ-TRANID.
PERFORM A300-CLEARQ
THRU A300-EXIT.
EXEC CICS
SEND CONTROL ERASE END-EXEC
EXEC CICS
RETURN END-EXEC
GOBACK.
EXIT.
这个是比较定式,当然也可以根据需要来自行的加一些动作。
5. 其他
除了以上的部分外,还要注意一点:在所有代码段的第一层,必须加
“.”,在第一层以下的都不要加,否则会导致程序逻辑出错,或语法
错误。
6.2 COBOL+CICS样例程序开发


本节在6.1节的基础上,论述COBOL+CICS样例程序的开发过程。
COBOL+CICS样例程序的MAP源代码如下面三页所示:

COBOL+CICS样例程序的COPY BOOK如下面两页所示:

注意COBOL+CICS样例程序的MAP源代码和COPY BOOK不需要用户手工编
写,而是由主机端的SDFII工具自动生成。因生成过程比较繁杂,在此
略。有兴趣的同学可参考相关文档。

编译、链接上述COBOL+CICS样例程序的MAP源代码的JCL如下:

上述JCL要调用到的过程DFHASMV1代码如下:

上述JCL要调用到的过程DFHLNKV1代码如下:

提交上述JCL并成功(MAXCC<=4)后,便在STRB.CICS.LOAD中生成一个
MAPSET M211T01。
自此,COBOL+CICS样例程序的CICS MAP代码生成并执行完毕。


COBOL+CICS程序样例源代码如下面八页所示,其中程序的基本逻辑在
6.1 程序编写规范已经基本论述完毕。

CICS翻译、COBOL编译、链接上面的COBOL+CICS源程序的JCL如下面三
页所示:


提交上述JCL并成功(MAXCC<=4)后,便在STRB.CICS.LOAD中生成一个
PROGRAM C0O11T1。
自此,COBOL+CICS样例程序的源代码编写并执行完毕。






下面在CICS Region里创建各个资源,这些资源包括MAPSET,
PROGRAM和TRANSACTION。
在CICS Region里输入如下命令创建MAPSET:
CEDA DEF MAPSET(M211T01) G(TJD0211)
在CICS Region里输入如下命令创建PROGRAM:
CEDA DEF PROG(C0O11T1) G(TJD0211)
在CICS Region里输入如下命令创建TRANSACTION:
CEDA DEF TRANSACTION(A211) PROG(C0O11T1) G(TJD0211)
在CICS Region里输入如下命令安装定义的上述资源:
CEDA INS G(TJD0211)
自此,COBOL+CICS样例程序的CICS资源都已经定义并安装完毕。

下面执行刚刚创建并安装好的交易。在CICS Region里输入A211,回车,
如果一切正常,将出现如下屏幕:

在ENTER YOUR ID HERE:处随意输入一个用户名,如TANGJF,按回车,
MESSAGE:处将显示:HELLO,TANGJF!。
6.3 COBOL+CICS+VSAM样例程序开发


本节在6.1节的基础上,论述COBOL+CICS+VSAM样例程序的开发过程。
创建本节中用到的VSAM数据集的JCL如下:



VSAM数据集定义好以后,下一步是向VSAM数据集
TJD0211.L11.C0K11T01中插入样本数据,我们用DITTO工具来完成这一
工作。方法如下:
在ISPF主菜单中输入M.7,进入DITTO 界面。按如下界面输入信息:
按回车后得到如下界面,在Data set name处输入要插入数据的VSAM数
据集的名字,用单引号括起来,如下所示:

按回车后,出现空的VSAM数据集,向VSAM数据集插入如下内容
(操作同在普通PDS数据集的Member或PS数据集中插入数据的方
法相同,此处略):

自此,本节中要用到的VSAM数据集创建完毕并插入数据。



COBOL+CICS+VSAM样例程序的MAP源代码和COPY BOOK与COBOL+CICS样例
程序的MAP源代码和COPY BOOK几乎相同,限于篇幅,此处略去。相应
的编译、链接上述COBOL+CICS+VSAM样例程序的MAP源代码的JCL也略去。
提交上述JCL并成功(MAXCC<=4)后,便在STRB.CICS.LOAD中生成一个
MAPSET M211T02。
自此,COBOL+CICS+VSAM样例程序的CICS MAP生成并执行完毕。

在编写COBOL+CICS+VSAM样例程序源代码之前,应该首先编写好VSAM数
据集的COPY BOOK,如下所示:

然后开始编写COBOL+CICS+VSAM样例程序的源代码。COBOL+CICS+VSAM
与COBOL+CICS源程序的主逻辑非常相似,受篇幅限制,此处只介绍加
入VSAM的处理逻辑后与COBOL+CICS的程序不同之处的代码。
(1)首先在程序一开始的注释中加入如下代码:

上述注释表示应用程序中将用到VSAM文件C0K11T01,并且VSAM对应的
COPYBOOK是C0S11T01。
(2)在第二个01 WS-VARIABLE.中加入如下代码:

上述WS-STDNUM作为VSAM的Key送入READ FILE命令的RIDFLD,当CICS反
馈信息为正常时,将得到VSAM的其他Non Key的数据。
(3)在引入COPYBOOK的代码COPY C0M11T2. 后面加入如下代码:

上述COPY语句在上文6.1中的(2)COPY 部分已经解释完毕,故此处略。
(4)在A300-PROCESS程序段书写如下代码:
该代码片断实现的功能
在上文6.1中的
4.PROCEDURE DIVISION
部分已经解释完毕,故
此处略。



CICS翻译、COBOL编译、链接上面的COBOL+CICS+VSAM源程序的JCL与
CICS翻译、COBOL编译、链接上面的COBOL+CICS源程序的JCL非常类似,
只需要将所有含C0O11T1的地方(共计两处)替换成C0O11T2,提交即可,
故在此省略JCL代码。
提交上述JCL并成功(MAXCC<=4)后,便在STRB.CICS.LOAD中生成一个
PROGRAM C0O11T2。
自此,COBOL+CICS+VSAM样例程序的源代码编写并执行完毕。



下面在CICS Region里创建各个资源,这些资源包括FILE,MAPSET,
PROGRAM和TRANSACTION。
在CICS Region里输入如下命令创建VSAM FILE的定义:
CEDA DEF FILE(K211T01) G(TJD0211)
运行以上命令后,还需要进到K211T01中进行如下设置(部分)。其中粗
体项表示必填参数。

如果VSAM数据集没有打开,还需要在CICS Region里运行如下命令将
K211T01打开:
CEMT I FILE(K211T01)
结果如下:

将Clo替换成Ope,回车,将VSAM数据集K211T01打开。

在CICS Region里输入如下命令创建MAPSET:
CEDA DEF MAPSET(M211T02) G(TJD0211)
在CICS Region里输入如下命令创建PROGRAM:
CEDA DEF PROG(C0O11T2) G(TJD0211)
在CICS Region里输入如下命令创建TRANSACTION:
CEDA DEF TRANSACTION(B211) PROG(C0O11T2) G(TJD0211)
在CICS Region里输入如下命令安装定义的上述资源:
CEDA INS G(TJD0211)
自此,COBOL+CICS+VSAM样例程序的CICS资源都已经定义并安装完毕。






下面执行刚刚创建并安装好的交易。在CICS Region里输入B211,回车,
如果一切正常,将出现如下屏幕:

在ENTER YOUR ID HERE:处输入VSAM数据集中具有的一个KEY值。如
000001,按回车,MESSAGE:处将显示:HELLO,
VSAMDATA1
!其中VSAMDATA1是KEY 000001对应
的NON KEY的值。
6.4 COBOL+CICS+DB2样例程序开发


本节在6.1节的基础上,论述COBOL+CICS+DB2样例程序的开发过程。
在编写COBOL+CICS+DB2样例程序的源代码之前,必须在DB2中创建相应
的数据库、表空间和表并插入样本数据。方法是:在ISPF菜单中输入
以下SQL命令或语句创建样例程序中需要的表和数据(假设用户
TJD0211具有SYSADM的权限):

表创建好并插入数据后,可以生成表TJD0211.TT01C01对应的数据结构,
该数据结构在后续COBOL+CICS+DB2样例程序的源代码中将用到。生成
方法是:在ISPF主菜单中输入:M.11.2,按回车,然后在如下界面输
入相应的项,其中粗体为必填项:

这样表TJD0211.TT01C01对应的数据结构就存入
TJD0211.CICS.INCLUDE(TT01C01)中,如下所示:

自此,COBOL+CICS+DB2样例程序中要用到的DB2表创建完毕并生成了对
应数据结构。

COBOL+CICS+DB2样例程序的MAP源代码如下面两页所示:

COBOL+CICS+DB2样例程序的COPY BOOK如下面两页所示:



编译、链接上述COBOL+CICS+DB2样例程序的MAP源代码的JCL同编译、
链接COBOL+CICS样例程序的MAP源代码的JCL基本相同,故此处略。
提交上述JCL并成功(MAXCC<=4)后,便在STRB.CICS.LOAD中生成一个
MAPSET M211T03。
自此,COBOL+CICS+DB2样例程序的CICS MAP生成并执行完毕。

COBOL+CICS+DB2与COBOL+CICS程序的主逻辑非常相似,受篇幅
限制,此处只介绍加入DB2的处理逻辑后与COBOL+CICS的程序不
同之处的代码。
(1)首先在程序一开始的注释中加入如下代码:

上述注释表示应用程序中将用到数据库表TT01C01,且是关于书籍信息
的表。
(2)在引入COPYBOOK的代码COPY C0M11T2.后面加入如下代码:

上述代码第一行表示将含有关键的SQLCODE变量的SQLCA结构加入到代
码中来,下面的代码将用到SQLCODE这个代表SQL是否运行成功的变量。
第二行表示将TT01C01这个含有数据库表中各个列对应的各个变量定义
的PDS成员加入到代码中来,下面的代码用到表中列对应的各个变量时
将不需要再定义。

(3)在A300-PROCESS程序段书写如下代码:

该代码片断实现的功能在上文6.1中的4. PROCEDURE DIVISION部分已
经解释完毕,故此处略。

DB2预编译、CICS翻译、COBOL编译、链接上面的COBOL+CICS+DB2源程
序的JCL如下面五页所示:


提交上述JCL并成功(MAXCC<=4)后,便在STRB.CICS.LOAD中生成一个
PROGRAM C0O11T3。
自此,COBOL+CICS+DB2样例程序的源代码编写并执行完毕。







下面在CICS Region里创建各个资源,这些资源包括MAPSET,PROGRAM,
TRANSACTION,DB2CONNECTION和DB2ENTRY。
在CICS Region里输入如下命令创建MAPSET:
CEDA DEF MAPSET(M211T03) G(TJD0211)
在CICS Region里输入如下命令创建PROGRAM:
CEDA DEF PROG(C0O11T3) G(TJD0211)
在CICS Region里输入如下命令创建TRANSACTION:
CEDA DEF TRANSACTION(C211) PROG(C0O11T3) G(TJD0211)
在CICS Region里输入如下命令创建DB2CONNECTION:
CEDA DEF DB2CONN(DB8G) DB2ID(DB8G) G(TJD0211)
在CICS Region里输入如下命令创建DB2ENTRY:
CEDA DEF DB2ENTRY(E211T01) TRANSID(C211) PLAN(P211T03)
G(TJD0211)
在CICS Region里输入如下命令安装定义的上述资源:
CEDA INS G(TJD0211)


注:DB2CONNECTION表示CICS和DB2的连接,且是DB2子系统独占的,即
DB2CONNECTION中指定的DB2ID(DB8G)表示将使用子系统DB8G,如果之
前CICS和DB2的连接采用另一个子系统DB7G,那么在采用DB8G之前,必
须在CICS Region中:
(1)运行如下命令将CICS和DB2的连接断开:
DSNC STOP
(2)安装DB2CONNECTION(步骤略)
(3)运行如下命令将CICS和DB2重新连接起来,此时将采用子系统
DB8G:
DSNC STRT
(4)可以运行如下命令查看CICS和DB2的连接细节:
DSNC DISP STAT
自此,COBOL+CICS+DB2样例程序的CICS资源都已经定义并安装完毕。

下面执行刚刚创建并安装好的交易。在CICS Region里输入C211,回车,
如果一切正常,将出现如下屏幕:

在ENTER KEY处输入DB2表中的KEY值,如00001,按回车,CONTENT处将
显示DB2表中KEY值00001对应的NON KEY值BOOK1。