CL using SQL
CL allows multiple ways to incorporate SQL into jobs.
Simplify Command Execution with CL
CL offers a commmand RUNSQLSTM, which is based on source file data. This is simple, but if the SQL string is predictable, without extensive variables, it is simple and effective. In V7.1 of the OS IBM introduced the RUNSQL command allowing users to run a single SQL statement. It had the same limitations as RUNSQLSTM; non-SELECT statements. INSERT, UPDATE, DELETE, DROP and CREATE may be executed with RUNSQL, but not the SELECT.
However, you can create a version of the RUNSQL statement that can make use of the SELECT statement. See the example below. This program has a user-created command that executes an SQL statement generating an output file based on data selected.
PGM DCLPRCOPT DFTACTGRP(*NO) ACTGRP(TRACE) + BNDSRVPGM((ISI000SV)) DCL VAR(&IMPFOLDER) TYPE(*CHAR) LEN(200) DCL VAR(&ARCFOLDER) TYPE(*CHAR) LEN(200) DCL VAR(&MSGKEY) TYPE(*CHAR) LEN(4) DCL VAR(&PGMNAME) TYPE(*CHAR) LEN(10) DCL VAR(&FUNCTION) TYPE(*CHAR) LEN(25) DCL VAR(&PROGRAM) TYPE(*CHAR) LEN(15) DCL VAR(&SENDER) TYPE(*CHAR) LEN(80) DCL VAR(&FILEPATH) TYPE(*CHAR) LEN(200) DCL VAR(&FILENAME) TYPE(*CHAR) LEN(25) DCL VAR(&JOBTYPE) TYPE(*CHAR) LEN(1) DCL VAR(&JOBDATE) TYPE(*CHAR) LEN(6) /* sac01 */ DCL VAR(&SYSNAME) TYPE(*CHAR) LEN(8) DCL VAR(&LIBRARY) TYPE(*CHAR) LEN(10) + VALUE('*LIBL') DCL VAR(&EXCEPTION) TYPE(*CHAR) LEN(25) /* sac01 */ DCL VAR(&DOCUMENT) TYPE(*CHAR) LEN(15) /* sac01 */ DCL VAR(&EXPFOLDER) TYPE(*CHAR) LEN(200) /* sac01 */ DCL VAR(&ERRPATH) TYPE(*CHAR) LEN(200) /* sac01 */ DCL VAR(&ERRNAME) TYPE(*CHAR) LEN(17) /* sac01 */ DCL VAR(&ERRFOLDER) TYPE(*CHAR) LEN(200) /* sac02 */ DCL VAR(&SCANREC) TYPE(*DEC) LEN(10 0) DCL VAR(&XREFREC) TYPE(*DEC) LEN(10 0) DCL VAR(&POS) TYPE(*UINT) LEN(2) DCL VAR(&SUBJECT) TYPE(*CHAR) LEN(50) /* sac02 */ dcl var(&message) type(*char) len(80) /* sac02 */ dcl var(&reason) type(*char) len(80) /* sac02 */ dcl var(&ERROR) type(*LGL) len(1) /* sac02 */ RTVJOBA TYPE(&JOBTYPE) DATE(&JOBDATE) RTVNETA SYSNAME(&SYSNAME) /*-------------------------------------------------------------------*/ /* Get the program name */ /*-------------------------------------------------------------------*/ SNDPGMMSG MSG(' ') TOPGMQ(*SAME) MSGTYPE(*INFO) + KEYVAR(&MSGKEY) RCVMSG PGMQ(*SAME) MSGTYPE(*INFO) RMV(*YES) + SENDER(&SENDER) CHGVAR VAR(&PGMNAME) VALUE(%SST(&SENDER 56 10)) CHGVAR VAR(&PROGRAM) VALUE(&PGMNAME) /*-------------------------------------------------------------------*/ /* Get the folder where the data is located */ /*-------------------------------------------------------------------*/ CHGVAR VAR(&PROGRAM) VALUE(&PGMNAME) CHGVAR VAR(&FUNCTION) VALUE('IMPFOLDER') CALL PGM(ISI005RP) PARM(&PROGRAM &FUNCTION &IMPFOLDER) CHGVAR VAR(&FUNCTION) VALUE('ARCFOLDER') CALL PGM(ISI005RP) PARM(&PROGRAM &FUNCTION &ARCFOLDER) CHGVAR VAR(&FUNCTION) VALUE('ERRFOLDER') /* sac02 */ CALL PGM(ISI005RP) PARM(&PROGRAM &FUNCTION + &ERRFOLDER) /*-------------------------------------------------------------------*/ /* Read the files in the folder and move them to archive */ /*-------------------------------------------------------------------*/ LIST: CALL PGM(ISI010RP) PARM(&IMPFOLDER) READ: DOUNTIL COND(&FILEPATH *EQ '*****') CALL PGM(ISI020RP) PARM(&FILEPATH) /*-------------------------------------------------------------------*/ /* Copy the current file to the mail trace file */ /*-------------------------------------------------------------------*/ STRCOPY: IF COND(&FILEPATH *NE '*****') THEN(DO) CLRPFM FILE(ISIIMBWF) DLTF FILE(QTEMP/DUPSCANS) /* sac01 */ MONMSG MSGID(CPF0000) DLTF FILE(QTEMP/NOPOXREF) MONMSG MSGID(CPF0000) CHGVAR VAR(&SCANREC) VALUE(0) CHGVAR VAR(&XREFREC) VALUE(0) CPYFRMIMPF FROMSTMF(&FILEPATH) TOFILE(ISIIMBWF) + RCDDLM(*LF) STRDLM(*NONE) FLDDLM('|') + RPLNULLVAL(*FLDDFT) EXECSQL STMT('SELECT + count(*),IMZIPP,IMROUT,IMZIPC,imddtm FROM + ISIimbwf GROUP BY + imzipp,imrout,imzipc,imddtm HAVING + count(*) > 1') OUTPUT(*OUTFILE) + OUTFILE(QTEMP/DUPSCANS) RTVMBRD FILE(DUPSCANS) NBRCURRCD(&SCANREC) IF COND(&SCANREC *GT 0) THEN(DO) CALLSUBR SUBR(EXCEPTION) GOTO CMDLBL(ENDCOPY) ENDDO EXECSQL STMT('select distinct aa.imdesc, bb.uspcod + from ISIimbwf aa left join ISIpocpf bb + on aa.imdesc = bb.uspdsc where + bb.uspcod is null') OUTPUT(*OUTFILE) + OUTFILE(QTEMP/NOPOXREF) RTVMBRD FILE(NOPOXREF) NBRCURRCD(&XREFREC) IF COND(&XREFREC *GT 0) THEN(DO) CALLSUBR SUBR(EXCEPTION) GOTO CMDLBL(ENDCOPY) ENDDO MOV OBJ(&FILEPATH) TODIR(&ARCFOLDER) MONMSG MSGID(CPFA0A0) EXEC(DO) CHGVAR VAR(&SUBJECT) VALUE(' ') CHGVAR VAR(&message) VALUE(' ') CHGVAR VAR(&reason) VALUE(' ') CALLSUBR SUBR(ARCHIVESR) ENDDO CALL PGM(ISIG071RP) /*-------------------------------------------------------------------*/ /* Move the data file to archive */ /*-------------------------------------------------------------------*/ ARCHIVE: ENDCOPY: ENDDO ENDREAD: ENDDO TERMINATE: RETURN /*-----------------------------------------------------------------*/ /* subroutine added to manage file exceptions */ /*-----------------------------------------------------------------*/ ERRFILE: SUBR SUBR(EXCEPTION) CHGVAR VAR(&DOCUMENT) VALUE('POLICY') CHGVAR VAR(&EXCEPTION) VALUE('EXCEPTION') CALL PGM(ISI005RP) PARM(&DOCUMENT &EXCEPTION + &EXPFOLDER) MOV OBJ(&FILEPATH) TODIR(&EXPFOLDER) CHGVAR VAR(&DOCUMENT) VALUE('ISIFTP') CHGVAR VAR(&EXCEPTION) VALUE('OUTBOUNDFOLDER') CALL PGM(ISI005RP) PARM(&DOCUMENT &EXCEPTION + &ERRFOLDER) CHGVAR VAR(&POS) VALUE(%SCAN('.7640' &FILEPATH)) CHGVAR VAR(&ERRNAME) VALUE(%SST(&FILEPATH &POS 18)) IF COND(&SCANREC *GT 0) THEN(DO) CHGVAR VAR(&ERRFOLDER) VALUE(&ERRFOLDER *TCAT + 'DUPSCANS' *TCAT &ERRNAME *TCAT '.TXT') CPYTOIMPF FROMFILE(DUPSCANS) TOSTMF(&ERRFOLDER) + MBROPT(*REPLACE) STMFCCSID(1252) + RCDDLM(*CRLF) STRDLM(*NONE) FLDDLM('|') ENDDO IF COND(&XREFREC *GT 0) THEN(DO) CHGVAR VAR(&ERRFOLDER) VALUE(&ERRFOLDER *TCAT + 'NOPOXREF' *TCAT &ERRNAME *TCAT '.TXT') CPYTOIMPF FROMFILE(NOPOXREF) TOSTMF(&ERRFOLDER) + MBROPT(*REPLACE) STMFCCSID(1252) + RCDDLM(*CRLF) STRDLM(*NONE) FLDDLM('|') ENDDO ENDSUBR /*==================================================================*/ /* sac02 - move file to archive */ /*==================================================================*/ SUBR SUBR(ARCHIVESR) RETRY: CHGVAR VAR(&ERROR) VALUE('0') MOV OBJ(&FILEPATH) TODIR(&ARCFOLDER) MONMSG MSGID(CPFA0A0) EXEC(DO) CHGVAR VAR(&ERROR) VALUE('1') CALL PGM(ISI305RP) PARM(&FILEPATH &ARCFOLDER) ENDDO IF COND(&ERROR) THEN(GOTO CMDLBL(RETRY)) CHGVAR VAR(&SUBJECT) VALUE('Return file error + occurred') CHGVAR VAR(&MESSAGE) VALUE('Error occurred when + attempting to move to the archive + folder.') CHGVAR VAR(&REASON) VALUE('Check the job log of + ISIIMBTRC for details.') CALL PGM(ISI415CL) PARM(&SUBJECT &MESSAGE &REASON) ENDSUBR ENDPGM
EXECSQL Command
Here is the EXECSQL command, a wrapper over a Query Manager query (STRQMQRY) which will allow you to include a SELECT statement in SQL string.
CMD PROMPT('EXECUTE SQL STATEMENT') PARM KWD(STMT) TYPE(*CHAR) LEN(1430) MIN(1) + EXPR(*YES) PROMPT('SQL statement') PARM KWD(OUTPUT) TYPE(*CHAR) LEN(10) RSTD(*YES) + DFT(*) VALUES(* *PRINT *OUTFILE) + PROMPT('Output') PARM KWD(OUTFILE) TYPE(QUAL1) PMTCTL(PROMPT1) + PROMPT('Output file name') PARM KWD(MEMBER) TYPE(QUAL2) PMTCTL(PROMPT1) + PROMPT('Output member options') PARM KWD(PRTFILE) TYPE(QUAL3) PMTCTL(PROMPT2) + PROMPT('Printer file to use') QUAL1: QUAL TYPE(*NAME) LEN(10) QUAL TYPE(*NAME) LEN(10) DFT(*LIBL) SPCVAL((*LIBL + *N) (*CURLIB *N)) PROMPT('Library') QUAL2: QUAL TYPE(*NAME) LEN(10) DFT(*FIRST) + SPCVAL((*FIRST *N)) QUAL TYPE(*NAME) LEN(10) RSTD(*YES) DFT(*REPLACE) + SPCVAL((*REPLACE *N) (*ADD *N)) + PROMPT('Replace or add records') QUAL3: QUAL TYPE(*NAME) LEN(10) DFT(QSYSPRT) QUAL TYPE(*NAME) LEN(10) DFT(*LIBL) SPCVAL((*LIBL + *N) (*CURLIB *N)) PROMPT('Library') PROMPT1: PMTCTL CTL(OUTPUT) COND((*EQ *OUTFILE)) PROMPT2: PMTCTL CTL(OUTPUT) COND((*EQ *PRINT))