Michael Coughlan
Page 21
03 AddressLine3 PIC X(10).
02 StudentGPA.
05 Year1GPA
10 Sem1GPA PIC 9V99.
10 Sem2GPA PIC 9V99.
05 Year2GPA.
10 Sem1GPA PIC 9V99.
10 Sem2GPA PIC 9V99.
05 Year3GPA
10 Sem1GPA PIC 9V99.
10 Sem2GPA PIC 9V99.
147
Chapter 7 ■ IntroduCtIon to SequentIal FIleS
2. Complete the SELECT and ASSIGN clause for a sequential file called Stock.dat in the
directory C:COBOL-Data. the record buffer for the file has this description:
FD StockFile.
01 StockRec.
02 StockNumber PIC 9(5)
02 ManfNumber PIC 9(4)
02 QtyInStock PIC 9(6)
02 ReorderLevel PIC 9(6)
02 ReorderQty PIC 9(6).
Write your answer here:
IDENTIFICATION DIVISION.
PROGRAM-ID. Exercise7-2.
ENVIRONMENT DIVISION.
148
Chapter 7 ■ IntroduCtIon to SequentIal FIleS
prOGraMMING eXerCISe 1
a StockFile holds details of gadgets sold by the Gadget Shop (GadgetShop.Com). the StockFile is a sequential file sorted in ascending GadgetId order. It is named GadgetStock.dat. each record has the following description: Field
Type
Length
Value
GadgetID
N
6
000001–999999
GadgetName
X
30
–
QtyInStock
N
4
0000–9999
Price
N
6
0000.00–9999.99
Write a program to process the data in the StockFile and, for each record, display the item’s GadgetName and the total value of the quantity in stock (QtyInStock * Price). When the StockFile has ended, display the total value of all the stock.
Example Test Data
123456SoundDisk MP3 Player 4GB 0650003095
234567BioLite Camp Stove 0057029550
345678Collapsible Kettle - Green 0155002590
456789Digital Measuring Jug 0325000895
567890MicroLite LED Torch 0512000745
678901Pocket Sized Fishing Rod 0055001799
note: place the test data in the data file as one long string.
Example Run
SoundDisk MP3 Player 4GB $20,117.50
BioLite Camp Stove $16,843.50
Collapsible Kettle - Green $4,014.50
Digital Measuring Jug $2,908.75
MicroLite LED Torch $3,814.40
Pocket Sized Fishing Rod $989.45
Stock Total: $48,688.10
149
Chapter 7 ■ IntroduCtIon to SequentIal FIleS
prOGraMMING eXerCISe 2
amend the program you wrote for exercise 1 so that it adds the following two records to the end of the file. then display the stock report as before:
313245Spy Pen - HD Video Camera 0125003099
593486Scout Cash Capsule - Red 1234000745
the records in the StockFile are held in ascending GadgetID order. When you add these two records to the file, the records will be out of order. Without sorting the StockFile after the update, how could you update the file so that the ordering of the records was maintained?
Example Run
SoundDisk MP3 Player 4GB $20,117.50
BioLite Camp Stove $16,843.50
Collapsible Kettle - Green $4,014.50
Digital Measuring Jug $2,908.75
MicroLite LED Torch $3,814.40
Pocket Sized Fishing Rod $989.45
Spy Pen - HD Video Camera $3,873.75
Scout Cash Capsule - Red $9,193.30
Stock Total: $61,755.15
LaNGUaGe KNOWLeDGe eXerCISeS: aNSWerS
unsheath your 2B pencil. It is exercise time again.
1. locate errors in these FILE SECTION entries.
150
Chapter 7 ■ IntroduCtIon to SequentIal FIleS
151
Chapter 7 ■ IntroduCtIon to SequentIal FIleS
2. Complete the SELECT and ASSIGN clause for a sequential file called Stock.dat in the
directory C:COBOL-Data. the record buffer for the file has this description:
FD StockFile.
01 StockRec.
02 StockNumber PIC 9(5)
02 ManfNumber PIC 9(4)
02 QtyInStock PIC 9(6)
02 ReorderLevel PIC 9(6)
02 ReorderQty PIC 9(6).
Write your answer here:
IDENTIFICATION DIVISION.
PROGRAM-ID. Exercise7-2.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT StockFile ASSIGN TO "C:COBOL-DataStock.dat"
ORGANIZATION IS SEQUENTIAL.
prOGraMMING eXerCISe 1: aNSWer
a StockFile holds details of gadgets sold by the Gadget Shop (GadgetShop.Com). the StockFile is a sequential file sorted in ascending GadgetId order. It is named GadgetStock.dat. each record has the following description.
Field
Type
Length
Value
GadgetID
N
6
000001–999999
GadgetName
X
30
–
QtyInStock
N
4
0000–9999
Price
N
6
0000.00–9999.99
Write a program to process the data in the StockFile and, for each record, display the item’s GadgetName and the total value of the quantity in stock (QtyInStock * Price). When the StockFile has ended, display the total value of all the stock.
Example Test Data
123456SoundDisk MP3 Player 4GB 0650003095
234567BioLite Camp Stove 0057029550
345678Collapsible Kettle - Green 0155002590
456789Digital Measuring Jug 0325000895
567890MicroLite LED Torch 0512000745
678901Pocket Sized Fishing Rod 0055001799
152
Chapter 7 ■ IntroduCtIon to SequentIal FIleS
note: place the test data in the data file as one long string.
Example Run
SoundDisk MP3 Player 4GB $20,117.50
BioLite Camp Stove $16,843.50
Collapsible Kettle - Green $4,014.50
Digital Measuring Jug $2,908.75
MicroLite LED Torch $3,814.40
Pocket Sized Fishing Rod $989.45
Stock Total: $48,688.10
Listing 7-4. Displays the Value of the Gadgets in Stock
IDENTIFICATION DIVISION.
PROGRAM-ID. Listing7-4.
AUTHOR. Michael Coughlan
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT GadgetStockFile ASSIGN TO "input.txt"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD GadgetStockFile.
01 StockRec.
88 EndOfStockFile VALUE HIGH-VALUES.
02 GadgetID PIC 9(6).
02 GadgetName PIC X(30).
02 QtyInStock PIC 9(4).
02 Price PIC 9(4)V99.
WORKING-STORAGE SECTION.
01 PrnStockValue.
02 PrnGadgetName PIC X(30).
02 FILLER PIC XX VALUE SPACES.
02 PrnValue PIC $$$,$$9.99.
01 PrnFinalStockTotal.
02 FILLER PIC X(16) VALUE SPACES.
02 FILLER PIC X(16) VALUE "Stock Total:".
02 PrnFinalTotal PIC $$$,$$9.99.
01 FinalStockTotal PIC 9(6)V99.
01 StockValue PIC 9(6)V99.
153
Chapter 7 ■ IntroduCtIon to SequentIa
l FIleS
PROCEDURE DIVISION.
Begin.
OPEN INPUT GadgetStockFile
READ GadgetStockFile
AT END SET EndOfStockFile TO TRUE
END-READ
PERFORM DisplayGadgetValues UNTIL EndOfStockFile
MOVE FinalStockTotal TO PrnFinalTotal
DISPLAY PrnFinalStockTotal
CLOSE GadgetStockFile
STOP RUN.
DisplayGadgetValues.
COMPUTE StockValue = Price * QtyInStock
ADD StockValue TO FinalStockTotal
MOVE GadgetName TO PrnGadgetName
MOVE StockValue TO PrnValue
DISPLAY PrnStockValue
READ GadgetStockFile
AT END SET EndOfStockFile TO TRUE
END-READ.
prOGraMMING eXerCISe 2: aNSWer
amend the program you wrote for exercise 1 so that it adds the following two records to the end of the file.
then display the stock report as before:
313245Spy Pen - HD Video Camera 0125003099
593486Scout Cash Capsule - Red 1234000745
the records in the StockFile are held in ascending GadgetID order. When you add these two records to the file, the records will be out of order. Without sorting the StockFile after the update, how could you update the file so that the ordering of the records was maintained?
Example Run
SoundDisk MP3 Player 4GB $20,117.50
BioLite Camp Stove $16,843.50
Collapsible Kettle - Green $4,014.50
Digital Measuring Jug $2,908.75
MicroLite LED Torch $3,814.40
Pocket Sized Fishing Rod $989.45
Spy Pen - HD Video Camera $3,873.75
Scout Cash Capsule - Red $9,193.30
Stock Total: $61,755.15
154
Chapter 7 ■ IntroduCtIon to SequentIal FIleS
Listing 7-5. Adds Two Records and Then Displays Stock Values Again
IDENTIFICATION DIVISION.
PROGRAM-ID. Listing7-5.
AUTHOR. Michael Coughlan
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT GadgetStockFile ASSIGN TO "input.txt"
ORGANIZATION IS LINE SEQUENTIAL.
DATA DIVISION.
FILE SECTION.
FD GadgetStockFile.
01 StockRec.
88 EndOfStockFile VALUE HIGH-VALUES.
02 GadgetID PIC 9(6).
02 GadgetName PIC X(30).
02 QtyInStock PIC 9(4).
02 Price PIC 9(4)V99.
WORKING-STORAGE SECTION.
01 PrnStockValue.
02 PrnGadgetName PIC X(30).
02 FILLER PIC XX VALUE SPACES.
02 PrnValue PIC $$$,$$9.99.
01 PrnFinalStockTotal.
02 FILLER PIC X(16) VALUE SPACES.
02 FILLER PIC X(16) VALUE "Stock Total:".
02 PrnFinalTotal PIC $$$,$$9.99.
01 FinalStockTotal PIC 9(6)V99.
01 StockValue PIC 9(6)V99.
PROCEDURE DIVISION.
Begin.
OPEN EXTEND GadgetStockFile
MOVE "313245Spy Pen - HD Video Camera 0125003099"
TO StockRec
WRITE StockRec
MOVE "593486Scout Cash Capsule - Red 1234000745"
TO StockRec
WRITE StockRec
CLOSE GadgetStockFile
OPEN INPUT GadgetStockFile
READ GadgetStockFile
AT END SET EndOfStockFile TO TRUE
END-READ
155
Chapter 7 ■ IntroduCtIon to SequentIal FIleS
PERFORM DisplayGadgetValues UNTIL EndOfStockFile
MOVE FinalStockTotal TO PrnFinalTotal
DISPLAY PrnFinalStockTotal
CLOSE GadgetStockFile
STOP RUN.
DisplayGadgetValues.
COMPUTE StockValue = Price * QtyInStock
ADD StockValue TO FinalStockTotal
MOVE GadgetName TO PrnGadgetName
MOVE StockValue TO PrnValue
DISPLAY PrnStockValue
READ GadgetStockFile
AT END SET EndOfStockFile TO TRUE
END-READ.
156
Chapter 8
Advanced Sequential Files
In the previous chapter, you saw how sequential files are declared, written, and read. In this chapter, you continue your exploration of sequential files by examining advanced issues such as multiple-record-type files, print files, and variable-length records.
The previous chapter dealt with sequential files that contained only fixed-length records of a single record type. This chapter shows how a file may have records of different lengths either because the file contains a number of different types of fixed-length records or because it contains variable-length records. The discussion of files that contain multiple record types also considers the implications of these multiple record types for the record buffer.
When the WRITE verb was introduced in the previous chapter, I ignored some of the metalanguage because it
dealt with print files. This chapter addresses the issue of print files and shows how they are declared and used. I also discuss the problem caused by the different types of print lines that must be sent to a print file.
Files with Multiple Record Types
Quite often, complex data sets cannot store all their data in just one record type. In such cases, a single file contains more than one type of record. For instance, consider the following problem specification.
Problem Specification
A company has shops all over Ireland. Every night, a sequential file of cash register receipts is sent from each branch to the head office. These files are merged into a single, large, sequential file called the ShopReceiptsFile.
In the ShopReceiptsFile, there are two types of records:
• A ShopDetails record, used to record the ShopId and ShopLocation
• A SaleReceipt record, used to record the ItemId, QtySold, and ItemCost for each item sold
In the file, a single shop record precedes all the SaleReceipt records for a particular shop.
Write a program to process the ShopReceiptsFile and, for each shop in the file, produce a summary line that shows the ShopId of the shop and the total value of sales for that shop.
Implications of Files with Multiple Record Types
As you can see from the previous specification, the ShopReceiptsFile contains two different types of records.
When a file contains different record types, the records will have different structures and, possibly, different lengths.
In a specification, the different record types are usually represented as shown in Figure 8-1 and Figure 8-2. The ShopDetails record is 35 characters in size, but the SaleReceipt record is only 16 characters. For each shop in the file, there is one ShopDetails record but many SaleReceipt records.
157
Chapter 8 ■ advanCed Sequential FileS
Figure 8-1. ShopDetails description
Figure 8-2. SaleReceipt description
The different types of records in the ShopReceiptsFile means you need more than one record description in the file’s file description (FD) entry. Because record descriptions always begin with level 01, you must provide a 01-level description for each type of record in the file.
Example 8-1 shows the file description for the ShopReceiptsFile. What is not obvious from this description is that even though there are two record descriptions, only one area of memory is reserved for the record buffer, and it is only able to store a single record at a time. Because only one area of memory is reserved, both record descriptions map on to the same record buffer. The size of that record buffer is the size of the largest record.
Example 8-1. File Description for the ShopReceiptsFile
FILE SECTION.
FD ShopReceiptsFile.
01 ShopDetails.
02 ShopId PIC X(5).
02 ShopLocation PIC X(30).
01 SaleReceipt.
02 ItemId PIC X(8).
02 QtySold PIC 9(3).
02 ItemCost PIC 999V99.
This is the magic of the FILE SECTION. When, in the FILE SECTION, multiple records are defined in a file’s FD
entry, all the record descriptions share (map on to) the same area of memory, and all the record descriptions are current (live) at the same time.
158
Chapter 8 ■ advanCed Sequential FileS
Multiple Record Descriptions, One Record Buffer
When multiple records are described for the same FD entry, only a single area of storage (record buffer) is created (the size of the largest record). All the record descriptions map on to this single area of storage, and all the descriptions are current no matter which record is actually in the buffer. Obviously, though, even though both record descriptions are available, only one makes sense for the values in the buffer. For instance, Figure 8-3 is a graphical representation of the shared buffer for the ShopReceiptsFile, and the record currently in the buffer is a SaleReceipt record. If you execute the statement DISPLAY ItemId, the value ABC12345 is displayed. If you execute DISPLAY QtySold, you get the value 003.
But because both record descriptions are current at the same time, you can also execute DISPLAY ShopLocation, which displays the nonsensical value 34500300399. It is up to the programmer to know what type of record is in the buffer and to use only the record description that makes sense for those values. The question is, how can you know what type of record has been read into the buffer?
Figure 8-3. A graphical representation of the shared record buffer
The Type Code
When a record is read into a shared record buffer, it is your responsibility to discover what type of record has been read in and to refer only to the fields that make sense for that type of record. Looking at the record in Figure 8-3, you might wonder how you can discover what type of record had been read into the buffer. Sometimes you can determine the record type by looking for identifying characteristics that are unique to that type of record, such as a particular value or data type. However, generally it is not possible to establish reliably what type of record is in the buffer simply by examining the buffer values.
A special identifying data item called the type code is usually inserted into each record to allow you to distinguish between record types. The type code is usually one character in size and is the first field in each record, but its size and placement are merely conventions. The type code can be placed anywhere in the record and be of any size and any type.