COBOL 作為歷史悠久的大型主機程式語言,在檔案和表格處理方面具備獨特機制。理解這些機制對於維護和最佳化既有 COBOL 系統至關重要。本文從索引檔案的存取邏輯開始,逐步深入 VSAM 檔案的結構、引數設定及現代化轉換趨勢,並探討第三方工具的支援。接著,文章詳細介紹了 COBOL 表格的宣告、初始化、單層及多層級表格的應用,以及與循序檔案和索引檔案的整合運用。最後,文章分析了索引在表格處理中的優勢、COBOL 表格搜尋技術,並提供多層級表格處理的最佳實踐,幫助開發者更好地運用 COBOL 進行高效的資料處理。
COBOL 檔案處理技術深度解析
索引檔案的高階操作與實務應用
在 COBOL 的檔案處理中,索引檔案(Indexed Files)提供了高效的資料存取機制,特別是在需要快速查詢和更新記錄的應用場景中。本文將探討索引檔案的操作細節,包括記錄的存取、更新和刪除,並結合實務案例進行分析。
索引檔案的存取邏輯
索引檔案允許程式直接存取特定的記錄,而無需循序讀取整個檔案。這種機制大大提高了資料處理的效率。以下是一個典型的索引檔案存取範例:
MOVE TRANS-NO TO PART-NO
READ MASTER-FILE
INVALID KEY DISPLAY "The record does not exist"
END-READ.
內容解密:
MOVE TRANS-NO TO PART-NO:將交易編號(TRANS-NO)移至主檔案的零件編號(PART-NO),以便進行索引查詢。READ MASTER-FILE:讀取主檔案(MASTER-FILE)中對應的記錄。INVALID KEY子句:當指定的索引不存在時,顯示錯誤訊息「The record does not exist」。
索引檔案的更新與刪除操作
除了讀取記錄,索引檔案還支援更新和刪除操作。更新操作使用 REWRITE 陳述式,而刪除操作則使用 DELETE 陳述式。以下是範例程式碼:
MOVE TRANS-FIRST-NAME TO MASTER-FIRST-NAME
REWRITE MASTER-RECORD
INVALID KEY DISPLAY "There was an error in writing the record to the file"
END-REWRITE.
MOVE TRANS-NO TO PART-NO
READ MASTER-FILE
INVALID KEY DISPLAY "The record does not exist"
NOT INVALID KEY
DELETE MASTER-FILE RECORD
INVALID KEY DISPLAY "The record could not be deleted"
END-DELETE
END-READ.
內容解密:
REWRITE MASTER-RECORD:更新主檔案中的記錄。如果更新失敗,將顯示錯誤訊息。DELETE MASTER-FILE RECORD:刪除主檔案中的指定記錄。如果刪除失敗,將顯示錯誤訊息「The record could not be deleted」。
VSAM 檔案技術詳解
VSAM(Virtual Storage Access Method)檔案是 IBM 開發的一種高效檔案存取方法,結合了資料和索引,支援直接存取和循序存取。本文將探討 VSAM 檔案的結構和建立方法。
VSAM 檔案的結構與引數設定
VSAM 檔案由控制區間(Control Interval, CI)和控制區域(Control Area, CA)組成。建立 VSAM 檔案需要使用 IDCAMS 工具,並在 JCL 指令碼中定義相關引數,例如:
//FILEPROG JOB 1,TOM001,MSGCLASS=C
//STEP1 EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEFINE CLUSTER (NAME(TOM001.INVENT) -
RECSZ(90,90) -
FREESPACE(5,10) -
KEYS(5,0) -
CISZ(4096) -
VOLUMES(XFV01) -
INDEXED -
DATA(NAME(TOM001.INVENT.DATA))
/*
內容解密:
RECSZ(90,90):定義記錄的大小,平均和最大長度均為 90 位元組。FREESPACE(5,10):設定控制區間和控制區域的空閒空間百分比,以便於插入新記錄。KEYS(5,0):定義索引鍵的長度和偏移位置,此例中索引鍵長度為 5,從第 0 位開始。CISZ(4096):設定控制區間的大小為 4096 位元組。
現代化轉換趨勢與第三方工具支援
儘管 VSAM 檔案功能強大,但其管理和維護相對複雜,且缺乏現代資料函式庫的功能。因此,許多企業傾向於將 VSAM 檔案轉換為現代資料函式庫,以獲得更強大的資料分析能力。以下是一些常見的第三方工具:
- BMC Compuware Storage Performance:提升 VSAM 檔案的磁碟效能,提供比 IDCAMS 更快的重組速度。
- Rocket VSAM Assist:簡化 VSAM 應用程式的備份、還原和遷移流程,無需深入的技術知識。
- CA File Master Plus:提高大型主機資料的準確性,並降低測試檔案編輯和資料建立的工作量。
COBOL 表格與報告
在商業世界中,Microsoft Excel 是最廣泛使用的應用程式之一。它允許輕鬆建立互動式報告,幫助做出關鍵決策。結果是,Excel 繼續產生巨大的現金流,即使該軟體已經存在超過 35 年。
但在大型主機上的 COBOL 中,內建功能可以幫助建立表格和報告。雖然它們不如 Excel 那麼複雜或無縫,但仍然強大,可以幫助在全球範圍內執行關鍵業務應用程式。它們一直是 COBOL 和大型主機電腦最重要的功能之一。
在本章中,我們將探討如何在 COBOL 中使用表格和報告。我們還將涵蓋相關主題,如字串操作。
表格簡介
在某種程度上,COBOL 表格類別似於電子試算表。您可以將數字放在某些區域,進行計算,搜尋資料等。事實上,應用程式似乎無窮無盡。您可以建立一個表格來幫助計算稅金,確定保險費,或提出銷售預測。
請記住,COBOL 表格是該語言的陣列版本。在典型的語言中,陣列儲存一串資料。每個資料項都透過索引編號參照。例如,假設我們有一個陣列,我們稱之為 Months,用於一年中的月份。但每個都有一個從 0 開始的索引。所以 Months[0] 等於 January,Months[1] 等於 February 等等。換句話說,這是一種更有效的方式來處理相關資料,而不是為每個資料都有一個唯一的變數,如 Month1 和 Month2。
但 COBOL 有自己的方法。索引被稱為下標(subscript),並且從 1 開始。其次,因為記錄是關於分組層次資訊,所以在使用表格時必須強制執行這一點,這可能會變得複雜。
宣告表格
我們在 DATA DIVISION 的 WORKING-STORAGE SECTION 中宣告表格,並使用 OCCURS 子句。這表示元素的數量。
假設我們想要為一家零售公司的 10 家商店建立一個表格。這就是我們要做的:
01 RETAIL-STORE-TABLE.
05 RETAIL-RECORD OCCURS 10 TIMES.
10 STORE-ADDRESS PIC X(20).
10 STORE-PHONE PIC X(12).
內容解密:
01 RETAIL-STORE-TABLE:宣告一個名為RETAIL-STORE-TABLE的表格。05 RETAIL-RECORD OCCURS 10 TIMES:建立一個名為RETAIL-RECORD的資料群組,並使用OCCURS 10 TIMES建立 10 個例項。10 STORE-ADDRESS PIC X(20)和10 STORE-PHONE PIC X(12):定義每個RETAIL-RECORD中的欄位,分別用於儲存商店地址和電話號碼。
我們設定了一個名為 RETAIL-STORE-TABLE 的表格標頭,然後建立了一個名為 RETAIL-RECORD 的資料群組。我們使用 OCCURS 10 TIMES 建立了 10 個例項。每個例項都有一個用於商店地址和電話號碼的欄位。
這個表格被稱為一級表格。記錄依賴於一個變數,即零售商店的數量。
在大多數情況下,表格的資料將從外部檔案中填充。但如果資料相對較小並且不會改變太多,您可以在 DATA DIVISION 或 PROCEDURE DIVISION 中放置值。
讓我們看一個暢銷耐克鞋的例子:
01 NIKE-SHOES.
05 FILLER PIC X(30) VALUE "Nike Air Force 1".
05 FILLER PIC X(30) VALUE "Nike Air Max 270".
05 FILLER PIC X(30) VALUE "Nike Air Max 270".
05 FILLER PIC X(30) VALUE "Nike Benassi JDI".
05 FILLER PIC X(30) VALUE "Nike Flex Runner".
01 NIKE-SHOES-TABLE REDEFINES NIKE-SHOES.
05 SHOE-NAME PIC X(30) OCCURS 5 TIMES.
PROCEDURE DIVISION.
DISPLAY SHOE-NAME(4)
GOBACK.
內容解密:
01 NIKE-SHOES:宣告一個名為NIKE-SHOES的資料群組,其中包含五個耐克品牌。05 FILLER PIC X(30) VALUE "...":使用FILLER為每個鞋子名稱設定值,因為我們不需要為欄位命名。01 NIKE-SHOES-TABLE REDEFINES NIKE-SHOES:重新定義NIKE-SHOES為NIKE-SHOES-TABLE。05 SHOE-NAME PIC X(30) OCCURS 5 TIMES:建立一個名為SHOE-NAME的基本專案,使用OCCURS 5 TIMES重複五次。DISPLAY SHOE-NAME(4):顯示第四項,即 “Nike Benassi JDI”。
還有更緊湊的方式來建立這種表格。例如,讓我們看看如何建立一個包含月份的表格:
01 MONTHS-TABLE VALUE "JanFebMarAprMayJunJulAugSepOctNovDec".
05 MONTH-GROUP OCCURS 12 TIMES.
10 MONTH-ABBREVIATION PIC X(3).
PROCEDURE DIVISION.
DISPLAY MONTH-ABBREVIATION(3).
內容解密:
01 MONTHS-TABLE VALUE "...":將MONTHS-TABLE設定為一個包含月份縮寫的字串。05 MONTH-GROUP OCCURS 12 TIMES:建立一個名為MONTH-GROUP的資料群組,使用OCCURS 12 TIMES建立 12 個例項。10 MONTH-ABBREVIATION PIC X(3):自動填入每個月份的縮寫。DISPLAY MONTH-ABBREVIATION(3):顯示第三項,即 “Mar”。
從某種意義上說,這兩個程式都是關於建立一組常數。您可以建立每個程式的副本以供其他程式使用,這是透過使用副本成員來完成的。您將在本文後面瞭解更多關於這方面的內容。
到目前為止,我們已經使用數字來參照表格中的專案。但是您也可以使用欄位來做到這一點。讓我們繼續我們的月份程式:
01 MONTHS-TABLE VALUE "JanFebMarAprMayJunJulAugSepOctNovDec".
05 MONTH-GROUP OCCURS 12 TIMES.
10 MONTH-ABBREVIATION PIC X(3).
01 MONTH-SUBSCRIPT PIC S99 BINARY.
PROCEDURE DIVISION.
MOVE 2 TO MONTH-SUBSCRIPT
DISPLAY MONTH-ABBREVIATION(MONTH-SUBSCRIPT)
內容解密:
01 MONTH-SUBSCRIPT PIC S99 BINARY:建立一個名為MONTH-SUBSCRIPT的欄位,並使其成為無符號整數。使用二進位資料型別通常比使用壓縮十進位更有效率。MOVE 2 TO MONTH-SUBSCRIPT:將 2 設定為MONTH-SUBSCRIPT,並將其用作MONTH-ABBREVIATION的下標,這將列印 “Feb”。
另一種使用表格下標的方法是相對下標。這是一個加或減欄位的值。為了說明這一點,以下是我們的月份程式的 PROCEDURE DIVISION 的一些程式碼:
MOVE 2 TO MONTH-SUBSCRIPT
DISPLAY MONTH-ABBREVIATION(MONTH-SUBSCRIPT + 2)
內容解密:
- 將 2 加到欄位
MONTHS-SUBSCRIPT上。因此,程式將列印 “Apr”。
瞭解表格下標的大小非常重要。例如,如果它設定為 20,而您使用 21,程式將當機。如果下標為 0 或更小,也會發生這種情況。
COBOL 表格與檔案讀取
在前面的章節中,我們已經瞭解瞭如何使用循序檔案和索引檔案。在本章節中,我們將探討如何將這些概念應用於 COBOL 表格。
初始化表格資料
在處理表格資料時,我們需要初始化資料專案。COBOL 提供了兩種方式來實作這一點:使用 MOVE 陳述式或 INITIALIZE 陳述式。
MOVE 0 TO ITEM-PRICES
或
INITIALIZE ITEM-PRICES
然而,當處理大量資料時,INITIALIZE 陳述式可能會降低效率。
循序檔案與表格
讓我們考慮一個例子。假設我們有一個名為 SALES-FILE 的循序檔案,其中包含了各個分公司的銷售資料。
資料部份(DATA DIVISION)
DATA DIVISION.
FILE SECTION.
FD SALES-FILE.
01 LOCATION-SALES.
88 END-OF-FILE VALUE HIGH-VALUES.
02 LOCATION-NO PIC 99.
02 RECEIPTS PIC 9(4).
WORKING-STORAGE SECTION.
01 SALES-TABLE.
05 SALES-TOTALS PIC 9(4) OCCURS 5 TIMES.
01 LOCATION-COUNTER PIC 99.
01 SALES-FORMAT PIC $$$,$$$.
程式部份(PROCEDURE DIVISION)
PROCEDURE DIVISION.
MOVE ZEROES TO SALES-TABLE
OPEN INPUT SALES-FILE
READ SALES-FILE
AT END SET END-OF-FILE TO TRUE
END-READ
PERFORM UNTIL END-OF-FILE
MOVE RECEIPTS TO SALES-TOTALS(LOCATION-NO)
READ SALES-FILE
AT END SET END-OF-FILE TO TRUE
END-READ
END-PERFORM
DISPLAY " Monthly Sales By Location"
PERFORM VARYING LOCATION-COUNTER FROM 1 BY 1
UNTIL LOCATION-COUNTER GREATER THAN 5
MOVE SALES-TOTALS(LOCATION-COUNTER) TO SALES-FORMAT
DISPLAY "Sales for location number ", LOCATION-COUNTER
" " SALES-FORMAT
END-PERFORM
CLOSE SALES-FILE
GOBACK.
程式碼解析:
- 初始化銷售表格:使用
MOVE ZEROES TO SALES-TABLE初始化銷售表格。 - 讀取檔案:使用
OPEN INPUT SALES-FILE和READ SALES-FILE陳述式讀取SALES-FILE檔案。 - 迴圈處理資料:使用
PERFORM UNTIL END-OF-FILE迴圈處理檔案中的資料,並將銷售資料存入SALES-TOTALS表格中。 - 顯示銷售資料:使用
PERFORM VARYING LOCATION-COUNTER FROM 1 BY 1迴圈顯示各個分公司的銷售資料。
多層級表格
在實際應用中,表格通常具有多個變數。COBOL 允許建立最多七層的表格。
多層級表格範例
假設我們有一個名為 SALES-TABLE 的多層級表格,其中包含了五個區域的銷售資料,每個區域有四個季度的銷售資料。
01 SALES-TABLE.
05 REGION OCCURS 5 TIMES.
10 ST-QUARTERLY-SALES PIC 9(3) OCCURS 4 TIMES.
程式碼解析:
- 定義多層級表格:使用
OCCURS陳述式定義多層級表格SALES-TABLE。 - 存取表格資料:使用下標變數存取表格中的資料。
COBOL 表格與報表處理技術深度解析
多層級表格的實務應用與挑戰
在COBOL程式設計中,多層級表格(Multilevel Tables)是處理複雜資料結構的重要工具。透過巢狀的PERFORM VARYING陳述式,可以實作對多維資料的有效存取和處理。
程式碼例項與解析
PERFORM UNTIL END-OF-FILE
PERFORM VARYING QUARTER-INDEX FROM 1 BY 1
UNTIL QUARTER-INDEX > 4
ADD QUARTERLY-SALES(QUARTER-INDEX) TO
ST-QUARTERLY-SALES(REGION-NO, QUARTER-INDEX)
END-PERFORM
READ SALES-FILE
AT END SET END-OF-FILE TO TRUE
END-READ
END-PERFORM
內容解密:
- 外部迴圈控制:
PERFORM UNTIL END-OF-FILE確保資料讀取直到檔案結束。 - 內部迴圈處理:
PERFORM VARYING QUARTER-INDEX用於遍歷四個季度的銷售資料。 - 資料轉換邏輯:將一維的
QUARTERLY-SALES資料轉存到二維的ST-QUARTERLY-SALES表格中。 - 索引管理:正確使用
QUARTER-INDEX和隱含的REGION-NO來定位二維表格中的元素。
索引(Index)在表格處理中的優勢
與下標(Subscript)相比,索引提供了更高效的資料存取方式。在COBOL中,索引是透過INDEXED BY子句來定義:
01 INVENTORY-TABLE.
05 INVENTORY-TRANSACTIONS OCCURS 100 TIMES INDEXED BY INDEX-1.
10 SKU PIC 9(5).
10 PRODUCT-DESCRIPTION PIC X(30).
索引操作說明:
- 索引定義:在
OCCURS子句中使用INDEXED BY來指定索引名稱。 - 索引值設定:使用
SET INDEX-1 TO 2來直接設定索引值。 - 索引值調整:透過
SET INDEX-1 UP/DOWN BY 1來遞增或遞減索引值。
內容解密:
- 索引由編譯器自動處理底層實作細節。
- 索引直接指向記憶體位置,效率高於使用下標。
- 在搜尋表格時,索引是必要的。
表格搜尋技術的實務應用
COBOL提供了順序搜尋(Sequential Search)機制,可以從指定的索引值開始搜尋:
- 從索引對應的記錄開始搜尋。
- 逐筆記錄進行比較,直到找到匹配或到達檔案結尾。
搜尋技術特點:
- 搜尋起點由索引值決定。
- 支援順序存取模式。
- 可用於大型資料表的查詢。
多層級表格處理的最佳實踐
- 結構化設計:合理規劃表格維度,避免過度複雜的結構。
- 索引最佳化:適當使用索引提升資料存取效率。
- 迴圈控制:謹慎設計巢狀迴圈,確保邏輯正確性和效能。
- 報表格式化:利用
DISPLAY陳述式和格式化欄位產生清晰的報表輸出。