Chinaunix首页 | 论坛 | 博客
  • 博客访问: 55984
  • 博文数量: 18
  • 博客积分: 161
  • 博客等级: 入伍新兵
  • 技术积分: 135
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-14 21:52
文章分类
文章存档

2012年(18)

分类: LINUX

2012-04-16 22:03:54

转自:http://blog.163.com/xiao_maomao_chong/blog/static/31686239200711712157133/  
9.数据区操作

                1IN   :检索一个数据区并可选择允许你指定是否允许其它的程序更新这个数据区,IN检索的数据区,必须在*NAMVAR   DEFN 语句的结果字段上说明。

当因子1是保留字*LOCK时,该数据区已上锁,直到执行一个UNCLK操作或执行因子1上为空的OUT操作或程序结束情况之一方可解琐。

当因子2是保留字*NAMVAR时,检索程序中定义的所有数据区,当遇到错误时,如结果指示器未指定,可以说明异常情况/程序例外错监控子程序(*PSSR)来处理。

                2OUT  :更新一个数据区更新之前,必须先做两件事,其一,该数据区必须在一个*NAMVAR     DEFN语句的结果字段上说明,其二,该数据区必须用一个*LOCK     IN语句预先上锁。它的因子1*LOCK时,更新之后保留上锁状态,因子1是空时,更新之后不上锁。当因子2是局部数据区时,因子1必须是空。当因子2为保留字*NAMVAR时,程序中定义的所有数据区都被更新,更新发生错误时,处理方式同IN操作。

C     *DTAARA       DEFINE    SSCDTAARA     DTAARA            5  

C     *LOCK         IN        DTAARA                              

C     DTAARA        DSPLY                                        

C                   EVAL      DTAARA  = %SUBST(DTAARA:1:3)       

C     DTAARA        DSPLY                                        

C                                                                 

C                   OUT       DTAARA                                                           

                3UNLCK/UNLOCK:解锁一个数据区,一个数据区可以和UNLCK操作联用之前,它必须在一个*NAMVAR     DEFN语句的结果字段上说明,因子2必须是一个数据区名或保留字*NAMVAR,当因子2NAMVAR时,程序中所有上锁的数据区都被解锁。

                                                                      UNLOCK                            DTAARA1

                                                                      UNLOCK                            *NAMVAR

 

10其它操作

                1LOKUP/LOOKUP:

                                SRCHNO          LOOKUP          ARR                                     11 = EQ

                                在数组ARR中查找等于SRCHNO的元素,找到时结果指示器为ON

                2XFOOT:       求一个数组中所有元素的和

                                XFOOT           ARR                     SUM

                3.SORTA:       给一个数注重的元素排序

                                            SORTA           ARR

                4.MOVEA:       数组传递

                                MOVEA           *BLANKS    ARR(X)(从第X元素开始,ARR的其余部分是空格)                         MOVEA           *ALL'XY'                ARR(X)(从第X元素开始,ARR的其余部分给‘XY’)

                                MOVEA           ARRX                ARRY(3)(自数组ARRX第一元素起传递给数组ARRY的自第3个元素起的元素)

                                MOVEA           ARRX                ARRY

                                MOVEA           ARRX(3)     ARRY(自数组ARRX3元素起传递给数组ARRY的自第1个元素起的元素)

                                MOVEA           FLDA                ARR

            FLDA                                                                    ARR

            1234567          传送前         |986|543|210|ABC|

            1234567          传送后         |123|456|710|ABC|

                                MOVEA           ARR                 FLDA

                            ARR                                                             FLDA

            |01|0A|02|0B|O3|0C|      传送前         01OA

            |01|0A|02|0B|O3|0C|      传送后         02OB

ILE    RPGRPG/400的扩充 1ILE  RPG基本概念 过程(PROCEDURE

是一组字包含的高级语言语句的集合,它执行特定的任务然后返回调用者。MODULE中的PROCEDURE已经可以被其他任何ILE程序共享,当然,作为ILE语言之一,ILE RPG也可以调用任何ILE子程序(包括ILE RPG本身)。

模块对象(MODULE

是不可运行的对象,在系统中使用符号为*MODULE来代表模块对象。它是建立可运行ILE对象的基本构件块。我们也可以使用CRTRPGMOD命令将一个程序编译成MODULE

我们还可以将一个或者多个MODULE共同编译成一个服务程序,供其它应用系统调用。当然,我们可以使用其它第三方厂商提供的服务程序,或者将我们自己的程序编译成一个服务程序作为第三方产品提供给客户。这种服务程序实际上就是一个函数库。在AS/400中,系统API也都是通过这种方式提供的。

PROCEDUREMODULE都是ILEOPM之间的显著区别。

ILE程序

可运行的对象,在系统中使用符号为*PGM来代表ILE程序对象(和OPM  RPG一样)。

编译RPGLE程序有两种方式:

                            1.对于单独一个RPGLE程序,我们可以使用命令CRTBNDRPG(与在PDM中使用14同)将一个单独的程序变成一个可执行程序。这个命令实际上实现将RPGLE程序编译成一个临时的MODULE然后再将它编译成一个可执行程序。

                            2.我们也可以先使用CRTRPGMOD命令将一个程序编译成MODULE,然后再使用CRTPGM将这个MODULE和其他MODULE一起编译成一个可执行程序。使用这种方法的好处就是可以利用其它MODULE中的子程序。当然这个程序自己的子程序也可以被其他的ILE程序共享。

 

服务程序

是一个由可运行的过程和可用数据项组成的集合。其他的ILE程序和服务程序可以直接地存取这些过程和数据项。在许多方面,服务程序类似于子程序库或过程库。

联编目录

包含建立ILE程序或服务程序时可能需要的模块和服务程序的名称。是一个系统对象,对系统用符号*BNDDIR来表示。当建立ILE程序或服务程序时,联编目录提供了将可能用到的模块或服务程序打包在一起的便利方法。例如,一个联编目录可能包含提供数学函数的所有模块和服务程序。当想要使用其中的一些函数时,只需指定一个联编目录而不用将使用的每个模块或服务程序都指定。

对程序和过程的调用

ILE程序中既可以调用程序也可以调用过程。ILE语言通过调用语句CALLCALLPCALLB来标识调用的目标是程序还是过程。

1.动态程序调用

使用call调用*pgm程序其实是在程序运行时将被调用的程序转换成地址,因此可以将这种方式称之为动态调用。动态程序调用包括:

AOPM程序可以调用一个OPM程序或ILE程序

BILE程序可以调用一个OPM程序或另一个ILE程序

C.服务程序可以调用OPM程序或ILE程序

2.静态过程调用

使用callp调用procedure是在binding(联编)的时候将被调用的程序转换位地址,因此可以被称之为静态调用。静态调用在效率上比动态调用高。可以用静态过程调用来调用下列任何项:

       A.在同一模块内的对象

B.在同一个ILE程序或服务程序内的一个单独模块中的过程

C.在一个单独的ILE服务程序中的过程

 

CALL, CALLB, CALLP的区别:

CALL只能调用*PGM 是动态调用,程序运行效率低。CALLBCALLP都只能调用PROCEDURE,大部分时候是静态调用,只有调用指针变量中所指的PROCEDURE时才是动态调用;但是CALLB不参加接口合法性检查,即:不需要原型说明,因此在运行时可能会导致一些错误。CALL CALLB都只能使用固定格式的实参传递,即:使用PLIST

RPG IV中的全局变量与局部变量:

每一个OPM程序都只有一个唯一的程序入口,但是在ILE程序中每一个Procedure都可以有一个入口。在OPM程序中每一个内部子程序的变量都是全局变量,但是在ILE程序的Procedure中声明的所有变量都是局部变量,其余所有用到的变量都是全局变量。如果在Procedure中声明的变量和某一全局变量同名的话,那么这两个变量将在内存中使用不同的两个空间,也就是说这两个变量将互不影响,同名的那个全局变量将不被此procedure 使用。局部变量也将在此procedure执行完成后被全部释放。

活动组(Activation Group

              活动组是一个作业的子结构,由系统资源组成,例如:存储器、提交机制、文件打开、重定向文件(Override files)。这些资源被分配给活动组以运行一个或者多个ILE或者是OPM程序。活动组使得我们可以在一个作业中相对独立地运行一些程序,而这些程序之间不会互相影响(如:Commitment Control & Overrides)。

              一个程序所属的活动组是在编译它(CRTPGM & CRTSRVPGM)的时候指定的,但是OPM程序只能运行在默认的活动组中,不能改变。如果使用CRTBNDRPG来编译程序,那么只有在DFTACTGRP的值为*NO时才可以指定ACTGRPDFTACTGRP的默认值是*YES,此时程序就运行在DFTACTGRP中。

              活动组可以选以下几种值:

1 a named activation group

              一个指定名称的活动组可以将您的ILE程序和服务程序作为一个整体来管理。这样的一个活动组是在第一个属于该组的程序被调用的时候被建立。

                            用户可以使用了RCLACTGRP命令删除一个活动组。但是,必须是在这个活动组没有被使用的时候才能被删除。

2*NEW

              如果我们为ACTGRP指定了*NEW,那么这个程序在任何被调用的时候都会重新生成一个新的活动组, 系统会自动为这个ACTGRP指定一个在这个JOB中唯一的一个名称。

              一个以*NEW方式产生的活动组总是在生成它的那个程序结束时被系统自动删除(无论这个程序是不是以*INLR=*ON的方式退出的)。因此,如果你想使用*INLR=*OFF的方式结束一个程序,以便保持这个程序仍为Active 状态,那么你就不应该为此程序在ACTGRP参数指定*NEW

              注意:*NEW对于SERVICE PROGRAM是不适用的。SERVICE PROGRAM只能使用Named group or *CALLERCRTPGMACTGRP默认值是*NEWCRTBNDRPG的默认值是DFTACTGRP

3*CALLER

              此参数将使得被调用的程序被激活在调用它的那个程序所属的活动组中。

             

              对于OPM程序来说,它只能运行在*DFTACTGRP中。在以下两种情况下,ILE程序将也会运行在*DFTACTGRP中:

AILE程序在编译时使用了DFTACTGRP(*YES)

      BILE程序在编译时使用了DFTACTGRP(*NO) ACTGRP(*CALLER),并且此程序被一个OPM程序调用。

 

注意:通常情况下,如果我们在编译程序的时候不对有关Activation Group的参数进行任何修改,那么我们的程序都会运行在DFTACTGRP中,也就是说,我们的一个JOB实际上就只有一个活动组,因此我们的override commitment control也都是在整个作业的范围内起作用的。

 

*NEW DFTACTGRP(*YES), NAMED ACTIVATION GROUP的区别:

              *NEW类型的活动组在与此活动组相关的子程序RETURN(不管*INLR的值如何)时被删除,也就是在作业还没有结束的时候就会被删除,此时此活动组的所有资源都被释放。

              NAMED ACTIVATION GROUP只有在整个作业结束的时候或者是在用户使用显式的RCLACTGRP时才会被删除。程序占用的存储器空间也只有这时才会被释放。

              DFTACTGRP中,只有在程序以*INLR=1’的方式退出或者非正常退出的情况下才会释放他占用的存储器空间。因为ACTGRP=*CALLER而运行在DFTACTGRP中的程序只有用户在签退的情况下(交互式作业Interactive Job)或者是作业运行完毕(批作业Batch Job)的情况下才会被释放占用的内存。

              注意:如果系统中有许多程序在占用存储器,那么系统就可能因为存储器资源不够而瘫痪。因此,我们必须避免让大量的程序都运行在DFTACTGRP中,因为这时存储器只有在作业停止的时候才会被系统回收。

              服务程序的资源只有在它运行的活动组结束的时候才会被系统回收。如果服务程序是运行在DFTACTGRP中,那么只有在整个作业运行结束后系统才会回收它所占用的资源。

              我们可以使用RCLACTGRP命令来删除一个Named Activation Group

              RCLRSC命令可以用来回收那些已经结束但是*INLR=*ON的程序所占的资源。

 

2.表达式的使用及可使用表达式的操作码 表达式中的有效操作符

       1. 一元操作符:

+      保持原来的数值

-      取原来数值的相反值

NOT    逻辑取反

                   例如:如果A=12.8 那么-A就等于-12.8

       2. 二元操作符:

+   两个数值相加;连接两个字符串或者是图形变量;给一个指针变量加偏移量

          -  两个数值相减;修改指针偏移量;两个指针变量相减

*           两个数值相乘

/           两个数值相除

**   求幂,例如2**3=8,即23次方为8

=           判断两个变量是否相等,‘1’相等,‘0’不等

<>   判断两个变量是否不等

>           大于

<           小于

>=   大于等于

<=   小于等于

AND  逻辑与操作

OR   逻辑或操作

3. 嵌入式函数:

           4. 用户自定义函数:

                  例如:

         C                           IF            MYFUNCSTRING1=%TRIMMYFUNCSTING2))

         C                           EVAL   %SUBSTX3=MYFUNC(‘ABC’)

         C                           ENDIF

 

表达式中结果字段的数据类型

    1+ *

           如果操作数中至少有一个浮点数类型的变量,那么结果字段为浮点数

           否则,如果操作数中至少有一个操作数是packed-decimalzone-decimalbinary类型,那么结果字段是packed-decimal

           否则,如果两个操作数都是integerunsigned integer,那么结果字段是integer或者unsigned integer

           一个最多十个数字并且小数位为0的数字变量会被认为是整形数

    2/

           如果两个操作数中至少有一个浮点数,那么结果就是浮点数,否则的话结果就是packed decimal类型

    3**

           结果是float类型

 

表达式中的数据精确度

    RPG IV必须决定它的表达式中的每一个中间结果的格式(format)和精确度,而在RPG III中,程序员必须指定每一个独立运算的结果被放入哪一个变量中去,也就是说RPG III每一步计算结果的格式和精确度都是由程序员指定的。

    如果一个计算的结果是浮点数、整数或者是无符号整数,那么精确度就是这个结果的长度。但是,如果一个计算的结果是packed decimal或者zone decimal 或者binary 那么计算结果的精确度取决于参与运算的操作数。RPG IV最大支持30位长度的操作数,因此如果运算结果的长度超过了30位的话,结果字段会被调整到30位长,剩下的位数将被切除。

1.默认情况下,为了减少溢出的可能性,表达式得到的结果会尽可能的长

2.“result decimal position”和默认情况下的工作是一样的,任何中间值的小数点位数都不会低于最终结果要求的小数点位数。除非操作涉及到向一个数值变量中指定一个数值(an assignment to a numeric variable)或者是涉及到转化成一个明确小数点位数的精度。

在实际中,你不用担心精确度,只要你在编译时注意了编译列表(compile list.当表达式中涉及到指定数值时(an assignment to a numeric variable,我们可以通过在result decimal position位上指定(R)来确保小数位精确度被保持。

result decimal position无法被使用时,我们还可以使用%DEC来将结果的精确度降低,以防止小数位丢失。使用%DEC可以用来指定中间结果的小数位位数不能低于%DEC指定的位数。

 

可用表达式的操作码

DOU (Do Until) 

DOW (Do While)

EVAL (Evaluate expression)

IF (If)

RETURN (Return to Caller)

WHEN (When True Then Select)

 

DOU

例子:

           C                           DOU           *INKC

           C                           ……

           C                           ENDDO

           C* 直到F3被按下,循环中的语句至少被执行一次

 

           C                           DOU           *IN10 OR FIELD2 > FIELD3

           C                           ……

           C                           ENDDO

 

           C                           DOU           X > %ELEM(ARRAY)

           C                           ……

           C                           ENDDO

DOW

       例子:

              C                           DOW           A<=5 AND B+C=0

              C                           ……

              C                           ENDDO

EVAL

       例子:

              C                           EVAL   ARR*=FIELD2*FIELD3

              C* 数组ARR的所有元素都被赋予同样的值

 

              C                           EVAL   RES=FIELD1<10+    *IN10 +(FIELD2>=5)

              C* 逻辑判断的值为字符形,因此RES的值就是三个逻辑判断的结果的连接,‘010

RETURN

       例子:

              D*无参数返回

              D RETNONE                   PR

              ………………

              P RETNONE                   B

              D RETNONE                   PI

              ……

              C                                         RETURN

              P RETNONE                   E

 

              D*返回一个参数

              D RETFIELD                  PR            5P     2

              D      PARM                               5I     2

              ………………

              P RETFIELD                  B

              D RETFIELD                  PI            5P     2

              D      PARM                               5I     2

              D FLD                       S         12S 1      INZ13.8

              ……

              C                                  RETURN 7RETURN FLD*3 / RETURN FLD

              P RETFIELD                  E

 

              D* 返回数组

              D RETARRAY                  PR            D            DIM3DATFMT*YMD/

              ………………

              P RETARRAY                  B

              D RETARRAY                  PI            D            DIM3

              D SMALLARR                  S                           DIM2DATFMT*ISO

              D BIGARR                    S                           DIM4DATFMT*USA

              C* 如果使用下面的方法返回参数,那么接口数组中所有元素都含有相同的值

              C                                  RETURN        D’1995-06-27’

              C*如果使用比接口定义的数组元素个数少的数组,那么接口数组的第三个元素将         C*被赋予默认值

              C                                  RETURN        SMALLARR

              C*如果使用比接口定义的数组元素个数多的数组,那么多余的数组元素将被忽略

              C                                  RETURN        BIGARR

              P RETARRAY                  E

WHEN

例子:

           C                                  SELECT

           C                                  WHEN          *INKA

           C                                  ………………

           C                                  WHEN          NOT*IN10 AND DAY=’FRIDAY’

           C                                  ………………

           C                                  WHEN          %SUB(A:4:3)=’ABC’

           C                                  ………………

           C                                  OTHER

           C                                  ………………

C                                  ENDSL

3.内嵌式函数及新增、改变的操作 内嵌式函数

%ABSnumeric expression)返回表达式的绝对值

       %ADDRvariable name)返回表达式的地址

       %CHARgraphic,date,time,timestamp expression)返回字符类型的值

       %DECnumeric expression(:digits:decimal position)按照参数指定的数据长度和精度返回返回P类型的值

              %decposnumeric expression)按照参数指定的小数位返回P类型的数值

       %ELEMarray,table,multiple occurrence data structure name)返回元素个数

       %EOFfilename)当最近一次input操作或向一个SUBFILE写操作遇到文件头或文件尾,就返回‘1’,否则返回‘0

       %EQUALfilename)如果最近一次SETLLfor a particular file ,if  specified)或者LOOKUP遇到了一个完全一致的匹配,就返回‘1’,否则返回‘0

       %ERROR无参数,如果最近一次(在EXTENDER字段填有‘E’的)操作码产生了一个错误,就返回‘1’,否则返回‘0

              %float(numeric expression)返回float类型的值

       %FOUNDfilename)如果最近一次对文件的操作(CHAINDELETESETGTSETLL)、对数组的操作(LOOKUP)、对字符串的操作(CHECKCHECKRSCAN)成功的话,就返回‘1’,否则返回‘0

       %INTnumeric expression)返回整形的值

       %LENany expression)返回数字或字符串的长度

       %OPENfilename)如果指定的文件的状态为打开,就返回‘1’,否则返回‘0

       %PADDRprocedure name)返回函数的指针

       %PARMS无参数,返回传递给函数的参数个数

       %REPLACE(替代串:被替代的串(:开始位(:替代的长度)))用‘替代串’替代‘被替代串中’的一部分

       %SCANsearch argumentstring to be searched(:start position))当找到STRING TO BE SEARCHED时,返回位置数,否则返回‘0

       %SIZEvariable,array,literal(:* all))返回变量或者是数组的大小

       %STRpointer(:maximum length))返回由pointer指定的字符串去掉前导空格之后的串

       %SUBSTRstring:start(:length))取子串

       %TRIMstring)去掉字符串的前导和末尾空格

       %TRIMLstring)去掉字符串的前导空格

       %TRIMRstring)去掉字符串的末尾空格

       %UNSnumeric expression)返回无符号数

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