August 2005 Technical Tip - Variable Length Records: VB, RDW, BDW, Oh my!

One-to-many relationships are common in business systems. For example, one sales rep can have many customers, one customer can have many invoices, one invoice can have many items, etc. In modern systems, these relationships would likely be implemented with a relational database system using joins of multiple tables. In legacy systems, such relationships were commonly implemented in a hierarchical database or, more simply, with variable length records. This article will focus on how variable length records are stored internally.

To illustrate, consider the following credit card example. Let's assume one person can have many credit cards, but each credit card belongs to one and only one person. Since each record will have a variable number of credit cards, the record will typically include a field which indicates how many. We will choose an arbitrary maximum of 3 credit cards per person (artifically low to simplify our example.) The fixed portion of each record will contain an ID number (3 bytes), first name (10 bytes), last name (10 bytes), and occurances count (2 bytes), for a total of 25 bytes. For each credit card we will store the credit card number (4 bytes), credit card type (4 bytes) and balance due (4 bytes), for a total of 12 bytes. So each record contains from 25 bytes to 61 bytes (25 + (3*12)).

When the system stores a variable length record, it puts a four byte record descriptor word (RDW) on the front of each record. This RDW is not always visible (such as within a COBOL program) but it's there. The first two bytes of the RDW is a binary halfword (PIC S9(4) COMP) containing the length of the record. This length includes the data and the RDW itself. Consequently, our RDW will have a value of 29 to 65. This highest number (65) will be the LRECL when we allocate the file. The second two bytes of the RDW contains X'0000'.

We can allocate a simple variable length file with ISPF panel 3.2. For example:

   Menu  RefList  Utilities  Help                                               
 ______________________________________________________________________________ 
                             Allocate New Data Set                              
 Command ===>                                                                   
  
 Data Set Name  . . . : U0290.CREDIT.CARDS                                      
                                                                                
 Management class . . . MCTSOX         (Blank for default management class)     
 Storage class  . . . . SCBASE         (Blank for default storage class)        
  Volume serial . . . . XTSO05         (Blank for system default volume) **     
  Device type . . . . .                (Generic unit or device address) **      
 Data class . . . . . .                (Blank for default data class)           
  Space units . . . . . TRACK          (BLKS, TRKS, CYLS, KB, MB, BYTES         
                                        or RECORDS)                             
  Average record unit                  (M, K, or U)                             
  Primary quantity  . . 1              (In above units)                         
  Secondary quantity    1              (In above units)                         
  Directory blocks  . . 0              (Zero for sequential data set) *         
  Record format . . . . VB                                                      
  Record length . . . . 65                                                      
  Block size  . . . . . 0                                                       
  Data set name type  :                (LIBRARY, HFS, PDS, or blank)  *         
                                       (YY/MM/DD, YYYY/MM/DD                    
  Expiration date . . .                 YY.DDD, YYYY.DDD in Julian form         
                                                                                

We can then edit the file with ISPF panel 2. Be sure to choose the Preserve VB record length option!

   Menu  RefList  RefMode  Utilities  Workstation  Help                         
 ______________________________________________________________________________ 
                                Edit Entry Panel                                
 Command ===>                                                                   
                                                                                
 ISPF Library:                                                                  
    Project . . . U0290                                                         
    Group . . . . ISPF     . . .          . . .          . . .                  
    Type  . . . . CNTL                                                          
    Member  . . .                 (Blank or pattern for member selection list)  
                                                                                
 Other Partitioned, Sequential or VSAM Data Set:                                
    Data Set Name . . . credit.cards                                            
    Volume Serial . . .           (If not cataloged)                            
                                                                                
 Workstation File:                                                              
    File Name . . . . .                                                         
                                         Options                                
 Initial Macro  . . . .                     Confirm Cancel/Move/Replace         
 Profile Name . . . . .                     Mixed Mode                          
 Format Name  . . . . .                     Edit on Workstation                 
 Data Set Password  . .                  /  Preserve VB record length           
                                                                                

We can enter the data as follows. Note that although the LRECL is 65, the ruler (from the COLS command) only goes out to column 61. The difference is the RDW (4 bytes) which is not seen.

   File  Edit  Edit_Settings  Menu  Utilities  Compilers  Test  Help            
 _______________________________________________________________________________ 
 EDIT       U0290.CREDIT.CARDS                              Columns 00001 00061 
 Command ===>                                                  Scroll ===> HALF 
 ****** ***************************** Top of Data ******************************
 =COLS> ----+----1----+----2----+----3----+----4----+----5----+----6-           
 000001 987BILL      QUALLS    035555VISA10002345MAST05001234DISC0100           
 000002 123RUBECCA   ALINIAZEE 011010VISA0000                                   
 000003 786ERIC      ALBERT    022323MAST01003434DISC9999                       
 000004 432JASON     ROGERS    017777DISC0750                                   
 ****** **************************** Bottom of Data ****************************

IDCAMS can be used to dump the file. The JCL appears as follow:

   File  Edit  Edit_Settings  Menu  Utilities  Compilers  Test  Help            
 _______________________________________________________________________________ 
 EDIT       U0290.ISPF.CNTL(DUMPVB) - 01.00                 Columns 00001 00072 
 Command ===>                                                  Scroll ===> HALF 
 ****** ***************************** Top of Data ******************************
 000001 //U0290DMP JOB (PRM,0,T),'BILL QUALLS',                                 
 000002 //  CLASS=A,MSGCLASS=T,TIME=(0,59),NOTIFY=U0290                         
 000003 //STEP010 EXEC PGM=IDCAMS                                               
 000004 //MYINPUT  DD DSN=U0290.CREDIT.CARDS,DISP=SHR                           
 000005 //SYSIN    DD *                                                         
 000006   PRINT INFILE(MYINPUT) DUMP                                            
 000007 //SYSPRINT DD SYSOUT=*                                                  
 ****** **************************** Bottom of Data ****************************

We can see from the following dump that the records are, in fact, varying in length.

LISTING OF DATA SET -U0290.CREDIT.CARDS  

RECORD SEQUENCE NUMBER - 1  
000000  F9F8F7C2 C9D3D340 40404040 40D8E4C1   D3D3E240 404040F0 F3F5F5F5 F5E5C9E2   *987BILL      QUALLS    035555VIS* 
000020  C1F1F0F0 F0F2F3F4 F5D4C1E2 E3F0F5F0   F0F1F2F3 F4C4C9E2 C3F0F1F0 F0         *A10002345MAST05001234DISC0100   * 

RECORD SEQUENCE NUMBER - 2  
000000  F1F2F3D9 E4C2C5C3 C3C14040 40C1D3C9   D5C9C1E9 C5C540F0 F1F1F0F1 F0E5C9E2   *123RUBECCA   ALINIAZEE 011010VIS* 
000020  C1F0F0F0 F0                                                                 *A0000                           * 
 
RECORD SEQUENCE NUMBER - 3  
000000  F7F8F6C5 D9C9C340 40404040 40C1D3C2   C5D9E340 404040F0 F2F2F3F2 F3D4C1E2   *786ERIC      ALBERT    022323MAS* 
000020  E3F0F1F0 F0F3F4F3 F4C4C9E2 C3F9F9F9   F9                                    *T01003434DISC9999               * 

RECORD SEQUENCE NUMBER - 4  
000000  F4F3F2D1 C1E2D6D5 40404040 40D9D6C7   C5D9E240 404040F0 F1F7F7F7 F7C4C9E2   *432JASON     ROGERS    017777DIS* 
000020  C3F0F7F5 F0                                                                 *C0750                           * 

But what about the RDW? The RDW is usually not shown, but there is a trick you can use to force its display. This involves adding DCB=RECFM=U to the JCL as follows:

   File  Edit  Edit_Settings  Menu  Utilities  Compilers  Test  Help            
 _______________________________________________________________________________ 
 EDIT       U0290.ISPF.CNTL(DUMPVB) - 01.00                 Columns 00001 00072 
 Command ===>                                                  Scroll ===> HALF 
 ****** ***************************** Top of Data ******************************
 000001 //U0290DMP JOB (PRM,0,T),'BILL QUALLS',                                 
 000002 //  CLASS=A,MSGCLASS=T,TIME=(0,59),NOTIFY=U0290                         
 000003 //STEP010 EXEC PGM=IDCAMS                                               
 000004 //MYINPUT  DD DSN=U0290.CREDIT.CARDS,DISP=SHR,DCB=RECFM=U 
 000005 //SYSIN    DD *                                                         
 000006   PRINT INFILE(MYINPUT) DUMP                                            
 000007 //SYSPRINT DD SYSOUT=*                                                  
 ****** **************************** Bottom of Data ****************************

The resulting dump is at the same time confusing and revealing:

LISTING OF DATA SET -U0290.CREDIT.CARDS
  
RECORD SEQUENCE NUMBER - 1
000000  00CC0000 00410000 F9F8F7C2 C9D3D340   40404040 40D8E4C1 D3D3E240 404040F0   *........987BILL      QUALLS    0* 
000020  F3F5F5F5 F5E5C9E2 C1F1F0F0 F0F2F3F4   F5D4C1E2 E3F0F5F0 F0F1F2F3 F4C4C9E2   *35555VISA10002345MAST05001234DIS* 
000040  C3F0F1F0 F0002900 00F1F2F3 D9E4C2C5   C3C3C140 4040C1D3 C9D5C9C1 E9C5C540   *C0100....123RUBECCA   ALINIAZEE * 
000060  F0F1F1F0 F1F0E5C9 E2C1F0F0 F0F00035   0000F7F8 F6C5D9C9 C3404040 404040C1   *011010VISA0000....786ERIC      A* 
000080  D3C2C5D9 E3404040 40F0F2F2 F3F2F3D4   C1E2E3F0 F1F0F0F3 F4F3F4C4 C9E2C3F9   *LBERT    022323MAST01003434DISC9* 
0000A0  F9F9F900 290000F4 F3F2D1C1 E2D6D540   40404040 D9D6C7C5 D9E24040 4040F0F1   *999....432JASON     ROGERS    01* 
0000C0  F7F7F7F7 C4C9E2C3 F0F7F5F0                                                  *7777DISC0750                    * 

Look at the first line and you will see 00410000. This is the RDW for the first record. X'0041' is the hexadecimal representation of the number 65 (4 * 16 + 1). This is the total length of the first record. Find 00290000 in the third line. This is the RDW for the second record: 29 base 16 = 41 base 10. Similarly, you will see 00350000 in the fourth line and 00290000 in the sixth line, representing the lengths of the third (53) and fourth (41) records respectively.

Just as an RDW describes each record, a BDW describes each block. Find 00CC0000 in the first line. CC base 16 = 204 base 10. This is the length of the block: 65 (first) + 41 (second) + 53 (third) + 41 (fourth) + 4 (for the BDW itself.)

I hope this article helped you to understand variable length records. In next month's article I will show you how to reformat variable length records using SyncSort. Until then, we hope you will continue to consider Caliber Data Training when searching for an IT training provider.


Go to the articles index. Written by Bill Qualls. Copyright © 2005 by Caliber Data Training 800.938.1222