Compaq ACMS for OpenVMS
Writing Server Procedures


Previous Contents Index

3.4.1.3 Using Hard-Coded Messages in the Form

Using this method, you return a status indicator that is processed by the form in a field in a user-defined workspace. See Section 3.3.2 for more information on returning status in a field in a user-defined workspace.

The advantage of this method is that you do not need to use message files or OpenVMS system services or RTL routines to return error messages to users. The disadvantage is that you must always modify the form if you need to change the format of an error message.

To use hard-coded messages in the form, follow these steps:

  1. Define a field in a user-defined workspace to hold the status indicator. For example:


    step_status           DATATYPE TEXT 8. 
    

  2. In the step procedure, return a status indicator in the STEP_STATUS field in the user-defined workspace.
    For example, in COBOL:


    MOVE "DUPLICAT" TO step_status OF task_control. 
    GO TO 999-end. 
    

    For example, in BASIC:


    task_ctrl_wksp::step_status = "DUPLICAT" 
    EXIT FUNCTION 
    

  3. In the task definition, check the status indicator field in the user-defined workspace.
    If the step procedure returns a failure indicator, then go to an exchange step that uses a form to display an error message based on the status indicator returned by the step procedure. For example:


    PROCESSING 
        WORK IS 
            CALL pers_add_employee_proc USING 
                        task_control, 
                        employee_record 
        ACTION IS 
            IF ( task_control.step_status <> "SUCCESS" ) 
            THEN 
                GOTO STEP get_new_employee_data; 
            END IF; 
    

3.4.1.4 Using Hard-Coded Messages in the Step Procedure

Using this method, you construct the complete error message directly in the step procedure. You use literal message text stored in the procedure, formatting variable error messages, if necessary.

The advantage of this method is that you do not need to use message files or OpenVMS system services or RTL routines to return error messages to users. The disadvantage is that you must always modify and recompile the step procedure and relink the procedure server image if you need to change the format of an error message.

To use hard-coded messages in a step procedure, follow these steps:

  1. Define a field in a user-defined workspace to hold the error message text. For example:


    task_status_msg       DATATYPE TEXT 80. 
    

  2. In the step procedure, construct the error message in the message text field.
    The following example in COBOL formats an error message and then returns a failure status to the task:


    * 
    * Format 'Employee already exists' error message. 
    * 
        MOVE SPACES TO task_status_msg. 
        STRING "Employee ID: " DELIMITED BY SIZE 
                emp_badge_number DELIMITED BY " " 
                " (last name: " DELIMITED BY SIZE 
                emp_last_name DELIMITED BY " " 
                ") already exists on file" DELIMITED BY SIZE 
        INTO    task_status_msg. 
        SET status-result TO FAILURE. 
        GO TO 999-end. 
    

    The following example in BASIC formats an error message and then returns a failure status to the task:


    ! 
    ! Format 'Employee already exists' error message. 
    ! 
    task_ctl_rec::task_status_msg =                                 & 
            "Employee ID: " +                                       & 
            emp_rec::emp_badge_number +                             & 
            " (last name: " +                                       & 
            TRM$( emp_rec::emp_last_name ) +                        & 
            ") already exists on file" 
    EXIT FUNCTION 0 
    

  3. In the task definition call to the procedure, test the ACMS$PROCESSING_STATUS workspace, and go to an exchange step that displays the error message on the form if an error occurs. For example:


    PROCESSING 
        WORK IS 
            CALL pers_add_employee_proc USING 
                        task_control, 
                        employee_record 
        ACTION IS 
            IF ( ACMS$T_STATUS_TYPE = "B" ) 
            THEN 
                GOTO STEP get_new_employee_data; 
            END IF; 
    

3.4.2 Raising Exceptions in Step Procedures

In some cases, rather than returning errors for the action part of a step to handle, you can let the exception handler part of a step deal with errors. If your task is designed in this way, you need to raise an exception from your step procedure. ACMS supplies three services that raise different kinds of exceptions:

The ACMS exception services differ in an important way from the superseded ACMSAD$REQ_CANCEL service. Whereas the ACMSAD$REQ_CANCEL service immediately cancels the current task and does not return control to the step procedure, the ACMS exception services all return control to the step procedure after setting the appropriate exception condition. This allows the step procedure to clean up any context in the server and to complete normally.

Allowing the step procedure to complete before raising the exception in the task means that ACMS does not have to interrupt the server process. Therefore, if a step procedure uses one of the exception services to raise an exception, and you have specified that your server is to be run down on cancel only if it is interrupted, ACMS does not need to run down the server process. See Section 2.3 for details on how to specify when ACMS should run down your server.

Because step exceptions, transaction exceptions, and nonrecoverable exceptions are not raised in the task until the step procedure completes, have the step procedure return as soon as possible after raising an exception.

Note

For all servers, Compaq recommends specifying that ACMS run down the server only if it is interrupted. Using this attribute does not, however, change the effect of using the ACMSAD$REQ_CANCEL service. Because the ACMSAD$REQ_CANCEL service causes the server to be interrupted, ACMS runs down the server in this situation. For this reason, use ACMS$RAISE_NONREC_EXCEPTION instead of ACMSAD$REQ_CANCEL.

3.4.2.1 Raising Recoverable Exceptions in Step Procedures

You can handle task execution errors in the exception handler part of a step, as explained in Compaq ACMS for OpenVMS Writing Applications. This manual discusses how to raise exceptions only in step procedures.

Step procedures can raise the following recoverable exceptions:

Following are explanations and examples of the two ACMS services that step procedures use to raise recoverable exceptions.

Chapter 9 contains reference information regarding recoverable exception services.

3.4.2.2 Raising Nonrecoverable Exceptions in Step Procedures

ACMS raises a nonrecoverable exception under the following conditions:

3.5 Performing Terminal I/O from a Procedure Server

One of the major advantages of implementing an application with ACMS is that you can easily separate your terminal I/O from your database I/O by performing all terminal I/O in exchange steps and all database I/O in processing steps. Following these guidelines has many advantages; two of the major ones are better performance and the ability to distribute tasks over multiple nodes.

Application developers find, however, that some situations require them to do terminal I/O in a processing step---for example, if they are incorporating an existing program into an application. Sometimes it is simpler to make an existing program a single-step task that does terminal I/O than to convert the program to a multiple-step task, which requires removing the terminal I/O from the program and placing it in exchange steps. For this reason, although it is not recommended, ACMS supports doing terminal I/O from processing steps. This section describes the limitations and restrictions involved.

ACMS does not automatically associate a terminal channel with the server process. If a procedure is to do terminal I/O, it must open and close the channel it uses each time it is called. The terminal channel cannot be retained across processing steps, even if the task retains server context. If the procedure does not close the channel before it completes, ACMS cancels the task and runs down the server process.

For a server process to perform terminal I/O, the task must pass the terminal to that process. In single-step tasks, the default is to pass the terminal to the server process. In multiple-step tasks, however, the default is not to pass the terminal to the server process, regardless of whether the server is a DCL server or a procedure server.

In multiple-step tasks, therefore, the task definition must use the TERMINAL I/O phrase for any processing step that does terminal I/O. (When used as an attribute on a processing step, TERMINAL I/O and REQUEST I/O are equivalent; however, REQUEST I/O as a processing step attribute is a declining feature and is, therefore, discouraged.)

Note

Because distributed tasks cannot perform terminal I/O in processing steps, you cannot distribute a task that contains TERMINAL I/O (or REQUEST I/O) syntax in a processing step of the task definition.

Because the procedure must open and close the terminal channel, there are several restrictions on the kinds of statements used for terminal I/O from a procedure server. Keep in mind the following considerations:


Chapter 4
Accessing Resource Managers

This chapter explains how to write step procedures that access several of the resource managers you can use with ACMS applications: Rdb using SQL, and Rdb using RDO, DBMS, and RMS.

The primary example in the chapter shows how to access an Rdb database using SQL with a procedure that participates in a distributed transaction. Examples showing how to access other resource managers supported by ACMS with distributed transactions are partial; they contain only syntax that is different from the SQL example.

The COBOL step procedure that is the principal example in this chapter is part of the AVERTZ Sample Application. The step procedure VR_COMPLETE_CHECKOUT_PROC participates in a distributed transaction that starts and ends in the parent task. Figure 4-1 shows where VR_COMPLETE_CHECKOUT_PROC fits into the AVERTZ Sample Application. The figure shows the ACMS menu, from which users can select the Reservation Task or the Checkout Task as two of three tasks displayed on the menu. Both the Reservation Task and the Checkout Task can call the Complete Checkout Task, which, in turn, calls the procedure VR_COMPLETE_CHECKOUT_PROC.

See Compaq ACMS for OpenVMS Concepts and Design Guidelines for a description of the AVERTZ sample application and Compaq ACMS for OpenVMS Writing Applications for a description of VR_COMPLETE_CHECKOUT_TASK. For further explanation of VR_COMPLETE_CHECKOUT_PROC. see Section 4.1.

Figure 4-1 Calling the Procedure VR_COMPLETE_CHECKOUT_PROC


4.1 Using SQL with Rdb

This section describes how to write step procedures using the Structured Query Language (SQL) interface to Rdb. The techniques used with SQL are similar to those used in developing tasks and server procedures using Relational Data Manipulation Language (RDML), developed by Digital Equipment Corporation.

See the SQL documentation for general information regarding SQL.

The main example in this chapter, shown in Example 4-7, is a COBOL step procedure called VR_COMPLETE_CHECKOUT_PROC, which accesses an Rdb database using SQL. The procedure is part of the AVERTZ sample application.

Example 4-1 is part of the Complete Checkout Task, which calls the procedure VR_COMPLETE_CHECKOUT_PROC in the AVERTZ Sample Application. When checking out a car, the customer has the option of canceling the reservation. If the customer chooses to cancel the reservation, the task calls a procedure to perform the cancel processing. Otherwise, the task calls a procedure to complete the reservation. The task definition, in a simplified version, performs the following steps, which are also numbered in the example.

  1. If the customer chooses to check out the car, the task calls the procedure VR_COMPLETE_CHECKOUT_PROC to complete the checkout process.
  2. If the customer cancels the reservation, the task calls the procedure VR_CANCEL_RS_PROC to cancel the reservation.
  3. The task calls another procedure, VR_WRITE_HIST_RECORD_PROC, which writes the completion of the checkout or the cancellation to the database.

Example 4-1 Task Definition that Calls Server Procedures Using SQL

 
REPLACE TASK avertz_cdd_task:vr_complete_checkout_task 
 
USE WORKSPACES vr_control_wksp, 
. 
. 
. 
TASK ARGUMENTS ARE vr_sendctrl_wksp     WITH ACCESS READ, 
. 
. 
. 
BLOCK WORK WITH TRANSACTION 
                     NO I/O 
 
! 
perform: 
!+ 
!- 
! Perform the checkout process or cancel the reservation depending 
! on the user's choice. 
! 
 
     PROCESSING 
        SELECT FIRST TRUE 
                (vr_control_wksp.ctrl_key = "OK"): 
                     (1) CALL PROCEDURE    vr_complete_checkout_proc
                        IN      vr_update_server 
                        USING   vr_reservations_wksp, 
                                vr_vehicles_wksp, 
                                vr_control_wksp; 
                (vr_control_wksp.ctrl_key = "CANCL"): 
                     (2) CALL PROCEDURE     vr_cancel_rs_proc
                        IN      vr_update_server 
                        USING   vr_reservations_wksp, 
                                vr_control_wksp; 
        END SELECT; 
 
  . 
  . 
  . 
! Write to the history record to record the completion of the checkout or the 
! the cancellation of the reservation. 
! 
     PROCESSING 
     (3) CALL PROCEDURE        vr_write_hist_record_proc
        IN      vr_log_server 
        USING   vr_hist_wksp, 
                vr_reservations_wksp; 
 
      . 
      . 
      . 
! 
END BLOCK; 
! 
END DEFINITION; 

4.1.1 Using Embedded SQL Statements in Step Procedures

When using embedded SQL statements in step procedures, follow these guidelines:

Example 4-2 contains examples illustrating each of these guidelines.

For other high-level languages, the rules for beginning and ending SQL statements in step procedures vary. See the SQL documentation for more information about beginning and ending SQL statements in step procedures.

Before you can use SQL to access a database, you must declare the database. You do this in each server procedure that accesses the database. If you are using COBOL, name the Rdb database in the Working-Storage Section of the Data Division of your procedure using the DECLARE SCHEMA statement. This must appear in the procedure before you can use other SQL statements to reference data in the database.

Example 4-2 shows the DECLARE SCHEMA statement used in the procedure VR_COMPLETE_CHECKOUT_PROC to declare the database. (Example 4-7 contains the complete procedure.)

Example 4-2 Declaring the Database

 
************************************************************ 
DATA DIVISION. 
************************************************************ 
WORKING-STORAGE SECTION. 
* 
*  Return status to pass to ACMS 
* 
01 RET-STAT      PIC S9(9) COMP. 
01 RSTAT         PIC S9(9) COMP. 
 
. 
. 
. 
* 
*  Declare the database schema. 
* 
EXEC SQL 
   DECLARE EXTERNAL SCHEMA FILENAME AVERTZ_DATABASE:VEHICLE_RENTALS
END-EXEC. 

4.1.2 Using SQL with Distributed Transactions

When you use SQL with a distributed transaction, you must pass the transaction ID (TID) to SQL on each executable DML verb using an SQL context structure.

This section describes how to:

See Example 4-7 for a complete example of using precompiled SQL in a distributed transaction using COBOL. See the SQL documentation for information on how to define and use an SQL context structure.


Previous Next Contents Index