# Compaq COBOL
DBMS Database Programming Manual

Previous | Contents | Index

Refer to the Oracle CODASYL DBMS documentation set for more information.

Examples

1. This example references the default subschema in the PARTS database:

       DB DEFAULT_SUB-SCHEMA WITHIN PARTS.

2. This example references the NEW database that contains the PARTS schema and the PARTSS1 subschema:

       DB PARTSS1 WITHIN PARTS FOR "DB1:[COBOL88]NEW.ROO".

3. This example references the default subschema in the PARTS database through the stream STREAM1.

       DB DEFAULT_SUB-SCHEMA WITHIN PARTS THRU "STREAM1".

# LD (Keeplist Description)

Function

The Keeplist Description entry names a keeplist.

> ### keeplist-name

> is a user-defined name.

> ### integer

> is a positive integer.

Syntax Rules

1. The LD entry can appear only in the Subschema Section following the DB entry or another LD entry.
2. The LIMIT clause is for documentation only. The compiler ignores this clause.

General Rules

1. Keeplist-name implicitly has the global attribute. Any program defining the name, and any program contained within that defining program, can reference keeplist-name.
2. A keeplist is a table containing an ordered list of database key values.
3. At program initiation, each existing keeplist is empty.
4. A KEEP or a FIND ALL statement adds a database key value to the end of keeplist-name. FIND ALL can add multiple database keys to a keeplist.
5. A FREE statement selectively removes a database key value from keeplist-name.
6. A keeplist with zero entries is called an empty keeplist. The order of the entries in the keeplist reflects their sequence of insertion. As entries are added, the cardinality increases. As entries are removed, the cardinality decreases.
7. A COBOL program can reference a keeplist entry by using a database key identifier.
8. The Database Control System (DBCS) creates and maintains all keeplists.
9. Each value in keeplist-name represents a database record in the database.
10. A keeplist can contain the same database key value more than once.
11. More than one keeplist can contain the same database key value at the same time.
12. No other run unit can update a record whose database key value is in a keeplist. Every entry in the keeplist causes the DBCS to perform a retrieval lock on the record it identifies. The record remains locked until the entry is freed, or until the program executes a COMMIT (without the RETAINING option) or ROLLBACK statement, or until the program terminates. If another run unit references a locked record, the DBCS forces the run unit to wait until the record is unlocked.

Additional Reference

- Section 4.4, on database key identifiers

Example

The following example defines three keeplists to navigate through the PARTSS1 subschema: KEEP-COMPONENT, K-EMPLOYEE, and KL-ID:

    DB PARTSS1 WITHIN PARTS.
    LD KEEP-COMPONENT.
    LD K-EMPLOYEE.
    LD KL-ID.

# Chapter 4
Procedure Division

The Procedure Division of your COBOL database programs may contain declarative and nondeclarative procedures. These may include:

- Directive and imperative statements
- Conditional statements
- Database key identifiers
- Explicit and implicit scope terminators
- Section 4.6, on record selection expressions

# 4.1 COBOL Statements for the Database Programmer

There are four types of COBOL statements:

- Compiler-directing statements specify an action taken by the compiler during compilation.
- Imperative statements specify an unconditional action taken by the object program at run time.
- Conditional statements specify a conditional action taken by the object program at run time; the action depends upon a truth value that is generated by the program. (A truth value is either a yes or no answer to the question, "Is the condition true?")
- Delimited-scope statements specify their explicit scope terminator.

Table 4-1 shows the three types of COBOL statements (conditional, imperative, delimited-scope) that are considered particularly relevant to database programming.

Table 4-1 Types of COBOL Statements
Type | Verb
--- | ---
Conditional | COMMIT ([NOT] ON ERROR) CONNECT ([NOT] ON ERROR) DISCONNECT ([NOT] ON ERROR) ERASE ([NOT] ON ERROR) FETCH ([NOT] AT END or [NOT] ON ERROR) FIND ([NOT] AT END or [NOT] ON ERROR) FREE ([NOT] ON ERROR) GET ([NOT] ON ERROR) KEEP ([NOT] ON ERROR) MODIFY ([NOT] ON ERROR) READY ([NOT] ON ERROR) RECONNECT ([NOT] ON ERROR) ROLLBACK ([NOT] ON ERROR) STORE ([NOT] ON ERROR)
Imperative | COMMIT (1) CONNECT (1) DISCONNECT (1) ERASE (1) FETCH (2) FIND (2) FREE (1) GET (1) KEEP (1) MODIFY (1) READY (1) RECONNECT (1) ROLLBACK (1) STORE (1)
Delimited-Scope | COMMIT (END-COMMIT) CONNECT (END-CONNECT) DISCONNECT (END-DISCONNECT) ERASE (END-ERASE) FETCH (END-FETCH) FIND (END-FIND) FREE (END-FREE) GET (END-GET) KEEP (END-KEEP) MODIFY (END-MODIFY) READY (END-READY) RECONNECT (END-RECONNECT) ROLLBACK (END-ROLLBACK) STORE (END-STORE)

Legend:

> ( 1 ) Without the optional [NOT ] ON ERROR phrase
> ( 2 ) Without the optional [NOT ] AT END or [NOT ] ON ERROR phrase

Like statements, COBOL sentences also can be compiler-directing, imperative, or conditional. Sentence type depends upon the types of clauses the statement contains. Table 4-2 summarizes the contents of the three types of COBOL sentences. The remaining text in this section discusses each type of statement and sentence in greater detail.

Table 4-2 Contents of COBOL Sentences
Type | Contents of Sentence
--- | ---
Imperative | One or more consecutive imperative statements ending with a period
Conditional | One or more conditional statements, optionally preceded by an imperative statement, terminated by the separator period
Compiler-Directing | Only one compiler-directing statement ending with a period

## 4.1.1 Compiler-Directing Statements and Sentences

A compiler-directing statement causes the compiler to take an action during compilation. The verbs COPY, REPLACE, RECORD, or USE define a compiler-directing statement. When it is part of a sentence that contains more than one statement, the COPY, REPLACE, RECORD, or USE statement must be the last statement in the sentence.

A compiler-directing sentence is one COPY, REPLACE, RECORD, or USE statement that ends with a period.

## 4.1.2 Imperative and Conditional Statements and Sentences

An imperative statement specifies an unconditional action for the program. It must contain a verb and the verb's operands, and cannot contain any conditional phrases. For example, the following statement is imperative:

    READY UPDATE.

However, the following statement is not imperative because it contains the phrase ON ERROR, which makes the program's action conditional:

    STORE PART-REC ON ERROR PERFORM BAD-STORE.

A delimited-scope statement is a special category of imperative statement used in structured programming. A delimited-scope statement is any statement that includes its explicit scope terminator. For more information, see the section on Explicit and Implicit Attributes.

In the Procedure Division rules, an imperative statement can be a sequence of consecutive imperative statements. The sequence must end with: (1) a separator period or (2) any phrase associated with a statement that contains the imperative statement. For example, the following sentence contains a sequence of two imperative statements following the AT END phrase.

    FIND NEXT PART-REC AT END PERFORM NO-MORE-RECS
                       DISPLAY "No more records."     END-FIND.

An imperative sentence contains only imperative statements and ends with a separator period.

# 4.2 Explicit and Implicit Scope Terminators

Scope terminators delimit the scope of some Procedure Division statements.

Explicit scope terminators for database programs are as follows:

END-COMMIT | END-FIND | END-READY
END-CONNECT | END-FREE | END-RECONNECT
END-DISCONNECT | END-GET | END-ROLLBACK
END-ERASE | END-KEEP | END-STORE
END-FETCH | END-MODIFY |

Implicit scope terminators are as follows:

- At the end of a sentence: the separator period. It terminates the scope of all previously unterminated statements.
- In a statement containing another statement: the next phrase of the containing statement after the contained statement terminates the scope of all unterminated contained statements. Examples are ELSE and WHEN.

# 4.3 Scope of Names

A contained COBOL program can refer to a user-defined word in its containing program if the user-defined word has the global attribute. (See the section on User-Defined Words.) Some user-defined words always have the global attribute, some never have the attribute (that is, they are local), and some may or may not, depending on the use of the GLOBAL clause. The following rules explain how to use different kinds of user-defined words and what kinds of local and global name scoping to expect.

User-defined words in the Subschema Section are always global. The program defining this section and in any program it contains can reference these user-defined words:

- Data-name
- Keeplist-name
- Realm-name
- Record-name
- Set-name

# 4.4 Database Key Identifiers

Database key identifiers are indicated by the reserved words CURRENT, OFFSET, FIRST, and LAST as shown in the two formats below. FETCH and FIND may use database key identifiers to access database data records. Conditional clauses may also use them.

General Rules

Format 1

1. Record-name references a database record in the subschema.
2. Set-name references a database set in the subschema.
3. Realm-name references a subschema realm.
4. Use this format to select a record whose database key value is in a currency indicator.
5. The referenced currency indicator is the currency indicator for the record, set, or realm you specify in record-name, set-name, or realm-name.
6. If you do not specify the WITHIN phrase, the referenced currency indicator is the currency indicator of the current record of the run unit.
7. An exception condition occurs if the referenced currency indicator is null:
   1. Run-unit currency indicator (DB-CONDITION is set to DBM$_CRUN_NULL).
   2. Record type currency indicator (DB-CONDITION is set to DBM$_CRTYP_NULL).
   3. Set type currency indicator (DB-CONDITION is set to DBM$_CSTYP_NULL).
   4. Realm currency indicator (DB-CONDITION is set to DBM$_CRELM_NULL).
   See the USE statement for information on USE FOR DB-EXCEPTION.
8. Other exception conditions occur if the referenced currency indicator points to a vacant position in the database collection:
   1. Run-unit currency indicator (DB-CONDITION is set to DBM$_CRUN_POS).
   2. Set type currency indicator (DB-CONDITION is set to DBM$_CSTYP_POS).
   3. Realm currency indicator (DB-CONDITION is set to DBM$_CRELM_POS).
   See the USE statement for information on USE FOR DB-EXCEPTION.

Format 2

9. Integer-exp is an arithmetic expression or integer. It refers to a position in keeplist-name. Integer-exp cannot be zero.
10. Keeplist-name is a keeplist defined in the Subschema Section.
11. Use this format to select a record whose database key value is in a keeplist. Because a keeplist can contain more than one entry, you must specify which keeplist entry you want.
12. Integer-exp can be either an integer or an arithmetic expression. Both result in a longword integer value.
13. Using the FIRST clause is equivalent to OFFSET plus 1. It references the first database key value in the keeplist.
14. Using the LAST clause is equivalent to OFFSET minus 1. It references the last database key value in the keeplist.
15. The value of integer-exp points to an entry in keeplist-name. The entry whose ordinal position in the keeplist is equal to the value of integer-exp is called the referenced keeplist entry.
    1. If integer-exp is positive, the ordinal position is relative to the first entry in the keeplist.
    2. If integer-exp is negative, the ordinal position is relative to the last entry in the keeplist.
16. An exception condition occurs if:
    1. Integer-exp is zero. DB-CONDITION is set to DBM$_BADZERO.
    2. The absolute value of integer-exp is greater than the number of database key values in the keeplist. DB-CONDITION is set to DBM$_END.
    3. The identified keeplist is empty. DB-CONDITION is set to DBM$_END.
    See the USE statement for information on the USE FOR DB-EXCEPTION statement.

# 4.5 Database Conditions

Database conditions allow alternate paths of control depending on the truth value of a test involving conditions specific to the database environment. The database conditions are the tenancy, member, and database key conditions.

Database exception conditions can occur during evaluation of these conditions. If a database exception condition occurs during the execution of a database condition, the Database Control System (DBCS) places a database exception condition code in the special register DB-CONDITION. This code identifies the condition. The DBCS also does the following:

1. Places the record name of database-record in the special register DB-CURRENT-RECORD-NAME.
2. Places the UID (User ID number) of the database record in DB-CURRENT-RECORD-ID.
3. Invokes an applicable USE FOR DB-EXCEPTION Declaratives procedure, if any; otherwise, the DBCS abnormally terminates the run unit (see the USE statement). Under these circumstances, the result of the test is false.

## 4.5.1 Tenancy Conditions

These conditions determine whether a record in the database is an owner, or member, or a tenant in one or more sets.

> ### set-name

> is a subschema set name.

The result of the test is true if the current record of the run unit is as follows:

- Owner of an occurrence of set-name (OWNER clause)
- Member of an occurrence of set-name (MEMBER clause)
- Owner or member of an occurrence of set-name (TENANT clause)

Otherwise, the result of the test is false. For example:

    IF PART_USES OWNER PERFORM 100-PART-OWNER.
    IF PART_USED_ON MEMBER ...
    IF RESPONSIBLE_FOR TENANT ...

If NOT is used, the result of the test is reversed.

Omitting set-name allows all subschema set types in which the record participates to be considered in determining the truth value of the condition.

If the run-unit currency indicator is null, a database exception condition occurs and DB-CONDITION is set to DBM$_CRUN_NULL. If the run-unit currency indicator only specifies a position, a database exception condition occurs and DB-CONDITION is set to DBM$_CRUN_POS. See Section 4.8.3, Exception Conditions and the USE Statement for information on USE FOR DB-EXCEPTION.

## 4.5.2 Empty Condition

The empty condition determines whether member records are present in one or more sets. Only member record types defined in the Subschema Section are considered in determining the truth value of the condition.

> ### set-name

> is a subschema set name.

If set-name is specified, the object set is the current set of that set type. If the object set has no member records, the result of the test is true. If the object set has member records, the result of the test is false.

If set-name is not specified, the object sets, if any, are owned by the current record of the run unit whose set type is defined in the Subschema Section. If each object set has no member records, the result of the test is true. If any object set has member records, the result of the test is false. For example:

    IF PART_USES EMPTY ...
    IF EMPTY ...

If NOT is used, the result of the test is reversed.

A database exception condition occurs if either:

- The currency indicator for the run unit is null (DB-CONDITION is set to DBM$_CRUN_NULL).
- The currency indicator for the run unit specifies a position (DB-CONDITION is set to DBM$_CRUN_POS).
- The current record of run unit is not the owner of set-name (DB-CONDITION is set to DBM$_NOTOTYP).

See Section 4.8.3, Exception Conditions and the USE Statement for information on USE FOR DB-EXCEPTION.

## 4.5.3 Database Key Condition

The database key condition determines whether: (1) two database key values identify the same database record, (2) a database key value is null, or (3) a database key value is identical to any database key value in a keeplist.

> ### database-key

> references a currency indicator (see section on Database Key Identifiers) or a keeplist entry in the Subschema Section.

The result of the test is true if:

- When using the ALSO phrase, both database-keys reference identical database key values. This example compares a set currency indicator for ALL_PARTS to the currency indicator of the current record.

      IF CURRENT WITHIN ALL_PARTS IS ALSO CURRENT ...

- When using the NULL phrase, the currency indicator referenced by database-key is null. This example checks the currency indicator for the current record before storing its key in a keeplist:

      IF CURRENT IS NULL NEXT SENTENCE
        ELSE
         KEEP USING KEEP-LIST-A.

- When using the WITHIN phrase, any database key value in keeplist-name is identical to database-key. For example:

      IF CURRENT IS WITHIN KEEP-LIST-A
                 PERFORM 200-ITS-IN-THE-LIST.

Otherwise, the result of the test is false.

If NOT is used, the result of the test is reversed.

A database exception condition occurs if:

- The program identifies an invalid database key identifier. (See the Database Key Identifiers section for more information.)
- For the NULL condition, the referenced currency indicator points to a vacant position in the database or collection:
  - Realm currency indicator (DB-CONDITION is set to DBM$_CRELM_POS).
  - Set currency indicator (DB-CONDITION is set to DBM$_CSTYP_POS).
  - Run-unit currency indicator (DB-CONDITION is set to DBM$_CRUN_POS).
  See the USE statement for more information on USE FOR DB-EXCEPTION.

## 4.5.4 Condition Evaluation Rules

Parentheses can specify the evaluation order in complex conditions. Conditions in parentheses are evaluated first. In nested parentheses, evaluation starts with the innermost set of parentheses. It proceeds to the outermost set.

Conditions are evaluated in a hierarchical order when there are no parentheses in a complex condition. This same order applies when all sets of parentheses are at the same level (none are nested). The hierarchy is shown in the following list:

1. Values for arithmetic expressions
2. Truth values for simple conditions, in this order:
   1. Relation
   2. Class
   3. Condition-name
   4. Switch-status
   5. Sign
   6. Database
   7. Success/failure
3. Truth values for negated simple conditions
4. Truth values for combined conditions, in this order:
   1. AND logical operators
   2. OR logical operators
5. Truth values for negated combined conditions

In the absence of parentheses, the order of evaluation of consecutive operations at the same hierarchical level is from left to right.

Previous | Next | Contents | Index