Site logo
Tác giả
  • avatar Nguyễn Đức Xinh
    Name
    Nguyễn Đức Xinh
    Twitter
Ngày xuất bản
Ngày xuất bản

Biến và kiểu dữ liệu trong COBOL – Hướng dẫn chi tiết với ví dụ và bài tập

Biến và kiểu dữ liệu trong COBOL là gì? Vì sao quan trọng?

Trong phần trước, bạn đã làm quen với cấu trúc chương trình COBOL và các division cơ bản. Bước tiếp theo để có thể viết được bất kỳ chương trình thực tế nào là hiểu rõ biến (variable) và kiểu dữ liệu (data type) trong COBOL.

Khác với nhiều ngôn ngữ hiện đại như Java, Python, COBOL mô tả dữ liệu rất chi tiết bằng PIC (PICTURE clause). Điều này giúp mô tả chính xác độ dài, loại ký tự, dấu thập phân, dấu âm dương của từng field – cực kỳ quan trọng trong hệ thống tài chính, ngân hàng, bảo hiểm nơi mà 1 sai số nhỏ cũng có thể gây lỗi lớn.

Trong bài này, bạn sẽ học:

  • Cách khai báo biến trong COBOL (level number, tên biến, PIC)
  • Các kiểu dữ liệu cơ bản: numeric, string, signed number, decimal
  • Giới thiệu COMP, COMP-3 (packed decimal) – rất phổ biến trong banking
  • Cách dùng group item (giống struct) để mô hình hóa dữ liệu thực tế
  • Các lỗi thường gặp khi khai báo biến
  • Bài tập thực hành để luyện tập ngay

Tổng quan: DATA DIVISION và WORKING-STORAGE

Tất cả biến trong COBOL (trừ parameter đặc biệt) đều được khai báo trong DATA DIVISION. Phần bạn sẽ làm việc nhiều nhất khi khai báo biến là:

  • WORKING-STORAGE SECTION – khai báo biến dùng trong suốt chương trình
  • (Sau này nâng cao) FILE SECTION, LINKAGE SECTION – dùng cho file và parameter

Ví dụ một skeleton đơn giản:

	IDENTIFICATION DIVISION.
	PROGRAM-ID. VARIABLE-DEMO.

	DATA DIVISION.
	WORKING-STORAGE SECTION.
	01 WS-NAME           PIC X(20).
	01 WS-AGE            PIC 99.

	PROCEDURE DIVISION.
	    MOVE "Nguyen Van A" TO WS-NAME.
	    MOVE 25 TO WS-AGE.
	    DISPLAY WS-NAME.
	    DISPLAY WS-AGE.
	    STOP RUN.

Điểm quan trọng:

  • Mỗi biến bắt đầu bằng level number (01, 05, 10, ...)
  • Theo sau là tên biến (WS-NAME, WS-AGE, ...)
  • PIC để mô tả kiểu dữ liệu

Giải thích:

  • DISPLAY WS-NAME. / DISPLAY WS-AGE.: câu lệnh I/O console, in giá trị field ra output device (tương đương print/println hoặc printf tối giản).
  • STOP RUN.: statement kết thúc chương trình COBOL, trả control về OS – về mặt ý nghĩa giống return ở cuối main trong C/Java.

Level number và Group Item – Mô hình hóa dữ liệu như "struct"

Trong COBOL, cấu trúc dữ liệu được xây dựng bằng level number.

  • 01: thường là mức cao nhất (tương đương một record, một entity)
  • Các mức 05, 10, 15,...: là các field con bên trong

Ví dụ: Mô tả khách hàng bằng group item

	DATA DIVISION.
	WORKING-STORAGE SECTION.

	01 CUSTOMER.
	   05 CUST-ID        PIC 9(5).
	   05 CUST-NAME      PIC X(30).
	   05 CUST-AGE       PIC 99.
	   05 CUST-PHONE     PIC X(15).

Giải thích:

  • CUSTOMERgroup item – giống struct trong C hoặc class data-only trong các ngôn ngữ hiện đại.
  • Các field CUST-ID, CUST-NAME, CUST-AGE, CUST-PHONEelementary item (biến đơn).

Bạn có thể:

  • MOVE riêng từng field: MOVE 12345 TO CUST-ID.
  • MOVE cả group: MOVE CUSTOMER-OLD TO CUSTOMER-NEW. (khi 2 group có cùng cấu trúc)

So sánh với struct trong C và class trong Java

Khía cạnh COBOL Group Item C struct Java class (POJO)
Cách định nghĩa Level number + PIC Kiểu + tên field Kiểu + tên field
Hỗ trợ method Không Không
Mục đích chính Mô hình hóa record Mô hình hóa record Mô hình hóa object
Truy cập field Tên-group.Tên-field? customer.id customer.getId()
Độ chi tiết dữ liệu Rất chi tiết (PIC) Phụ thuộc vào kiểu cơ bản Phụ thuộc vào kiểu cơ bản

PIC (PICTURE) – Trái tim của data type trong COBOL

Trong COBOL, PIC là cách bạn mô tả hình dạng dữ liệu. Thay vì viết int hay string, bạn chỉ rõ:

  • Dữ liệu là số hay chữ
  • Độ dài bao nhiêu ký tự
  • Có dấu thập phân không
  • Có dấu âm/dương không

Các ký tự PIC cơ bản

Ký hiệu Ý nghĩa Ví dụ
9 Chữ số (0-9) PIC 9(5) → 5 chữ số
X Ký tự bất kỳ (chữ, số, symbol) PIC X(10)
A Chữ cái (A-Z, a-z) PIC A(3)
V Dấu thập phân ảo (không chiếm byte) PIC 9(3)V99
S Số có dấu (+/-) PIC S9(5)
P Digit ẩn (thường dùng với scale) PIC 9(3)P

Một số ký hiệu dùng cho formatting khi DISPLAY/REPORT (sẽ học sau): Z, 0, ,, ..


Numeric Data Type – Số trong COBOL

Số nguyên đơn giản

	01 WS-AGE       PIC 99.
	01 WS-COUNT     PIC 9(4).
  • PIC 99: 2 chữ số, giá trị 0–99
  • PIC 9(4): 4 chữ số, giá trị 0–9999

Số có dấu (Signed number)

	01 WS-BALANCE   PIC S9(7).
  • S cho phép giá trị âm/dương, ví dụ: -5000, +1200000

Số thập phân (Decimal) với V

	01 WS-SALARY    PIC 9(7)V99.
  • 9(7)V99 có nghĩa là: 7 chữ số nguyên, 2 chữ số thập phân
  • Giá trị thực: nếu bạn gán 1234567.89, trong bộ nhớ sẽ lưu là 123456789V chỉ là vị trí thập phân ảo.

Ví dụ: Tính lương nhân viên

	DATA DIVISION.
	WORKING-STORAGE SECTION.
	01 WS-BASIC-SALARY      PIC 9(7)V99 VALUE 0001500000.
	01 WS-ALLOWANCE         PIC 9(5)V99 VALUE 00020000.
	01 WS-TOTAL-SALARY      PIC 9(7)V99.

	PROCEDURE DIVISION.
	    ADD WS-BASIC-SALARY WS-ALLOWANCE
		 GIVING WS-TOTAL-SALARY.
	    DISPLAY "Total Salary: " WS-TOTAL-SALARY.
	    STOP RUN.

Ghi chú:

  • Khi mới học, bạn có thể gán giá trị theo dạng số nguyên (không dấu chấm) vì V là dấu thập phân ảo.

String Data Type – X và A

Kiểu X (Alphanumeric – ký tự bất kỳ)

	01 WS-NAME      PIC X(30).
	01 WS-CODE      PIC X(10).
  • X cho phép cả chữ, số, ký tự đặc biệt.

Kiểu A (Alphabetic – chỉ chữ cái)

	01 WS-ONLY-ALPHA    PIC A(10).
  • A chỉ cho phép chữ cái. Trong thực tế banking, X thường phổ biến hơn vì linh hoạt.

Ví dụ: Gộp string và số

	DATA DIVISION.
	WORKING-STORAGE SECTION.
	01 WS-NAME          PIC X(20).
	01 WS-AGE           PIC 99.
	01 WS-MESSAGE       PIC X(50).

	PROCEDURE DIVISION.
	    MOVE "Nguyen Van A" TO WS-NAME.
	    MOVE 25 TO WS-AGE.
	    MOVE "Customer: " TO WS-MESSAGE.
	    STRING WS-NAME " - Age: " WS-AGE
		 DELIMITED BY SIZE
		 INTO WS-MESSAGE
	    END-STRING.

	    DISPLAY WS-MESSAGE.
	    STOP RUN.

Ở đây, STRING dùng để nối nhiều field vào một biến message.


COMP, COMP-3 (Packed Decimal) – Data type "chuẩn banking"

Trong hệ thống mainframe, để tiết kiệm bộ nhớ và tối ưu xử lý số học, COBOL sử dụng:

  • COMP (binary)
  • COMP-3 (packed decimal)

COMP (Binary)

	01 WS-COUNT-BINARY   PIC S9(4) COMP.
  • Lưu dưới dạng nhị phân, nhanh hơn khi tính toán
  • Dùng cho counter, index, số nguyên nhỏ đến vừa

COMP-3 (Packed Decimal)

	01 WS-AMOUNT-PACKED  PIC S9(7)V99 COMP-3.
  • Lưu dạng packed decimal – mỗi byte chứa 2 digit, digit cuối cùng chứa cả dấu.
  • Rất phổ biến trong banking vì chính xác thập phân (không bị lỗi như float/double).

So sánh: DISPLAY vs COMP vs COMP-3

Thuộc tính DISPLAY (PIC 9...) COMP (binary) COMP-3 (packed decimal)
Cách lưu ASCII/EBCDIC Nhị phân Packed decimal
Dùng cho Hiển thị, input/output Tính toán, counter Số tiền, số tài chính
Tốc độ tính toán Chậm hơn Nhanh Nhanh, chính xác thập phân
Tiết kiệm bộ nhớ Kém Tốt Rất tốt

Ở mức cơ bản, bạn chỉ cần nắm: DISPLAY để hiển thị, COMP/COMP-3 dùng cho performance & financial data.


Các lỗi thường gặp khi khai báo biến trong COBOL

  1. PIC không đủ dài cho dữ liệu thực tế
    • Ví dụ: PIC 9(3) nhưng dữ liệu có thể lên đến 9999 → overflow.
  2. Dùng X thay vì 9 cho numeric → khó tính toán, phải MOVE/CONVERT trước khi cộng trừ.
  3. Quên S cho số âm/dương → không lưu được số âm.
  4. Không thống nhất định dạng giữa các chương trình → khi MOVE giữa các program dễ sai.
  5. Nhầm lẫn giữa V thật và dấu chấm hiển thị – V không chiếm chỗ trong bộ nhớ.

Ví dụ tổng hợp: Quản lý thông tin tài khoản ngân hàng đơn giản

	IDENTIFICATION DIVISION.
	PROGRAM-ID. ACCOUNT-DEMO.

	DATA DIVISION.
	WORKING-STORAGE SECTION.

	01 ACCOUNT-INFO.
	   05 ACC-NO          PIC 9(10).
	   05 ACC-NAME        PIC X(30).
	   05 ACC-BALANCE     PIC S9(7)V99 COMP-3.

	01 WS-DEPOSIT-AMOUNT  PIC 9(5)V99.

	PROCEDURE DIVISION.
	    MOVE 1234567890        TO ACC-NO.
	    MOVE "Nguyen Van B"   TO ACC-NAME.
	    MOVE 0005000000       TO ACC-BALANCE.   *> 50000.00
	    MOVE 0000010000       TO WS-DEPOSIT-AMOUNT. *> 100.00

	    ADD WS-DEPOSIT-AMOUNT TO ACC-BALANCE.

	    DISPLAY "Account No : " ACC-NO.
	    DISPLAY "Name       : " ACC-NAME.
	    DISPLAY "Balance    : " ACC-BALANCE.
	    STOP RUN.

Qua ví dụ này, bạn thấy sự kết hợp của:

  • Group item (ACCOUNT-INFO)
  • Numeric với V (WS-DEPOSIT-AMOUNT)
  • COMP-3 cho số tiền (ACC-BALANCE)

So sánh kiểu dữ liệu COBOL và các ngôn ngữ hiện đại

Khái niệm COBOL Java Python
Số nguyên PIC 9(n) [COMP] int int
Số thập phân tiền tệ PIC 9(n)V9(m) COMP-3 BigDecimal decimal.Decimal
Chuỗi PIC X(n) String str
Cấu trúc record Group item (01/05/10...) Class/POJO Class / dict
Số có dấu PIC S9(n) int, long int
Kiểm soát độ dài Bắt buộc, qua PIC Linh hoạt, runtime Linh hoạt, runtime

Từ bảng so sánh, có thể thấy COBOL mô tả dữ liệu chặt chẽ hơn – đây là lý do nó được tin dùng trong các hệ thống tài chính.


Bài tập thực hành – Luyện COBOL Variable & Data Type

Bài 1 – Khai báo thông tin sinh viên

Yêu cầu:

  • Tạo một chương trình COBOL lưu thông tin sinh viên:
    • Student ID (5 số)
    • Full name (30 ký tự)
    • Age (2 số)
    • GPA (3 số, 2 số thập phân – ví dụ 3.75)
  • Hiển thị thông tin ra màn hình.

Gợi ý khai báo:

	01 STUDENT.
	   05 STU-ID       PIC 9(5).
	   05 STU-NAME     PIC X(30).
	   05 STU-AGE      PIC 99.
	   05 STU-GPA      PIC 9V99.

Bài 2 – Tính tổng tiền hàng

Yêu cầu:

  • Khai báo các biến:
    • Unit price: 5 số, 2 số thập phân
    • Quantity: 3 số
    • Total amount: đủ lớn để chứa kết quả
  • Gán thử: Unit price = 120.50, Quantity = 3
  • Tính TOTAL = UNIT-PRICE * QUANTITY và hiển thị kết quả.

Gợi ý:

	01 UNIT-PRICE      PIC 9(3)V99.
	01 QUANTITY        PIC 9(3).
	01 TOTAL-AMOUNT    PIC 9(5)V99.

Bài 3 – Thiết kế cấu trúc hóa đơn (Invoice)

Yêu cầu thiết kế phần DATA DIVISION (chưa cần viết logic):

  • Hóa đơn gồm:
    • Invoice number (10 số)
    • Customer name (30 ký tự)
    • Ngày xuất hóa đơn (YYYYMMDD – 8 số)
    • Tổng tiền hàng (9 số, 2 thập phân)
    • Thuế VAT (9 số, 2 thập phân)
    • Tổng thanh toán (9 số, 2 thập phân)

Hãy thiết kế group item INVOICE với các field phù hợp.

Bài 4 – Phân tích lỗi PIC

Cho đoạn khai báo sau (cố ý sai):

	01 WS-AMOUNT      PIC X(5).

Sau đó bạn thực hiện:

	ADD 100 TO WS-AMOUNT.

Hãy giải thích:

  • Vì sao đây là thiết kế không tốt?
  • Sửa lại PIC thế nào để phù hợp hơn?

Gợi ý cách tự học và thực hành thêm

  • Luôn bắt đầu bằng việc vẽ cấu trúc dữ liệu ra giấy (customer, account, invoice...).
  • Với mỗi field, tự hỏi: cần bao nhiêu ký tự? có cần số thập phân không? có thể âm không?
  • Tránh dùng PIC X(...) cho các field numeric nếu bạn biết chắc đó là số.
  • Thử khai báo cùng một dữ liệu ở dạng DISPLAY, COMP và COMP-3 để quan sát sự khác nhau khi hiển thị và khi debug.

Kết luận

Biến (variable) và kiểu dữ liệu (data type) là nền tảng để bạn có thể đọc – hiểu – và không sợ những chương trình COBOL dài hàng chục ngàn dòng trong hệ thống thực tế.

Trong COBOL, dữ liệu được mô tả chi tiết bằng PIC, level number và các storage type như DISPLAY, COMP, COMP-3. Khi nắm vững các khái niệm này, bạn sẽ:

  • Dễ dàng hiểu cấu trúc record trong banking, insurance
  • Giảm rủi ro sai số trong xử lý số tiền, số lượng
  • Tự tin refactor và tích hợp hệ thống COBOL với các dịch vụ hiện đại (API, microservices)

Ở các phần tiếp theo của khóa học COBOL, bạn sẽ đi sâu hơn vào file handling (FILE SECTION, VSAM)database (DB2, embedded SQL) – nơi mà data type chính xác là yếu tố sống còn.

Nếu bạn muốn, mình có thể tiếp tục xây dựng phần 3: Điều kiện (IF), vòng lặp (PERFORM) và control flow trong COBOL theo format khóa học, kèm thêm bài tập thực hành nâng cao.