| Pro*COBOL Precompiler Programmer's Guide Release 9.2 Part Number A96109-01 |
|
This chapter provides the basic information you need to write a Pro*COBOL program, including:
Oracle9i recognizes two kinds of datatypes: internal and external. Internal datatypes specify how Oracle9i stores data in database columns.
For complete descriptions of the Oracle internal (also called built-in) datatypes, see Oracle9i SQL Reference.
Oracle9i also uses internal datatypes to represent database pseudocolumns. An external datatype specifies how data is stored in a host variable.
Table 4-1 summarizes the information about each Oracle built-in datatype.
The external datatypes include all the internal datatypes plus several datatypes found in other supported host languages. Use the datatype names in datatype equivalencing, and the datatype codes in dynamic SQL Method 4. The following table lists external datatypes.
Notes:
CHAR is datatype 1 when PICX=VARCHAR2 and datatype 96 when PICX=CHARF.
Maximum size is 32767 (32K) on some platforms.
CHAR behavior depends on the settings of the option PICX. See "PICX".
By default, the CHARF datatype represents all non-varying character host variables. You use the CHARF datatype to store fixed-length character strings. On most platforms, the maximum length of a CHARF value is 65535 (64K) bytes. See "PICX".
On Input. Oracle9i reads the number of bytes specified for the input host variable, does not strip trailing blanks, then stores the input value in the target database column.
If the input value is longer than the defined width of the database column, Oracle9i generates an error. If the input value is all-blank, then a string of spaces is stored.
On Output. Oracle9i returns the number of bytes specified for the output host variable, blank-padding if necessary, then assigns the output value to the target host variable. If a NULL is returned, then the original value of the variable is not overwritten.
If the output value is longer than the declared length of the host variable, Oracle9i truncates the value before assigning it to the host variable. If an indicator variable is available, Oracle9i sets it to the original length of the output value.
The CHARZ datatype represents fixed-length, null-terminated character strings. On most platforms, the maximum length of a CHARZ value is 65535 bytes. You usually will not need this external type in Pro*COBOL.
The DATE datatype represents dates and times in 7-byte, fixed-length fields. As Table 4-3 shows, the century, year, month, day, hour (in 24-hour format), minute, and second are stored in that order from left to right.
| Byte | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|
|
Meaning |
Century |
Year |
Month |
Day |
Hour |
Minute |
Second |
|
17-Oct-1994 at 1:23:12 PM |
119 |
194 |
10 |
17 |
14 |
24 |
13 |
The century and year bytes are in excess-100 notation. The hour, minute, and second are in excess-1 notation. Dates before the Common Era (B.C.E.) are less than 100. The epoch is January 1, 4712 B.C.E. For this date, the century byte is 53 and the year byte is 88. The hour byte ranges from 1 to 24. The minute and second bytes range from 1 to 60. The time defaults to midnight (1, 1, 1). Pro*COBOL also supports five additional datetime datetypes, as described in "Datetime and Interval Datatype Descriptors" .
The DECIMAL datatype represents packed decimal numbers for calculation. In COBOL, the host variable must be a signed COMP-3 field with an implied decimal point. If significant digits are lost during data conversion, the value is truncated to the declared length.
The DISPLAY datatype represents numeric character data. The DISPLAY datatype refers to a COBOL "DISPLAY SIGN LEADING SEPARATE" number, which requires n + 1 bytes of storage for PIC S9(n), and n + d + 1 bytes of storage for PIC S9(n)V9(d).
The FLOAT datatype represents numbers that have a fractional part or that exceed the capacity of the INTEGER datatype. FLOAT relates to the COBOL datatypes COMP-1 (4-byte floating point) and COMP-2 (8-byte floating point).
Oracle9i can represent numbers with greater precision than floating point implementations because the internal format of Oracle9i numbers is decimal.
Note: In SQL statements, when comparing FLOAT values, use the SQL function ROUND because FLOAT stores binary (not decimal) numbers; so, fractions do not convert exactly.
The INTEGER datatype represents numbers that have no fractional part. An integer is a signed, 2-byte, 4-byte, or 8-byte binary number. (8-byte on 64-bit platforms.) The order of the bytes in a word is platform-dependent. You must specify a length for input and output host variables. On output, if the column has a fractional part, the digits after the decimal point are truncated.
The LONG datatype represents fixed-length character strings. The LONG datatype is like the VARCHAR2 datatype, except that the maximum length of a LONG value is 2147483647 bytes (two gigabytes).
The LONG RAW datatype represents fixed-length, binary data or byte strings. The maximum length of a LONG RAW value is 2147483647 bytes (two gigabytes).
LONG RAW data is like LONG data, except that Oracle9i assumes nothing about the meaning of LONG RAW data and does no character set conversions when you transmit LONG RAW data from one system to another.
The LONG VARCHAR datatype represents variable-length character strings. LONG VARCHAR variables have a 4-byte length field followed by a string field. The maximum length of the string field is 2147483643 bytes. In an EXEC SQL VAR statement, do not include the 4-byte length field.
The LONG VARRAW datatype represents binary data or byte strings. LONG VARRAW variables have a 4-byte length field followed by a data field. The maximum length of the data field is 2147483643 bytes. In an EXEC SQL VAR statement, do not include the 4-byte length field.
The NUMBER datatype represents the internal Oracle NUMBER format which cannot be represented by a COBOL datatype.
OVER-PUNCH is the default signed numeric for the COBOL language. Digits are held in ASCII or EBCDIC format in radix 10, with one digit for each byte of computer storage. The sign is held in the high order nibble of one of the bytes. It is called OVER-PUNCH because the sign is "punched-over" the digit in either the first or last byte. The default sign position will be over the trailing byte. PIC S9(n)V9(m) TRAILING or PIC S9(n)V9(m) LEADING is used to specify the over-punch.
The RAW datatype represents fixed-length binary data or byte strings. On most platforms, the maximum length of a RAW value is 65535 bytes.
RAW data is like CHAR data, except that Oracle9i assumes nothing about the meaning of RAW data and does no character set conversions when you transmit RAW data from one system to another.
The ROWID datatype is the database row identifier in COBOL. To support both logical and physical ROWIDs (as well as ROWIDs of non-Oracle tables) the Universal ROWID (UROWID) was defined. Use the SQL-ROWID pseudotype for this datatype (see "Universal ROWIDs").
You can use VARCHAR2 host variables to store ROWIDs in a readable format. When you select or fetch a ROWID into a VARCHAR2 host variable, Oracle9i converts the binary value to an 18-byte character string and returns it in the format:
BBBBBBBB.RRRR.FFFF
where BBBBBBBB is the block in the database file, RRRR is the row in the block (the first row is 0), and FFFF is the database file. These numbers are hexadecimal. For example, the ROWID:
0000000E.000A.0007
points to the 11th row in the 15th block in the 7th database file.
Typically, you fetch a ROWID into a VARCHAR2 host variable, and hen compare the host variable to the ROWID pseudocolumn in the WHERE clause of an UPDATE or DELETE statement. That way, you can identify the latest row fetched by a cursor. For an example, see "Mimicking the CURRENT OF Clause".
Note: If you need full portability or your application communicates with a non-Oracle database through Transparent Gateway, specify a maximum length of 256 (not 18) bytes when declaring the VARCHAR2 host variable. If your application communicates with a non-Oracle data source through Oracle Open Gateway, specify a maximum length of 256 bytes. Though you can assume nothing about its contents, the host variable will behave normally in SQL statements.
The STRING datatype is like the VARCHAR2 datatype except that a STRING value is always terminated by a LOW-VALUE character.This datatype is usually not used in Pro*COBOL.
The UNSIGNED datatype represents unsigned integers.This datatype is usually not used in Pro*COBOL.
The VARCHAR datatype represents variable-length character strings. VARCHAR variables have a 2-byte length field followed by a 65533-byte string field. However, for VARCHAR array elements, the maximum length of the string field is 65530 bytes. When you specify the length of a VARCHAR variable, be sure to include 2 bytes for the length field. For longer strings, use the LONG VARCHAR datatype. In an EXEC SQL VAR statement, do not include the 2-byte length field.
The VARCHAR2 datatype represents variable-length character strings. On most platforms, the maximum length of a VARCHAR2 value is 65535 bytes.
Specify the maximum length of a VARCHAR2(n) value in bytes, not characters. So, if a VARCHAR2(n) variable stores multibyte characters, its maximum length is less than n characters.
On Input. Oracle9i reads the number of bytes specified for the input host variable, strips any trailing blanks, and then stores the input value in the target database column.
If the input value is longer than the defined width of the database column, Oracle9i generates an error. If the input value is all SPACES, Oracle9i treats it like a NULL.
Oracle9i can convert a character value to a NUMBER column value if the character value represents a valid number. Otherwise, Oracle9i generates an error.
On Output. Oracle9i returns the number of bytes specified for the output host variable, blank-padding if necessary, and then assigns the output value to the target host variable. If a NULL is returned, Oracle9i fills the host variable with blanks.
If the output value is longer than the declared length of the host variable, Oracle9i truncates the value before assigning it to the host variable. If an indicator variable is available, Oracle9i sets it to the original length of the output value.
Oracle9i can convert NUMBER column values to character values. The length of the character host variable determines precision. If the host variable is too short for the number, scientific notation is used. For example, if you select the column value 123456789 into a host variable of length 6, Oracle9i returns the value 1.2E08 to the host variable.
The VARNUM datatype is similar in format to NUMBER and is usually not used in Pro*COBOL.
The VARRAW datatype represents variable-length binary data or byte strings. The VARRAW datatype is like the RAW datatype, except that VARRAW variables have a 2-byte length field followed by a <= 65533-byte data field. For longer strings, use the LONG VARRAW datatype. In an EXEC SQL VAR statement, do not include the 2-byte length field. To get the length of a VARRAW variable, simply refer to its length field.
SQL recognizes the pseudocolumns listed in Table 4-4, which return specific data items.
| Pseudocolumn | Internal Datatype |
|---|---|
|
CURRVAL |
NUMBER |
|
LEVEL |
NUMBER |
|
NEXTVAL |
NUMBER |
|
ROWID |
ROWID |
|
ROWNUM |
NUMBER |
Pseudocolumns are not actual columns in a table. However, pseudocolumns are treated like columns, so their values must be SELECTed from a table. Sometimes it is convenient to select pseudocolumn values from a dummy table.
In addition, SQL recognizes the functions without parameters listed in Table 4-5, which also return specific data items.
| Function | Internal Datatype |
|---|---|
|
SYSDATE |
DATE |
|
UID |
NUMBER |
|
USER |
VARCHAR2 |
You can refer to SQL pseudocolumns and functions in SELECT, INSERT, UPDATE, and DELETE statements. In the following example, you use SYSDATE to compute the number of months since an employee was hired:
EXEC SQL SELECT MONTHS_BETWEEN(SYSDATE, HIREDATE) INTO :MONTHS-OF-SERVICE FROM EMP WHERE EMPNO = :EMP-NUMBER END EXEC.
Brief descriptions of the SQL pseudocolumns and functions follow. For details, see the Oracle9i SQL Reference.
CURRVAL returns the current number in a specified sequence. Before you can reference CURRVAL, you must use NEXTVAL to generate a sequence number.
LEVEL returns the level number of a node in a tree structure. The root is level 1, children of the root are level 2, grandchildren are level 3, and so on.
LEVEL is used in the SELECT CONNECT BY statement to incorporate some or all the rows of a table into a tree structure. In an ORDER BY or GROUP BY clause, LEVEL segregates the data at each level in the tree.
Specify the direction in which the query walks the tree (down from the root or up from the branches) with the PRIOR operator. In the START WITH clause, you can specify a condition that identifies the root of the tree.
NEXTVAL returns the next number in a specified sequence. After creating a sequence, you can use it to generate unique sequence numbers for transaction processing. In the following example, the sequence named partno assigns part numbers:
EXEC SQL INSERT INTO PARTS VALUES (PARTNO.NEXTVAL, :DESCRIPTION, :QUANTITY, :PRICE END EXEC.
If a transaction generates a sequence number, the sequence is incremented when you commit or roll back the transaction. A reference to NEXTVAL stores the current sequence number in CURRVAL.
ROWNUM returns a number indicating the sequence in which a row was selected from a table. The first row selected has a ROWNUM of 1, the second row has a ROWNUM of 2, and so on. If a SELECT statement includes an ORDER BY clause, ROWNUMs are assigned to the selected rows before the sort is done.
You can use ROWNUM to limit the number of rows returned by a SELECT statement. Also, you can use ROWNUM in an UPDATE statement to assign unique values to each row in a table. Using ROWNUM in the WHERE clause does not stop the processing of a SELECT statement; it just limits the number of rows retrieved. The only meaningful use of ROWNUM in a WHERE clause is:
... WHERE ROWNUM < constant END-EXEC.
because the value of ROWNUM increases only when a row is retrieved. The following search condition can never be met because the first four rows are not retrieved:
... WHERE ROWNUM = 5 END-EXEC.
SYSDATE returns the current date and time.
UID returns the unique ID number assigned to an Oracle user.
USER returns the username of the current Oracle user.
The OCI datetime and interval datatypes supported by Pro*COBOL are briefly summarized here.
| See Also:
Oracle9i SQL Reference for more a more complete discussion datetime datatype descriptors |
The ANSI DATE is based on the DATE, but contains no time portion. (Therefore, it also has no time zone.) ANSI DATE follows the ANSI specification for the DATE datatype. When assigning an ANSI DATE to a DATE or a timestamp datatype, the time portion of the Oracle DATE and the timestamp are set to zero. When assigning a DATE or a timestamp to an ANSI DATE, the time portion is ignored.
You are encouraged to instead use the TIMESTAMP datatype which contains both date and time.
The TIMESTAMP datatype is an extension of the DATE datatype. It stores the year, month, and day of the DATE datatype, plus the hour, minute, and second values. It has no time zone. The TIMESTAMP datatype has the form:
TIMESTAMP(fractional_seconds_precision)
where fractional_seconds_precision (which is optional) specifies the number of digits in the fractional part of the SECOND datetime field and can be a number in the range 0 to 9. The default is 6.
TIMESTAMP WITH TIME ZONE (TSTZ) is a variant of TIMESTAMP that includes an explicit time zone displacement in its value. The time zone displacement is the difference (in hours and minutes) between local time and UTC (Coordinated Universal Time--formerly Greenwich Mean Time). The TIMESTAMP WITH TIME ZONE datatype has the form:
TIMESTAMP(fractional_seconds_precision) WITH TIME ZONE
where fractional_seconds_precision optionally specifies the number of digits in the fractional part of the SECOND datetime field and can be a number in the range 0 to 9. The default is 6.
Two TIMESTAMP WITH TIME ZONE values are considered identical if they represent the same instant in UTC, regardless of the TIME ZONE offsets stored in the data.
TIMESTAMP WITH LOCAL TIME ZONE (TSLTZ) is another variant of TIMESTAMP that includes a time zone displacement in its value. Storage is in the same format as for TIMESTAMP. This type differs from TIMESTAMP WITH TIME ZONE in that data stored in the database is normalized to the database time zone, and the time zone displacement is not stored as part of the column data. When users retrieve the data, Oracle returns it in the users' local session time zone.
The time zone displacement is the difference (in hours and minutes) between local time and UTC (Coordinated Universal Time--formerly Greenwich Mean Time). The TIMESTAMP WITH LOCAL TIME ZONE datatype has the form:
TIMESTAMP(fractional_seconds_precision) WITH LOCAL TIME ZONE
where fractional_seconds_precision optionally specifies the number of digits in the fractional part of the SECOND datetime field and can be a number in the range 0 to 9. The default is 6.
INTERVAL YEAR TO MONTH stores a period of time using the YEAR and MONTH datetime fields. The INTERVAL YEAR TO MONTH datatype has the form:
INTERVAL YEAR(year_precision) TO MONTH
where the optional year_precision is the number of digits in the YEAR datetime field. The default value of year_precision is 2.
INTERVAL DAY TO SECOND stores a period of time in terms of days, hours, minutes, and seconds. The INTERVAL DAY TO SECOND datatype has the form:
INTERVAL DAY (day_precision) TO SECOND(fractional_seconds_precision)
where:
day_precision is the number of digits in the DAY datetime field. It is optional. Accepted values are 0 to 9. The default is 2.fractional_seconds_precision is the number of digits in the fractional part of the SECOND datetime field. It is optional. Accepted values are 0 to 9. The default is 6.
Host variables are the key to communication between your host program and the server. Typically, a host program inputs data to the server, and the server outputs data to the program. The server stores input data in database columns and stores output data in program host variables.
Host variables are declared according to COBOL rules, using the COBOL datatypes that are supported by Pro*COBOL. COBOL datatypes must be compatible with the source/target database column.
The supported COBOL variable declarations, descriptions, corresponding external datatypes, and Oracle datatype codes are shown in Table 4-6.
| Variable Declaration | Description | External Datatype | Type Code |
|---|---|---|---|
|
fixed-length string of 1-byte characters (1) n-length string of 1-byte characters variable-length string of 1-byte characters (1,2) variable-length (n max.) string of 1-byte characters (2) |
VARCHAR |
9 |
|
|
PIC G(n) VARYING |
fixed-length string of multibyte NCHAR n-length string of multibyte NCHAR characters (3) variable-length string of multibyte characters (2,3) |
VARCHAR |
9 |
|
PIC S9(n) COMP-4 |
INTEGER |
3 |
|
|
PIC S9(n) COMP-5 |
INTEGER |
3 |
|
|
COMP-2 |
floating-point number (5) |
FLOAT |
4 |
|
PACKED-DECIMAL |
DECIMAL |
7 |
|
|
SIGN TRAILING SEPARATE |
display trailing (8) |
DISPLAY TRAILING |
152 |
|
PIC 9(n)[V9(m)] DISPLAY |
unsigned display(9) |
UNSIGNED DISPLAY |
153 |
|
SIGN LEADING |
over-punch leading (9) |
OVER-PUNCH LEADING |
172 |
|
SQL-CURSOR |
cursor variable |
||
|
SQL-CONTEXT |
runtime context |
||
|
SQL-ROWID |
universal ROWID |
UROWID |
104 |
|
SQL-BFILE |
external binary file |
BFILE |
112 |
|
SQL-BLOB |
binary LOB |
BLOB |
113 |
|
SQL-CLOB |
character LOB |
CLOB |
114 |
Notes:
In Table 4-6 and Table 4-7 the symbols '[' and ']' denote that an optional entry is contained inside. The symbols '{' and '}' denote that a choice must be made between tokens separated by the symbol '|'.
Table 4-7, "Compatible Oracle Internal Datatypes" shows all the COBOL datatypes that can be converted to and from each internal datatype.
| Internal Datatype | Notes | COBOL Datatype | Description |
|---|---|---|---|
|
CHAR(x) VARCHAR2(y) |
(1) (1) |
PIC S9(n)[V9(n)] DISPLAY |
|
|
NCHAR(u) NVARCHAR2(v) |
(2) {2} |
PIC { N(n) | G(n)} |
n-national character string |
|
BFILE |
SQL-BFILE |
external binary file |
|
|
NUMBER (p,s) |
(3) |
PIC X(n) VARYING |
character string (4) n-character string (4) n-byte variable-length string |
|
ROWID |
(5) (1) (6) |
SQL-ROWID |
universal rowid |
Notes:
The following example declares several host variables for later use:
... 01 STR1 PIC X(3). 01 STR2 PIC X(3) VARYING. 01 NUM1 PIC S9(5) COMP. 01 NUM2 COMP-1. 01 NUM3 COMP-2. ...
You can also declare one-dimensional tables of simple COBOL types, as the next example shows:
... 01 XMP-TABLES. 05 TAB1 PIC XXX OCCURS 3 TIMES. 05 TAB2 PIC XXX VARYING OCCURS 3 TIMES. 05 TAB3 PIC S999 COMP-3 OCCURS 3 TIMES. ...
You can initialize host variables, except pseudotype host variables, using the VALUE clause, as shown in the following example:
01 USERNAME PIC X(10) VALUE "SCOTT". 01 MAX-SALARY PIC S9(4) COMP VALUE 5000.
If a string value assigned to a character variable is shorter than the declared length of the variable, the string is blank-padded on the right. If the string value assigned to a character variable is longer than the declared length, the string is truncated.
No error or warning is issued, but any VALUES clause on a pseudotype variable is ignored and discarded.
You cannot use alphabetic character (PIC A) variables or edited data items as host variables. Therefore, the following variable declarations cannot be made for host variables:
.... 01 AMOUNT-OF-CHECK PIC ****9.99. 01 FIRST-NAME PIC A(10). 01 BIRTH-DATE PIC 99/99/99. ....
Host variables are used in SQL data manipulation statements. A host variable must be prefixed with a colon (:) in SQL statements but must not be prefixed with a colon in COBOL statements, as this example shows:
WORKING-STORAGE SECTION. ... EXEC SQL BEGIN DECLARE SECTION END-EXEC. 01 EMP-NUMBER PIC S9(4) COMP VALUE ZERO. 01 EMP-NAME PIC X(10) VALUE SPACE. 01 SALARY PIC S9(5)V99 COMP-3. EXEC SQL END DECLARE SECTION END-EXEC. ... PROCEDURE DIVISION. ... DISPLAY "Employee number? " WITH NO ADVANCING. ACCEPT EMP-NUMBER. EXEC SQL SELECT ENAME, SAL INTO :EMP-NAME, :SALARY FROM EMP WHERE EMPNO = :EMP-NUMBER END-EXEC. COMPUTE BONUS = SALARY / 10. ...
Though it might be confusing, you can give a host variable the same name as a table or column, as the following example shows:
WORKING-STORAGE SECTION. ... EXEC SQL BEGIN DECLARE SECTION END-EXEC. 01 EMPNO PIC S9(4) COMP VALUE ZERO. 01 ENAME PIC X(10) VALUE SPACE. 01 COMM PIC S9(5)V99 COMP-3. EXEC SQL END DECLARE SECTION END-EXEC. ... PROCEDURE DIVISION. ... EXEC SQL SELECT ENAME, COMM INTO :ENAME, :COMM FROM EMP WHERE EMPNO = :EMPNO END-EXEC.
Pro*COBOL allows the use of group items in embedded SQL statements. Group items with elementary items (containing only one level) can be used as host variables. The host group items (also referred to as host structures) can be referenced in the INTO clause of a SELECT or a FETCH statement, and in the VALUES list of an INSERT statement. When a group item is used as a host variable, only the group name is used in the SQL statement. For example, given the following declaration
01 DEPARTURE. 05 HOUR PIC X(2). 05 MINUTE PIC X(2).
the following statement is valid:
EXEC SQL SELECT DHOUR, DMINUTE INTO :DEPARTURE FROM SCHEDULE WHERE ...
The order that the members are declared in the group item must match the order that the associated columns occur in the SQL statement, or in the database table if the column list in the INSERT statement is omitted. Using a group item as a host variable has the semantics of substituting the group item with elementary items. In the above example, it would mean substituting :DEPARTURE with :DEPARTURE.HOUR, :DEPARTURE.MINUTE.
Group items used as host variables can contain host tables. In the following example, the group item containing tables is used to INSERT three entries into the SCHEDULE table:
01 DEPARTURE. 05 HOUR PIC X(2) OCCURS 3 TIMES. 05 MINUTE PIC X(2) OCCURS 3 TIMES. ... EXEC SQL INSERT INTO SCHEDULE (DHOUR, DMINUTE) VALUES (:DEPARTURE) END-EXEC.
If VARCHAR=YES is specified, Pro*COBOL will recognize implicit VARCHARs. If the nested group item declaration resembles a VARCHAR host variable, then the entire group item is treated like an elementary item of VARYING type. See "VARCHAR".
When referencing elementary items instead of the group items as host variables elementary names need not be unique because you can qualify them using the following syntax:
group_item.elementary_item
This naming convention is allowed only in SQL statements. It is similar to the IN (or OF) clause in COBOL, examples of which follow:
MOVE MINUTE IN DEPARTURE TO MINUTE-OUT. DISPLAY HOUR OF DEPARTURE.
The COBOL IN (or OF) clause is not allowed in SQL statements. Qualify elementary names to avoid ambiguity. For example:
EXEC SQL BEGIN DECLARE SECTION END-EXEC. 01 DEPARTURE. 05 HOUR PIC X(2). 05 MINUTE PIC X(2). 01 ARRIVAL. 05 HOUR PIC X(2). 05 MINUTE PIC X(2). EXEC SQL END DECLARE SECTION END-EXEC. ... EXEC SQL SELECT DHR, DMIN INTO :DEPARTURE.HOUR, :DEPARTURE.MINUTE FROM TIMETABLE WHERE ...
A host variable cannot substitute for a column, table, or other object in a SQL statement and must not be an Oracle9i reserved word. See Appendix C, "Reserved Words, Keywords, and Namespaces"for a list of reserved words and keywords.
You can associate any host variable with an optional indicator variable. Each time the host variable is used in a SQL statement, a result code is stored in its associated indicator variable. Thus, indicator variables let you monitor host variables.
You use indicator variables in the VALUES or SET clause to assign NULLs to input host variables and in the INTO clause to detect NULLs (or truncated values for character columns) in output host variables.
Here are the values indicator variables can take on.
The values your program can assign to an indicator variable have the following meanings:
| Indicator Variables | Description |
|---|---|
|
-1 |
Oracle will assign a NULL to the column, ignoring the value of the host variable. |
|
>=0 |
Oracle will assign the value of the host variable to the column. |
The values Oracle can assign to an indicator variable have the following meanings:
An indicator variable must be explicitly declared as PIC S9(4) COMP and must not be a reserved word. In the following example, you declare an indicator variable named COMM-IND (the name is arbitrary):
WORKING-STORAGE SECTION. ... 01 EMP-NAME PIC X(10) VALUE SPACE. 01 SALARY PIC S9(5)V99 COMP-3. 01 COMMISSION PIC S9(5)V99 COMP-3. 01 COMM-IND PIC S9(4) COMP. ...
In SQL statements, an indicator variable must be prefixed with a colon and appended to its associated host variable. In COBOL statements, an indicator variable must not be prefixed with a colon or appended to its associated host variable. An example follows:
EXEC SQL SELECT SAL, COMM INTO :SALARY, :COMMISSION:COMM-IND FROM EMP WHERE EMPNO = :EMP-NUMBER END-EXEC. IF COMM-IND = -1 COMPUTE PAY = SALARY ELSE COMPUTE PAY = SALARY + COMMISSION.
To improve readability, you can precede any indicator variable with the optional keyword INDICATOR. You must still prefix the indicator variable with a colon. The correct syntax is
:host_variableINDICATOR:indicator_variable
and is equivalent to
:host_variable:indicator_variable
You can use both forms of expression in your host program.
Indicator variables cannot be used in the WHERE clause to search for NULLs. For example, the following DELETE statement triggers an error at run time:
* Set indicator variable. COMM-IND = -1 EXEC SQL DELETE FROM EMP WHERE COMM = :COMMISSION:COMM-IND END-EXEC.
The correct syntax follows:
EXEC SQL DELETE FROM EMP WHERE COMM IS NULL END-EXEC.
If you SELECT or FETCH a NULL into a host variable that has no indicator, Oracle9i issues an error message.
You can disable the error message by also specifying UNSAFE_NULL=YES on the command line. For more information, see Chapter 14, "Precompiler Options".
When MODE=ORACLE, if you SELECT or FETCH a truncated column value into a host variable that is not associated with an indicator variable, Oracle9i issues an error message.
However, when MODE={ANSI | ANSI14 | ANSI13}, no error is generated. Values for indicator variables are discussed in Chapter 5, "Embedded SQL".
Indicator variables for multibyte NCHAR character variables can be used as with any other host variable. However, a positive value (the result of a SELECT or FETCH was truncated) represents the string length in multibyte characters instead of 1-byte characters.
To use indicator variables with a host group item, either setup a second group item that contains an indicator variable for each nullable variable in the group item or use a table of half-word integer variables. You do NOT have to have an indicator variable for each variable in the group item, but the nullable fields which you wish to use indicators for must be placed at the beginning of the data group item. The following indicator group item can be used with the DEPARTURE group item:
01 DEPARTURE-IND. 05 HOUR-IND PIC S9(4) COMP. 05 MINUTE-IND PIC S9(4) COMP.
If you use an indicator table, you do NOT have to declare a table of as many elements as there are members in the host group item. The following indicator table can be used with the DEPARTURE group item:
01 DEPARTURE-IND PIC S9(4) COMP OCCURS 2 TIMES.
Reference the indicator group item in the SQL statement in the same way that a host indicator variable is referenced:
EXEC SQL SELECT DHOUR, DMINUTE INTO :DEPARTURE:DEPARTURE-IND FROM SCHEDULE WHERE ...
When the query completes, the NULL/NOT NULL status of each selected component is available in the host indicator group item. The restrictions on indicator host variables and the ANSI requirements also apply to host indicator group items.
COBOL string datatypes are fixed length. However, Pro*COBOL lets you declare a variable-length string pseudotype called VARCHAR. A VARCHAR variable is a pseudotype that enables you to specify the exact length of the data stored in the database and to specify the exact length of the data to be passed to the database.
You define a VARCHAR host variable by adding the keyword VARYING to its declaration, as shown in the following example:
01 ENAME PIC X(15) VARYING.
Note: PIC N and PIC G are not allowed in definitions that use VARYING. To see how to correctly use PIC N and PIC G in VARCHAR variables, see "Implicit VARCHAR Group Items"
The COBOL VARYING phrase is used in PERFORM and SEARCH statements to increment subscripts and indexes. Do not confuse this with the Pro*COBOL VARYING clause in the preceding example.
VARCHAR is an extended Pro*COBOL datatype or pre-declared group item. For example, Pro*COBOL expands the VARCHAR declaration
01 ENAME PIC X(15) VARYING.
into a group item with length and string fields, as follows:
01 ENAME. 05 ENAME-LEN PIC S9(4) COMP. 05 ENAME-ARR PIC X(15).
The length field (suffixed with -LEN) holds the current length of the value stored in the string field (suffixed with -ARR). The maximum length in the VARCHAR host-variable declaration must be in the range of 1 to 9,999 bytes.
The advantage of using VARCHAR variables is that you can explicitly set and reference the length field. With input host variables, Pro*COBOL reads the value of the length field and uses that many characters of the string field. With output host variables, Pro*COBOL sets the length value to the length of the character string stored in the string field.
Pro*COBOL implicitly recognizes some group items as VARCHAR host variables when the precompiler option VARCHAR=YES is specified on the command line. For variable-length single-byte character types, use the following structure (length expressed in single-byte characters):
nn data-name-1. 49 data-name-2 PIC S9(4) COMP. 49 data-name-3 PIC X(length).
nn must be 01 through 48.
For variable-length multibyte NCHAR characters, use these formats (length is expressed in double-byte characters):
nn DATA-NAME-1. 49 DATA-NAME-2 PIC S9(4) COMP. 49 DATA-NAME-3 PIC N(length). nn DATA-NAME-1. 49 DATA-NAME-2 PIC S9(4) COMP. 49 DATA-NAME-3 PIC G(length). The elementary items in these group-item structures must be declared as level 49 for Pro*COBOL to recognize them as VARCHAR host variables.
The VARCHAR=YES command line option must be specified for Pro*COBOL to recognize the extended form of the VARCHAR group items. If VARCHAR=NO, then any declarations that resemble the above formats will be interpreted as regular group items. If VARCHAR=YES and a group item declaration format looks similar (but not identical) to the extended VARCHAR format, then the item will be interpreted as a regular group item rather than a VARCHAR group item. For example, if VARCHAR=YES is specified and you write the following:
01 LASTNAME. 48 LASTNAME-LEN PIC S9(4) COMP. 48 LASTNAME-TEXT PIC X(15).
then, since level 48 instead of 49 is used for the group item elements, the item is interpreted as a regular group item rather than a VARCHAR group item.
For more information about the Pro*COBOL VARCHAR option, see Chapter 14, "Precompiler Options"
In SQL statements, you reference a VARCHAR variable using the group name prefixed with a colon, as the following example shows:
WORKING-STORAGE SECTION. ... EXEC SQL BEGIN DECLARE SECTION END-EXEC. ... 01 PART-NUMBER PIC X(5). 01 PART-DESC PIC X(20) VARYING. EXEC SQL END DECLARE SECTION END-EXEC. ... PROCEDURE DIVISION. ... EXEC SQL SELECT PDESC INTO :PART-DESC FROM PARTS WHERE PNUM = :PART-NUMBER END-EXEC.
After the query executes, PART-DESC-LEN holds the actual length of the character string retrieved from the database and stored in PART-DESC-ARR.
This section explains how Pro*COBOL handles character host variables. There are two kinds of single-byte character host variables and two kinds of multibyte Globalization Support (formerly called NLS) character host variables:
Attention: Before using multibyte NCHAR datatypes, verify that the PIC N or PIC G datatype is supported by your COBOL compiler.
The default datatype of PIC X variables is CHARF (was VARCHAR2 before release 8.0.) The precompiler command line option, PICX, is provided for backward compatibility. PICX can be entered only on the command line or in a configuration file. See "PICX" for more details.
The PICX option determines how Pro*COBOL treats data in character strings. The PICX option enables your program to use ANSI fixed-length strings or to maintain compatibility with previous versions of the database server and Pro*COBOL.
You must use PICX=VARCHAR2 (not the default) to obtain the same results as releases of Pro*COBOL before 8.0. Or, use
EXEC SQL varname IS VARCHAR2 END-EXEC.
for each variable.
Fixed-length character variables are declared using the PIC X(n) and PIC G(n) and PIC N(n) datatypes. These types of variables handle character data based on their roles as input or output variables.
When PICX=VARCHAR2, the program interface strips trailing blanks before sending the value to the database. If you insert into a fixed-length CHAR column, Pro*COBOL re-appends trailing blanks up to the length of the database column. However, if you insert into a variable-length VARCHAR2 column, Pro*COBOL never appends blanks.
When PICX=CHARF, trailing blanks are never stripped.
Host input variables for multibyte Globalization Support data are not stripped of trailing double-byte spaces. The length component is assumed to be the length of the data in characters, not bytes.
Make sure that the input value is not trailed by extraneous characters. Normally, this is not a problem because when a value is ACCEPTed or MOVEd into a PIC X(n) variable, COBOL appends blanks up to the length of the variable.
The following example illustrates the point:
WORKING-STORAGE SECTION. ... EXEC SQL BEGIN DECLARE SECTION END-EXEC. 01 EMPLOYEES. 05 EMP-NAME PIC X(10). 05 DEPT-NUMBER PIC S9(4) VALUE 20 COMP. 05 EMP-NUMBER PIC S9(9) VALUE 9999 COMP. 05 JOB-NAME PIC X(8). ... EXEC SQL END DECLARE SECTION END-EXEC. ... PROCEDURE DIVISION. ... DISPLAY "Employee name? " WITH NO ADVANCING. ACCEPT EMP-NAME. * Assume that the name MILLER was entered * EMP-NAME contains "MILLER " (4 trailing blanks) MOVE "SALES" TO JOB-NAME. * JOB-NAME now contains "SALES " (3 trailing blanks) EXEC SQL INSERT INTO EMP (EMPNO, ENAME, DEPTNO, JOB) VALUES (:EMP-NUMBER, :EMP-NAME, :DEPT-NUMBER, :JOB-NAME END-EXEC. ...
If you precompile the last example with PICX=VARCHAR2 and the target database columns are VARCHAR2, the program interface strips the trailing blanks on input and inserts just the 6-character string "MILLER" and the 5-character string "SALES" into the database. However, if the target database columns are CHAR, the strings are blank-padded to the width of the columns.
If you precompile the last example with PICX=CHARF and the JOB column is defined as CHAR(10), the value inserted into that column is "SALES#####" (five trailing blanks). However, if the JOB column is defined as VARCHAR2(10), the value inserted is "SALES###" (three trailing blanks), because the host variable is declared as PIC X(8). This might not be what you want, so be careful.
The PICX option has no effect on output to fixed-length character variables. When you use a PIC X(n) variable as an output host variable, Pro*COBOL blank-pads it. In our example, when your program fetches the string "MILLER" from the database, EMP-NAME contains the value "MILLER####" (with four trailing blanks). This character string can be used without change as input to another SQL statement.
VARCHAR variables handle character data based on their roles as input or output variables.
When you use a VARCHAR variable as an input host variable, your program must assign values to the length and string fields of the expanded VARCHAR declaration, as shown in the following example:
IF ENAME-IND = -1 MOVE "NOT AVAILABLE" TO ENAME-ARR MOVE 13 TO ENAME-LEN.
You need not blank-pad the string variable. In SQL operations, Pro*COBOL uses exactly the number of characters given by the length field, counting any spaces.
When you use a VARCHAR variable as an output host variable, Pro*COBOL sets the length field. An example follows:
WORKING-STORAGE SECTION. ... EXEC SQL BEGIN DECLARE SECTION END-EXEC. 01 EMPNO PIC S9(4) COMP. 01 ENAME PIC X(15) VARYING. ... EXEC SQL END DECLARE SECTION END-EXEC. ... PROCEDURE DIVISION. ... EXEC SQL SELECT ENAME INTO :ENAME FROM EMP WHERE EMPNO = :EMPNO END-EXEC. IF ENAME-LEN = 0 MOVE FALSE TO VALID-DATA.
An advantage of VARCHAR variables over fixed-length strings is that the length of the value returned by Pro*COBOL is available right away. With fixed-length strings, to get the length of the value, your program must count the number of characters.
Host output variables for multibyte NCHAR data are not padded at all. The length of the buffer is set to the length in characters, not bytes.
There are two kinds of table organization used in the database server: heap tables and index-organized tables.
Heap tables are the default. This is the organization used in all tables before Oracle9. The physical row address (ROWID) is a permanent property that is used to identify a row in a heap table. The external character format of the physical ROWID is an 18-byte character string in base-64 encoding.
An index-organized table does not have physical row addresses as permanent identifiers. A logical ROWID is defined for these tables. When you use a SELECT ROWID ... statement from an index-organized table the ROWID is an opaque structure that contains the primary key of the table, control information, and an optional physical "guess". You can use this ROWID in a SQL statement containing a clause such as "WHERE ROWID = ..." to retrieve values from the table.
The universal ROWID was introduced in the Oracle 8.1 release. Universal ROWID can be used for both physical ROWID and logical ROWID. You can use universal ROWIDs to access data in heap tables, or index-organized tables, since the table organization can change with no effect on applications. The column datatype used for ROWID is UROWID(length), where length is optional.
Use the universal ROWID in all new applications.
For more information on universal ROWIDs, see Oracle9i Database Concepts.
Declare a universal ROWID, which uses the pseudotype SQL-ROWID, this way:
01 MY-ROWID SQL-ROWID.
Memory for the universal ROWID is allocated with the ALLOCATE statement:
EXEC SQL ALLOCATE :MY-ROWID END-EXEC.
Use MY-ROWID in SQL DML statements like this:
EXEC SQL SELECT ROWID INTO :MY-ROWID FROM MYTABLE WHERE ... END-EXEC. ... EXEC SQL UPDATE MYTABLE SET ... WHERE ROWID = :MY-ROWID END-EXEC. ...
Free the memory when you no longer need it with the FREE directive:
EXEC SQL FREE :MY-ROWID END-EXEC.
You also have the option of using a character host variable of width between 18 and 4000 as the host bind variable for universal ROWID. Character-based universal ROWIDs are supported for heap tables only for backwards compatibility. Because a universal ROWID can be variable length there can be truncation when it is selected. For a more complete discussion of this variable see Oracle9i Database Concepts.
Use the character variable like this:
01 MY-ROWID-CHAR PIC X(4000) VARYING. ... EXEC SQL ALLOCATE :MY-ROWID-CHAR END-EXEC. EXEC SQL SELECT ROWID INTO :MY-ROWID-CHAR FROM MYTABLE WHERE ... END-EXEC. ... EXEC SQL UPDATE MYTABLE SET ... WHERE ROWID = :MY-ROWID-CHAR END-EXEC. ... EXEC SQL FREE :MY-ROWID-CHAR END-EXEC.
For an example of a positioned update using the universal ROWID, see "Positioned Update".
The Oracle subprogram SQLROWIDGET enables you to retrieve the ROWID of the last row inserted, updated, or selected. SQLROWIDGET requires a context or NULL and a ROWID as its arguments.