Vsam文件:
Vsam(virtual storage access method)文件是IBM在虚拟存储和树型数据结构基础上,为满足数据量大,存取速度快和维护起来方便而 发展起来的一种文件组织形式。VSAM以索引键(key)或相对字节地址(BRA)来安排纪录的存放位置,它支持直接访问和顺序访问两种方式。
VASM文件结构:
VASM文件结构: VSAM文件中的数据都以纪录的格式存放,逻辑纪录是访问数据的单位,VSAM文件将纪录存放一个个CI(Control Interval)中,一个CI是 DASD中一片连续的区域,用来存储数据纪录以及控制信息。当读取一个记录时,这个记录所在的CI将整个读到VSAM I/O缓冲区,然后用 户要读的纪录才从VSAM缓冲区传输到用户定义工作区。CI的大小在创建VSAM文件时由用户指定,也可以让系统自动选择合适的大小。 每个CI含有如下信息: 逻辑纪录:纪录用户数据,每个CI可以含有多个逻辑纪录 自由空间:每个CI可以有一定的自由空间,可以用来插入新的纪录 控制信息:主要是RDF和CIDF,RDF描述每一个记录的信息,而CIDF则描述整个CI的信息。
CICS支持以下三种VSAM文件:
KSDS(Key Sequenced Data Set) ESDS(Entry Sequenced Data Set) RRDS(Relative Record Data Set)
VSAM文件的定义:
VSAM数据集可以通过访问方法集(Access Method Services)的DEFINE CULSTER或ALLOCATE命令来定义,定义VSAM时要制定数据集的属性。 如果系统中使用了SMS来管理存储,定义的数据集又是系统管理的数据集,则可指定DATA CLASS,MANAGEMENT CLASS和STORAGE CLASS, 也可以使用系统默认的存储定义。 VSAM数据集的属性信息有: INDEXED | NONINDEXED | NUMBERED | LINEAR:指定数据集的形式分别是 KSDS | ESDS | RRDS | LDS
RECORDSIZE:指定纪录的平均和最大长度。
KEY: 指明纪录的平均和最大长度
CATALOG: 指明所用编目的名字和口令
VOLUMES: 指明所用得卷
REDORDS | KILOBYIES | MEGABYIES | TRACKS | CYLINDERS:以不同方式份分配空间的大小。
BUFFERSPACE: 指明处理数据集时应分配的最小缓冲区
CONTRLINTERVALSIZE: 指明CI的大小
SPANNED: 指明CI可否跨CI存放
IMBED: 指示是否把索引的顺序集放在相应的CA中
FREESPACE 指明预留自由空间大小
SHAREOPTION 指明文件在不同REGION之间共享级别
一个定义VSAM的JCL例子:
//DEFVSAM JOB NOTIFY=&SYSUID,MSGLEVEL=(1,1),MSGCLASS=X
//STEP1 EXEC PGM=IDCAMS,REGION=4M
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DELETE VSAM.NAME CLUSTER PURGE
DEFINE CL(NAME(VSAM.NAME) –
CYNINDERS(1 1) –
SHAREOPTIONS (2) –
RECORDSIZE(80 80) –
INDEXED –
KEYS(10 0)
另一个例子:
//DEFVSAM JOB NOTIFY=&SYSUID,MSGLEVEL=(1,1),MSGCLASS=X
//JS10 EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEFINE CLUSTER -
(NAME(STJI.MJA.VSAM.VE025) -
BUFFERSPACE(57344) -
INDEXED -
KEYS(4 0) -
MANAGEMENTCLASS(MCDBSRND) -
OWNER(VE025) -
RECORDSIZE(60 60) -
SHAREOPTIONS(2 3) -
SPEED -
STORAGECLASS(SCDBS )) -
DATA(NAME(STJI.MJA.VSAM.VE025.DATA) -
VOLUMES(STJ814) -
TRACKS(9 1) -
CONTROLINTERVALSIZE(4096)) –
INDEX(NAME(STJI.MJA.VSAM.VE025.INDEX) -
VOLUMES(STJ814) -
TRACKS(1 1) -
CONTROLINTERVALSIZE(2048))
/*
//
做好的VSAM文件要在CICS中使用,还必须在CICS中定义
CEDA DEF FILE(SAVING) DSNAME(VSAM.NAME) GROUP(TESTGP)
CEDA INS FILE(SAVING) GROUP(TESTGP)
一个文件不能同时在CICS中和CICS外同时打开,如果想用DITTO查看,必须先在CICS中把它关闭。如:
CEMT SET FILE(SAVING) CLOSE
再次在CICS中使用时要把它打开:
CEMT SET FILE(SAVING) OPEN
CICS中使用VSAM文件要预先定义并打开,给VSAM文件指定一个名字,程序使用此文件名字来引用。查询VSAM文件要使用纪录标志域(RIDFLD), 对不同类型VSAM文件RIDFLD由不同含义:
KSDS:RIDFLD是文件的键值,可以是完整的键值 ,也可以是键值的一部分 ESDS:RIDFLD是一个4字节的相对字节数(RBA),指明纪录文件开始的偏移 RRDS:RIDFLD是一个4字节的相对记录号(RRN)
CICS中使用READ命令来把符合要求的数据读入用户数据区中。 VSAM文件纪录查询READ命令 READ命令选项:
FILE(filename): 要查询的文件名字,文件要在CICS FCT里面要有定义 UNCOMMITTED : 允许读未COMMIT的纪录 CONSISTENT : 读一致性保证,在命令执行期间在纪录上加SHARE锁 REPEATABLE: 读一致性保证,在整个UOW期间在纪录上加SHARE锁 UPDATE: 通知CICS读取的记录将用于修改或者删除,用于保持数据的一致性INTO(data-name): 给出接收数据的工作区 SET(ptr-ref): 把指针(ptr-ref)指向读到的数据区 LENGTH(data-area): 半字长二进制数据,存放读取纪录长度。读去完成后,里面是实际读出的记录长度。 RIDFLD(data-area): 见上面描述 KEYLENGTH(data-value):半字长二进制变量,存放KEY长度 SYSUID(systemname):给定CICS REGION名字,指明文件在那个REGION上 RBA: 指明前面给出的RIDFLD是那个RBA RRN: 指明前面给出的RIDFLD是个RRD NOSUSPEND: 如果要查询的纪录正在被锁定,不等待,立即返回。
异常:
NOTFND: 指定键值的纪录没有找到 ENDFILE: 已到文件结尾,没有找到 INVREQ: 非法请求 FILENOTFOUND: 文件没有在CICS里面定义,FCT里面找不到 ILLOGIC: 其VSAM文件错误 IOERR: 文件I/O错误 DISABLED: 文件已被禁止使用 NOTOPEN: 文件已关闭
READ FILE(SBVSAM2) RIDFLD('CITI')
STATUS: ABOUT TO EXECUTE COMMAND NAME=
EXEC CICS READ
FILE( 'SBVSAM2 ' )
< SYSID() >
( SET() | INTO() )
< LENGTH() >
RIDFLD( 'CITI' )
< KEYLENGTH() < GENERIC > >
< RBA | RRN | DEBREC | DEBKEY >
< GTEQ | EQUAL >
< UNCOMMITTED | CONSISTENT | REPEATABLE | UPDATE < TOKEN() > >
< NOSUSPEND >
PF 1 HELP 2 HEX 3 END 4 EIB 5 VAR 6 USER 7 SBH 8 SFH 9 MSG 10 SB 11 SF
READ FILE(SBVSAM2) RIDFLD('CITI')
STATUS: COMMAND EXECUTION COMPLETE NAME=
EXEC CICS READ
FILE( 'SBVSAM2 ' )
< SYSID() >
( SET() | INTO( 'CITI AVENDBDMF39778172' ) )
< LENGTH( +00023 ) >
RIDFLD( 'CITI' )
< KEYLENGTH() < GENERIC > >
< RBA | RRN | DEBREC | DEBKEY >
< GTEQ | EQUAL >
< UNCOMMITTED | CONSISTENT | REPEATABLE | UPDATE < TOKEN() > >
< NOSUSPEND >
RESPONSE: NORMAL EIBRESP=+0000000000 EIBRESP2=+0000000000
PF 1 HELP 2 HEX 3 END 4 EIB 5 VAR 6 USER 7 SBH 8 SFH 9 MSG 10 SB 11 SF
@admin
VSAM文件纪录的浏览:
对VSAM文件可以从头开始,依次查询各条纪录,这要用到4条CICS命令:STARTBR, READNEXT, READPREV, ENDBR, 依次为开始浏览,读下 条纪录,读前条纪录和结束浏览命令。 这些命令使用的选项含义与READ命令大致相同,但增加了一条REQID,这个选项用来使程序能对一个文件同时发动多个查询,各个查询可 以有不同的当前位置。在STARTBR时,返回打开的浏览的REQID,在后面的命令中使用REQID指明进行那个浏览的操作。程序通过检查命令 的返回码来判断文件结束等情况。
STARTBR FILE('SBVSAM2') RIDFLD(&KEY)
STATUS: ABOUT TO EXECUTE COMMAND NAME=
EXEC CICS STARTBR
FILE( 'SBVSAM2 ' )
< SYSID() >
RIDFLD( 'CITI' )
< KEYLENGTH() < GENERIC > >
< REQID( +00000 ) >
< RBA | RRN | DEBREC | DEBKEY >
< GTEQ | EQUAL >
PF 1 HELP 2 HEX 3 END 4 EIB 5 VAR 6 USER 7 SBH 8 SFH 9 MSG 10 SB 11 SF
READNEXT FILE('SBVSAM2') RIDFLD(&KEY)
STATUS: ABOUT TO EXECUTE COMMAND NAME=
EXEC CICS READNEXT
FILE( 'SBVSAM2 ' )
< SYSID() >
( SET() | INTO() )
< LENGTH() >
RIDFLD( 'CITI' )
< KEYLENGTH() >
< REQID( +00000 ) >
< RBA | RRN >
< UNCOMMITTED | CONSISTENT | REPEATABLE | UPDATE TOKEN() >
< NOSUSPEND >
PF 1 HELP 2 HEX 3 END 4 EIB 5 VAR 6 USER 7 SBH 8 SFH 9 MSG 10 SB 11 SF
READNEXT FILE('SBVSAM2') RIDFLD(&KEY)
STATUS: COMMAND EXECUTION COMPLETE NAME=
EXEC CICS READNEXT
FILE( 'SBVSAM2 ' )
< SYSID() >
( SET() | INTO( 'ISSC BALAACCMF39778173' ) )
< LENGTH( +00023 ) >
RIDFLD( 'ISSC' )
< KEYLENGTH() >
< REQID( +00000 ) >
< RBA | RRN >
< UNCOMMITTED | CONSISTENT | REPEATABLE | UPDATE TOKEN() >
< NOSUSPEND >
RESPONSE: NORMAL EIBRESP=+0000000000 EIBRESP2=+0000000000
READNEXT FILE('SBVSAM2') RIDFLD(&KEY)
STATUS: COMMAND EXECUTION COMPLETE NAME=
EXEC CICS READNEXT
FILE( 'SBVSAM2 ' )
< SYSID() >
( SET() | INTO( '' ) )
< LENGTH( +00000 ) >
RIDFLD( 'ISSC' )
< KEYLENGTH() >
< REQID( +00000 ) >
< RBA | RRN >
< UNCOMMITTED | CONSISTENT | REPEATABLE | UPDATE TOKEN() >
< NOSUSPEND >
RESPONSE: ENDFILE EIBRESP=+0000000020 EIBRESP2=+0000000090
PF 1 HELP 2 HEX 3 END 4 EIB 5 VAR 6 USER 7 SBH 8 SFH 9 MSG 10 SB 11 SF
READPREV FILE('SBVSAM2') RIDFLD(&KEY)
STATUS: ABOUT TO EXECUTE COMMAND NAME=
EXEC CICS READPREV
FILE( 'SBVSAM2 ' )
< SYSID() >
( SET() | INTO() )
< LENGTH() >
RIDFLD( 'ISSC' )
< KEYLENGTH() >
< REQID( +00000 ) >
< RBA | RRN >
< UNCOMMITTED | CONSISTENT | REPEATABLE | UPDATE TOKEN() >
< NOSUSPEND >
PF 1 HELP 2 HEX 3 END 4 EIB 5 VAR 6 USER 7 SBH 8 SFH 9 MSG 10 SB 11 SF
READPREV FILE('SBVSAM2') RIDFLD(&KEY)
STATUS: COMMAND EXECUTION COMPLETE NAME=
EXEC CICS READPREV
FILE( 'SBVSAM2 ' )
< SYSID() >
( SET() | INTO( 'ISSC BALAACCMF39778173' ) )
< LENGTH( +00023 ) >
RIDFLD( 'ISSC' )
< KEYLENGTH() >
< REQID( +00000 ) >
< RBA | RRN >
< UNCOMMITTED | CONSISTENT | REPEATABLE | UPDATE TOKEN() >
< NOSUSPEND >
RESPONSE: NORMAL EIBRESP=+0000000000 EIBRESP2=+0000000000
PF 1 HELP 2 HEX 3 END 4 EIB 5 VAR 6 USER 7 SBH 8 SFH 9 MSG 10 SB 11 SF
VSAM文件纪录更新:
CICS使用REWRITE命令来更改数据,REWRITE命令一定要跟在一个READ UPDATE命令之后,而且KSDS的KEY是不能改变的。REWRITE命令 的选项前面都介绍过了,它的异常情况也与READ大致相同,但多了以下几项: LENGERR:写入纪录的长度没有指定或太长 NOSPACE: 文件空间不足,可能的原因是文件中变长纪录长度增加了 INVREQ: 多由以下原因造成:在REWITE一个记录前,没有运行过READ UPDATE命令 ILLOGIC: 其他VSAM文件操作错误。这种情况下可以通过检测EIBRCODE字段来判断错误种类:在EIBRCODE中,第二个字节为VSAM 错误码。具体代码可以到VSAM代码手册中查询。
READ FILE('SBVSAM2') RIDFLD('ISSC') UPDATE
STATUS: ABOUT TO EXECUTE COMMAND NAME=
EXEC CICS READ
FILE( 'SBVSAM2 ' )
< SYSID() >
( SET() | INTO() )
< LENGTH() >
RIDFLD( 'ISSC' )
< KEYLENGTH() < GENERIC > >
< RBA | RRN | DEBREC | DEBKEY >
< GTEQ | EQUAL >
< UNCOMMITTED | CONSISTENT | REPEATABLE | UPDATE < TOKEN() > >
< NOSUSPEND >
PF 1 HELP 2 HEX 3 END 4 EIB 5 VAR 6 USER 7 SBH 8 SFH 9 MSG 10 SB 11 SF
REWRITE FILE('SBVSAM2') FROM('ISSC BALAACCMF39778173')
STATUS: ABOUT TO EXECUTE COMMAND NAME=
EXEC CICS REWRITE
FILE( 'SBVSAM2 ' )
< SYSID() >
FROM( 'ISSC BALAACCMF39778173' )
< LENGTH( +00023 ) >
< TOKEN() >
< NOSUSPEND >
PF 1 HELP 2 HEX 3 END 4 EIB 5 VAR 6 USER 7 SBH 8 SFH 9 MSG 10 SB 11 SF
REWRITE FILE('SBVSAM2') FROM('ISSC BALAACCMF39778173')
STATUS: COMMAND EXECUTION COMPLETE NAME=
EXEC CICS REWRITE
FILE( 'SBVSAM2 ' )
< SYSID() >
FROM( 'ISSC BALAACCMF39778173' )
< LENGTH( +00023 ) >
< TOKEN() >
< NOSUSPEND >
RESPONSE: NORMAL EIBRESP=+0000000000 EIBRESP2=+0000000000
PF 1 HELP 2 HEX 3 END 4 EIB 5 VAR 6 USER 7 SBH 8 SFH 9 MSG 10 SB 11 SF
ENDBR FILE('SBVSAM2')
STATUS: COMMAND EXECUTION COMPLETE NAME=
EXEC CICS ENDBR
FILE( 'SBVSAM2 ' )
< SYSID() >
< REQID( +00000 ) >
RESPONSE: NORMAL EIBRESP=+0000000000 EIBRESP2=+0000000000
PF 1 HELP 2 HEX 3 END 4 EIB 5 VAR 6 USER 7 SBH 8 SFH 9 MSG 10 SB 11 SF
添加VSAM文件纪录:
CICS使用WRITE命令来向VSAM文件写入纪录。命令选项含义与前面的介绍相同。当我们需要按键值的升序排列插入多个纪录时,须使用 MASSINSERT选项,每个WRITE命令都要包含这个选项,要终止MASSINSERT,可通过UNLOCK命令来实现。
WRITE FILE('SBVSAM2') FROM( 'ISSC BALADBDMF39778173' ) RIDFLD('ISSC')
STATUS: ABOUT TO EXECUTE COMMAND NAME=
EXEC CICS WRITE FILE( 'SBVSAM2 ' )
< SYSID() >
FROM( 'ISSC BALADBDMF39778173' )
< LENGTH( +00023 ) >
RIDFLD( 'ISSC' )
< KEYLENGTH() >
< RBA | RRN >
< MASSINSERT >
< NOSUSPEND >
PF 1 HELP 2 HEX 3 END 4 EIB 5 VAR 6 USER 7 SBH 8 SFH 9 MSG 10 SB 11 SF
WRITE FILE('SBVSAM2') FROM( 'ISSC BALADBDMF39778173' ) RIDFLD('ISSC')
STATUS: COMMAND EXECUTION COMPLETE NAME=
EXEC CICS WRITE FILE( 'SBVSAM2 ' )
< SYSID() >
FROM( 'ISSC BALADBDMF39778173' )
< LENGTH( +00023 ) >
RIDFLD( 'ISSC' )
< KEYLENGTH() >
< RBA | RRN >
< MASSINSERT >
< NOSUSPEND >
RESPONSE: NORMAL EIBRESP=+0000000000 EIBRESP2=+0000000000
PF 1 HELP 2 HEX 3 END 4 EIB 5 VAR 6 USER 7 SBH 8 SFH 9 MSG 10 SB 11 SF
删除VSAM文件纪录:
CICS使用DELETE命令来删除VSAM文件的纪录。只有KSDS和RRDS结构的VSAM文件中的纪录能被删除,这与数据的存放格式有关。ESDS文件 的纪录按进入的顺序排放,只能在文件尾增加纪录,不能删除,而且更新时不能改变长度。如果该记录在请求删除前正在被更新,那么 参数RIDFLD可以不指定,默认为当前记录。如果使用GENERIC参数,必须给定KELENGTH参数,指出KEY长度,同时NUMREC指出要删除的记 录长度,这样就可以一次删除若干条记录。
DELETE FILE('SBVSAM2') RIDFLD('ISSC')
STATUS: ABOUT TO EXECUTE COMMAND NAME=
EXEC CICS DELETE FILE( 'SBVSAM2 ' )
< SYSID() >
< TOKEN() | RIDFLD( 'ISSC' ) < KEYLENGTH() < GENERIC < NUMREC() > > > >
< RBA | RRN >
< NOSUSPEND >
PF 1 HELP 2 HEX 3 END 4 EIB 5 VAR 6 USER 7 SBH 8 SFH 9 MSG 10 SB 11 SF
DELETE FILE('SBVSAM2') RIDFLD('ISSC')
STATUS: COMMAND EXECUTION COMPLETE NAME=
EXEC CICS DELETE FILE( 'SBVSAM2 ' )
< SYSID() >
< TOKEN() | RIDFLD( 'ISSC' ) < KEYLENGTH() < GENERIC < NUMREC() > > > >
< RBA | RRN >
< NOSUSPEND >
RESPONSE: NORMAL EIBRESP=+0000000000 EIBRESP2=+0000000000
PF 1 HELP 2 HEX 3 END 4 EIB 5 VAR 6 USER 7 SBH 8 SFH 9 MSG 10 SB 11 SF