[AS/400] Control Language(CL) 基本概念
本文内容源于 Go4AS400
简介
AS400 Control Language(CL) 是由指令(Command)组合而成,用于控制操作和调用系统功能。在 CL 程序中,指令用于和系统 OS400 进行交互。
以下是 CL 程序的主要功能
- 可以交互式地调用,也可以在批量模式下调用程序
- 决定程序的调用顺序
- 处理文件和其他对象(objects)
- 监控所有类型的消息
- 在不同的任务之间通信
- 改变对象的属性,然后进行处理
注,在 AS400 中,对象范指各种类型的概念,例如程序,文件。
尽管 CL 的功能丰富,但是它不是一个高级语言。有一些更接近高级语言的语言会调用 CL 。
有两种方法调用 CL 程序
1. 关键字表示法( Keyword notation ):可以调换传入参数的顺序,但是需要将所有传入的参数和其对应的键名称对应起来。
CPYF FROMFILE(A) + TOFILE(B) + FROMMBR(M1) + TOMBR(M2) + MBROPT(*ADD)
2. 位置表示法( Position notation ):根据位置依次分配传入参数和程序里的关键词
CPYF A + B + M1 + M2 + *ADD
CL 程序里的指令
PGM PARM (&A)
PGM 指令位于程序开始位置,可选。如果需要传入参数,则该指令是必须的
DCL, DCLF, COPYRIGHT
声明指令,用于声明程序中使用到的变量、文件,位于其他命令之前,仅在 PGM 指令后面。
CHGVAR, SNDPGMMSG, OVRDBF, DLTF...
用于处理程序中的文件、变量的操作指令
IF, THEN, ELSE, DO, ENDDO, DOWHILE, DOUNTIL, DOFOR, LEAVE, ITERATE, GOTO, SELECT, ENDSELECT, WHEN, OTHERWISE, ENDSUBR
CL 程序中的流程控制指令
%SUBSTRING (%SST), %BINARY(%BIN), %ADDRESS(%ADDR), %CAT()
内置方法,用于进行算术、关联或逻辑运算
CALL, RETURN, TFRCTL
用于转移控制权的指令
CALLPRC
转移控制权给其他 procedure
ENDPGM
结束程序指令,可选。
CL 的局限性(和 RPG 对比)
- 无法用于添加、更新数据库文件的记录
- 显示功能有局限
- 无法使用程序描述文件(Program Dscribed files)
- 不支持子文件(subfile,子文件用于展示多条记录),不过支持单一消息文件。单一消息文件是一种特殊类型的子文件
- 无法使用子程序 (subroutines)
- 无法定义多个对象(文件)。在 CLLE 中,可以通过 OPENID 来使用多个文件。
OPENID
OPENDID 用于标示 CL 程序中任何已打开的文件
DCLF FILE(AMIT/ACCOUNT) OPNID(ID1) QUALIFIED FILE NAME - AMIT/ACCOUNT RECORD FORMAT NAME - REC1
当程序编译完后,在池文件(spool file) 里可以看到带有 ID 作为前缀的字段。因此,在 CL 中声明的字段,都是用过唯一的 open-id 为标示的。
*CAT / *BCAT / *TCAT
*CAT, 拼接两个字符串
*BCAT, 拼接两个字符串,并使两个字符串之间只保留一个空格
*TCAT, 去掉前面字符串的尾空格,然后拼接两个字符串
'String One ' *CAT 'String Two '
输出 'String One String Two '
'String One ' *BCAT 'String Two '
输出'String One String Two '
'String One ' *TCAT 'String Two '
输出 'String OneString Two '
改变指示符 (Indicator) 的值
VERIFY: CHGVAR VAR(&IN69) VALUE('0') CHGVAR VAR(&IN91) VALUE('1') CHGVAR VAR(&F9301) VALUE(' ') CONFIRM: + CHGVAR VAR(&IN96) VALUE('0') CHGVAR VAR(&IN97) VALUE('1') CHGVAR VAR(&IN73) VALUE('1') SNDF RCDFMT(CAS09R90) SNDF RCDFMT(MSGSFLC)
读取多个文件
Columns . . . : 1 71 Browse AMIT/QRPGLESRC SEU==> READDSPFCL FMT ** ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 *************** Beginning of data ************************************* 0001.00 PGM 0002.00 DCLF FILE(*LIBL/ACC_DSPF) 0002.01 DCLF FILE(AMIT/ACCOUNT) OPNID(ID1) 0002.02 DCLF FILE(AMIT/CUST) OPNID(ID2) 0002.03 DCL VAR(&COUNT) TYPE(*INT) VALUE(0) 0002.04 DCL VAR(&CHAR) TYPE(*CHAR) VALUE(' ') 0003.00 READ: 0003.01 IF COND(&IN03 *EQ '0') THEN(DO) 0003.10 RCVF OPNID(ID1) 0003.12 MONMSG MSGID(CPF0864) EXEC(GOTO CMDLBL(END1)) 0003.13 RCVF OPNID(ID2) 0003.14 MONMSG MSGID(CPF0864) EXEC(GOTO CMDLBL(END1)) 0003.15 CHGVAR VAR(&S_ORG) VALUE(&ID1_ORG) 0003.16 CHGVAR VAR(&S_ACC) VALUE(&ID1_ACC) 0003.17 CHGVAR VAR(&S_CCY) VALUE(&ID1_CCY) 0003.18 CHGVAR VAR(&S_PARTY) VALUE(&ID1_PARTY) 0003.19 CHGVAR VAR(&COUNT) VALUE(&COUNT+1) 0003.20 CHGVAR VAR(&CHAR) VALUE(&COUNT) 0003.21 CHGVAR VAR(&S_MSG) VALUE('THIS IS RECORD NO' + 0003.22 *CAT ' ' *CAT &CHAR + 0003.23 *CAT ' ' *CAT &ID2_CSNAME) 0003.24 SNDF RCDFMT(HEADER) 0003.25 SNDF RCDFMT(FOOTER) 0003.26 RCVF RCDFMT(HEADER) 0003.27 GOTO READ 0005.10 ENDDO 0007.00 END1: 0007.01 CLOF OPNID(ID1) 0007.02 MONMSG MSGID(CPF4520) 0007.03 CLOF OPNID(ID2) 0007.04 MONMSG MSGID(CPF4520) 0007.05 /** BY USING THIS THE MSG CPF4520 WON'T APPEAR **/ 0009.00 ENDPGM ****************** End of data ****************************************
输出效果
ACCOUNT ENTRY DISPLAY ORG 190 ACC A00000000001 CCY EUR PARTY P00000000001 F3 = EXIT F12 = CANCEL
调用程序,并传入参数
CHGVAR VAR(&IPARM) VALUE(&LVLID || &ORGCODE || &RPTID || &PRINTQ- || &PRTQLIB || &HOLD || &SAVE || &PRIORITY || &COPIES || &LANGCODE - || &LPI || &CPI || &LPP || &FORM || &ALIGNMT || &EXTFID || &PRTFID ||- &PRTPID || &REQOPT || &LPPOS) CALL PGM(CTO04R00) PARM(&IPARM)
PGM PARM(&IPARM) DCL &IPARM TYPE(*CHAR) LEN(100) DCL &TYPE TYPE(*CHAR) LEN(1) DCL &LEVLID TYPE(*CHAR) LEN(2) DCL &ORGAN TYPE(*CHAR) LEN(3) DCL &REPID TYPE(*CHAR) LEN(10) DCL &PRTQ TYPE(*CHAR) LEN(10) DCL &PRTQLB TYPE(*CHAR) LEN(10) DCL &IHOLD TYPE(*DEC) LEN(1 0) DCL &ISAVE TYPE(*DEC) LEN(1 0) DCL &OUTPRI TYPE(*CHAR) LEN(1) CHGVAR &LEVLID %SST(&IPARM 1 2) CHGVAR &ORGAN %SST(&IPARM 3 3) CHGVAR &REPID %SST(&IPARM 6 10) CHGVAR &PRTQ %SST(&IPARM 16 10) CHGVAR &PRTQLB %SST(&IPARM 26 10) CHGVAR &IHOLD %SST(&IPARM 36 1) CHGVAR &ISAVE %SST(&IPARM 37 1) CHGVAR &OUTPRI %SST(&IPARM 38 1) CHGVAR &COPIES %SST(&IPARM 39 2)
QCMDEXC
用于执行来自 HLL 的指令。
0010.00 DCMDDSC S 256A 0011.00 DCMDLEN S 15P 5 0040.00 C Eval CMDDSC='DLTDTAQ DTAQ(IROBO1/DTAQ000)' 0041.00 0042.00 C Eval CMDLEN=%len(%trim(CMDDSC)) 0043.00 C CALL 'QCMDEXC' 0044.00 C PARM CMDDSC 0045.00 C PARM CMDLEN
输出结果
IROBO1 里面的数据队列 DTAQ000 被删除
SNDF, RCVF
用于读取数据库文件。
读取数据库文件
下面是一个例子,读取并显示数据库文件内容,在读取下一行之前都会弹出提示信息
CL 程序中使用的 Physical file - CUST
Columns . . . : 1 71 Browse AMIT/QRPGLESRC SEU==> CUST FMT PF .....A..........T.Name++++++RLen++TDpB......Functions++++++++++++++++++ *************** Beginning of data ************************************* 0001.00 0002.00 A R CUSTR 0003.00 A CSNBR 6A 0004.00 A CSNAME 10A 0005.00 A CS#OPN 5P 0 0006.00 A CS$OPN 10P 2 ****************** End of data ****************************************
CL 程序
Columns . . . : 1 71 Browse AMIT/QRPGLESRC SEU==> READFILE FMT ** ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 *************** Beginning of data ************************************* 0001.00 PGM 0001.01 DCL VAR(&VAR1) TYPE(*CHAR) LEN(20) 0001.03 DCL VAR(&REPLY) TYPE(*CHAR) LEN(1) + 0001.04 VALUE('N') 0002.00 DCLF FILE(AMIT/CUST) 0003.00 READ: 0004.00 RCVF 0005.00 MONMSG MSGID(CPF0864) EXEC(GOTO CMDLBL(END1)) 0005.02 CHGVAR VAR(&VAR1) VALUE(&CSNBR||' '|| + 0005.03 &CSNAME||' '||+ 0005.05 ' ') 0005.06 SNDUSRMSG MSG('DO U WANT TO CONTINUE FILE READING') + 0005.07 MSGRPY(&REPLY) VALUES('Y' 'N') 0005.10 0005.11 IF (&REPLY='Y') DO 0005.12 SNDUSRMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA(&VAR1) + 0005.13 MSGTYPE(*INFO) 0006.00 GOTO CMDLBL(READ) 0006.01 ENDDO 0006.02 ELSE DO 0006.03 GOTO CMDLBL(END2) 0006.04 ENDDO 0007.00 END1: 0008.00 SNDUSRMSG MSG('THE END OF FILE IS REACHED') 0008.01 END2: 0009.00 ENDPGM ****************** End of data ****************************************
输出结果
DO U WANT TO CONTINUE FILE READING Y 100001 AMI. DO U WANT TO CONTINUE FILE READING Y 100002 upi. DO U WANT TO CONTINUE FILE READING Y 100003 KUM. THE END OF FILE IS REACHED
DSPMSGD
下面的例子,用于显示消息文件 AM_MSGF 里面的所有消息
DSPMSGD RANGE(*FIRST *LAST) MSGF(AMIT/AM_MSGF) DETAIL(*BASIC) OUTPUT(*PRINT)
Work with All Spooled Files Type options, press Enter. 1=Send 2=Change 3=Hold 4=Delete 5=Display 6=Release 7=Messages 8=Attributes 9=Work with printing status Device or Total Cur Opt File User Queue User Data Sts Pages Page Copy QPMSGD AMIT AMIT RDY 1 1 Bottom Parameters for options 1, 2, 3 or command ===> F3=Exit F10=View 4 F11=View 2 F12=Cancel F22=Printers F24=More keys
Display Spooled File File . . . . . : QPMSGD Page/Line 1/1 Control . . . . . Columns 1 - 130 Find . . . . . . *...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9....+....2. 5722SS1 V5R4M0 060210 Message File 2/14/13 1:39:44 Page 1 Message file . . . . . . . . . : AM_MSGF Library . . . . . . . . . . . . : AMIT Start message ID . . . . . . . : *FIRST Ending message ID . . . . . . . : *LAST MSGID SEV MSG MSG0001 1 ORG CODE CAN NOT BE BLANK MSG0002 0 THE ACCOUNT NUMBER CAN NOT BE BLANK MSG0003 0 THE ACCOUNT CURRENCY CAN NOT BE BLANK MSG0004 0 THE PARTY NUMBER CAN NOT BE BLANK MSG0011 0 THE ORGANISATION CODE SHOULD BE EITHER 190 191 192 OR 193' MSG0012 0 THE ACCOUNT NUMBER SHOULD BE PREFIXED WITH A MSG0013 0 THE CURRENCY CAN BE THEREE CHARACTER CODE e.g. EUR,USD,TRY etc. MSG0014 0 THE PARTY NUMBER SHOULD START WITH PREFIX 'P' MSG0015 0 'THE CURRENCY CAN BE'THREE'CHARACTER CODE e.g. EUR,USD,TRY etc.' MSG0099 0 ORGANISATION CODE, ACCOUNT NUMBER , CURRENCY AND PARTY NUMBER ARE MANDATORY * * * * * E N D O F L I S T I N G * * * * * Bottom F3=Exit F12=Cancel F19=Left F20=Right F24=More keys
OPNQRYF
创建一个临时的文件访问路径。在使用结束后,该路径被被抛弃。详情
Logical file
Logical File 是持久化的对象,而 OPNQRYF 是临时的对象。
RETURN
CL 或 OPM 程序中的 RETURN 指令,会从调用栈(call stack)中移除该程序。
RTVJOBA
Retrive Job Attribute, 获取任务的属性。详情
RTVSYSVAL
用于获取系统值,例如系统的日期,时间,年月日,世纪等。
/* Retrieve current Timestamp (system value). */ RTVSYSVAL SYSVAL(QCENTURY) RTNVAR(&CENTURY) CHGVAR VAR(&CENT) VALUE('20') IF COND(&CENTURY *EQ '0') THEN(CHGVAR + VAR(&CENT) VALUE('19')) RTVSYSVAL SYSVAL(QYEAR) RTNVAR(&YEAR) RTVSYSVAL SYSVAL(QMONTH) RTNVAR(&MONTH) RTVSYSVAL SYSVAL(QDAY) RTNVAR(&DAY) RTVSYSVAL SYSVAL(QTIME) RTNVAR(&TIME) CHGVAR VAR(&TIMESTAMP) VALUE(&CENT *CAT &YEAR *CAT + &MONTH *CAT &DAY *CAT &TIME) SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) + MSGDTA('Performing Update') CHGVAR VAR(&ERROROUT) VALUE('1') CALL PGM(PGM001) PARM(&ERROROUT &LEVEL &ORG + &PARTY &PRCDATY &PRCDATM &PRCDATD &TIMESTAMP)
OVRDBF
用于重写 physical file 的属性。详情
CRTCMD
Create command,用于创建指令,像系统指令一样,在命令行上执行特定的请求。