IDMS Programmer's Handbook - Culprit

Culprit

Dumping Database Records With Culprit

  1. Culprit can be used to dump full or partial database records in hexadecimal format using the CULEDUMP user module. A sample annotated program that dumps the records in the NAME-ID PERSON STUDENT ACT path is shown below. It should be fairly easy to adapt this program to dump other records in other paths. The same program, excluding the UM(CULEDUMP) on the OUT line, may be run to simply list the records without a hex dump.

    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.

  2. Put the name of your subschema after SS=. The subschema should not have any index areas in it. Remember that your userid must be authorized to use a particular subschema with Culprit.

  3. Each record is redefined as one or more fields. Since a line can be only 132 characters long, the field can be only 117 bytes long if it starts in column 16, as in this case. The format of the REC line is REC new-field-name (db-record-name) start-position length.

  4. The PERSON record is defined in its entirety by two fields. If you want to dump only parts of a record, you may define separate fields for each part.

  5. Only the first 117 bytes of the STUDENT record are to be dumped.

  6. Four paths are defined:
    • Path 01 will be returned when all the records are found.
    • Path 02 will be returned when all but the ACT record are found.
    • Path 03 will be returned when only the NAME-ID and PERSON records are found.
    • Path 04 will be returned when only a NAME-ID record is found.


  7. The records will be sorted by the NAME-ID-1 field.

  8. UM(CULEDUMP) requests a hex dump. Omit, for an alpha listing.

  9. Here begin the detail lines for output. For reference, the format of the lines is:

    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.

  10. Test each path. This line means, 'If PATH-ID is not 01, go to line 150 otherwise, fall through to line 115. '

  11. This line selects the detail lines to be printed, in this case detail lines 1 through 5. Subsequent lines are not executed after a TAKE instruction.

Culprit Execution, Print, and Secondary Dictionary Access

Culprit Execution

Culprit should be executed using one of the two procedures provided:


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).

Culprit Print

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.

Culprit Secondary Dictionary Database Access

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= secdictname
where 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

Culprit User ID's

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.

Culprit Labels

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 

Culprit With Indexes

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:

ACCOUNT NUMBERS AND TITLES


001085101 CASH ONE HUNDRED
109001020
109001030
109001050
109001070
109001090 HOUSING
109030015

Using Culprit With Flat Files

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:

  1. ADD FILE Fxxx123.
  2. ADD REC Wxxx123 INCLUDE WITHIN FILE Fxxx123.
         10 FIELDS.
              15 FIELD-1 PIC X(50) USA DIS.
              15 FIELD-2 PIC X(30) USA DIS.
    

  3. You can then reference this file on your IN statement, and FIELD-1 and FIELD-2 will be copied in without the need for REC statements:
         //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.

Culprit Security

To run a Culprit job against the production database you will need to:

  1. Complete a Culprit authorization form and have it signed by the appropriate project leader.
  2. Bring the completed form to any member of the DBA group along with the MVS user number that the job will use.
  3. Setup your SYSIN card to read:
         //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.

Culprit Subschemas

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.

Using Condition Codes in Culprit

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 %%' 



table of contents prev page next page