MainframeMaster

COBOL Tutorial

COBOL INDEXED BY Clause

The INDEXED BY clause represents the foundational table index declaration mechanism within COBOL programming environments, providing automatic index creation and management capabilities that enable efficient table navigation, optimized array processing, and streamlined data structure access. This clause embodies advanced table handling principles by supporting multiple concurrent indexes, automatic index initialization, and enhanced performance characteristics while facilitating complex table operations, multi-dimensional array processing, and comprehensive data manipulation across enterprise applications requiring high-performance bulk data processing and optimal memory utilization patterns.

INDEXED BY Syntax

Index Declaration with INDEXED BY
cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
*> Basic INDEXED BY syntax 01 table-name. 05 entry-name OCCURS n TIMES INDEXED BY index-name-1 [, index-name-2, ...]. *> Single index example 01 EMPLOYEE-TABLE. 05 EMP-RECORD OCCURS 100 TIMES INDEXED BY EMP-IDX. 10 EMP-ID PIC 9(6). 10 EMP-NAME PIC X(30). 10 EMP-SALARY PIC 9(7)V99. *> Multiple indexes for same table 01 SALES-DATA. 05 SALES-RECORD OCCURS 500 TIMES INDEXED BY MAIN-IDX, BACKUP-IDX, SEARCH-IDX. 10 SALE-DATE PIC 9(8). 10 SALE-AMOUNT PIC 9(8)V99. 10 CUSTOMER-ID PIC X(10). *> Multi-dimensional tables with indexes 01 MONTHLY-REPORT. 05 MONTH-DATA OCCURS 12 TIMES INDEXED BY MONTH-IDX. 10 MONTH-NAME PIC X(10). 10 DAILY-SALES OCCURS 31 TIMES INDEXED BY DAY-IDX. 15 SALES-AMT PIC 9(8)V99. 15 TRANS-CNT PIC 9(4). *> Complex nested structure with multiple indexes 01 COMPANY-STRUCTURE. 05 DIVISION OCCURS 5 TIMES INDEXED BY DIV-IDX. 10 DIV-NAME PIC X(20). 10 DEPARTMENT OCCURS 10 TIMES INDEXED BY DEPT-IDX. 15 DEPT-NAME PIC X(15). 15 EMPLOYEE OCCURS 50 TIMES INDEXED BY EMP-IDX. 20 EMP-DATA. 25 EMP-ID PIC 9(6). 25 EMP-NAME PIC X(25). 25 EMP-GRADE PIC 9(2).
Table Definition
Index Declaration
Table Navigation

Comprehensive INDEXED BY Examples

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
IDENTIFICATION DIVISION. PROGRAM-ID. INDEXED-BY-DEMONSTRATION. DATA DIVISION. WORKING-STORAGE SECTION. 01 CUSTOMER-DATABASE. 05 CUSTOMER-RECORD OCCURS 2000 TIMES INDEXED BY CUST-IDX, READ-IDX, WRITE-IDX. 10 CUST-ID PIC X(10). 10 CUST-INFO. 15 CUST-NAME PIC X(40). 15 CUST-TYPE PIC X(10). 15 CREDIT-LIMIT PIC 9(8)V99. 15 BALANCE PIC S9(8)V99. 10 ADDRESS-INFO. 15 STREET PIC X(30). 15 CITY PIC X(20). 15 STATE PIC X(2). 15 ZIP-CODE PIC 9(5). 01 INVENTORY-SYSTEM. 05 CATEGORY OCCURS 20 TIMES INDEXED BY CAT-IDX. 10 CATEGORY-NAME PIC X(25). 10 PRODUCT OCCURS 100 TIMES INDEXED BY PROD-IDX, SORT-IDX. 15 PRODUCT-ID PIC X(15). 15 PRODUCT-NAME PIC X(40). 15 UNIT-PRICE PIC 9(6)V99. 15 QTY-ON-HAND PIC 9(6). 15 SUPPLIER OCCURS 5 TIMES INDEXED BY SUPP-IDX. 20 SUPP-ID PIC X(8). 20 SUPP-NAME PIC X(30). 20 COST PIC 9(6)V99. 01 TRANSACTION-LOG. 05 TRANS-ENTRY OCCURS 10000 TIMES INDEXED BY TRANS-IDX, PROCESS-IDX, ARCHIVE-IDX. 10 TRANS-HEADER. 15 TRANS-ID PIC X(12). 15 TRANS-DATE PIC 9(8). 15 TRANS-TIME PIC 9(6). 15 TRANS-TYPE PIC X(10). 10 TRANS-DETAILS. 15 CUSTOMER-ID PIC X(10). 15 AMOUNT PIC S9(8)V99. 15 DESCRIPTION PIC X(50). 10 TRANS-STATUS PIC X(10). 01 SALES-ANALYSIS. 05 YEAR-DATA OCCURS 5 TIMES INDEXED BY YEAR-IDX. 10 YEAR-NUMBER PIC 9(4). 10 QUARTER OCCURS 4 TIMES INDEXED BY QTR-IDX. 15 QTR-SALES PIC 9(10)V99. 15 MONTH OCCURS 3 TIMES INDEXED BY MONTH-IDX. 20 MONTH-SALES PIC 9(8)V99. 20 WEEK OCCURS 5 TIMES INDEXED BY WEEK-IDX. 25 WEEK-SALES PIC 9(6)V99. 25 DAY OCCURS 7 TIMES INDEXED BY DAY-IDX. 30 DAY-SALES PIC 9(5)V99. 01 WS-WORK-AREAS. 05 WS-CUSTOMER-COUNT PIC 9(4) VALUE 0. 05 WS-TOTAL-BALANCE PIC S9(10)V99 VALUE 0. 05 WS-SEARCH-KEY PIC X(10). 05 WS-FOUND-FLAG PIC X VALUE 'N'. 88 RECORD-FOUND VALUE 'Y'. 88 RECORD-NOT-FOUND VALUE 'N'. PROCEDURE DIVISION. MAIN-PROCESSING. PERFORM INITIALIZE-CUSTOMER-DATA PERFORM DEMONSTRATE-SINGLE-INDEX PERFORM DEMONSTRATE-MULTIPLE-INDEXES PERFORM DEMONSTRATE-NESTED-INDEXES PERFORM DEMONSTRATE-COMPLEX-PROCESSING PERFORM DEMONSTRATE-INDEX-COORDINATION STOP RUN. INITIALIZE-CUSTOMER-DATA. DISPLAY "=== INITIALIZING DATA WITH INDEXED TABLES ===" *> Initialize customer database using primary index PERFORM VARYING CUST-IDX FROM 1 BY 1 UNTIL CUST-IDX > 2000 STRING "CUST" CUST-IDX DELIMITED BY SIZE INTO CUST-ID(CUST-IDX) STRING "CUSTOMER " CUST-IDX " NAME" DELIMITED BY SIZE INTO CUST-NAME(CUST-IDX) *> Assign customer types cyclically EVALUATE FUNCTION MOD(CUST-IDX, 4) WHEN 0 MOVE "PLATINUM" TO CUST-TYPE(CUST-IDX) WHEN 1 MOVE "GOLD" TO CUST-TYPE(CUST-IDX) WHEN 2 MOVE "SILVER" TO CUST-TYPE(CUST-IDX) WHEN 3 MOVE "BRONZE" TO CUST-TYPE(CUST-IDX) END-EVALUATE *> Calculate credit limits based on type EVALUATE CUST-TYPE(CUST-IDX) WHEN "PLATINUM" COMPUTE CREDIT-LIMIT(CUST-IDX) = 100000.00 + (CUST-IDX * 10) WHEN "GOLD" COMPUTE CREDIT-LIMIT(CUST-IDX) = 50000.00 + (CUST-IDX * 5) WHEN "SILVER" COMPUTE CREDIT-LIMIT(CUST-IDX) = 25000.00 + (CUST-IDX * 3) WHEN "BRONZE" COMPUTE CREDIT-LIMIT(CUST-IDX) = 10000.00 + (CUST-IDX * 2) END-EVALUATE *> Generate balances COMPUTE BALANCE(CUST-IDX) = (FUNCTION MOD(CUST-IDX * 137, 50000)) - 10000 *> Generate addresses STRING "STREET " CUST-IDX DELIMITED BY SIZE INTO STREET(CUST-IDX) STRING "CITY" CUST-IDX DELIMITED BY SIZE INTO CITY(CUST-IDX) *> Cycle through states EVALUATE FUNCTION MOD(CUST-IDX, 5) WHEN 0 MOVE "NY" TO STATE(CUST-IDX) WHEN 1 MOVE "CA" TO STATE(CUST-IDX) WHEN 2 MOVE "TX" TO STATE(CUST-IDX) WHEN 3 MOVE "FL" TO STATE(CUST-IDX) WHEN 4 MOVE "IL" TO STATE(CUST-IDX) END-EVALUATE COMPUTE ZIP-CODE(CUST-IDX) = 10000 + FUNCTION MOD(CUST-IDX, 89999) END-PERFORM DISPLAY "Initialized " CUST-IDX " customer records" DISPLAY SPACES. DEMONSTRATE-SINGLE-INDEX. DISPLAY "=== SINGLE INDEX OPERATIONS ===" *> Basic index navigation SET CUST-IDX TO 1 DISPLAY "First customer: " CUST-NAME(CUST-IDX) DISPLAY "Type: " CUST-TYPE(CUST-IDX) DISPLAY "Balance: $" BALANCE(CUST-IDX) *> Jump to middle of table SET CUST-IDX TO 1000 DISPLAY "Middle customer: " CUST-NAME(CUST-IDX) DISPLAY "Credit Limit: $" CREDIT-LIMIT(CUST-IDX) *> Sequential processing with single index MOVE 0 TO WS-CUSTOMER-COUNT MOVE 0 TO WS-TOTAL-BALANCE PERFORM VARYING CUST-IDX FROM 1 BY 1 UNTIL CUST-IDX > 100 ADD 1 TO WS-CUSTOMER-COUNT ADD BALANCE(CUST-IDX) TO WS-TOTAL-BALANCE END-PERFORM DISPLAY "Processed " WS-CUSTOMER-COUNT " customers" DISPLAY "Total balance: $" WS-TOTAL-BALANCE DISPLAY SPACES. DEMONSTRATE-MULTIPLE-INDEXES. DISPLAY "=== MULTIPLE INDEX OPERATIONS ===" *> Use different indexes for different purposes *> READ-IDX for reading source data *> WRITE-IDX for writing filtered data SET READ-IDX TO 1 SET WRITE-IDX TO 1 *> Filter platinum customers to beginning of table PERFORM UNTIL READ-IDX > 2000 IF CUST-TYPE(READ-IDX) = "PLATINUM" *> Copy platinum customer to write position MOVE CUSTOMER-RECORD(READ-IDX) TO CUSTOMER-RECORD(WRITE-IDX) SET WRITE-IDX UP BY 1 END-IF SET READ-IDX UP BY 1 END-PERFORM SET WRITE-IDX DOWN BY 1 DISPLAY "Compacted " WRITE-IDX " platinum customers" *> Display first few platinum customers PERFORM VARYING CUST-IDX FROM 1 BY 1 UNTIL CUST-IDX > 10 DISPLAY "Platinum " CUST-IDX ": " CUST-NAME(CUST-IDX) END-PERFORM DISPLAY SPACES. DEMONSTRATE-NESTED-INDEXES. DISPLAY "=== NESTED INDEX OPERATIONS ===" *> Initialize inventory system with nested indexes PERFORM VARYING CAT-IDX FROM 1 BY 1 UNTIL CAT-IDX > 20 STRING "CATEGORY-" CAT-IDX DELIMITED BY SIZE INTO CATEGORY-NAME(CAT-IDX) *> Initialize products within each category PERFORM VARYING PROD-IDX FROM 1 BY 1 UNTIL PROD-IDX > 100 STRING "PROD-" CAT-IDX "-" PROD-IDX DELIMITED BY SIZE INTO PRODUCT-ID(CAT-IDX, PROD-IDX) STRING "PRODUCT " CAT-IDX "." PROD-IDX DELIMITED BY SIZE INTO PRODUCT-NAME(CAT-IDX, PROD-IDX) COMPUTE UNIT-PRICE(CAT-IDX, PROD-IDX) = (CAT-IDX * PROD-IDX * 1.50) + 10.00 COMPUTE QTY-ON-HAND(CAT-IDX, PROD-IDX) = FUNCTION MOD((CAT-IDX * PROD-IDX * 7), 1000) + 50 *> Initialize suppliers for each product PERFORM VARYING SUPP-IDX FROM 1 BY 1 UNTIL SUPP-IDX > 5 STRING "SUPP" SUPP-IDX DELIMITED BY SIZE INTO SUPP-ID(CAT-IDX, PROD-IDX, SUPP-IDX) STRING "SUPPLIER " CAT-IDX "." PROD-IDX "." SUPP-IDX DELIMITED BY SIZE INTO SUPP-NAME(CAT-IDX, PROD-IDX, SUPP-IDX) COMPUTE COST(CAT-IDX, PROD-IDX, SUPP-IDX) = UNIT-PRICE(CAT-IDX, PROD-IDX) * 0.60 END-PERFORM END-PERFORM END-PERFORM DISPLAY "Initialized inventory system:" DISPLAY "Categories: " CAT-IDX DISPLAY "Products per category: " PROD-IDX DISPLAY "Suppliers per product: " SUPP-IDX *> Sample nested access SET CAT-IDX TO 5 SET PROD-IDX TO 10 SET SUPP-IDX TO 2 DISPLAY "Sample product access:" DISPLAY "Category: " CATEGORY-NAME(CAT-IDX) DISPLAY "Product: " PRODUCT-NAME(CAT-IDX, PROD-IDX) DISPLAY "Supplier: " SUPP-NAME(CAT-IDX, PROD-IDX, SUPP-IDX) DISPLAY "Cost: $" COST(CAT-IDX, PROD-IDX, SUPP-IDX) DISPLAY SPACES. DEMONSTRATE-COMPLEX-PROCESSING. DISPLAY "=== COMPLEX MULTI-INDEX PROCESSING ===" *> Initialize transaction log PERFORM VARYING TRANS-IDX FROM 1 BY 1 UNTIL TRANS-IDX > 10000 STRING "TXN" TRANS-IDX DELIMITED BY SIZE INTO TRANS-ID(TRANS-IDX) COMPUTE TRANS-DATE(TRANS-IDX) = 20240101 + FUNCTION MOD(TRANS-IDX, 365) COMPUTE TRANS-TIME(TRANS-IDX) = FUNCTION MOD(TRANS-IDX * 137, 240000) EVALUATE FUNCTION MOD(TRANS-IDX, 4) WHEN 0 MOVE "PURCHASE" TO TRANS-TYPE(TRANS-IDX) WHEN 1 MOVE "PAYMENT" TO TRANS-TYPE(TRANS-IDX) WHEN 2 MOVE "REFUND" TO TRANS-TYPE(TRANS-IDX) WHEN 3 MOVE "ADJUSTMENT" TO TRANS-TYPE(TRANS-IDX) END-EVALUATE STRING "CUST" FUNCTION MOD(TRANS-IDX, 2000) + 1 DELIMITED BY SIZE INTO CUSTOMER-ID(TRANS-IDX) COMPUTE AMOUNT(TRANS-IDX) = (FUNCTION MOD(TRANS-IDX * 73, 100000)) / 100 MOVE "COMPLETED" TO TRANS-STATUS(TRANS-IDX) END-PERFORM *> Process transactions using multiple indexes SET TRANS-IDX TO 1 *> Read index SET PROCESS-IDX TO 1 *> Process index SET ARCHIVE-IDX TO 1 *> Archive index *> Separate transactions by type PERFORM UNTIL TRANS-IDX > 10000 EVALUATE TRANS-TYPE(TRANS-IDX) WHEN "PURCHASE" *> Process purchase transactions IF AMOUNT(TRANS-IDX) > 1000.00 MOVE TRANS-ENTRY(TRANS-IDX) TO TRANS-ENTRY(PROCESS-IDX) SET PROCESS-IDX UP BY 1 END-IF WHEN "PAYMENT" *> Archive payment transactions MOVE TRANS-ENTRY(TRANS-IDX) TO TRANS-ENTRY(ARCHIVE-IDX) SET ARCHIVE-IDX UP BY 1 END-EVALUATE SET TRANS-IDX UP BY 1 END-PERFORM SET PROCESS-IDX DOWN BY 1 SET ARCHIVE-IDX DOWN BY 1 DISPLAY "Transaction processing results:" DISPLAY "Large purchases identified: " PROCESS-IDX DISPLAY "Payments archived: " ARCHIVE-IDX DISPLAY SPACES. DEMONSTRATE-INDEX-COORDINATION. DISPLAY "=== INDEX COORDINATION PATTERNS ===" *> Initialize sales analysis with multi-dimensional indexes PERFORM VARYING YEAR-IDX FROM 1 BY 1 UNTIL YEAR-IDX > 5 COMPUTE YEAR-NUMBER(YEAR-IDX) = 2019 + YEAR-IDX PERFORM VARYING QTR-IDX FROM 1 BY 1 UNTIL QTR-IDX > 4 MOVE 0 TO QTR-SALES(YEAR-IDX, QTR-IDX) PERFORM VARYING MONTH-IDX FROM 1 BY 1 UNTIL MONTH-IDX > 3 COMPUTE MONTH-SALES(YEAR-IDX, QTR-IDX, MONTH-IDX) = (YEAR-IDX * QTR-IDX * MONTH-IDX * 10000) + 50000 ADD MONTH-SALES(YEAR-IDX, QTR-IDX, MONTH-IDX) TO QTR-SALES(YEAR-IDX, QTR-IDX) PERFORM VARYING WEEK-IDX FROM 1 BY 1 UNTIL WEEK-IDX > 5 COMPUTE WEEK-SALES(YEAR-IDX, QTR-IDX, MONTH-IDX, WEEK-IDX) = MONTH-SALES(YEAR-IDX, QTR-IDX, MONTH-IDX) / 5 PERFORM VARYING DAY-IDX FROM 1 BY 1 UNTIL DAY-IDX > 7 COMPUTE DAY-SALES(YEAR-IDX, QTR-IDX, MONTH-IDX, WEEK-IDX, DAY-IDX) = WEEK-SALES(YEAR-IDX, QTR-IDX, MONTH-IDX, WEEK-IDX) / 7 END-PERFORM END-PERFORM END-PERFORM END-PERFORM END-PERFORM *> Display coordinated analysis DISPLAY "Five-year sales analysis initialized" SET YEAR-IDX TO 3 SET QTR-IDX TO 2 DISPLAY "Sample data for " YEAR-NUMBER(YEAR-IDX) " Q" QTR-IDX ":" DISPLAY "Quarter total: $" QTR-SALES(YEAR-IDX, QTR-IDX) PERFORM VARYING MONTH-IDX FROM 1 BY 1 UNTIL MONTH-IDX > 3 DISPLAY " Month " MONTH-IDX ": $" MONTH-SALES(YEAR-IDX, QTR-IDX, MONTH-IDX) END-PERFORM DISPLAY SPACES. *> Advanced index manipulation routines SEARCH-CUSTOMER-BY-ID. *> Binary search using index (assumes sorted table) MOVE "CUST1000" TO WS-SEARCH-KEY SET RECORD-NOT-FOUND TO TRUE SET CUST-IDX TO 1 SET READ-IDX TO 2000 PERFORM UNTIL RECORD-FOUND OR CUST-IDX > READ-IDX SET WRITE-IDX TO CUST-IDX SET WRITE-IDX UP BY READ-IDX SET WRITE-IDX TO WRITE-IDX / 2 IF CUST-ID(WRITE-IDX) = WS-SEARCH-KEY SET RECORD-FOUND TO TRUE SET CUST-IDX TO WRITE-IDX ELSE IF CUST-ID(WRITE-IDX) < WS-SEARCH-KEY SET CUST-IDX TO WRITE-IDX SET CUST-IDX UP BY 1 ELSE SET READ-IDX TO WRITE-IDX SET READ-IDX DOWN BY 1 END-IF END-IF END-PERFORM IF RECORD-FOUND DISPLAY "Found customer: " CUST-NAME(CUST-IDX) ELSE DISPLAY "Customer not found: " WS-SEARCH-KEY END-IF. PARALLEL-TABLE-PROCESSING. *> Process two tables in parallel using separate indexes SET CUST-IDX TO 1 SET TRANS-IDX TO 1 PERFORM UNTIL CUST-IDX > 100 OR TRANS-IDX > 100 *> Process customer and corresponding transaction DISPLAY "Processing customer " CUST-IDX " and transaction " TRANS-IDX SET CUST-IDX UP BY 1 SET TRANS-IDX UP BY 1 END-PERFORM. TABLE-COMPRESSION. *> Compress table by removing empty entries SET READ-IDX TO 1 SET WRITE-IDX TO 1 PERFORM UNTIL READ-IDX > 2000 IF CUST-ID(READ-IDX) NOT = SPACES IF READ-IDX NOT = WRITE-IDX MOVE CUSTOMER-RECORD(READ-IDX) TO CUSTOMER-RECORD(WRITE-IDX) END-IF SET WRITE-IDX UP BY 1 END-IF SET READ-IDX UP BY 1 END-PERFORM SET WRITE-IDX DOWN BY 1 DISPLAY "Compressed table to " WRITE-IDX " active records".

Knowledge Check

Test Your Understanding

Question 1: Purpose

What does the INDEXED BY clause automatically create?

Answer: The INDEXED BY clause automatically creates index data items that can be used to navigate table elements efficiently. These indexes don't need to be explicitly declared in the Data Division.

Question 2: Multiple Indexes

Why would you define multiple indexes for the same table?

Answer: Multiple indexes allow different parts of your program to navigate the same table independently, enabling operations like reading with one index while writing with another, or maintaining separate search positions.

Related Pages