Thursday, November 16, 2023

A quick and easy way to end a job

I have written programs that capture information over time, using a "never ending" Do-loop in a RPG program. When I wanted the job to end I would use the ENDJOB command. There must be an easier way to use ENDJOB without having to search for the job, copy it's name, and then manually enter the information into the command. This post will give you an example of how to do this.

What is becoming one of my favorite SQL View, ACTIVE_JOB_INFO, has exactly what I need to accomplish this. The column JOB_NAME_SHORT was added to this View in 2021 as part of IBM i 7.4 TR4 and 7.3 TR10. This column contains the job name's name, in this case SIMON_JOB. I can use this column to return the full job name and then end the job with that.

Below is the program I wrote to accomplish ending the job:

01  **free
02  ctl-opt main(Main) option(*srcstmt) dftactgrp(*no) ;

03  dcl-proc Main ;
04    dcl-s JobName char(28) ;
05    dcl-s String char(80) ;

06    exec sql SELECT JOB_NAME INTO :JobName
07               FROM TABLE(QSYS2.ACTIVE_JOB_INFO())
08              WHERE JOB_NAME_SHORT = 'SIMON_JOB' ;

09    String = 'ENDJOB JOB(' + JobName + ') OPTION(*IMMED) SPLFILE(*YES) LOGLMT(0)' ;

10    exec sql CALL QSYS2.QCMDEXC(:String) ;
11  end-proc ;

Line 1: If I want to write a program that is modern I need to use totally free RPG.

Line 2: The control options for this program. The first tells the compiler there is a Main procedure, therefore, none of the RPG cycle will be executed by this program. The next is one of my favorite control options that tells the compiler to use the source line numbers, rather than the ones it can generate. Lastly as Main is a procedure I cannot run this in the default activation group.

Line 3: Start of the Main procedure

Lines 4 and 5: The definitions of the two variables I will be using in the program. The first will contain the full job name. The second will contain the command to end the job.

Lines 6 – 8: This is the statement that uses the ACTIVE_JOB_INFO Table function to return the full job name.

Line 6: The full job name is returned in the results and moved into the RPG variable JobName.

Line 8: This is where I say that I am only interested in the job that is called SIMON_JOB. If there could be more than one job with this name I am going to get an error here. And I would need to rethink how to retrieve just the job I am interested in.

Line 9: I prefer to build the CL command that is going to be executed by QCMDEXC in a variable. This way if the command errors I can look at a program dump to see the command that was used, and make my determination what was wrong with it.

Line 10: Here is where I call the SQL procedure QCMDEXC passing it the variable I built on line 9. Here the job is ended.

This program can now be scheduled to run at the time I want SIMON_JOB to stop capturing data.

I am pleased that this is a nice simple program that anyone else can easily understand and use.


This article was written for IBM i 7.5, and should work for some earlier releases too.


  1. You could even go so far to call the scalar function QCMDEXC in the SELECT. :-)

  2. This looks very similar to what my program ended up looking like when I needed to end a bunch of jobs belonging to a subsystem , we spoke briefly about it in Stockholm :) Instead of a single job, I had to loop through them but now I just run an SQL command in the session since it's not something that needs to be scheduled, you were right that ending a job through SQL shouldn't have caused any issues, I was just messing up!

    select QCMDEXC('ENDJOB JOB(' concat JOB_NAME concat ') OPTION(*CNTRLD)')
    from table(qsys2.job_info(JOB_USER_FILTER => 'ZZZZZ'))
    where JOB_N00001='XXXXX'
    and job_status='ACTIVE'


To prevent "comment spam" all comments are moderated.
Learn about this website's comments policy here.

Some people have reported that they cannot post a comment using certain computers and browsers. If this is you feel free to use the Contact Form to send me the comment and I will post it for you, please include the title of the post so I know which one to post the comment to.