- Tác giả

- Name
- Nguyễn Đức Xinh
- Ngày xuất bản
- Ngày xuất bản
Embedded SQL trong COBOL: Hiểu về Pro*COBOL và khối EXEC SQL
Embedded SQL (Pro*COBOL) là gì?
Trong hệ thống COBOL enterprise, business logic thường phải đọc/ghi dữ liệu trong relational database như Oracle. Thay vì tự viết các database call mức thấp, ta dùng Embedded SQL: các câu lệnh SQL được viết bên trong source COBOL, được đánh dấu bằng EXEC SQL ... END-EXEC.
Pro*COBOL là precompiler của Oracle hiểu các Embedded SQL này. Nó:
- Quét chương trình COBOL.
- Tìm tất cả block
EXEC SQL ... END-EXEC. - Dịch mỗi block thành lời gọi COBOL native tới Oracle runtime library.
Sau đó, bạn compile file COBOL đã được sinh ra bằng COBOL compiler như bình thường.
Về khái niệm:
- Bạn viết: COBOL + SQL trong các block
EXEC SQL. - Pro*COBOL dịch Embedded SQL → các lời gọi procedure COBOL.
- COBOL compiler chỉ thấy code COBOL chuẩn.
Lợi ích:
- COBOL xử lý control flow, batch, file I/O.
- SQL xử lý truy vấn dữ liệu quan hệ, transaction, join, aggregate.
Ví dụ chương trình dùng ba Embedded SQL quan trọng:
EXEC SQL COMMIT WORK RELEASE END-EXEC.EXEC SQL ROLLBACK WORK RELEASE END-EXEC.EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
Ba câu này điều khiển transaction boundary và error handling.
Pro*COBOL precompiler hoạt động như thế nào?
Từ source trộn (COBOL + SQL) đến COBOL thuần
Flow build điển hình:
- Viết source
PROGRAM.PCO:- Chứa câu lệnh COBOL.
- Chứa Embedded SQL:
EXEC SQL
SELECT COL1 INTO :WS-COL1
FROM MY_TABLE
WHERE KEY = :WS-KEY
END-EXEC.
-
Chạy Pro*COBOL precompiler:
- Input:
PROGRAM.PCO. - Output:
PROGRAM.CBL. - Mỗi block
EXEC SQLđược thay bằng code COBOL + lời gọi Oracle runtime.
- Input:
-
Compile bằng COBOL compiler (nhìn thấy COBOL thuần).
-
Link và run: executable dùng Oracle library để gửi SQL xuống DB.
Developer chủ yếu suy nghĩ ở mức COBOL + SQL, không phải ở mức call API thấp.
Cú pháp cơ bản: EXEC SQL ... END-EXEC
Mọi Embedded SQL đều bọc như sau:
EXEC SQL
<SQL statement or directive>
END-EXEC.
EXEC SQL/END-EXECđánh dấu biên block SQL.- Bên trong bạn viết SQL.
- Dùng host variable (biến COBOL) với prefix
:để trao đổi dữ liệu.
Ví dụ:
WORKING-STORAGE SECTION.
01 WS-EMP-NO PIC 9(5).
01 WS-EMP-NAME PIC X(30).
PROCEDURE DIVISION.
MOVE 12345 TO WS-EMP-NO.
EXEC SQL
SELECT EMP_NAME
INTO :WS-EMP-NAME
FROM EMPLOYEES
WHERE EMP_NO = :WS-EMP-NO
END-EXEC.
DISPLAY 'Employee name: ' WS-EMP-NAME.
WS-EMP-NO,WS-EMP-NAMElà host variable COBOL.:WS-EMP-NO,:WS-EMP-NAMElà cách SQL thấy các biến đó.
Ba Embedded SQL statement quan trọng
EXEC SQL COMMIT WORK RELEASE END-EXEC.
EXEC SQL ROLLBACK WORK RELEASE END-EXEC.
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC.
1. COMMIT WORK RELEASE
EXEC SQL
COMMIT WORK RELEASE
END-EXEC.
COMMIT WORK: ghi nhận tất cả thay đổi kể từ lần COMMIT gần nhất.RELEASE: đóng kết nối DB, giải phóng resource.
Dùng cho:
- Cuối chương trình khi không cần DB nữa.
- Job chạy lâu, muốn chủ động đóng session.
Nếu chỉ COMMIT WORK mà không RELEASE, session vẫn mở.
2. ROLLBACK WORK RELEASE
EXEC SQL
ROLLBACK WORK RELEASE
END-EXEC.
ROLLBACK WORK: huỷ toàn bộ thay đổi kể từ lần commit thành công trước đó.RELEASE: đóng session.
Dùng khi:
- Xảy ra lỗi nghiêm trọng.
- Không thể tiếp tục xử lý an toàn.
IF ERROR-FLAG = 'Y'
EXEC SQL
ROLLBACK WORK RELEASE
END-EXEC
GO TO ABEND-ROUTINE
END-IF.
3. WHENEVER SQLERROR CONTINUE
EXEC SQL
WHENEVER SQLERROR CONTINUE
END-EXEC.
- Báo cho Pro*COBOL: nếu có SQL error, tiếp tục trong COBOL, không nhảy đi đâu khác.
Một số directive khác:
WHENEVER SQLERROR STOPWHENEVER SQLERROR GOTO labelWHENEVER SQLERROR PERFORM paragraph
Dùng CONTINUE khi bạn muốn tự xử lý lỗi bằng cách kiểm tra SQLCODE.
Ví dụ:
EXEC SQL
WHENEVER SQLERROR CONTINUE
END-EXEC.
EXEC SQL
INSERT INTO ORDERS (ORDER_ID, AMOUNT)
VALUES (:WS-ORDER-ID, :WS-AMOUNT)
END-EXEC.
IF SQLCODE NOT = 0
MOVE 'Y' TO ERROR-FLAG
MOVE 'INSERT FAILED' TO ERROR-MESSAGE
PERFORM LOG-ERROR-PROC
END-IF.
Bảng tóm tắt 3 câu lệnh
| SQL Statement | Mục đích |
|---|---|
EXEC SQL COMMIT WORK RELEASE END-EXEC |
Ghi nhận mọi thay đổi DB và disconnect sạch sẽ |
EXEC SQL ROLLBACK WORK RELEASE END-EXEC |
Huỷ thay đổi từ lần commit gần nhất và disconnect |
EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC |
Bỏ xử lý lỗi tự động; cho phép tự xử lý lỗi trong COBOL |
Using host variable trong Embedded SQL
- Host variable khai báo trong
DATA DIVISION. - Dùng
:VAR-NAMEtrong blockEXEC SQL.
Ví dụ:
WORKING-STORAGE SECTION.
01 WS-CUST-ID PIC 9(10).
01 WS-CUST-NAME PIC X(50).
01 WS-SQLCODE PIC S9(9) COMP-5.
EXEC SQL INCLUDE SQLCA END-EXEC.
MOVE 1001 TO WS-CUST-ID.
EXEC SQL
SELECT CUST_NAME
INTO :WS-CUST-NAME
FROM CUSTOMERS
WHERE CUST-ID = :WS-CUST-ID
END-EXEC.
MOVE SQLCODE TO WS-SQLCODE.
IF WS-SQLCODE = 0
DISPLAY 'Customer Name: ' WS-CUST-NAME
ELSE
DISPLAY 'SQL ERROR: ' WS-SQLCODE
END-IF.
SQLCAchứaSQLCODEsau mỗi câu lệnh SQL.
Pattern transaction control trong Pro*COBOL
MAIN-PROC.
EXEC SQL
WHENEVER SQLERROR CONTINUE
END-EXEC
PERFORM OPEN-CONNECTION-PROC
PERFORM PROCESS-ALL-RECORDS
PERFORM TERMINATE-PROC
GOBACK.
- Trong
PROCESS-ALL-RECORDS, thường xuyên kiểm traERROR-FLAG,SQLCODE. - Commit định kỳ (ví dụ mỗi 100 hoặc 1000 record).
- Khi lỗi nghiêm trọng,
ROLLBACK WORK RELEASEvà đi vào đoạn ABEND.
So sánh Embedded SQL với các cách tích hợp khác
| Aspect | Embedded SQL (Pro*COBOL) | COBOL File I/O | Middleware / API ngoài |
|---|---|---|---|
| Data source | Relational DB (Oracle, ...) | Sequential/VSAM file | Web service, message queue, API |
| Syntax | SQL trong EXEC SQL ... END-EXEC |
READ, WRITE, REWRITE |
CALL tới API |
| Schema management | DBMS quản lý | Định nghĩa trong COBOL | Phụ thuộc contract API |
| Transactions | COMMIT / ROLLBACK đảm bảo ACID |
Thường tự xử lý | Phụ thuộc middleware/protocol |
| Tooling | SQL*Plus, AWR, công cụ DB | File utility, sort/merge | API gateway, monitoring |
| Use case | OLTP, báo cáo, query phức tạp, integrity mạnh | Batch, log, staging | Tích hợp hệ thống, microservice |
Best practice khi dùng Embedded SQL
- Tách business logic và SQL operation vào các paragraph nhỏ.
- Luôn kiểm tra
SQLCODE(hoặcSQLSTATE) sau câu lệnh quan trọng. - Dùng
COMMIT/ROLLBACKcó chủ đích, không commit từng record nếu không cần. - Dùng
COMMIT WORK RELEASEhoặcROLLBACK WORK RELEASEở cuối job hoặc đường đi lỗi. - Log lỗi với đủ context:
SQLCODE, message, key (ORDER-ID, CUSTOMER-ID, ...).
Ví dụ tổng hợp
IDENTIFICATION DIVISION.
PROGRAM-ID. LOAD-ORDERS.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-ORDER-ID PIC 9(10).
01 WS-AMOUNT PIC S9(9)V99 COMP-3.
01 WS-RECORD-COUNT PIC 9(5) VALUE ZERO.
01 WS-ERROR-FLAG PIC X VALUE 'N'.
EXEC SQL INCLUDE SQLCA END-EXEC.
PROCEDURE DIVISION.
MAIN-PROC.
EXEC SQL
WHENEVER SQLERROR CONTINUE
END-EXEC
PERFORM OPEN-FILES
PERFORM PROCESS-ORDERS
PERFORM CLOSE-FILES
IF WS-ERROR-FLAG = 'N'
EXEC SQL
COMMIT WORK RELEASE
END-EXEC
ELSE
EXEC SQL
ROLLBACK WORK RELEASE
END-EXEC
END-IF
GOBACK.
Ví dụ này minh hoạ Embedded SQL, manual error handling và transaction control trong một job COBOL.
