The flowchart in Figure 9-1 summarizes the functionality of
program pasex9. This program creates orders in the sample
DBEnvironment, PartsDBE. Each order is placed with a
specific vendor, to obtain one or more parts supplied by that vendor.
An order consists of
a row in table PurchDB.Orders, which comprises the order header:
OrderNumber (defined NOT NULL)
An order usually also consists of one or more line items, represented
by one or more rows in table PurchDB.OrderItems, such as the following:
OrderNumber (defined NOT NULL)
ItemNumber (defined NOT NULL)
PurchasePrice (defined NOT NULL)
Program pasex9 uses a simple INSERT command to create the order header and, optionally, a BULK INSERT command to insert line items.
The runtime dialog for pasex9 appears in Figure 9-2, and the
source code in Figure 9-3.
To establish a DBE session, pasex9 executes function
ConnectDBE 54 . This function evaluates to TRUE
when the CONNECT command 5 is successfully executed.
The program then executes procedure CreateOrder
until the Done flag is set to TRUE 55 .
Procedure CreateOrder prompts for a vendor number or
a 0 48 . When the user enters a 0, Done is set to
TRUE 53 and the program terminates. When the user enters a vendor number, pasex9 performs the tasks in the following list.
Validates the number entered.
Creates an order header if the vendor number is valid.
Optionally inserts line items if the order header has
been successfully created; the part number for each line item is validated to ensure the vendor actually supplies the part.
Displays the order created.
To validate the vendor number, procedure
ValidateVendor is executed 49 .
Procedure ValidateVendor
starts a transaction by invoking procedure BeginTransaction 9 ,
which executes the BEGIN WORK command 6 .
Then a SELECT command 10 is processed to determine whether the
vendor number exists in column VendorNumber of table
PurchDB.Vendors:
If the number exists in table PurchDB.Vendors, the vendor number
is valid. Flag
VendorOK is set to TRUE, and the transaction is terminated by invoking procedure CommitWork 11 .
CommitWork executes the COMMIT WORK command 7 .
If the vendor number is not found, COMMIT WORK is executed and a message is displayed to inform the user that the number entered is
invalid 12 . Several flags
are set to FALSE so that when control
returns to procedure CreateOrder, the user is again
prompted for a vendor number.
If the SELECT command fails, procedure SQLStatusCheck is invoked 13 to display any error messages 4 .
Then the COMMIT WORK
command is executed, and the appropriate flags set to FALSE.
If the vendor number is valid, pasex9 invokes procedure
CreateHeader to create the
order header 50 . The order header
consists of a row containing
the vendor number entered, plus two values computed
by the program: OrderNumber and OrderDate.
Procedure CreateHeader starts
a transaction 34 , then obtains
an exclusive lock on table PurchDB.Orders 35 . Exclusive access to this table ensures that when the row is inserted, no
row having the same number will have been inserted by another transaction. The unique index that
exists on column OrderNumber prevents
duplicate order numbers in table
PurchDB.Orders. Therefore an INSERT
operation fails if it attempts to insert a row having an order number
with a value already in column OrderNumber.
In this case, the exclusive lock does not threaten concurrency. No
operations conducted between the
time the lock is obtained and the time
it is released involve operator intervention:
Procedure CreateHeader invokes procedure
ComputeOrderNumber 36 to
compute the order number and the order
date.
Procedure ComputeOrderNumber executes a SELECT command to retrieve the highest order number in PurchDB.Orders 30 . The number retrieved is incremented
by one 31 to assign a number to
the order.
Procedure ComputeOrderNumber then executes procedure
SystemDate 32 . This procedure uses the HP-UX system call (time) and library call (nl_time) 2
to retrieve and format the current
date. The date retrieved is converted
into YYYYMMDD format, the format in which dates are stored in the sample DBEnvironment.
Procedure ComputeOrderNumber then executes procedure
InsertRow 33 . This procedure executes a simple INSERT command 22
to insert a row into PurchDB.Orders.
If the INSERT command succeeds,
the transaction is terminated with a COMMIT WORK command, and the HeaderOK flag is set to TRUE 24 .
If the INSERT command fails,
the transaction is terminated with COMMIT WORK, but the HeaderOK
flag is set to FALSE 23 so
that the user is prompted for another
vendor number when control returns to procedure CreateOrder.
To create line items, procedure CreateOrder
executes procedure CreateOrderItems
until the DoneItems flag is set to TRUE 51 . Procedure
CreateOrderItems asks the user whether she wants to specify line items 44 .
If the user wants to create line items,
CreateOrderItems executes
procedure ItemEntry until the DoneItems flag is set to TRUE 46 , then executes procedure BulkInsert 47 :
ItemEntry assigns values to host variable
array OrderItems 1 ; each
record in the array corresponds to one line item, or row in
PurchDB.OrderItems. The procedure
first assigns the order number and
a line number to each row 37 ,
beginning at one. ItemEntry then prompts fo
a vendor part number 38 , which
is validated by invoking procedure
ValidatePart 39 .
ValidatePart starts a transaction
14 . Then it executes a SELECT
command 15 to determine whether
the part number entered matches any
part number known to be supplied by the vendor.
If the part number is valid, the
COMMIT WORK command is executed 16
and the PartOK flag set to TRUE.
If the part number is invalid, COMMIT WORK is executed 17 , and
the user informed that the vendor does not supply any part having the number specified; then the PartOK flag is set to FALSE so that the user is prompted for another part number when control
returns to procedure ItemEntry.
If the part number is valid, procedure
ItemEntry completes the line item. It prompts for values to
assign to columns PurchasePrice, OrderQty, and
ItemDueDate 40 . The
procedure then assigns a negative value
to the indicator variable for column ReceivedQty 41
in preparation for inserting a null value into this column.
ItemEntry terminates when the user indicates that
she does not want to specify any more line items 42 or when the host variable array is full 43 .
Procedure BulkInsert starts a transaction 25 , then executes the BULK INSERT command 27 . The
line items in array OrderItems are inserted into table
PurchDB.OrderItems, starting with the first record and
continuing for as many records as there were line items
specified 26 . If the BULK INSERT command succeeds, the COMMIT WORK command is executed 29 and the ItemsOK flag set to
TRUE. If the BULK INSERT command fails,
procedure RollBackWork is executed 28 to process
the ROLLBACK WORK
command 8 so that any rows inserted prior
to the failure are rolled back.
If the user does not want to create line items,
procedure CreateOrderItems displays the order header by
invoking procedure DisplayHeader 45 . DisplayHeader
displays the row inserted earlier in PurchDB.Orders 18 .
If line items were inserted into PurchDB.OrderItems,
procedure DisplayOrder is invoked 52 to display the order created.
DisplayOrder invokes procedure
DisplayHeader 20 to display
the order header. Then it executes
procedure DisplayItems 21
to display each row inserted into PurchDB.OrderItems.
DisplayItems displays values
from array OrderItems 19 .
When the program user enters a 0 in response to the vendor
number prompt, the program terminates by executing
procedure TerminateProgram 56 , which executes
the RELEASE command 3 .