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

COPY Clause trong COBOL: Tái sử dụng code với copybook

COPY Clause trong COBOL là gì?

Trong COBOL, COPY clause là cơ chế tái sử dụng code thông qua các file gọi là copybook. Thay vì lặp lại cùng một đoạn khai báo hoặc cùng một nhóm paragraph trong nhiều chương trình, bạn đặt chúng vào một copybook và dùng câu lệnh COPY để nhúng vào nơi cần thiết.

Ví dụ:

COPY RZ6PCOMN.

Khi gặp câu lệnh này, COBOL compiler (hoặc preprocessor) sẽ chèn toàn bộ nội dung source của file copybook RZ6PCOMN vào đúng vị trí COPY trong chương trình chính. Kết quả là:

  • Chương trình gọi COPY có đầy đủ mọi khai báo và paragraph bên trong copybook.
  • Bạn có thể dùng trực tiếp các paragraph như LOGON-PROC, SQL-ERR-PROC, v.v. được định nghĩa trong copybook đó.

Nói cách khác, COPY clause hoạt động giống như cơ chế "include" theo kiểu text: copy-paste nội dung file chung vào chương trình tại thời điểm compile.

Tại sao cần COPY Clause?

Trong hệ thống COBOL lớn, thường có rất nhiều chương trình batch, online, utility… cần dùng chung:

  • Khai báo data structure giống nhau (ví dụ layout record của file, layout message gửi qua MQ, layout của giao diện màn hình,…).
  • Các paragraph xử lý chung: login, logging, xử lý lỗi SQL, chuẩn hoá dữ liệu, v.v.

Nếu bạn copy-paste code thủ công vào từng chương trình:

  • Rất khó bảo trì: sửa một lỗi phải sửa ở nhiều nơi.
  • Dễ không đồng bộ: nơi cập nhật, nơi quên cập nhật.

Dùng COPY clause:

  • Đặt phần dùng chung vào một copybook.
  • Mỗi chương trình chỉ cần COPY <tên-copybook>..
  • Khi cần sửa logic chung, chỉ sửa một file copybook.

COPY hoạt động như thế nào?

1. Giai đoạn compile

Giả sử chương trình chính có đoạn:

IDENTIFICATION DIVISION.
PROGRAM-ID. MAIN-PGM.

DATA DIVISION.
WORKING-STORAGE SECTION.
COPY RZ6PCOMN.

Và copybook RZ6PCOMN có nội dung (minh hoạ):

01  WS-COMMON-AREA.
    05  WS-LOGON-USER      PIC X(08).
    05  WS-LOGON-PASS      PIC X(16).

PROCEDURE DIVISION.

LOGON-PROC.
    *> Đăng nhập hệ thống
    ...
LOGON-EXIT.
    EXIT.

SQL-ERR-PROC.
    *> Xử lý lỗi SQL chung
    ...
SQL-ERR-EXIT.
    EXIT.

Khi compile, compiler (hoặc preprocessor) sẽ tạo một phiên bản tạm của chương trình chính, trong đó thay dòng COPY RZ6PCOMN. bằng nội dung thật của file copybook. Về bản chất, compiler sẽ nhìn thấy code như thể bạn đã gõ toàn bộ đoạn trên vào file chương trình chính.

2. Phạm vi (scope) của COPY

Vị trí bạn đặt COPY quyết định nội dung được chèn vào đâu:

  • COPY trong WORKING-STORAGE SECTION → thêm các khai báo biến.
  • COPY trong LINKAGE SECTION → thêm layout cho parameter truyền từ program khác.
  • COPY trong PROCEDURE DIVISION → thêm paragraph, section hoặc câu lệnh.

Ví dụ phổ biến:

DATA DIVISION.
WORKING-STORAGE SECTION.
COPY CUSTOMER-RECORD.

LINKAGE SECTION.
COPY IN-PARAMS.

PROCEDURE DIVISION USING IN-PARAMS-AREA.
COPY COMMON-PROCS.

COPY Clause như một thư viện paragraph dùng chung

Quay lại mô tả:

Khi chương trình chính chứa câu:

COPY RZ6PCOMN.

compiler sẽ chèn toàn bộ source của file này vào vị trí đó. Chương trình gọi sẽ truy cập được tất cả paragraph (LOGON-PROC, SQL-ERR-PROC, …) định nghĩa trong copybook.

Điều này có nghĩa là bạn có thể tổ chức một bộ thư viện paragraph dùng chung cho nhiều chương trình, ví dụ:

  • LOGON-PROC – xử lý đăng nhập hệ thống.
  • SQL-ERR-PROC – xử lý lỗi SQL chuẩn.
  • DATE-UTIL-PROC – các hàm tiện ích về ngày tháng.

Mỗi chương trình chỉ cần:

PROCEDURE DIVISION.
COPY RZ6PCOMN.

MAIN-PROC.
    PERFORM LOGON-PROC
    ...
    PERFORM SQL-ERR-PROC
    ...
    GOBACK.

COPY vs CALL: khác nhau thế nào?

COPY Clause và CALL đều giúp tái sử dụng logic, nhưng cách hoạt động khác nhau.

Bảng so sánh COPY và CALL

Tiêu chí COPY Clause CALL Subprogram
Cách hoạt động Chèn text copybook vào source khi compile Gọi một program khác lúc runtime
Biên dịch Một object program duy nhất Nhiều program, link riêng
Chia sẻ dữ liệu Dùng chung DATA DIVISION (tuỳ nơi COPY) Dùng LINKAGE SECTION + parameter USING
Mức tách biệt Thấp (code trộn vào nhau) Cao (program riêng biệt)
Khi nên dùng Khai báo chung, paragraph tiện ích nhỏ Business logic độc lập, module lớn

Tóm lại:

  • COPY phù hợp cho code chung nhỏ/khai báo: record layout, hằng số, paragraph tiện ích.
  • CALL phù hợp cho module độc lập cần tách version, deploy riêng, hoặc dùng ngữ nghĩa "gọi chương trình con" rõ ràng.

Best Practice khi dùng COPY Clause

1. Phân loại copybook rõ ràng

Thường chia copybook thành các loại:

  • Copybook khai báo dữ liệu (data layout): CUST-REC, ORDER-REC, …
  • Copybook hằng số, cấu hình: SYS-CONST, MSG-TEXT, …
  • Copybook paragraph tiện ích: COMMON-PROCS, DATE-UTILS, SQL-ERR-HANDLER, …

Đặt tên file copybook và paragraph nhất quán, dễ nhận biết loại nội dung.

2. Hạn chế copybook quá lớn

Nếu một copybook chứa quá nhiều paragraph và khai báo lẫn lộn:

  • Khó đọc, khó hiểu chương trình dùng nó.
  • Khó kiểm soát ảnh hưởng khi sửa.

Nên tách copybook theo chủ đề:

  • RZ6PCOMN – common login & DB error.
  • RZ6PDATE – xử lý ngày tháng.
  • RZ6PFMT – format output, v.v.

3. Không lạm dụng COPY trong PROCEDURE DIVISION

Dù có thể COPY cả đoạn PROCEDURE DIVISION, nhưng nếu lạm dụng:

  • Các chương trình trở nên khó theo dõi luồng.
  • Developer mới khó biết paragraph đến từ đâu.

Nên:

  • Dùng COPY cho các routine nhỏ, tiện ích rõ ràng.
  • Business logic lớn, phức tạp nên tách thành subprogram và CALL.

4. Luôn quản lý version copybook

Vì nhiều chương trình cùng dùng một copybook, khi sửa bạn cần:

  • Kiểm tra backward compatibility.
  • Build/test lại các chương trình phụ thuộc.
  • Ghi chú thay đổi (changelog) cho copybook quan trọng.

Ví dụ nhỏ: dùng COPY cho khai báo record

Copybook khai báo record: CUST-REC.cpy

01  CUST-REC.
    05  CUST-ID        PIC 9(10).
    05  CUST-NAME      PIC X(50).
    05  CUST-ADDR      PIC X(100).
    05  CUST-PHONE     PIC X(15).

Chương trình chính dùng copybook

DATA DIVISION.
WORKING-STORAGE SECTION.
COPY CUST-REC.

PROCEDURE DIVISION.
MAIN-PROC.
    MOVE 12345      TO CUST-ID
    MOVE 'NGUYEN A' TO CUST-NAME
    DISPLAY 'Customer: ' CUST-ID ' - ' CUST-NAME
    GOBACK.

Ở đây, COPY CUST-REC. giúp đảm bảo mọi chương trình dùng layout customer đều giống nhau.

Ví dụ nhỏ: dùng COPY cho paragraph LOGON chung

Copybook RZ6PCOMN (giản lược):

LOGON-PROC.
    *> Đọc user/password, gọi module bảo mật
    ...
LOGON-EXIT.
    EXIT.

SQL-ERR-PROC.
    *> In thông tin lỗi SQL chung
    ...
SQL-ERR-EXIT.
    EXIT.

Chương trình chính:

PROCEDURE DIVISION.
COPY RZ6PCOMN.

MAIN-PROC.
    PERFORM LOGON-PROC
    ... xử lý chính ...
    GOBACK.

Như vậy, mọi chương trình chỉ cần PERFORM LOGON-PROC với cùng một implementation trong copybook.

Tổng kết

  • COPY clause trong COBOL là cơ chế include code theo kiểu text, giúp tái sử dụng khai báo và paragraph dùng chung.
  • Câu lệnh COPY RZ6PCOMN. khiến compiler chèn toàn bộ source của copybook RZ6PCOMN vào vị trí đó.
  • Nhờ vậy, chương trình gọi có thể dùng mọi paragraph bên trong copybook, ví dụ LOGON-PROC, SQL-ERR-PROC, …
  • COPY rất phù hợp cho:
    • Khai báo record layout chung.
    • Hằng số, cấu hình.
    • Paragraph tiện ích nhỏ.
  • Với business logic lớn, nên cân nhắc tách thành subprogram và dùng CALL thay vì nhúng toàn bộ qua COPY.