如何存取任一工作 QTEMP 程式館的物件?
當使用者從 SignOn 畫面輸入使用者代碼及密碼後,進入系統的同時
系統會自動給予一組由工作站名稱 Jobname,使用者代碼 User,及工
作編號 Jobnbr,組成一個存於系統中的唯一代碼即"JOBNBR/USER/JOBNAME"
,當成系統用以辨別系統中每個工作的代碼,也同時依照該代碼於記
憶體中新增一個 QTEMP 程式館供該工作臨時使用,而當該工作結束作
業(SignOff)時,系統也自動將該工作的 QTEMP 程式館刪除,所以
QTEMP 是進入系統每個工作的臨時工作區僅供每個工作本身使用。
但若有需要存取任一工作 QTEMP 程式館的物件時,如某個工作狀態是
MSGW(有錯誤訊息,等待人工介入)時,就需要除錯或採取適當的回複
動作,如某些處理內容是存於 QTEMP 程式館中,有需要存取或修改讓
該工作能持續或僅是程式館路徑(library list)中缺一個程式館而找不
到正確的資料庫時,系統管理或程式人員可以利用執行遠端指令修正錯
誤讓程式繼續執行,此時使用者針對錯誤訊息應該回 "r" 重試,而不是
回 "c"取消。
可以利用二種方式存取任一工作 QTEMP 程式館的物件:
方式一:
設定工作站訊息佇列(workstation message queue)的回應方式為中
斷(*BREAK)模式,並使用中斷訊息處理理程式(break-handling program)
;當訊息抵達工作站訊息佇列時,中斷訊息處理理程式接收含有指令
的訊息,並執行從訊息中擷取的指令,即可完成。但這個方式僅適用
於線上即時的工作,並不適用於批次工作;你不能從另一個工作傳送
訊息至批次作業。然而使用這個方式也需要於使用者初始程式中設定
設定工作站訊息佇列(workstation message queue)的回應方式為中斷
(*BREAK)模式,這個方式較麻煩及僅適用於線上即時的工作。
Job1 Job2 使用者初始程式設定工作站訊息佇列中斷
(*BREAK)模式及中斷訊息處理理程式
送指令訊息 ==> 工作站訊息佇列
||
||
\/
中斷訊息處理理程式接收含有指令的訊息並執行
從訊息中擷取的指令
方式二:(在此我以方式二作一個範例)
這個方式適用於任何一種工作型態,線上即時式或批次,而且不需要其他
額外的設定,使用上較容易;它包含三個部分,一個指令(RUNJOBCMD),
一支指令處理程式(SNDCMDCL) 及一支執行 RUNJOBCMD 所發出指令的跳出
程式 exit program (RCVCMDCL)。
Job1 Job2
RUNJOBCMD('job2' 'command mesage')
SNDCMDCL ======> Data Queue ==> RCVCMDCL 程式指定於
/\ 發出指令訊息 指令TRCJOB
|| || /\ 參數 EXITPGM 中
||===========|| || 接收訊息指令
接收回傳訊息 ||<===== 並執行訊息指令
回傳訊息
處理權限如下:
1: 發出指令訊息的使用者(Job1 的使用者)對執行訊息指令的使用者
(Job2 的使用者)設定檔要有 *USE 的權限。
2: 發出指令訊息的使用者(Job1 的使用者)對指令 STRSRVJOB,
ENDSRVJOB,TRCJOB 要有 *USE 的權限。這些指令的預設公共權限
是 *EXCLUDE。
3: 或發出指令訊息的使用者(Job1 的使用者)有 *SERVICE 特殊權限。
程式碼如下:
RUNJOBCMD 指令接收二個參數,iSeries 400 的工作(即要執行內含指令訊
息的工作)及所要執行的指令(這個指令將於參數一所指定的工作中執行)。
它並不在執行 RUNJOBCMD 指令的現有工作(current job)中執行。
/* Command.....: RUNJOBCMD */
/* Description.: Runs a command on another job */
/* Compile.....: CRTCMD CMD(QGPL/RUNJOBCMD) PGM(QGPL/SNDCMDCL) + */
/* SRCFILE(YOURLIB/QCMDSRC) */
/* */
CMD PROMPT('Run job command')
PARM KWD(JOBNAME) TYPE(*CHAR) LEN(10) MIN(1) +
CHOICE('Name') PROMPT('Job name')
PARM KWD(JOBUSER) TYPE(*CHAR) LEN(10) MIN(1) +
CHOICE('Name') PROMPT('Job user')
PARM KWD(JOBNUMBER) TYPE(*CHAR) LEN(6) +
RANGE('000000' '999999') MIN(1) +
CHOICE('000000 - 999999') PROMPT('Job +
number')
PARM KWD(COMMAND) TYPE(*CHAR) LEN(512) MIN(1) +
CHOICE('Name') PROMPT('Command to run')
SNDCMDCL 程式是 RUNJOBCMD 指令的處理程式,它會藉由啟動一個服務需要求
(service request) 中斷 iSeries 400 的工作,然後以 資料佇列(Data queue)
的方式傳送要被執行的指令訊息,當發出的指令訊息於另一個工作執行完成後,
若有錯誤會通知發出指令訊息的使用者(Job1 的使用者)。
/* Program.....: SNDCMDCL */
/* Description.: CPP for RUNJOBCMD. Sends command to execute */
/* via data queue. */
/* Compile.....: CRTCLPGM PGM(QGPL/SNDCMDCL) + */
/* SRCFILE(YOURLIB/QCLSRC) */
/* */
PGM PARM(&JOBNAME &USER &JOBNO &CMD)
DCL VAR(&JOBNAME) TYPE(*CHAR) LEN(10)
DCL VAR(&USER) TYPE(*CHAR) LEN(10)
DCL VAR(&JOBNO) TYPE(*CHAR) LEN(06)
DCL VAR(&CMD) TYPE(*CHAR) LEN(512)
DCL VAR(&MSG) TYPE(*CHAR) LEN(132)
DCL VAR(&LEN) TYPE(*DEC) LEN(5 0) VALUE(80)
DCL VAR(&SNDDTAQ) TYPE(*CHAR) LEN(10)
DCL VAR(&RCVDTAQ) TYPE(*CHAR) LEN(10)
DCL VAR(&WAIT) TYPE(*DEC) LEN(5 0) VALUE(15)
MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))
/* Creates data queue to send command and receive messages */
CHGVAR VAR(&SNDDTAQ) VALUE('SND' || &JOBNO)
CHGVAR VAR(&RCVDTAQ) VALUE('RCV' || &JOBNO)
CHKOBJ OBJ(&SNDDTAQ) OBJTYPE(*DTAQ)
MONMSG MSGID(CPF9801) EXEC(DO)
CRTDTAQ DTAQ(QGPL/&SNDDTAQ) MAXLEN(512) TEXT('Send +
Command Data Queue')
CRTDTAQ DTAQ(QGPL/&RCVDTAQ) MAXLEN(512) TEXT('Status +
Data Queue')
ENDDO
/* Clear data queue just in case & sends the command to run */
CALL PGM(QCLRDTAQ) PARM(&SNDDTAQ 'QGPL')
CALL PGM(QCLRDTAQ) PARM(&RCVDTAQ 'QGPL')
CALL PGM(QSNDDTAQ) PARM(&SNDDTAQ 'QGPL' &LEN &CMD)
/* Interrupts the job and executes the command */
STRSRVJOB JOB(&JOBNO/&USER/&JOBNAME)
TRCJOB SET(*ON) MAXSTG(1024) EXITPGM(QGPL/RCVCMDCL)
/* Wait for indication that the command has completed processing */
CALL PGM(QRCVDTAQ) PARM(&RCVDTAQ 'QGPL' &LEN &MSG
&WAIT)
DLYJOB DLY(2)
TRCJOB SET(*END) MAXSTG(1024)
/* End servicing job and interrupt */
ENDSRVJOB
/* Receive the completion messages */
CHGVAR VAR(&WAIT) VALUE(0)
RCVMSG: CALL PGM(QRCVDTAQ) PARM(&RCVDTAQ 'QGPL' &LEN &MSG
&WAIT)
IF COND(&LEN *EQ 0) THEN(GOTO CMDLBL(CLEANUP))
SNDPGMMSG MSG(&MSG)
CHGVAR VAR(&MSG) VALUE(' ')
GOTO CMDLBL(RCVMSG)
/* Error occurred within this program, so just send error message*/
ERROR: RCVMSG MSGTYPE(*EXCP) RMV(*NO) MSG(&MSG)
SNDPGMMSG MSG(&MSG)
CLEANUP: DLTDTAQ DTAQ(QGPL/&SNDDTAQ)
MONMSG MSGID(CPF0000)
DLTDTAQ DTAQ(QGPL/&RCVDTAQ)
MONMSG MSGID(CPF0000)
ENDIT: ENDPGM
於指令 TRCJOB 參數 EXITPGM 所指定的跳出程式 RCVCMDCL,將執行在 TRCJOB
Job 參數所指定的工作下,即是 RUNJOBCMD 指令的 Job 指定值,它從資料佇列
(Data Queue)擷取指令訊息,並執行所擷取的指令,也將完成訊息藉由資料佇列
(Data Queue)回傳。
/* Program.....: RCVCMDCL */
/* Description.: Receives command from data queue and */
/* excecutes it via QCMDEXC */
/* Compile.....: CRTCLPGM PGM(QGPL/RCVCMDCL) + */
/* SRCFILE(YOURLIB/QCLSRC) */
/* */
PGM PARM(&DUMMY)
DCL VAR(&DUMMY) TYPE(*CHAR) LEN(100)
DCL VAR(&JOBNO) TYPE(*CHAR) LEN(06)
DCL VAR(&CMD) TYPE(*CHAR) LEN(512)
DCL VAR(&MSG) TYPE(*CHAR) LEN(132)
DCL VAR(&CLEN) TYPE(*DEC) LEN(15 5)
DCL VAR(&SNDDTAQ) TYPE(*CHAR) LEN(10)
DCL VAR(&RCVDTAQ) TYPE(*CHAR) LEN(10)
DCL VAR(&LEN) TYPE(*DEC) LEN(5 0)
DCL VAR(&WAIT) TYPE(*DEC) LEN(5 0) VALUE(0)
MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ENDIT))
RTVJOBA NBR(&JOBNO)
CHGVAR VAR(&RCVDTAQ) VALUE('SND' || &JOBNO)
CHGVAR VAR(&SNDDTAQ) VALUE('RCV' || &JOBNO)
/* Receive command from data queue */
CALL PGM(QRCVDTAQ) PARM(&RCVDTAQ 'QGPL' &LEN &CMD +
&WAIT)
/* Runs the command */
IF COND(&LEN *EQ 0) THEN(GOTO CMDLBL(ENDIT))
CHGVAR VAR(&CLEN) VALUE(&LEN)
CALL PGM(QCMDEXC) PARM(&CMD &CLEN)
MONMSG MSGID(CPF0000)
/* Indicates command completion and sends completion messages */
CHGVAR VAR(&LEN) VALUE(1)
SENDMSG: CALL PGM(QSNDDTAQ) PARM(&SNDDTAQ 'QGPL' &LEN &MSG)
RCVMSG RMV(*NO) MSG(&MSG) MSGLEN(&LEN)
IF COND(&MSG *NE ' ') THEN(GOTO CMDLBL(SENDMSG))
ENDIT: ENDPGM
使用範例:
RUNJOBCMD JOBNAME(FINGLPOST)
JOBUSER(FINUSER)
JOBNUMBER(123456)
COMMAND('DSPOBJD OBJ(QTEMP/*ALL) OBJTYPE(*ALL) OUTPUT(*PRINT)')
上述使用範例是將批次工作 FINGLPOST 的 QTEMP 程式館中物件細系列出。
因為這份報表是使用者 FINUSER 所產生的,所以要使用 WRKSPLF USER(FINUSER)
指令才能瀏覽上述指令所產生的 QTEMP 物件明細表。
A blog about IBM i (AS/400), MQ and other things developers or Admins need to know.
星期四, 11月 02, 2023
2002-08-27 如何存取任一工作 QTEMP 程式館的物件?
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言