COBOL 作為歷史悠久的程式語言,在金融和政府等大型主機系統中仍扮演著關鍵角色。理解其迴圈和檔案處理機制對於維護和開發這些系統至關重要。本文除了介紹常見的迴圈型別如 PERFORM UNTIL 和 PERFORM VARYING 外,也探討了循序檔案的特性,包含檔案的建立、讀取、更新和錯誤處理。此外,文章也說明瞭如何在大型主機環境中使用 JCL 來管理 COBOL 程式,這對於在實際專案中操作 COBOL 程式相當重要,也讓開發者更能掌握 COBOL 在大型主機環境的應用。
COBOL迴圈結構詳解與應用實務
在COBOL程式設計中,迴圈結構扮演著至關重要的角色。本篇將探討COBOL中的迴圈語法及其應用,包括PERFORM UNTIL、PERFORM WITH TEST AFTER和PERFORM VARYING等不同型別的迴圈結構,並透過例項展示其使用方法與注意事項。
PERFORM UNTIL迴圈
PERFORM UNTIL迴圈類別似於其他程式語言中的while迴圈,用於在滿足特定條件之前重複執行一段程式碼。
DATA DIVISION.
WORKING-STORAGE SECTION.
01 COUNTER PIC 9(1) VALUE 0.
PROCEDURE DIVISION.
PERFORM UNTIL COUNTER >= 5
ADD 1 TO COUNTER
DISPLAY "迴圈次數 " COUNTER
END-PERFORM
GOBACK.
內容解密:
PERFORM UNTIL COUNTER >= 5設定迴圈條件,當COUNTER大於等於5時停止迴圈。ADD 1 TO COUNTER將COUNTER的值加1。DISPLAY "迴圈次數 " COUNTER輸出目前的迴圈次數。- 使用
END-PERFORM結束迴圈區塊。
PERFORM WITH TEST AFTER迴圈
PERFORM WITH TEST AFTER保證迴圈內的程式碼至少會被執行一次,類別似於其他程式語言中的do-while迴圈。
DATA DIVISION.
WORKING-STORAGE SECTION.
01 COUNTER PIC 9(1) VALUE 0.
PROCEDURE DIVISION.
PERFORM WITH TEST AFTER UNTIL COUNTER >= 5
ADD 1 TO COUNTER
DISPLAY "迴圈次數 " COUNTER
END-PERFORM
GOBACK.
內容解密:
PERFORM WITH TEST AFTER UNTIL COUNTER >= 5設定迴圈條件,先執行迴圈內的程式碼後再檢查條件。- 即使
COUNTER初始值大於或等於5,迴圈內的程式碼仍會被執行一次。
PERFORM VARYING迴圈
PERFORM VARYING是一種類別似於傳統for迴圈的結構,但具有更多靈活性,可用於控制迴圈的起始值、增量和終止條件。
DATA DIVISION.
WORKING-STORAGE SECTION.
01 YEAR PIC 9(2) VALUE 0.
01 BALANCE PIC 9(4) VALUE 1000.
PROCEDURE DIVISION.
PERFORM VARYING YEAR FROM 1 BY 1
UNTIL YEAR > 10
COMPUTE BALANCE = BALANCE * 1.05
DISPLAY "餘額為 $" BALANCE
END-PERFORM
GOBACK.
內容解密:
PERFORM VARYING YEAR FROM 1 BY 1 UNTIL YEAR > 10設定迴圈從1開始,每次增加1,直到YEAR大於10。COMPUTE BALANCE = BALANCE * 1.05計算每年5%的利息增長。DISPLAY "餘額為 $" BALANCE輸出每年的餘額。
使用PERFORM VARYING呼叫子常式
PROCEDURE DIVISION.
100-BALANCE-LOOP.
PERFORM 200-DEPOSIT-CALC VARYING YEAR FROM 1 BY 1
UNTIL YEAR > 10
GOBACK.
200-DEPOSIT-CALC.
COMPUTE BALANCE = BALANCE * 1.05
DISPLAY "餘額為 $" BALANCE.
內容解密:
PERFORM 200-DEPOSIT-CALC VARYING YEAR FROM 1 BY 1 UNTIL YEAR > 10使用PERFORM VARYING呼叫子常式200-DEPOSIT-CALC。- 在子常式中計算並輸出餘額。
使用THRU命令執行多個段落
PROCEDURE DIVISION.
100-FIRST-PARAGRAPH.
PERFORM 200-SECOND-PARAGRAPH THRU 400-FOURTH-PARAGRAPH.
200-SECOND-PARAGRAPH.
DISPLAY '段落2'.
300-THIRD-PARAGRAPH.
DISPLAY '段落3'.
400-FOURTH-PARAGRAPH.
DISPLAY '段落4'.
GOBACK.
內容解密:
PERFORM 200-SECOND-PARAGRAPH THRU 400-FOURTH-PARAGRAPH從200-SECOND-PARAGRAPH開始執行,直到執行到400-FOURTH-PARAGRAPH為止。- 連續輸出「段落2」、「段落3」和「段落4」。
循序檔案處理與 COBOL 實作
循序檔案(Sequential File)是一種由字元組成的檔案,類別似於 Windows 的 Notepad 或 Mac 的 TextEdit。這種檔案結構簡單,通常用於儲存大量資料,並且可以透過分塊(blocking)來提高讀取效率。循序檔案中的記錄(records)可以是固定長度或變長的。
循序檔案的起源與應用
循序檔案的概念源自早期大型主機使用磁帶機的時代。當時,資料儲存必須按照順序進行,一筆記錄接著一筆記錄,這種方式一直沿用至今。雖然磁帶機已不再是主流儲存裝置,但循序檔案仍然在大型主機系統中佔有重要地位,因為它們在處理大量資料時具有很高的效率。
循序檔案的處理與排序
在處理循序檔案時,通常會進行排序(sorting),以便更有效地處理資料。排序可以根據記錄中的任意欄位進行。例如,在客戶主檔中,可以根據客戶編號或客戶名稱進行排序。
資料完整性與驗證
在建立和更新檔案時,確保資料的完整性至關重要。錯誤的資料可能導致稽核問題,甚至對企業造成處罰。因此,在程式碼中加入資料驗證規則是必要的。例如,使用 COBOL 語言可以透過 IF/THEN/ELSE 條件判斷來禁止輸入無效資料,如負數的生產單位。
循序檔案的更新流程
循序檔案常用於批次處理(batch processing),特別是在處理主檔(master files)時。主檔通常包含公司各部門的大量資料,如銷售、應付帳款、應收帳款、庫存和薪資等。交易檔(transaction files)則記錄了對主檔的更新活動,例如薪資主檔的交易可能是薪水或工時的更新。
當交易檔累積一段時間後,會與主檔進行循序更新(sequential update),產生新的主檔。這個過程需要 COBOL 程式根據交易檔和主檔的唯一鍵值進行匹配。如果匹配成功,則進行更新;如果匹配失敗,則將交易記錄寫入錯誤日誌或列印檔,以提供稽核軌跡。
例項解析:庫存主檔更新
假設某公司的庫存主檔包含五種 iPhone 型號的庫存數量,分別對應不同的 SKU(Stock-Keeping Unit)。在過去的一週內,公司進行了多次庫存採購,並將這些交易記錄儲存在交易檔中。當進行循序更新時,系統會根據 SKU 將交易檔中的資料與庫存主檔進行匹配,並更新庫存數量。如果交易檔中的 SKU 在主檔中找不到對應的記錄,則將該筆交易寫入錯誤日誌。
COBOL 程式實作
以下是一個使用 COBOL 處理循序檔案的範例程式:
IDENTIFICATION DIVISION.
PROGRAM-ID. CUST-FILE.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT CUSTOMER-FILE ASSIGN TO "Customers.dat"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD CUSTOMER-FILE.
01 CUSTOMER-RECORD.
05 FIRST-NAME PIC X(20).
05 LAST-NAME PIC X(20).
WORKING-STORAGE SECTION.
01 WS-CUSTOMER-RECORD.
05 WS-FIRST-NAME PIC X(20).
05 WS-LAST-NAME PIC X(20).
01 WS-EOF PIC X.
PROCEDURE DIVISION.
OPEN INPUT CUSTOMER-FILE.
PERFORM UNTIL WS-EOF = 'Y'
READ CUSTOMER-FILE INTO WS-CUSTOMER-RECORD
AT END MOVE 'Y' TO WS-EOF
NOT AT END DISPLAY WS-CUSTOMER-RECORD
END-READ
END-PERFORM.
CLOSE CUSTOMER-FILE.
GOBACK.
程式碼解析:
IDENTIFICATION DIVISION和PROGRAM-ID:定義程式的識別資訊和名稱。ENVIRONMENT DIVISION和INPUT-OUTPUT SECTION:指定程式使用的外部檔案和裝置。DATA DIVISION:定義程式使用的資料結構,包括檔案描述(FD)和工作儲存區(WORKING-STORAGE)。PROCEDURE DIVISION:程式的主要邏輯部分,負責開啟檔案、讀取記錄並顯示內容,最後關閉檔案。
內容解密:
SELECT陳述式:將外部檔案Customers.dat對應到程式中的CUSTOMER-FILE。ORGANIZATION IS LINE SEQUENTIAL:指設定檔案的組織方式為循序存取。READ陳述式:從檔案中讀取一筆記錄到WS-CUSTOMER-RECORD,並根據是否到達檔案結尾設定WS-EOF旗標。PERFORM UNTIL迴圈:持續讀取檔案直到到達結尾。DISPLAY陳述式:顯示讀取到的客戶記錄。
COBOL 檔案處理詳解:從基礎到錯誤處理
在 COBOL 程式設計中,檔案處理是一項基本且重要的技能。本文將探討 COBOL 中的檔案處理機制,包括順序檔的讀取、寫入以及錯誤處理等關鍵議題。
檔案處理基礎
在 COBOL 中處理檔案,首先需要在 ENVIRONMENT DIVISION 中使用 SELECT 和 ASSIGN TO 命令來指設定檔案名稱和路徑。這裡需要注意的是,檔案路徑必須正確無誤,否則將導致錯誤。
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT CUSTOMER-FILE ASSIGN TO "Customers.dat"
ORGANIZATION IS LINE SEQUENTIAL.
內容解密:
ENVIRONMENT DIVISION:此部分用於定義程式的環境相關資訊。INPUT-OUTPUT SECTION:指定程式的輸入輸出相關設定。FILE-CONTROL:在此段落中定義檔案控制項。SELECT CUSTOMER-FILE ASSIGN TO "Customers.dat":將邏輯檔名CUSTOMER-FILE對應到實體檔案Customers.dat。ORGANIZATION IS LINE SEQUENTIAL:指設定檔案的組織方式為順序檔。
資料部份的檔案定義
在 DATA DIVISION 中,我們需要定義檔案的結構。
DATA DIVISION.
FILE SECTION.
FD CUSTOMER-FILE.
01 CUSTOMER-RECORD.
05 FIRST-NAME PIC X(20).
05 LAST-NAME PIC X(20).
內容解密:
DATA DIVISION:定義程式中使用的資料結構。FILE SECTION:描述檔案的結構。FD CUSTOMER-FILE:定義與CUSTOMER-FILE相關的檔案描述項(File Descriptor)。01 CUSTOMER-RECORD:定義記錄的名稱和結構。PIC X(20):指定欄位的資料型別和長度。
讀取檔案
要讀取檔案,首先需要開啟檔案,然後使用 READ 命令逐一讀取記錄。
PROCEDURE DIVISION.
OPEN INPUT CUSTOMER-FILE
PERFORM UNTIL WS-EOF = 'Y'
READ CUSTOMER-FILE INTO WS-CUSTOMER-RECORD
AT END MOVE 'Y' TO WS-EOF
NOT AT END DISPLAY WS-CUSTOMER-RECORD
END-READ
END-PERFORM
CLOSE CUSTOMER-FILE
內容解密:
OPEN INPUT CUSTOMER-FILE:開啟CUSTOMER-FILE以供讀取。PERFORM UNTIL WS-EOF = 'Y':使用迴圈直到檔案結束。READ CUSTOMER-FILE INTO WS-CUSTOMER-RECORD:讀取一筆記錄到WS-CUSTOMER-RECORD。AT END MOVE 'Y' TO WS-EOF:當到達檔案末尾時,將WS-EOF設為 ‘Y’。CLOSE CUSTOMER-FILE:關閉檔案。
錯誤處理
COBOL 提供了檔案狀態碼(FILE STATUS)來處理檔案操作中的錯誤。
FILE-CONTROL.
SELECT CUSTOMER-FILE ASSIGN TO "Customers.dat"
FILE STATUS IS FILE-EXISTS
ORGANIZATION IS LINE SEQUENTIAL.
...
OPEN INPUT CUSTOMER-FILE
IF FILE-EXISTS NOT = "00"
DISPLAY "File does not exist"
PERFORM 200-END-PROGRAM
END-IF
內容解密:
FILE STATUS IS FILE-EXISTS:定義一個變數FILE-EXISTS來儲存檔案狀態碼。IF FILE-EXISTS NOT = "00":檢查開啟檔案後是否發生錯誤(狀態碼非 “00”)。
常見的檔案狀態碼
| 狀態碼 | 定義 |
|---|---|
| 00 | 輸入/輸出操作成功。 |
| 04 | 成功讀取,但記錄長度與程式定義不符。 |
| 10 | 已到達檔案末尾。 |
| 35 | 開啟不存在的檔案。 |
COBOL 檔案處理與 JCL 應用詳解
COBOL 檔案處理基礎
在 COBOL 程式設計中,檔案處理是一項基本且重要的功能。本文將介紹如何使用 COBOL 進行檔案的讀寫操作,並探討在大型主機(Mainframe)環境中使用工作控制語言(Job Control Language, JCL)來管理和執行 COBOL 程式。
COBOL 檔案處理範例
以下是一個簡單的 COBOL 程式範例,展示如何建立一個客戶檔案並寫入資料,然後再讀取並顯示檔案內容。
IDENTIFICATION DIVISION.
PROGRAM-ID. CUSTOMERFILE.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT CUSTOMER-FILE ASSIGN TO "C:\Users\ttaul\OneDrive\Desktop\Customers.dat"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD CUSTOMER-FILE.
01 CUSTOMER-RECORD.
05 FIRST-NAME PIC X(20).
05 LAST-NAME PIC X(20).
WORKING-STORAGE SECTION.
01 WS-CUSTOMER-RECORD.
05 WS-FIRST-NAME PIC X(20).
05 WS-LAST-NAME PIC X(20).
01 WS-EOF PIC X.
PROCEDURE DIVISION.
OPEN OUTPUT CUSTOMER-FILE
PERFORM UNTIL CUSTOMER-RECORD = SPACES
DISPLAY "Enter the first and last name for the customer"
ACCEPT CUSTOMER-RECORD
WRITE CUSTOMER-RECORD
END-PERFORM
CLOSE CUSTOMER-FILE
DISPLAY "Output from the Customer File:"
OPEN INPUT CUSTOMER-FILE
PERFORM UNTIL WS-EOF = 'Y'
READ CUSTOMER-FILE INTO WS-CUSTOMER-RECORD
AT END MOVE 'Y' TO WS-EOF
NOT AT END DISPLAY WS-CUSTOMER-RECORD
END-READ
END-PERFORM
CLOSE CUSTOMER-FILE
GOBACK.
內容解密:
- 檔案定義:在
ENVIRONMENT DIVISION中定義了客戶檔案CUSTOMER-FILE,並指定其為順序檔案。 - 資料結構:在
DATA DIVISION中定義了檔案記錄CUSTOMER-RECORD的結構,包括FIRST-NAME和LAST-NAME欄位。 - 寫入操作:在
PROCEDURE DIVISION中,首先開啟檔案進行輸出,然後透過PERFORM UNTIL迴圈接受使用者輸入的客戶資料並寫入檔案,直到輸入空白記錄為止。 - 讀取操作:關閉檔案後,再次開啟檔案進行輸入,透過另一個
PERFORM UNTIL迴圈讀取檔案內容並顯示,直到到達檔案結尾。
JCL 在 Mainframe 環境中的應用
在 Mainframe 環境中,JCL 用於控制工作(Job)的執行,包括程式的編譯、連結和執行。以下是一個範例 JCL,用於編譯和執行上述 COBOL 程式。
//FILEJOB JOB 400000000,'MSV1 JOB CARD ',MSGLEVEL=(1,1),
// CLASS=A,MSGCLASS=Q,NOTIFY=&SYSUID,TIME=1440,REGION=0M
//COMPILE1 EXEC IGYWCL,PARM=(OFFSET,NOLIST,ADV),PGMLIB='INSTPS1.COBOL.LOADLIB',
// GOPGM=CUST-FILE
//SYSIN DD *
//CUSTOMER DD DISP=(NEW,CATLG,DELETE),
// DSN=DIV2.CUST-FILE,
// LRECL=40,
// AVGREC=U,
// RECFM=FB,
// SPACE=(40,(10,10),RLSE)
//SYSOUT DD SYSOUT=*
//CEEDUMP DD SYSOUT=*
JCL 解說:
JOB陳述式:定義了一個名為FILEJOB的工作,並指定了相關的引數,如訊息級別、工作類別等。EXEC陳述式:執行 COBOL 編譯步驟,使用IGYWCL編譯器,並指定了編譯選項和程式函式庫。DD陳述式:定義了輸入輸出資料集,包括程式原始碼(SYSIN)、客戶資料集(CUSTOMER)和輸出訊息(SYSOUT)。