MainframeMaster

COBOL Tutorial

COBOL INDEX

INDEX represents the sophisticated table navigation and array access mechanism within COBOL programming environments, providing optimized data structure traversal capabilities that enable efficient table processing, high-performance array manipulation, and streamlined data access patterns. This concept embodies advanced memory management principles by supporting automatic displacement calculations, optimized address arithmetic, and enhanced performance characteristics while facilitating complex table operations, multi-dimensional array processing, and comprehensive data structure navigation across enterprise applications requiring efficient bulk data processing and optimal system resource utilization.

INDEX Definition and Usage

INDEX Declaration and Operations
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
*> INDEX definition with INDEXED BY 01 EMPLOYEE-TABLE. 05 EMPLOYEE-ENTRY 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 the same table 01 SALES-TABLE. 05 SALES-ENTRY OCCURS 500 TIMES INDEXED BY SALES-IDX, BACKUP-IDX. 10 SALE-DATE PIC 9(8). 10 SALE-AMOUNT PIC 9(8)V99. 10 CUSTOMER-ID PIC X(10). *> INDEX operations using SET SET EMP-IDX TO 1 *> Set to first occurrence SET EMP-IDX UP BY 1 *> Increment by 1 SET EMP-IDX DOWN BY 5 *> Decrement by 5 SET EMP-IDX TO EMP-IDX + 10 *> Add 10 to current value *> Accessing table elements with INDEX MOVE "JOHN SMITH" TO EMP-NAME(EMP-IDX) MOVE 75000.00 TO EMP-SALARY(EMP-IDX) COMPUTE TOTAL-SALARY = TOTAL-SALARY + EMP-SALARY(EMP-IDX) *> INDEX in conditional statements IF EMP-IDX > 50 DISPLAY "Processing second half of table" END-IF *> INDEX in loops PERFORM VARYING EMP-IDX FROM 1 BY 1 UNTIL EMP-IDX > 100 PERFORM PROCESS-EMPLOYEE END-PERFORM.
Table Navigation
Array Access
Performance

Comprehensive INDEX 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
IDENTIFICATION DIVISION. PROGRAM-ID. INDEX-DEMONSTRATION. DATA DIVISION. WORKING-STORAGE SECTION. 01 CUSTOMER-MASTER-TABLE. 05 CUSTOMER-ENTRY OCCURS 1000 TIMES INDEXED BY CUST-IDX, SEARCH-IDX, TEMP-IDX. 10 CUST-ID PIC X(10). 10 CUST-NAME PIC X(30). 10 CUST-TYPE PIC X(10). 10 BALANCE PIC S9(8)V99. 10 LAST-ACTIVITY PIC 9(8). 01 PRODUCT-INVENTORY. 05 PRODUCT-ENTRY OCCURS 500 TIMES INDEXED BY PROD-IDX. 10 PRODUCT-CODE PIC X(15). 10 PRODUCT-NAME PIC X(40). 10 UNIT-PRICE PIC 9(6)V99. 10 QUANTITY-OH PIC 9(6). 10 REORDER-POINT PIC 9(5). 01 MONTHLY-SALES. 05 MONTH-DATA OCCURS 12 TIMES INDEXED BY MONTH-IDX. 10 MONTH-NAME PIC X(10). 10 SALES-AMOUNT PIC 9(10)V99. 10 SALES-COUNT PIC 9(6). 10 DAILY-SALES OCCURS 31 TIMES INDEXED BY DAY-IDX. 15 DAY-AMOUNT PIC 9(8)V99. 15 DAY-COUNT PIC 9(4). 01 WS-WORK-FIELDS. 05 WS-TOTAL-CUSTOMERS PIC 9(4) VALUE 0. 05 WS-FOUND-FLAG PIC X VALUE 'N'. 88 CUSTOMER-FOUND VALUE 'Y'. 88 CUSTOMER-NOT-FOUND VALUE 'N'. 05 WS-SEARCH-KEY PIC X(10). 05 WS-HIGH-BALANCE PIC S9(8)V99 VALUE 0. 05 WS-TEMP-BALANCE PIC S9(8)V99. PROCEDURE DIVISION. MAIN-PROCESSING. PERFORM INITIALIZE-TABLES PERFORM DEMONSTRATE-BASIC-INDEX-OPS PERFORM DEMONSTRATE-TABLE-SEARCH PERFORM DEMONSTRATE-TABLE-SORTING PERFORM DEMONSTRATE-MULTI-DIM-ACCESS PERFORM DEMONSTRATE-INDEX-ARITHMETIC STOP RUN. INITIALIZE-TABLES. DISPLAY "=== INITIALIZING TABLES WITH INDEX ===" *> Initialize customer table using index PERFORM VARYING CUST-IDX FROM 1 BY 1 UNTIL CUST-IDX > 1000 STRING "CUST" CUST-IDX DELIMITED BY SIZE INTO CUST-ID(CUST-IDX) STRING "CUSTOMER-" CUST-IDX DELIMITED BY SIZE INTO CUST-NAME(CUST-IDX) *> Alternate customer types IF FUNCTION MOD(CUST-IDX, 3) = 0 MOVE "PREMIUM" TO CUST-TYPE(CUST-IDX) ELSE IF FUNCTION MOD(CUST-IDX, 2) = 0 MOVE "STANDARD" TO CUST-TYPE(CUST-IDX) ELSE MOVE "BASIC" TO CUST-TYPE(CUST-IDX) END-IF END-IF *> Generate random-like balances COMPUTE BALANCE(CUST-IDX) = (FUNCTION MOD(CUST-IDX * 137, 50000)) + 100 COMPUTE LAST-ACTIVITY(CUST-IDX) = 20240101 + FUNCTION MOD(CUST-IDX, 365) END-PERFORM DISPLAY "Initialized " CUST-IDX " customer records" *> Initialize product table PERFORM VARYING PROD-IDX FROM 1 BY 1 UNTIL PROD-IDX > 500 STRING "PROD-" PROD-IDX DELIMITED BY SIZE INTO PRODUCT-CODE(PROD-IDX) STRING "PRODUCT NAME " PROD-IDX DELIMITED BY SIZE INTO PRODUCT-NAME(PROD-IDX) COMPUTE UNIT-PRICE(PROD-IDX) = (FUNCTION MOD(PROD-IDX * 73, 1000)) + 1 COMPUTE QUANTITY-OH(PROD-IDX) = FUNCTION MOD(PROD-IDX * 91, 1000) COMPUTE REORDER-POINT(PROD-IDX) = QUANTITY-OH(PROD-IDX) / 4 END-PERFORM DISPLAY "Initialized " PROD-IDX " product records" DISPLAY SPACES. DEMONSTRATE-BASIC-INDEX-OPS. DISPLAY "=== BASIC INDEX OPERATIONS ===" *> Set index to specific position SET CUST-IDX TO 1 DISPLAY "First customer: " CUST-NAME(CUST-IDX) DISPLAY "Balance: $" BALANCE(CUST-IDX) *> Move to specific position and display SET CUST-IDX TO 500 DISPLAY "Middle customer: " CUST-NAME(CUST-IDX) DISPLAY "Balance: $" BALANCE(CUST-IDX) *> Index arithmetic SET CUST-IDX UP BY 100 DISPLAY "Customer +100: " CUST-NAME(CUST-IDX) SET CUST-IDX DOWN BY 50 DISPLAY "Customer -50: " CUST-NAME(CUST-IDX) *> Find highest balance customer SET CUST-IDX TO 1 MOVE BALANCE(CUST-IDX) TO WS-HIGH-BALANCE SET TEMP-IDX TO CUST-IDX PERFORM VARYING CUST-IDX FROM 2 BY 1 UNTIL CUST-IDX > 1000 IF BALANCE(CUST-IDX) > WS-HIGH-BALANCE MOVE BALANCE(CUST-IDX) TO WS-HIGH-BALANCE SET TEMP-IDX TO CUST-IDX END-IF END-PERFORM DISPLAY "Highest balance customer: " CUST-NAME(TEMP-IDX) DISPLAY "Balance: $" WS-HIGH-BALANCE DISPLAY SPACES. DEMONSTRATE-TABLE-SEARCH. DISPLAY "=== TABLE SEARCH USING INDEX ===" *> Linear search for specific customer MOVE "CUST250" TO WS-SEARCH-KEY SET CUSTOMER-NOT-FOUND TO TRUE PERFORM VARYING CUST-IDX FROM 1 BY 1 UNTIL CUST-IDX > 1000 OR CUSTOMER-FOUND IF CUST-ID(CUST-IDX) = WS-SEARCH-KEY SET CUSTOMER-FOUND TO TRUE END-IF END-PERFORM IF CUSTOMER-FOUND DISPLAY "Found customer: " CUST-NAME(CUST-IDX) DISPLAY "Type: " CUST-TYPE(CUST-IDX) DISPLAY "Balance: $" BALANCE(CUST-IDX) ELSE DISPLAY "Customer " WS-SEARCH-KEY " not found" END-IF *> Search for premium customers MOVE 0 TO WS-TOTAL-CUSTOMERS PERFORM VARYING CUST-IDX FROM 1 BY 1 UNTIL CUST-IDX > 1000 IF CUST-TYPE(CUST-IDX) = "PREMIUM" ADD 1 TO WS-TOTAL-CUSTOMERS END-IF END-PERFORM DISPLAY "Total premium customers: " WS-TOTAL-CUSTOMERS DISPLAY SPACES. DEMONSTRATE-TABLE-SORTING. DISPLAY "=== TABLE SORTING WITH INDEX ===" *> Simple bubble sort using indexes (first 20 customers) PERFORM VARYING CUST-IDX FROM 1 BY 1 UNTIL CUST-IDX > 19 PERFORM VARYING SEARCH-IDX FROM 1 BY 1 UNTIL SEARCH-IDX > (20 - CUST-IDX) SET TEMP-IDX TO SEARCH-IDX SET TEMP-IDX UP BY 1 IF BALANCE(SEARCH-IDX) > BALANCE(TEMP-IDX) PERFORM SWAP-CUSTOMER-RECORDS END-IF END-PERFORM END-PERFORM DISPLAY "First 20 customers sorted by balance (ascending):" PERFORM VARYING CUST-IDX FROM 1 BY 1 UNTIL CUST-IDX > 20 DISPLAY CUST-IDX ": " CUST-NAME(CUST-IDX) " - $" BALANCE(CUST-IDX) END-PERFORM DISPLAY SPACES. SWAP-CUSTOMER-RECORDS. *> Swap records at SEARCH-IDX and TEMP-IDX positions MOVE CUST-ID(SEARCH-IDX) TO WS-SEARCH-KEY MOVE CUST-ID(TEMP-IDX) TO CUST-ID(SEARCH-IDX) MOVE WS-SEARCH-KEY TO CUST-ID(TEMP-IDX) MOVE CUST-NAME(SEARCH-IDX) TO WS-SEARCH-KEY MOVE CUST-NAME(TEMP-IDX) TO CUST-NAME(SEARCH-IDX) MOVE WS-SEARCH-KEY TO CUST-NAME(TEMP-IDX) MOVE BALANCE(SEARCH-IDX) TO WS-TEMP-BALANCE MOVE BALANCE(TEMP-IDX) TO BALANCE(SEARCH-IDX) MOVE WS-TEMP-BALANCE TO BALANCE(TEMP-IDX). DEMONSTRATE-MULTI-DIM-ACCESS. DISPLAY "=== MULTI-DIMENSIONAL INDEX ACCESS ===" *> Initialize monthly sales data PERFORM VARYING MONTH-IDX FROM 1 BY 1 UNTIL MONTH-IDX > 12 EVALUATE MONTH-IDX WHEN 1 MOVE "JANUARY" TO MONTH-NAME(MONTH-IDX) WHEN 2 MOVE "FEBRUARY" TO MONTH-NAME(MONTH-IDX) WHEN 3 MOVE "MARCH" TO MONTH-NAME(MONTH-IDX) WHEN 4 MOVE "APRIL" TO MONTH-NAME(MONTH-IDX) WHEN 5 MOVE "MAY" TO MONTH-NAME(MONTH-IDX) WHEN 6 MOVE "JUNE" TO MONTH-NAME(MONTH-IDX) WHEN 7 MOVE "JULY" TO MONTH-NAME(MONTH-IDX) WHEN 8 MOVE "AUGUST" TO MONTH-NAME(MONTH-IDX) WHEN 9 MOVE "SEPTEMBER" TO MONTH-NAME(MONTH-IDX) WHEN 10 MOVE "OCTOBER" TO MONTH-NAME(MONTH-IDX) WHEN 11 MOVE "NOVEMBER" TO MONTH-NAME(MONTH-IDX) WHEN 12 MOVE "DECEMBER" TO MONTH-NAME(MONTH-IDX) END-EVALUATE *> Initialize daily sales for each month PERFORM VARYING DAY-IDX FROM 1 BY 1 UNTIL DAY-IDX > 31 COMPUTE DAY-AMOUNT(MONTH-IDX, DAY-IDX) = (FUNCTION MOD((MONTH-IDX * DAY-IDX * 123), 10000)) + 500 COMPUTE DAY-COUNT(MONTH-IDX, DAY-IDX) = FUNCTION MOD((MONTH-IDX * DAY-IDX * 7), 50) + 1 END-PERFORM *> Calculate monthly totals MOVE 0 TO SALES-AMOUNT(MONTH-IDX) MOVE 0 TO SALES-COUNT(MONTH-IDX) PERFORM VARYING DAY-IDX FROM 1 BY 1 UNTIL DAY-IDX > 31 ADD DAY-AMOUNT(MONTH-IDX, DAY-IDX) TO SALES-AMOUNT(MONTH-IDX) ADD DAY-COUNT(MONTH-IDX, DAY-IDX) TO SALES-COUNT(MONTH-IDX) END-PERFORM END-PERFORM *> Display quarterly summaries DISPLAY "Q1 Sales Summary:" PERFORM VARYING MONTH-IDX FROM 1 BY 1 UNTIL MONTH-IDX > 3 DISPLAY " " MONTH-NAME(MONTH-IDX) ": $" SALES-AMOUNT(MONTH-IDX) END-PERFORM DISPLAY "Best day in March:" SET MONTH-IDX TO 3 MOVE 0 TO WS-HIGH-BALANCE PERFORM VARYING DAY-IDX FROM 1 BY 1 UNTIL DAY-IDX > 31 IF DAY-AMOUNT(MONTH-IDX, DAY-IDX) > WS-HIGH-BALANCE MOVE DAY-AMOUNT(MONTH-IDX, DAY-IDX) TO WS-HIGH-BALANCE MOVE DAY-IDX TO WS-TOTAL-CUSTOMERS END-IF END-PERFORM DISPLAY " Day " WS-TOTAL-CUSTOMERS ": $" WS-HIGH-BALANCE DISPLAY SPACES. DEMONSTRATE-INDEX-ARITHMETIC. DISPLAY "=== INDEX ARITHMETIC OPERATIONS ===" *> Set indexes to specific positions SET CUST-IDX TO 100 SET SEARCH-IDX TO 200 SET TEMP-IDX TO 300 DISPLAY "Initial positions:" DISPLAY " CUST-IDX: " CUST-IDX DISPLAY " SEARCH-IDX: " SEARCH-IDX DISPLAY " TEMP-IDX: " TEMP-IDX *> Index calculations and movements SET CUST-IDX UP BY 50 SET SEARCH-IDX DOWN BY 25 SET TEMP-IDX TO TEMP-IDX + 100 DISPLAY "After arithmetic:" DISPLAY " CUST-IDX: " CUST-IDX DISPLAY " SEARCH-IDX: " SEARCH-IDX DISPLAY " TEMP-IDX: " TEMP-IDX *> Index comparisons IF CUST-IDX > SEARCH-IDX DISPLAY "CUST-IDX is greater than SEARCH-IDX" END-IF IF TEMP-IDX > CUST-IDX AND TEMP-IDX > SEARCH-IDX DISPLAY "TEMP-IDX has the highest value" END-IF *> Copy index values SET SEARCH-IDX TO CUST-IDX DISPLAY "After copying CUST-IDX to SEARCH-IDX: " SEARCH-IDX DISPLAY SPACES. *> Advanced index manipulation examples ADVANCED-INDEX-OPERATIONS. *> Index-based table processing with multiple indexes SET CUST-IDX TO 1 SET SEARCH-IDX TO 1 PERFORM UNTIL CUST-IDX > 1000 *> Process current customer IF CUST-TYPE(CUST-IDX) = "PREMIUM" *> Copy premium customer to search index position MOVE CUSTOMER-ENTRY(CUST-IDX) TO CUSTOMER-ENTRY(SEARCH-IDX) SET SEARCH-IDX UP BY 1 END-IF SET CUST-IDX UP BY 1 END-PERFORM SET SEARCH-IDX DOWN BY 1 DISPLAY "Compacted " SEARCH-IDX " premium customers". PARALLEL-INDEX-PROCESSING. *> Process two tables simultaneously using different indexes SET CUST-IDX TO 1 SET PROD-IDX TO 1 PERFORM UNTIL CUST-IDX > 100 OR PROD-IDX > 100 DISPLAY "Customer " CUST-IDX ": " CUST-NAME(CUST-IDX) DISPLAY "Product " PROD-IDX ": " PRODUCT-NAME(PROD-IDX) SET CUST-IDX UP BY 1 SET PROD-IDX UP BY 1 END-PERFORM.

INDEX vs Subscript Comparison

INDEX Advantages
  • • More efficient memory access
  • • Automatic displacement calculation
  • • Optimized for table operations
  • • Better performance in loops
Subscript Advantages
  • • Can perform arithmetic operations
  • • Can be displayed and moved
  • • Easier to debug and trace
  • • More intuitive for beginners

Performance Considerations

INDEX Performance Tips
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
*> Efficient index usage patterns *> Good: Use index in tight loops PERFORM VARYING TABLE-IDX FROM 1 BY 1 UNTIL TABLE-IDX > 1000 PROCESS TABLE-ENTRY(TABLE-IDX) END-PERFORM *> Good: Minimize index calculations SET START-IDX TO 1 SET END-IDX TO 100 PERFORM VARYING PROCESS-IDX FROM START-IDX BY 1 UNTIL PROCESS-IDX > END-IDX PROCESS-RECORD END-PERFORM *> Good: Use multiple indexes for complex operations SET READ-IDX TO 1 SET WRITE-IDX TO 1 PERFORM UNTIL READ-IDX > TABLE-SIZE IF VALID-RECORD(READ-IDX) MOVE TABLE-ENTRY(READ-IDX) TO TABLE-ENTRY(WRITE-IDX) SET WRITE-IDX UP BY 1 END-IF SET READ-IDX UP BY 1 END-PERFORM.

Knowledge Check

Test Your Understanding

Question 1: Definition

What is the primary advantage of using INDEX over subscripts?

Answer: INDEX provides more efficient table access because it stores displacement values internally, eliminating the need for address calculation during runtime, resulting in better performance.

Question 2: Operations

How do you manipulate INDEX values in COBOL?

Answer: Use the SET statement: SET index-name TO value, SET index-name UP BY value, SET index-name DOWN BY value, or SET index-name TO another-index.

Related Pages