MainframeMaster

COBOL Tutorial

Data Movement Operations

Progress0 of 0 lessons

MOVE Statement Basics

The MOVE statement is the most fundamental data movement operation in COBOL. It transfers data from one field to another, automatically handling any necessary data type conversions according to COBOL's conversion rules.

Basic Syntax

cobol
1
MOVE {identifier-1|literal-1} TO identifier-2 [identifier-3 ...]

This format moves the contents of a source field or literal to one or more receiving fields.

MOVE Statement Examples

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
* Example 1: Move a literal to a field MOVE "JOHN DOE" TO CUSTOMER-NAME. * Example 2: Move one field to another MOVE ACCOUNT-NUMBER TO OUTPUT-ACCOUNT. * Example 3: Move to multiple fields MOVE SPACES TO FIRST-NAME, LAST-NAME, MIDDLE-INITIAL. * Example 4: Move a numeric literal MOVE 100.50 TO ITEM-PRICE. * Example 5: Move figurative constants MOVE ZEROS TO QUANTITY-ON-HAND, REORDER-POINT. MOVE HIGH-VALUES TO END-OF-TABLE-MARKER. MOVE LOW-VALUES TO BINARY-SEARCH-START.

Data Type Conversion Rules

  • Numeric to Numeric: Decimal points are aligned; truncation or zero padding may occur
  • Alphanumeric to Alphanumeric: Left-justified with space padding or right truncation
  • Numeric to Alphanumeric: Numeric value is converted to display format
  • Alphanumeric to Numeric: Data must contain valid digits; spaces are treated as zeros
  • Group Items: Moved as a single alphanumeric field regardless of content

Potential Issues with MOVE

  • Truncation: When the receiving field is smaller than the sending field
  • Data corruption: When moving non-numeric data to numeric fields
  • Sign loss: When moving signed numbers to unsigned fields
  • Precision loss: When decimal positions are lost in numeric conversions

Always ensure that receiving fields have appropriate sizes and data types for the expected data.

MOVE CORRESPONDING Statement

The MOVE CORRESPONDING (or MOVE CORR) statement transfers data between group items by matching field names at any level. This powerful feature allows for selective copying of fields without explicitly naming each one.

MOVE CORRESPONDING Syntax

cobol
1
MOVE CORRESPONDING|CORR identifier-1 TO identifier-2

Both identifiers must be group items. Only elementary items with matching names will be moved.

Data Structure Example

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
* Source and target record structures 01 INPUT-RECORD. 05 CUSTOMER-ID PIC X(10). 05 CUSTOMER-NAME PIC X(30). 05 ACCOUNT-NUMBER PIC X(15). 05 TRANSACTION-DATE PIC X(10). 05 TRANSACTION-AMT PIC S9(7)V99. 01 OUTPUT-RECORD. 05 ORDER-NUMBER PIC X(12). 05 CUSTOMER-ID PIC X(10). 05 CUSTOMER-NAME PIC X(30). 05 ACCOUNT-NUMBER PIC X(15). 05 PAYMENT-METHOD PIC X(10).

MOVE CORRESPONDING Example

cobol
1
2
3
4
5
6
7
8
9
10
11
* Using MOVE CORRESPONDING MOVE CORRESPONDING INPUT-RECORD TO OUTPUT-RECORD. * This is equivalent to writing: MOVE INPUT-RECORD-CUSTOMER-ID TO OUTPUT-RECORD-CUSTOMER-ID. MOVE INPUT-RECORD-CUSTOMER-NAME TO OUTPUT-RECORD-CUSTOMER-NAME. MOVE INPUT-RECORD-ACCOUNT-NUMBER TO OUTPUT-RECORD-ACCOUNT-NUMBER. * Note that TRANSACTION-DATE and TRANSACTION-AMT are not moved * because OUTPUT-RECORD does not have fields with those names. * Similarly, ORDER-NUMBER and PAYMENT-METHOD are not affected.

Qualification Rules

  • Only elementary items (not group items) with identical names are moved
  • Items must have the same qualified name (all parent levels must match)
  • The REDEFINES, RENAMES, and OCCURS clauses do not affect name matching
  • Receiving fields with JUSTIFIED RIGHT are moved according to standard rules
  • Level numbers do not need to match, only names matter

Best Practices for MOVE CORRESPONDING

  • Use for copying between structures with many matching fields
  • Be cautious when field definitions change - MOVE CORRESPONDING silently adjusts
  • Consider explicit moves when traceability is more important than brevity
  • Document field mappings when using MOVE CORRESPONDING for clarity
  • Check for unintended side effects when structures evolve over time

INITIALIZE Statement

The INITIALIZE statement is a powerful tool for setting fields to their default values or to specific values. It's especially useful for clearing large data structures with a single statement.

Basic Syntax

cobol
1
2
3
4
INITIALIZE identifier-1 [identifier-2 ...] [REPLACING {ALPHABETIC|ALPHANUMERIC|NUMERIC|ALPHANUMERIC-EDITED|NUMERIC-EDITED} DATA BY {identifier-3|literal-1}] ...

Without the REPLACING phrase, numeric items are set to zero and non-numeric items to spaces.

Basic INITIALIZE Examples

cobol
1
2
3
4
5
6
7
8
* Example 1: Simple initialization INITIALIZE CUSTOMER-RECORD. * Example 2: Initialize multiple items INITIALIZE CUSTOMER-NAME, CUSTOMER-ADDRESS, CUSTOMER-PHONE. * Example 3: Initialize a table (all elements are set) INITIALIZE PRODUCT-TABLE.

Advanced INITIALIZE with REPLACING

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
* Example 1: Set all numeric fields to a specific value INITIALIZE EMPLOYEE-RECORD REPLACING NUMERIC DATA BY 9999. * Example 2: Set multiple categories with different values INITIALIZE TRANSACTION-RECORD REPLACING NUMERIC DATA BY ZERO ALPHANUMERIC DATA BY "PENDING" ALPHANUMERIC-EDITED DATA BY SPACES. * Example 3: Initialize with values from other fields INITIALIZE CUSTOMER-RECORD REPLACING ALPHANUMERIC DATA BY DEFAULT-CUSTOMER-NAME NUMERIC DATA BY DEFAULT-CREDIT-LIMIT.

INITIALIZE Behavior Rules

  • Only elementary items are initialized, not the group items themselves
  • If the identifier is a group item, all elementary items within it are initialized
  • OCCURS clauses are fully processed - all table elements are initialized
  • REDEFINES areas are all processed - redefined items are initialized
  • Data items with BLANK WHEN ZERO are handled appropriately
  • 88-level condition items are not directly affected, but their values may change

INITIALIZE vs. Multiple MOVEs

FeatureINITIALIZEMultiple MOVEs
Code brevityMore conciseMore verbose
Execution speedMay be slowerMay be faster
Handling complex structuresHandles automaticallyRequires more code
Data type sensitivityAutomatically handles each data typeManual control needed
Selective initializationREPLACING option allows type selectionTotal control over what gets initialized

STRING Operations

The STRING statement concatenates multiple fields or literals into a single field, providing powerful string manipulation capabilities for building complex text strings.

Basic STRING Syntax

cobol
1
2
3
4
5
6
7
STRING {identifier-1|literal-1} [DELIMITED BY {identifier-2|literal-2|SIZE}] [{identifier-3|literal-3} [DELIMITED BY {identifier-4|literal-4|SIZE}]] ... INTO identifier-5 [WITH POINTER identifier-6] [ON OVERFLOW imperative-statement-1] [NOT ON OVERFLOW imperative-statement-2] [END-STRING]

The STRING statement combines multiple source fields or literals into a single receiving field.

Key Components

  • DELIMITED BY: Specifies where to stop copying from the sending field
  • SIZE: Uses the entire sending field
  • INTO: Specifies the receiving field
  • WITH POINTER: Specifies where to start placing data in the receiving field
  • ON OVERFLOW: Handles cases when the receiving field is too small

Basic STRING Examples

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
* Example 1: Combining fields with spaces STRING FIRST-NAME DELIMITED BY SIZE SPACE DELIMITED BY SIZE LAST-NAME DELIMITED BY SIZE INTO FULL-NAME. * Example 2: Using specific delimiters STRING AREA-CODE DELIMITED BY SIZE "-" DELIMITED BY SIZE PREFIX DELIMITED BY SIZE "-" DELIMITED BY SIZE LINE-NUMBER DELIMITED BY SIZE INTO FORMATTED-PHONE. * Example 3: Delimiting by a character STRING PRODUCT-CODE DELIMITED BY "/" CATEGORY-CODE DELIMITED BY SPACE INTO OUTPUT-CODE.

Advanced STRING Features

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
* Example 1: Using the POINTER phrase MOVE 1 TO STRING-PTR. STRING PREFIX DELIMITED BY SIZE ROOT-WORD DELIMITED BY SIZE SUFFIX DELIMITED BY SIZE INTO COMPOUND-WORD WITH POINTER STRING-PTR. * Example 2: Handling overflow STRING FIELD-1 DELIMITED BY SIZE FIELD-2 DELIMITED BY SIZE FIELD-3 DELIMITED BY SIZE INTO SHORT-OUTPUT ON OVERFLOW DISPLAY "Output field too small" PERFORM ERROR-ROUTINE NOT ON OVERFLOW DISPLAY "String operation successful" END-STRING. * Example 3: Building a CSV line STRING ID-NUMBER DELIMITED BY SIZE "," DELIMITED BY SIZE CUSTOMER-NAME DELIMITED BY "," "," DELIMITED BY SIZE TRANSACTION-AMT DELIMITED BY SIZE INTO CSV-LINE.

STRING Execution Flow

  1. If POINTER is specified, its value determines the starting position in the receiving field
  2. Each sending field is processed from left to right
  3. Characters are copied until the delimiter is encountered or the entire field is copied (with SIZE)
  4. The pointer value is automatically incremented for each character moved
  5. If the receiving field becomes full, the ON OVERFLOW condition triggers
  6. After all sending fields are processed, the NOT ON OVERFLOW condition triggers (if no overflow)
  7. The final pointer value is available for subsequent operations

UNSTRING Operations

The UNSTRING statement splits a string field into multiple fields based on specified delimiters. It's the complement to STRING and is particularly useful for parsing formatted input data.

Basic UNSTRING Syntax

cobol
1
2
3
4
5
6
7
8
9
UNSTRING identifier-1 [DELIMITED BY [ALL] {identifier-2|literal-1} [OR [ALL] {identifier-3|literal-2}] ...] INTO {identifier-4 [DELIMITER IN identifier-5] [COUNT IN identifier-6]} [{identifier-7 [DELIMITER IN identifier-8] [COUNT IN identifier-9]}] ... [WITH POINTER identifier-10] [TALLYING IN identifier-11] [ON OVERFLOW imperative-statement-1] [NOT ON OVERFLOW imperative-statement-2] [END-UNSTRING]

The UNSTRING statement parses data from the sending field into multiple receiving fields.

Key Components

  • DELIMITED BY: Defines what separates the fields in the source string
  • ALL: Treats consecutive delimiters as one delimiter
  • INTO: Specifies the receiving fields
  • DELIMITER IN: Captures the actual delimiter found
  • COUNT IN: Records the number of characters moved to each field
  • WITH POINTER: Specifies where to start scanning in the sending field
  • TALLYING IN: Counts the number of fields processed

Basic UNSTRING Examples

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
* Example 1: Parse a name (First Last) UNSTRING FULL-NAME DELIMITED BY SPACE INTO FIRST-NAME LAST-NAME. * Example 2: Parse a comma-separated value UNSTRING CSV-RECORD DELIMITED BY "," INTO FIELD-1 FIELD-2 FIELD-3 FIELD-4. * Example 3: Multiple delimiter options UNSTRING ADDRESS-LINE DELIMITED BY "," OR ";" OR SPACE INTO STREET-NUMBER STREET-NAME APARTMENT-NUMBER.

Advanced UNSTRING Features

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
* Example 1: Using DELIMITER IN and COUNT IN UNSTRING SOURCE-FIELD DELIMITED BY "," OR ":" OR ";" INTO FIELD-1 DELIMITER IN DELIM-1 COUNT IN COUNT-1 FIELD-2 DELIMITER IN DELIM-2 COUNT IN COUNT-2 FIELD-3 DELIMITER IN DELIM-3 COUNT IN COUNT-3. * Example 2: Using POINTER and TALLYING MOVE 1 TO UNSTR-PTR. MOVE 0 TO FIELD-COUNT. UNSTRING SOURCE-STRING DELIMITED BY ALL SPACES INTO FIELD-1 FIELD-2 FIELD-3 FIELD-4 FIELD-5 WITH POINTER UNSTR-PTR TALLYING IN FIELD-COUNT ON OVERFLOW DISPLAY "Too many fields in input" END-UNSTRING. * Example 3: Parsing a date (MM/DD/YYYY) UNSTRING DATE-STRING DELIMITED BY "/" INTO MONTH-FIELD DAY-FIELD YEAR-FIELD.

Practical Example: CSV Parsing

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
* Example of parsing a complex CSV record * Input: "101,"Smith, John",Active,10000.50" UNSTRING CSV-RECORD DELIMITED BY "," OR ALL SPACES INTO CUSTOMER-ID TEMP-NAME DELIMITER IN DELIM-1 COUNT IN NAME-LENGTH STATUS-FIELD BALANCE-FIELD WITH POINTER CSV-POINTER TALLYING IN FIELD-COUNT ON OVERFLOW PERFORM CSV-OVERFLOW-HANDLING NOT ON OVERFLOW PERFORM RECORD-PROCESSING END-UNSTRING. * Note: This example would need additional processing for the * quoted field "Smith, John" which contains a comma.

Complex data parsing often requires multiple steps, including pre-processing for quoted fields or other special cases.

Data Conversion Considerations

COBOL performs automatic data type conversions during data movement operations. Understanding these conversions is crucial for writing reliable programs that handle data correctly.

Numeric to Numeric Conversions

  • Decimal points are aligned during conversion
  • Truncation occurs if the receiving field has fewer digits
  • Zeros are padded if the receiving field has more digits
  • Sign is preserved if the receiving field is signed
  • Sign is lost if moving from signed to unsigned field
  • Different USAGE types (COMP, DISPLAY, etc.) are automatically converted
cobol
1
2
3
4
5
6
7
8
9
10
11
12
* Examples of numeric to numeric conversions * Receiving field: PIC 9(4) MOVE 123 TO NUMERIC-FIELD. * Result: 0123 MOVE 12345 TO NUMERIC-FIELD. * Result: 2345 (truncated) * Receiving field: PIC S9(4) MOVE -123 TO SIGNED-FIELD. * Result: -0123 MOVE 12345 TO SIGNED-FIELD. * Result: +2345 (truncated) * Receiving field: PIC 9(4)V99 MOVE 123.456 TO DECIMAL-FIELD. * Result: 0123.45 (truncated) MOVE 123 TO DECIMAL-FIELD. * Result: 0123.00 (padded)

Alphanumeric to Alphanumeric Conversions

  • Data is left-justified in the receiving field
  • If the receiving field is longer, spaces are padded on the right
  • If the receiving field is shorter, the data is truncated from the right
  • JUSTIFIED RIGHT clause affects the alignment of data (rare in COBOL)
cobol
1
2
3
4
5
6
7
* Examples of alphanumeric to alphanumeric conversions * Receiving field: PIC X(10) MOVE "ABC" TO ALPHA-FIELD. * Result: "ABC " (padded) MOVE "ABCDEFGHIJKL" TO ALPHA-FIELD. * Result: "ABCDEFGHIJ" (truncated) * Receiving field: PIC X(10) JUSTIFIED RIGHT MOVE "ABC" TO JUSTIFIED-FIELD. * Result: " ABC" (right-justified)

Numeric to Alphanumeric Conversions

  • The numeric value is converted to its display representation
  • Leading zeros are included in the conversion
  • Signs are included in the conversion if present
  • Decimal points are included in the conversion if present
  • Standard left-justification and potential truncation applies
cobol
1
2
3
4
5
6
7
8
9
10
11
12
* Examples of numeric to alphanumeric conversions * Numeric field: PIC 9(4)V99 VALUE 123.45 * Receiving field: PIC X(10) MOVE NUMERIC-FIELD TO ALPHA-FIELD. * Result: "0123.45 " (left-justified) * Numeric field: PIC S9(4) VALUE -123 * Receiving field: PIC X(10) MOVE SIGNED-FIELD TO ALPHA-FIELD. * Result: "-0123 " (sign included) * Numeric field: PIC 9(6) VALUE 123456 * Receiving field: PIC X(4) MOVE LARGE-NUM TO SMALL-ALPHA. * Result: "1234" (truncated)

Alphanumeric to Numeric Conversions

  • The alphanumeric data must contain valid numeric characters
  • Leading and trailing spaces are treated as zeros
  • The data is aligned by the decimal point, if present
  • If the data contains invalid characters, runtime errors may occur
  • It's recommended to validate alphanumeric data before conversion
cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
* Examples of alphanumeric to numeric conversions * Alphanumeric field: PIC X(10) VALUE "123" * Receiving field: PIC 9(5) MOVE ALPHA-FIELD TO NUMERIC-FIELD. * Result: 00123 * Alphanumeric field: PIC X(10) VALUE " 123 " * Receiving field: PIC 9(5) MOVE ALPHA-FIELD TO NUMERIC-FIELD. * Result: 00123 (spaces treated as zeros) * Alphanumeric field: PIC X(10) VALUE "12.34" * Receiving field: PIC 9(3)V99 MOVE ALPHA-FIELD TO DECIMAL-FIELD. * Result: 012.34 * Alphanumeric field: PIC X(10) VALUE "ABC123" * Receiving field: PIC 9(5) MOVE ALPHA-FIELD TO NUMERIC-FIELD. * Runtime error or unpredictable result

Best Practices for Data Conversion

  1. Always validate data before conversion, especially alphanumeric to numeric
  2. Use appropriate field sizes to prevent truncation
  3. Consider the ROUNDED phrase for numeric operations to maintain precision
  4. Be aware of sign handling when moving between signed and unsigned fields
  5. Use explicit data validation with IF...NUMERIC conditions before conversion
  6. Document data conversion assumptions and requirements in your code
  7. Test edge cases, including maximum and minimum values

Exercises: Data Movement Operations

Exercise 1: Customer Record Processing

Write COBOL statements to convert a raw customer input record to a formatted output record.

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
* Given these data structures: 01 RAW-CUSTOMER-RECORD. 05 RAW-CUSTOMER-ID PIC X(8). 05 RAW-CUSTOMER-NAME PIC X(30). 05 RAW-PHONE-NUMBER PIC X(10). 05 RAW-ADDRESS PIC X(50). 05 RAW-CREDIT-LIMIT PIC X(8). 01 FORMATTED-CUSTOMER. 05 FORMATTED-ID PIC X(8). 05 FORMATTED-NAME PIC X(30). 05 FORMATTED-PHONE. 10 AREA-CODE PIC X(3). 10 FILLER PIC X VALUE "-". 10 PREFIX PIC X(3). 10 FILLER PIC X VALUE "-". 10 LINE-NUMBER PIC X(4). 05 FORMATTED-CREDIT PIC 9(6)V99. * Your task: * 1. Move the customer ID and name fields appropriately * 2. Parse the phone number into its components using UNSTRING * 3. Convert the credit limit from character to numeric format * 4. Write error handling for invalid numeric data

Exercise 2: Address Formatting

Use STRING operations to create a properly formatted mailing address from component fields.

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
* Given these data structures: 01 ADDRESS-COMPONENTS. 05 STREET-NUMBER PIC X(10). 05 STREET-NAME PIC X(20). 05 APARTMENT PIC X(10). 05 CITY PIC X(20). 05 STATE PIC XX. 05 ZIP-CODE PIC X(10). 01 FORMATTED-ADDRESS. 05 ADDRESS-LINE-1 PIC X(40). 05 ADDRESS-LINE-2 PIC X(40). 05 CITY-STATE-ZIP PIC X(40). * Your task: * 1. Format ADDRESS-LINE-1 with the street number and name * 2. Format ADDRESS-LINE-2 with apartment info (if non-blank) * 3. Format CITY-STATE-ZIP as "CITY, STATE ZIP-CODE" * 4. Use STRING statements with appropriate delimiters * 5. Include error handling for potential overflow

Exercise 3: Initializing Complex Records

Use the INITIALIZE statement to efficiently reset fields in a complex data structure.

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
* Given this complex record structure: 01 TRANSACTION-RECORD. 05 TRANSACTION-HEADER. 10 TRANS-TYPE PIC X. 88 SALE VALUE "S". 88 RETURN VALUE "R". 88 ADJUSTMENT VALUE "A". 10 TRANS-DATE PIC X(8). 10 TRANS-TIME PIC X(6). 10 REGISTER-NUMBER PIC 9(3). 10 EMPLOYEE-ID PIC X(5). 05 TRANSACTION-DETAILS. 10 ITEM-COUNT PIC 9(3). 10 ITEMS OCCURS 0 TO 50 TIMES DEPENDING ON ITEM-COUNT. 15 ITEM-ID PIC X(10). 15 ITEM-QUANTITY PIC 9(3). 15 ITEM-PRICE PIC 9(5)V99. 15 ITEM-DISCOUNT PIC 9(3)V99. 05 TRANSACTION-TOTALS. 10 SUBTOTAL PIC 9(7)V99. 10 TAX-AMOUNT PIC 9(5)V99. 10 TOTAL-AMOUNT PIC 9(7)V99. * Your task: * 1. Write INITIALIZE statements to reset this record between transactions * 2. Keep certain header fields (like REGISTER-NUMBER) unchanged * 3. Reset all numeric amounts to zero * 4. Reset all item identifiers to spaces * 5. Use the REPLACING phrase where appropriate

Frequently Asked Questions

Test Your Knowledge

1. What happens when a numeric field is moved to an alphanumeric field?

  • The operation fails with a compilation error
  • The numeric value is converted to its display representation
  • The field is filled with spaces
  • A runtime error occurs

2. What does MOVE CORRESPONDING do?

  • Moves all fields from one group item to another
  • Moves only fields with matching names from one group item to another
  • Moves items in the corresponding order
  • Automatically handles data type conversions

3. In STRING operation, what does the POINTER phrase do?

  • Points to the next field to be processed
  • Specifies where to begin storing characters in the receiving field
  • Contains the address of the field in memory
  • Points to the delimiter character

4. What does the INITIALIZE statement do by default?

  • Sets numeric items to zeros and non-numeric items to spaces
  • Sets all items to their default values as in WORKING-STORAGE
  • Sets all items to null
  • Resets all items to zero

5. What is a key difference between STRING and UNSTRING operations?

  • STRING requires a fixed-length field while UNSTRING can use variable-length fields
  • STRING combines multiple sending fields into one receiving field, while UNSTRING splits one sending field into multiple receiving fields
  • STRING is for numeric data, UNSTRING is for alphanumeric data
  • STRING is a legacy operation, UNSTRING is the modern replacement