Factory 1 Operation Factory 2 Result HI LO EQ
READ(N) 文件记录格式名 45 46
这样读文件,就不会锁记录,但是同时也不能修改记录。如果需要修改记录,那么在修改之前(包括对文件字段赋值之前),还必须再对该记录进行一次定位操作(比如CHAIN、READ语句均可)。也就是说,如果要修改记录,必须先锁住当前记录(很合理吧)
3. 当执行READ操作时,程序是根据游标当前在文件中所指向的位置,顺序读取下
一条记录。关于游标是如何指向,还不是一个很简单的问题,所以将会在下一章“数据库相关知识”中具体讲解。
4. 执行READ操作时,允许声明的文件没有键值。(即PF文件) READC {(E)} (Read Next Changed Record) 没用过,读下一次修改过的记录?
READE {(N | E)} (Read Equal Key) 读取键值相等的记录 语法与READ操作码大致一样,这里不再重复,只说不同的: 假设程序中已声明逻辑文件PFFHSL3(键值为FHS01+FHS02)
Factory 1 Operation Factory 2 Result HI LO EQ FHSKEY KLIST KFLD FLD01 KFLD FLD02 FHSKEY SETLL FMTFHS DOW 1=1 FHSKEY READE FMTFHS 15 IF *IN15=’1’ LEAVE ENDIF ENDDO 这段话的意思,就是定义组合键值FHSKEY,然后根据这个FHSKEY在逻辑文件PFFHSL3中去定位,循环读取PFFHSL3中,FHS01、FHS03与FLD01、FLD02相等的记录。当读取记录结束,或键值不等时,退出循环(*IN15是EQ指示器)。如果将READE操作码换成READ操作码的话(当然,Factory 1 处也就不能有值),就没有“键值不等时退出循环”这一层意思,只是读不到记录时就退出循环,但有时我们使用逻辑文件,仅仅是需要它的排序,而不需要读不到键值相等的记录就退出循环。所以说,使用READ操作码,还是READE操作码,需要根据实际的要求来决定。 以上的Factory 1处填写值的系统处理,当READE操作码在Factory 1处未填写值时,系统实际上是将当前的值与读到的上一条记录的关键字进行比较,而不是与SETLL时的键值做比较(读第一条记录不做比较!),如果键值不等时,置EQ指示器为1。。也就是说,如果没有与FHSKEY键值相同的录,那么系统并不是直接找开EQ指示器,而是会一直保持正常地往下读,直到找到与读到的第一条记录关键字不同的记录,才会打开EQ 指示器,所以要注意。
READP {(N | E)} (Read Prior Record) 读取记录—游标上移 简单来说,READ、READE操作时,游标在数据文件中,是下移的;即读完第一条记录,游标指向第二条记录;读完第二条记录,游标指向第三条记录,依此类推,直至最后一条记录。但READP则正好相反,游标是上移的,即读完第三条记录后,游标指向第二条记录;读完第二条记录后,游标指向第一条记录,直至读完第一条记录。
一般来说,用READ、READE的概率会比READP、READPE的概率高得多,不过在某些情况下,使用READP操作,又的确会很省事,这个一时间想不起例子来,大家可在编程序时多实践。
READPE {(N | E)} (Read Prior Equal) 虽然我没用过,但猜想它应该就是指游标上移,按键值去读取文件。与READP的关系,就类似于READE与READ的关系。
REALLOC {(E)} (Re-allocate Storage) 没用过
REL {(E)} (Release) 没用过
RESET {(E)} (Reset)
将数据结构赋值成为初始值。 注意是初始值,不是清空。 如定义结构: D FHSDS DS D FHS01 10 INZ(’ABCD’) D FHS02 5 INZ(’EFGH’) 那么,不管对该结构如何赋值,当执行语句: C RESET FHSDS
之后,FHS01将会变成’ABCD,FHS02将会变成’EFGH’,即恢复成为初始值。 RETURN {(H | M | R)} (Return to Caller)
RETURN是程序结束。 在前面,“简单的程序流程”中,我们讲过,“SETON LR” 与RETURN这两句话一起,做为程序的结束。这里,再详细解释一下两者之间的区别,以及关系:
如果不写RETURN,只写“SETON LR”,程序执行完最后一句之后,将会再从第一句开始执行,造成死循环。在简单的程序流程这个例子中,程序原来只想修改读到的第一条记录,而如果没有RETURN的话,将会把所有的记录都修改掉,直到最后找不到可修改的记录,然后系统报错,异常中断。(这种离奇的现象现在又测试不到了,可能是当时写错程序了?把F写成了P?不管它,当是我写错了,总之RETURN是表示程序结束,没有RETURN,主程序无可执行的语句时,它也会结束;如果RETURN出现在主程序的中间,那么RETURN后面的语句将不会执行)
如果只写RETURN,不打开指示器*INLR,根据blogliou所说 “程序不会强制将内存中的数据写到磁盘中。400缺省的是BLOCK输出,即数据记录满一个BLOCK块时才会将这一组记录写到磁盘上。那么如果这时BLOCK没满,数据信息不会立刻写到磁盘上。之后有其它作业用到该文件,读取的数据就不完整。”
但如果文件有唯一键字,或记录日志,必须同步写时,其实BLOCK实际被忽略,也就是此时不会有错。目前我们用的是MIMIX备份,客户实际上将所有的文件都列入日志,这时不写也不会出现上述错误。但为避免一些潜在的问题,养成良好的编程风格,建议将SETON LR与RETURN一同,做为程序结束的标志。当然,如果某个程序频繁被调用,且不涉及文 操作时,可考虑不打开指示器*INLR,仅用RETURN作为结束,这样程序不会被PURGE出内存,可提高调用效率。
如果没写RETURN,也没有打开指示器*INLR,在编译时,系统将会报40级错,说找不到程序结束的语句,所以大可放心。
ROLBK {(E)} (Roll Back)
1. 基本语法
Factory 1 Operation Factory 2 Result ROLBK
2. 该操作码无其它参数,就是指对事务处理进行回滚操作。
3. ILE程序中,ROLBK操作可随时进行,也允许在没有声明COMMIT类型的文件
的情况下,仍进行ROLBK操作(对该进程这前的事务进行确认处理)f 4. 关于日志的确认回滚操作,在后面会另设专门章节讲述。
2.8.4.5 S--Z
SCAN {(E)} (Scan Character String) 扫描字符串 扫描字符或字符串Factory 1 在目标字符串Factory 2中是否存在
Factory 1 Operation Factory 2 Result HI LO EQ
FLD01 SCAN FLD02 N 26 FLD01可以是字符,也可以是字符变量;可以是一位长,也可以是多位长。
当FLD01在FLD02中存在时,EQ指示器打开,即*IN26=’1’,同时将FLD02中的起始位置,赋值给N; 当FLD01在FLD02中不存在时,EQ指示器保持关闭状态,即*IN26=’0’,同时N=0
允许从FLD02中的指定位置开始检查: FLD01 SCAN FLD02:2 N 26 如上句,即表示从FLD02的第2位,开始扫描。 在实际使用中,比如说我们判断某个字符是否为数字,就可以先定义一个0—9的常量,然后将要判断的字符去SCAN一下这个常量 SELECT (Begin a Select Group) 分支语句 在操作码“OTHER”中讲过,为方便读者,列出简单语法如下:
Factory 1 Operation Factory 2 Result HI LO EQ SELECT WHEN 条件判断1 处理语句1 WHEN 条件判断2 处理语句2
OTHER 处理语句3 ENDSL
要注意,SELECT操作码,必须有对应的ENDSL操作码,否则编译无法通过。 SETGT {(E)} (Set Greater Than) 定位操作—大于 举个例子吧,假设文件中有一个字段,是标识顺序号的,1、2、3、4。即该字段为1,表示第一条记录,该字段为2,表示第2条记录。那么:
Factory 1 Operation Factory 2 Result HI LO EQ
2 SETGT 文件记录格式名 READ 文件记录格式名 这个READ操作,READ到的,是第3条记录。也就是说,SETGT操作码,会将游标定位到大于键值的第一条记录前。 在实际使用中,如果我们是按逻辑文件读取,而且读了一条记录之后,对其键值相同的记录都不需要再读取时,就可以用SETGT,不过需要注意,Factory 1项,需要是与键值相同的变量,即如果文件是使用多个字段做为键值,那么我们也需要先定义一个组合键值的变量,然后Factory 1处填写这个组合键值的变量名。 当声明文件的键值有多项时,Factory 1项的键值,允许小于文件的键值,但顺序必须一致。即声明的文件如果键值为:FHS01、FHS02、FHS03,那么我们在程序中定义三个类型与之相同的变量FLD01、FLD02、FLD03,以下写法都是有效的 FLDKEY KLIST KFLD FLD01 KFLD FLD02 KFLD FLD03 FLDKEY SETGT 文件记录格式名 FLDKEY KLIST KFLD FLD01 KFLD FLD02 FLDKEY SETGT 文件记录格式名 FLD01 SETLL 文件记录格式名 SETLL {(E)} (Set Lower Limit) 定位操作—小于 语法与SETGT相同,含义与SETGT不同。SETLL操作码,会将游标定位到与键值相等的第一条记录之前,仍是上例,如果是 2 SETLL 文件记录格式名 READ 文件记录格式名 那么READ操作码读到的记录,就是第2条记录,看到了吧,和SETGT不同。 SETLL操作码还可以用来简单判断当前键值是否存在有记录,以PFFHSL3为例(键值为FHS01、FHS02)
Factory 1 Operation Factory 2 Result HI LO EQ FHSKEY KLIST KFLD FLD01 KFLD FLD02 EVAL FLD01=’01’ EVAL FLD02=’02’ FHSKEY SETLL 文件记录格式名 44 当文件中有相应记录时,EQ指示器打开,即*IN44=’1’ 当文件中无相应记录时,EQ指示器关闭,即*IN44=’0’(与CHAIN正好相反,要注意) 而在这种用法中,SETLL与CHAIN的区别在于,CHAIN是定位读取了记录,而SETLL仅仅只是判断该记录是否存在。所以用SETLL操作,不能修改记录,也无法取出记录的值。只能判断记录是否存在。如果要修改记录,或取出记录的值,还需要有一个读取定位的操作,
如READ,或READE、READP等(最常用的,应该就是READ操作) SETOFF (Set Indicator Off) 关闭指示器
Factory 1 Operation Factory 2 Result HI LO EQ SETOFF 10 11 12 等价于 EVAL *IN10=’0’ EVAL *IN11=’0’ EVAL *IN12=’0’ 在SETOFF这个操作码中,指示器填在HI、LO、EQ哪里都没关系,都是表示要被关闭的指示器
SETON (Set Indicator On) 打开指示器
Factory 1 Operation Factory 2 Result HI LO EQ SETOFF 10 11 12 等价于 EVAL *IN10=’1’ EVAL *IN11=’1’ EVAL *IN12=’1’ 在SETON这个操作码中,指示器填在HI、LO、EQ哪里都没关系,都是表示要被关闭的指示器
SHTDN (Shut Down) 没用过 SORTA (Sort an Array) 没用过 SQRT {(H)} (Square Root) 开方
Factory 1 Operation Factory 2 Result HI LO EQ 9 SQRT 3 N 这时,N=3(因为3的平方为9) 9、3都可以是数字型变量,或者直接是数字 SUB {(H)} (Subtract) 减法操作
Factory 1 Operation Factory 2 Result HI LO EQ FLD01 SUB FLD02 FLD03 SUB FLD02 FLD03 看过前面的ADD、MULT操作码,这里不用解释也应该明白是什么意思了吧。那就不多说了。
SUBDUR {(E)} (Subtract Duration) 日期相减
1. 减日期 Factory 1 Operation Factory 2 Result HI LO EQ FLD01 SUBDUR N:*Y FLD02
表示将日期型变量FLD01减去N年,赋值到日期型变量FLD02中; N可以是一个数字型变量,也可以就是一个数字,N允许为负数
*Y,*M,*D(还有其它的参数值,可见ADDDUR,其中有详细解释) 2. 判断两个日期型变量之间的天/月/年数 Factory 1 Operation Factory 2 Result HI LO EQ FLD01 SUBDUR FLD02 N:*D