IN 5000 DB SS=ZSASB001 $ 2 SUBSCHEMA REC NAME-ID-1 (NAME-ID) 1 54 $ 3 REDEFINE EACH RECORD REC PERSON-1 (PERSON) 1 117 $ 4 AS ONE OR MORE FIELDS REC PERSON-2 (PERSON) 118 15 $ 5 MAX. LENGTH = 117 IF REC STUDENT1 (STUDENT) 1 117 $ 6 OUTPUT BEGINS IN 16 REC ACT-1 (ACT) 1 52 $ 7 2ND NUMBER = LENGTH PATH01 NAME-ID PERSON(04) STUDENT(03) ACT(02) $ 8 PATHS 01SORT NAME-ID-1 $ 9 SORT FIELDS 01OUT132 UM(CULEDUMP) LP=55 $ 10 DUMP MODULE, LINES/PG 01D1 010'NAME-ID:' $ 11 RECORD NAME 01D1 16 NAME-ID-1 $ 12 RECORD CONTENTS 01D2 01 'PERSON 1:' $ 13 01D2 16 PERSON-1 $ 14 01D3 01 'PERSON 2:' $ 15 01D3 16 'PERSON 2:' $ 16 01D4 01 'STUDENT:' $ 17 01D4 16 STUDENT-1 $ 18 01D5 01 'ACT:' $ 19 01D5 16 ACT-1 $ 20 01I110 IF PATH-ID NE '01 150 $ 21 GOT THE WHOLE PATH 01I115 TAKE (1 2 3 4 5) $ 22 PRINT ALL LINES 01I150 IF PATH-ID NE '02' 200 $ DIDN'T GET ACT 01I155 TAKE (1 2 3 4) $ 24 PRINT FIRST 4 LINES 01I200 IF PATH-ID NE '03' 250 $ DIDN'T GET STUDENT 01I205 TAKE (1 2 3) $ 26 PRINT FIRST 3 LINES 01I250 IF PATH-ID NE '04' 300 $ DIDN'T GET NAME-ID 01I255 TAKE 1 $ 28 PRINT FIRST LINE ONLY 01I300 DROP $ 29 INVALID PATH-ID
The notes on the next page refer to the line numbers following the dollar signs in the program. Dollar signs begin comment fields.
Col. 2-3 Report Number
4 'D' for Detail
5 Line number (8 is the maximum!)
6-9 Column within Line. In this example, the record name has
been inserted in column 1 and the record contents in column
16. In the dump, a blank is inserted before each field, so
they actually begin in 'columns' 2 and 17.
10 Carriage control. Can make first one '0'.
11 Field name, either literal or variable.
Note: A maximum of 132 characters may be defined for each line. you may omit or shorten the RECORD-NAME field and increase the RECORD-CONTENTS field. The entire 133 bytes for the line (including carriage control) are printed in the dump, padded with blanks.
CULPPROD to access the production IDMS02 databases (CV2) CUL3PROD to access the production IDMS03 databases (CV3) CULPTEST to access the IDMSTEST databases (CV1) CUL4TEST to access the IDMST04 databases (CV4)
Both procedures are set up to run local rather than under CV, And DD cards for all the database files have been included in the cataloged procedures. You must use a xxZ899 subschema in your program.The only thing you need to do before executing your Culprit program is to have a DBA Group member authorize your project's Culprit user to access the xxxZ899 subschema used by the program (Production IDMS only).
A modification has been made at UNM to the standard Culprit so that only the program source listing is directed to the SYS004 ddname. The report itself is directed to the REPORTS ddname in order to separate it from the source listing, just in case the report requires a special form.
When accessing a database defined by a subschema on a secondary dictionary, the first Culprit statement, even before the PROFILE statement, must be:
DATABASE DICTNAME= secdictnamewhere secdictname is the name of the secondary dictionary (e.g., IAI). No 'PARM' is required on the EXEC JCL statement. If the Culprit program is reading the secondary dictionary itself as a database, the statement should read:
DATABASE DBNAME= secdictname
Each project has its own in-house user ID named CULPppp for ITS programmer usage ('ppp' is the project code). Each project also has and end-user Culprit user ID named CULPppp. These user ID's are for end users to access the database with Culprit.
On production IDMS only these CULPppp users will be allowed to access subschemas for Culprit reporting. On test IDMS all users are allowed to use all subschemas with Culprit.
C.A. provides a user output module, CULELABL, to print mailing labels. If other reports are produced at the same time as the label report, the label report must be the first ('01' level. Its output will be directed to the REPORTS ddname definition. Subsequent reports must use SYS030, SYS031, etc., to direct their output to appropriate forms. The program source code is printed on SYS004.
See the manual Culprit User Modules for more information on CULELABL. Following is an example of a program that reads a sequential input file to produce labels and a report. The data could also be retrieved from the database with a PATH card.
//stepname EXEC CULPPROD (or CULPTEST) //REPORTS DD SYSOUT=(F,,6673) <---labels form //SYS030 DD SYSOUT="*,DCB=(RECFM=FBA,LRECL=133,BLKSIZE=133)" //INPUTA DD DSN="nondatabase" sequential input file //SYSIN DD DSN="IDMS.Culprit.xxx,DISP=SHR" // DD * IN 140 DD="INPUTA" REC STU-NO 1 9 'STUDENT NUMBER' REC STU-NAME 10 30 'STUDENT NAME' REC STU-NAME-REV 40 30 REC STREET 71 30 REC CITY 101 23 REC STATE 124 2 REC ZIP 126 9 REC TESTDATE 134 6 'TESTDATE' REC EDUCATLVL 70 1 'EDUCATIONAL LEVEL' 01OUT 36 108 UM(CULELABL) $PRINT THREE UP LABELS 01SORT ZIP,A 01511 1STU-NAME-REV 01521 STREET 01531 CITY 015324 STATE 01551 ZIP 02OUT 132 NS DD="SYS030" 02SORT STU-NO,A 020 COUNT 023 STUDENTS CHANGED FROM JUNIOR TO SENIOR 0251* 10STU-NO HH ' ', ' ', 'STUDENT NUMBER' 0251* 20STU-NAME HH ' ', ' ', 'STUDENT NAME' 0251* 30TESTDATE HH ' ', ' ', 'TESTDATE' 0251* 40EDUCATLVL HH ' ', ' ', 'EDUCATIONAL LEVEL' 0262 600 'TOTAL STUDENTS CHANGED' 0262 850COUNT SZ="6" $COUNT PRINTED ONLY AT END 027 COMPUTE COUNT + 1 COUNT
The following Culprit program is an example of how to use indexes with Culprit. The keys are stored in a KEYFILE defined by ddname FILEA. The index is OLD-ACCT-IX, an index on the OLDACCT record
(now gone).
//CULPRIT EXEC CULPTEST //CULP0.FILEA DD DSN=DPC.LSS.FS039XXX,DISP=OLD //SYSIN DD DSN=IDMS.CULPRIT.xxx,DISP=SHR // DD * IN DB SS=ZSAR039 PATH01 OLDACCT(OLD-ACCT-IX) ACCOUNT KEYFILE 10 F 4000 PS DD=FILEA KF=1,9 REC IN-ACCT(KEYFILE) 1 9 010BLNKLINE ' ' 01OUT 73 D 01H10031 'ACCOUNT NUMBERS AND TITLES' 01D1*010 IN-ACCT 01D1*020 AC-ACCT-NAME 01D2*020 BLNKLINE 01I IF OA-OLD-ACCT = IN-ACCT 100 01I DROP 01I100 RELS 1 01I TAKE 2
The report turned out as follows:
This is the method for handling non-database input files on production Culprit. This requires production flat file users to include the following on their IN statement:
IN... FN=Fxxx899 (Where xxx = the project code, FAP, SRG, PSS, etc.)
This reference is to a dummy IDD file. This file is used to insure security for production Culprit jobs that use non-database files. Note that the DD name of the non-database file can be selected by adding any DD name to the IN card:
//INFILE DD DSN=YOUR.FLAT.FILE
IN 80 FN=Fxxx899 DD=INFILE
Rather than using Fxxx899, which will require you to define each field in many REC statements, you can define the entire record within IDD. When executed, IDD automatically picks up all record names associated with the file, and no REC parameters are necessary. For example, to create a file called Fxxx123 you can:
10 FIELDS.
15 FIELD-1 PIC X(50) USA DIS.
15 FIELD-2 PIC X(30) USA DIS.
//INFILE DD DSN=ACTUAL.DATA.FILE,DISP=SHR
IN 80 FN=Fxxx123 DD=INFILE
This can be done on test IDD and the DBA group will migrate the file definitions into production.
To run a Culprit job against the production database you will need to:
//SYSIN DD DSN=IDMS. CULPRIT.xxx,DISP=SHR
// DD * (where xxx=SAS,SRG...)
Only the MVS user numbers that the DBA group has authorized will be able to use this DD statement. The IDMS.CULPRIT.xxx file contains the dummy user and password that can access the subschema.
All of the subschemas for Culprit use are in the form: xxxZ899 These subschemas have been authorized in IDD for the corresponding Culprit user, and they will not function properly if used in anything other than a Culprit statement.
Example: IN 1000 DB SS=xxxZ899
The xxxZ899 subschemas are restricted to readying all areas in retrieval mode.
All Culprit programs should be able to issue a nonzero condition code in the event of an error. There are two types of errors that can be identified in a Culprit program. The first type is a system error such as a Culprit syntax error or a file I/O error. The other type is an error that is recognized internal to the application, such as a data error.
To flag the first error, the parameter RC=0,0,99,99 should be entered on the profile statement. This will return a condition code of 0 if the error is informational or a warning, and 99 if the error is severe or fatal. Note that this parameter has been added to the profile statement in the Culprit security datasets. Therefore, if an application uses a security dataset, this parameter should not be repeated in the Culprit program, because any duplication of a parameter on a profile statement will result in a syntax error.
To flag the second type of error, include a profile statement in your Culprit program that includes the parameters EE=0,ABEND,n,NODUMP. "n" should be replaced by the condition code that will be returned when an error is detected by your program. To cause an error detected by your program to abend the program, when the error is detected, branch to an error routine. The error routine should contain a type 7 statement with a divide by zero and a statement to issue an error message. These statements, in conjunction with the error specification on the profile statement, will cause a condition code to be returned and the error message to be displayed along with the Culprit messages.
The example shown below is a check for an empty input dataset. If the dataset is empty, the program will abnormally terminate with a condition code of 9. If it is not empty, it will execute normally.
PROFILE EE=0,ABEND,9,NODUMP . . (initial part of program) . 01I010 IF EOF EQ AND NO-DATA = 'Y' 200 $EMPTY DATASET PROCESSING 01I020 IF EOF EQ AND NO-DATA = 'N' DROP $VALID END OF FILE PROCESSING 01I030 MOVE'N' TO NO-DATA 01I TAKE 01I200 CALL US48 (MESSAGE) 01I ZERO / ZERO ZERO 010 ZERO 010 NO-DATA 'Y' 010 MESSAGE '0' EMPTY DATASET %%'