Pro*COBOL Precompiler Programmer's Guide Release 8.1.5 A68023-01 |
|
This chapter describes Oracle's implementation of ANSI dynamic SQL (also known as SQL92 dynamic SQL) which should be used for new Method 4 applications. It has enhancements over the older Oracle dynamic SQL Method 4, which is described in "Oracle Dynamic SQL: Method 4". The ANSI Method 4 supports all Oracle types, while the older Oracle Method 4 does not support cursor variables, tables of group items, the DML returning clause, and LOBs.
In ANSI dynamic SQL, descriptors are internally maintained by Oracle, while in the older Oracle dynamic SQL Method 4, descriptors are defined in the user's Pro*COBOL program. In both cases, Method 4 means that your Pro*COBOL program accepts or builds SQL statements that contain a varying number of host variables.
The main sections in this chapter are:
Consider the SQL statement:
SELECT ename, empno FROM emp WHERE deptno = :deptno_data
The steps you follow to use ANSI dynamic SQL are:
deptno_data)
.
ename
and empno)
.
ename
and empno
data fields from each row.
Set the micro precompiler option DYNAMIC to ANSI, or set the macro option MODE to ANSI, which causes the default value of DYNAMIC to be ANSI. The other setting of DYNAMIC is ORACLE. For more about micro options, see "Macro and Micro Options".
In order to use ANSI type codes, set the precompiler micro option TYPE_CODE to ANSI, or set the macro option MODE to ANSI which changes the default setting of TYPE_CODE to ANSI. To set TYPE_CODE to ANSI, DYNAMIC must also be ANSI.
Oracle's implementation of the ANSI SQL types in Table 10-1 does not exactly match the ANSI standard. For example, a describe of a column declared as INTEGER will return the code for NUMERIC. As Oracle moves closer to the ANSI standard, small changes in behavior may be required. Use the ANSI types with precompiler option TYPE_CODE set to ANSI if you want your application to be portable across database platforms and as ANSI compliant as possible. Do not use TYPE_CODE set to ANSI if such changes are not acceptable.
Allocate a descriptor area first before using it in a dynamic SQL statement.
The ALLOCATE DESCRIPTOR statement syntax is:
EXEC SQL ALLOCATE DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} [WITH MAX {:occurrences | numeric_literal}] END-EXEC.
A global descriptor can be used in any module in the program. A local descriptor can be accessed only in the file in which it is allocated. Local is the default.
The descriptor name, desc_nam
, is a host variable. A string literal can be used instead.
occurrences
is the maximum number of bind variables or columns that the descriptor can hold, with a default of 100.
When a descriptor is no longer needed, deallocate it to conserve memory. Deallocation is done automatically when there are no more database connections.
The deallocate statement is:
EXEC SQL DEALLOCATE DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} END-EXEC.
Use the DESCRIBE statement to obtain information on a prepared SQL statement. DESCRIBE INPUT describes bind variables for the dynamic statement that has been prepared. DESCRIBE OUTPUT (the default) can give the number, type, and length of the output columns. The simplified syntax is:
EXEC SQL DESCRIBE [INPUT | OUTPUT] sql_statement USING [SQL] DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} END-EXEC.
If your SQL statement has input and output values, you must allocate two descriptors: one for input and one for output values. If there are no input values, for example:
SELECTename, empno
FROMemp
then the input descriptor is not needed.
Use the SET DESCRIPTOR statement to specify input values for INSERTS, UPDATES, DELETES and the WHERE clauses of SELECT statements. Use SET DESCRIPTOR to set the number of input bind variables (stored in COUNT) when you have not done a DESCRIBE into your input descriptor:
EXEC SQL SET DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} COUNT = {:kount | numeric_literal} END-EXEC.
kount
can be a host variable or a numeric literal, such as 5. Use a SET DESCRIPTOR statement for each host variable, giving at least the data value of the variable:
EXEC SQL SET DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} VALUE item_number DATA = :hv3 END-EXEC.
You can also set the type and length of the input host variable:
Note: If you do not set the type and length, either explicitly, via the SET DESCRIPTOR statement, or implicitly by doing a DESCRIBE OUTPUT, when TYPE_CODE=ORACLE, the precompiler will use values for these derived from the host variable itself. When TYPE_CODE=ANSI, you must set the type using the values in Table 10-1, "ANSI SQL Datatypes". You should also set the length because the ANSI default lengths may not match those of your host variable.
EXEC SQL SET DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} VALUE item_number TYPE = :hv1, LENGTH = :hv2, DATA = :hv3 END-EXEC.
We use the identifiers hv1
, hv2
, and hv3
to remind us that the values must be supplied by host variables. item_number is the position of the input variable in the SQL statement. It can be a host variable or an integer number.
TYPE is the Type Code selected from the following table, if TYPE_CODE is set to ANSI:
Datatype | Type Code |
---|---|
CHARACTER |
1 |
CHARACTER VARYING |
12 |
DATE |
9 |
DECIMAL |
3 |
DOUBLE PRECISION |
8 |
FLOAT |
6 |
INTEGER |
4 |
NUMERIC |
2 |
REAL |
7 |
SMALLINT |
5 |
See Table 11-2, "Oracle External and Related COBOL Datatypes" for the Oracle type codes. Use the negative value of the Oracle code if the ANSI datatype is not in the table, and TYPE_CODE = ANSI.
DATA is the host variable value which is input.
You can also set other input values such as indicator, precision and scale. See the more complete discussion of "SET DESCRIPTOR" for a list of all the possible descriptor item names.
The numeric values in the SET DESCRIPTOR statement must be declared as either PIC S9(9) COMP
or PIC S9(4) COMP
, except for indicator and returned length values which you must declare as PIC S9(4)COMP
.
In the following example, when you want to retrieve empno, set these values: VALUE=2, because empno
is the second output host variable in the dynamic SQL statement. The host variable EMPNO-TYP
is set to 3 (Oracle Type for integer). The length of a host integer, EMPNO-LEN
, is set to 4, which is the size of the host variable. The DATA is equated to the host variable EMPNO-DATA which will receive the value from the database table. The code fragment is as follows:
... 01 DYN-STATEMENT PIC X(58) VALUE "SELECT ename, empno FROM emp WHERE deptno =:deptno_number". 01 EMPNO-DATA PIC S9(9) COMP. 01 EMPNO-TYP PIC S9(9) COMP VALUE 3. 01 EMPNO-LEN PIC S9(9) COMP VALUE 4. ... EXEC SQL SET DESCRIPTOR 'out' VALUE 2 TYPE=:EMPNO-TYP, LENGTH=:EMPNO-LEN, DATA=:EMPNO-DATA END-EXEC.
After setting the input values, execute or open your statement using the input descriptor. If there are output values in your statement, set them before doing a FETCH. If you have done a DESCRIBE OUTPUT, you may have to reset the actual types and lengths of your host variables because the DESCRIBE execution will produce internal types and lengths which differ from your host variable external types and length.
After the FETCH of the output descriptor, use GET DESCRIPTOR to access the returned data. Again we show a simplified syntax with details later in this chapter:
EXEC SQL GET DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} VALUE item_number :hv1 = DATA, :hv2 = INDICATOR, :hv3 = RETURNED_LENGTH END-EXEC.
desc_nam
and item_number
can be literals or host variables. A descriptor name can be a literal such as 'out'. An item number can be a numeric literal such as 2.
hv1, hv2, and hv3
are host variables. They must be host variables, not literals. Only three are shown in the example. See Table 10-4, "Definitions of Descriptor Item Names" for a list of all possible items of returned data that you can get.
Use either PIC S9(n) COMP
where n is the platform-dependent upper limit, PIC S9(9)COMP
or PIC S9(4)COMP for all numeric values, except for indicator and returned length variables, which must be PIC S9(4) COMP.
The following example demonstrates the use of ANSI Dynamic SQL. It allocates an input descriptor ('in') and an output descriptor ('out') to execute a SELECT statement. Input values are set via the SET DESCRIPTOR statement. The cursor is opened and fetched from and the resulting output values are retrieved via a GET DESCRIPTOR statement.
... 01 DYN-STATEMENT PIC X(58) VALUE "SELECT ENAME, EMPNO FROM EMP WHERE DEPTNO =:DEPTNO-DAT". 01 EMPNO-DAT PIC S9(9) COMP. 01 EMPNO-TYP PIC S9(9) COMP VALUE 3. 01 EMPNO-LEN PIC S9(9) COMP VALUE 4. 01 DEPTNO-TYP PIC S9(9) COMP VALUE 3. 01 DEPTNO-LEN PIC S9(9) COMP VALUE 2. 01 DEPTNO-DAT PIC S9(9) COMP VALUE 10. 01 ENAME-TYP PIC S9(9) COMP VALUE 3. 01 ENAME-LEN PIC S9(9) COMP VALUE 30. 01 ENAME-DAT PIC X(30). 01 SQLCODE PIC S9(9) COMP VALUE 0. ... * Place preliminary code, including connection, here ... EXEC SQL ALLOCATE DESCRIPTOR 'in' END-EXEC. EXEC SQL ALLOCATE DESCRIPTOR 'out' END-EXEC. EXEC SQL PREPARE s FROM :DYN-STATEMENT END-EXEC. EXEC SQL DESCRIBE INPUT s USING DESCRIPTOR 'in' END-EXEC. EXEC SQL SET DESCRIPTOR 'in' VALUE 1 TYPE=:DEPTNO-TYP, LENGTH=:DEPTNO-LEN, DATA=:DEPTNO-DAT END-EXEC. EXEC SQL DECLARE c CURSOR FOR s END-EXEC. EXEC SQL OPEN c USING DESCRIPTOR 'in' END-EXEC. EXEC SQL DESCRIBE OUTPUT s USING DESCRIPTOR 'out' END-EXEC. EXEC SQL SET DESCRIPTOR 'out' VALUE 1 TYPE=:ENAME-TYP, LENGTH=:ENAME-LEN, DATA=:ENAME-DAT END-EXEC. EXEC SQL SET DESCRIPTOR 'out' VALUE 2 TYPE=:EMPNO-TYP, LENGTH=:EMPNO-LEN, DATA=:EMPNO-DAT END-EXEC. EXEC SQL WHENEVER NOT FOUND GOTO BREAK END-EXEC. LOOP. IF SQLCODE NOT = 0 GOTO BREAK. EXEC SQL FETCH c INTO DESCRIPTOR 'out' END-EXEC. EXEC SQL GET DESCRIPTOR 'OUT' VALUE 1 :ENAME-DAT = DATA END-EXEC. EXEC SQL GET DESCRIPTOR 'OUT' VALUE 2 :EMPNO-DAT = DATA END-EXEC. DISPLAY "ENAME = " WITH NO ADVANCING DISPLAY ENAME-DAT WITH NO ADVANCING DISPLAY "EMPNO = " WITH NO ADVANCING DISPLAY EMPNO-DAT. GOTO LOOP. BREAK: EXEC SQL CLOSE c END-EXEC. EXEC SQL DEALLOCATE DESCRIPTOR 'in' END-EXEC. EXEC SQL DEALLOCATE DESCRIPTOR 'out' END-EXEC.
These extensions are described next:
The ANSI standard specifies value semantics. To improve performance, Oracle has extended this standard to include reference semantics.
Value semantics makes a copy of your host variables data. Reference semantics uses the addresses of your host variables, avoiding a copy. Thus, reference semantics can provide performance improvements for large amounts of data.
To help speed up fetches, use the REF keyword before the data clauses:
EXEC SQL SET DESCRIPTOR 'out' VALUE 1 TYPE=:ENAME-TYP, LENGTH=:ENAME-LEN, REF DATA=:ENAME-DAT END-EXEC. EXEC SQL DESCRIPTOR 'out' VALUE 2 TYPE=:EMPNO-TYP, LENGTH=:EMPNO-LEN, REF DATA=:EMPNO-DAT END-EXEC.
Then the host variables receive the results of the retrieves. The GET statement is not needed. The retrieved data is written directly into ename_data
and empno_data
after each FETCH.
Use of the REF keyword is allowed only before DATA, INDICATOR and RETURNED_LENGTH items (which can vary with each row fetched) as in this fragment of code:
01 INDI PIC S9(4) COMP. 01 RETRN-LEN PIC S9(9) COMP. ... EXEC SQL SET DESCRIPTOR 'out' VALUE 1 TYPE=:ENAME-TYP, LENGTH=:ENAME-LEN, REF DATA=:ENAME-DAT, REF INDICATOR=:INDI, REF RETURNED_LENGTH =:RETRN-LEN END-EXEC.
After each fetch, RETRN-LEN
holds the actual retrieved length of the ename
field, which is useful for CHAR
or VARCHAR2
data.
ENAME-LEN
will not receive the returned length. It will not be changed by the FETCH statement. Use a DESCRIBE statement, followed by a GET statement to find out the maximum column width before fetching rows of data.
REF keyword is also used for other types of SQL statements than SELECT, to speed them up. Note that with reference semantics, the host variable is used rather than a value copied into the descriptor area. The host variable data at the time of execution of the SQL statement is used, not its data at the time of the SET. Here is an example:
... MOVE 1 to VAL. ... EXEC SQL SET DESCRIPTOR 'value' VALUE 1 DATA = :VAL END-EXEC. EXEC SQL SET DESCRIPTOR 'reference' VALUE 1 REF DATA = :VAL END-EXEC. MOVE 2 to VAL. * Will use VAL = 1 EXEC SQL EXECUTE s USING DESCRIPTOR 'value' END-EXEC. *Will use VAL = 2 EXEC SQL EXECUTE s USING DESCRIPTOR 'reference' END-EXEC.
See "SET DESCRIPTOR" for many more details on the differences.
Oracle extends the SQL92 ANSI dynamic standard by providing bulk operations. To use bulk operations, use the FOR
clause with an array size to specify the amount of input data or the number of rows you want to process.
The FOR
clause is used in the ALLOCATE statement to give the maximum amount of data or number of rows. For example, to use a maximum array size of 100:
EXEC SQL FOR 100 ALLOCATE DESCRIPTOR 'out' END-EXEC.
or:
MOVE 100 TO INT-ARR-SIZE. EXEC SQL FOR :INT-ARR-SIZE ALLOCATE DESCRIPTOR 'out' END-EXEC.
The FOR
clause is then used in subsequent statements that access the descriptor. In an output descriptor the FETCH statement must have an array size equal to or less than the array size already used in the ALLOCATE statement:
EXEC SQL FOR 20 FETCH c1 USING DESCRIPTOR 'out' END-EXEC.
Subsequent GET statements for the same descriptor, that get DATA, INDICATOR, or RETURNED_LENGTH values, must use the same array size as the FETCH statement.
01 VAL-DATA OCCURS 20 TIMES PIC S9(9) COMP. 01 VAL-INDI OCCURS 20 TIMES PIC S9(4) COMP. ... EXEC SQL FOR 20 GET DESCRIPTOR 'out' VALUE 1 :VAL-DATA = DATA, :VAL-INDI = INDICATOR END-EXEC.
However, GET statements that reference other items which do not vary from row to row, such as LENGTH, TYPE and COUNT, must not use the FOR
clause:
01 CNT PIC S9(9) COMP. 01 LEN PIC S9(9) COMP. ... EXEC SQL GET DESCRIPTOR 'out' :CNT = COUNT END-EXEC. EXEC SQL GET DESCRIPTOR 'out' VALUE 1 :LEN = LENGTH END-EXEC.
The same holds true for SET statements with reference semantics. SET statements which precede the FETCH and employ reference semantics for DATA, INDICATOR, or RETURNED_LENGTH must have the same array size as the FETCH:
... 01 REF-DATA OCCURS 20 TIMES PIC S9(9) COMP. 01 REF-INDI OCCURS 20 TIMES PIC S9(4) COMP. ... EXEC SQL FOR 20 SET DESCRIPTOR 'out' VALUE 1 REF DATA = :REF-DATA, REF INDICATOR = :REF-INDI END-EXEC.
Similarly, for a descriptor that is used for input, to insert a batch of rows, for instance, the EXECUTE or OPEN statement must use an array size equal to or less than the size used in the ALLOCATE statement. The SET statement, for both value and reference semantics, that accesses DATA, INDICATOR, or RETURNED_LENGTH, must use the same array size as in the EXECUTE statement.
The FOR clause is never used on the DEALLOCATE or PREPARE statements.
The following code sample illustrates a bulk operation with no output descriptor (there is no output, only input to be inserted into the table emp
). The value of CNT
is 2 (there are two host variables, ENAME and EMPNO
, in the INSERT statement). The data table ENAME-TABLE
holds three character strings: "Tom ", "Dick " and "Harry ", in that order. Their employee numbers are in the table EMPNO-TABLE
. The indicator table ENAME-IND
has a value of -1 for the second element; so a NULL
will be inserted instead of "Dick". A RETURNING clause could be used to confirm the actual names inserted.
01 DYN-STATEMENT PIC X(240) value "INSERT INTO EMP(ENAME, EMPNO) VALUES (:ENAME,:EMPNO)". 01 ARRAY-SIZE PIC S9(9) COMP VALUE 3. 01 ENAME-VALUES. 05 FILLER PIC X(6) VALUE "Tom ". 05 FILLER PIC X(6) VALUE "Dick ". 05 FILLER PIC X(6) VALUE "Harry ". 01 ENAME-TABLE REDEFINES ENAME-VALUES. 05 ENAME PIC X(6)OCCURS 3 TIMES. 01 ENAME-IND PIC S9(4) COMPOCCURS 3 TIMES. 01 ENAME-LEN PIC S9(9) COMP VALUE 6. 01 ENAME-TYP PIC S9(9) COMP VALUE 96. 01 EMPNO-VALUES. 05 FILLER PIC S9(9) COMP VALUE 8001. 05 FILLER PIC S9(9) COMP VALUE 8002. 05 FILLER PIC S9(9) COMP VALUE 8003. 01 EMPNO-TABLE REDEFINES EMPNO-VALUES. 05 EMPNO PIC S9(9) DISPLAY SIGN LEADING OCCURS 3 TIMES. 01 EMPNO-LEN PIC S9(9) COMP VALUE 4. 01 EMPNO-TYP PIC S9(9) COMP VALUE 3. 01 CNT PIC S9(9) COMP VALUE 2. ........ EXEC SQL FOR :ARRAY-SIZE ALLOCATE DESCRIPTOR 'in' END-EXEC. EXEC SQL PREPARE S FROM :DYN-STATEMENT END-EXEC. MOVE 0 TO ENAME-IND(1). MOVE -1 TO ENAME-IND(2). MOVE 0 TO ENAME-IND(3). EXEC SQL SET DESCRIPTOR 'in' COUNT = :CNT END-EXEC. EXEC SQL SET DESCRIPTOR 'in' VALUE 1 TYPE = :ENAME-TYP, LENGTH =:ENAME-LEN END-EXEC. EXEC SQL FOR :ARRAY-SIZE SET DESCRIPTOR 'in' VALUE 1 DATA = :ENAME, INDICATOR = :ENAME-IND END-EXEC. EXEC SQL SET DESCRIPTOR 'in' VALUE 2 TYPE = :EMPNO-TYP, LENGTH =:EMPNO-LEN END-EXEC. EXEC SQL FOR :ARRAY-SIZE SET DESCRIPTOR 'in' VALUE 2 DATA = :EMPNO END-EXEC. EXEC SQL FOR :ARRAY-SIZE EXECUTE S USING DESCRIPTOR 'in' END-EXEC. ...
The preceding code will insert these values into the table:
EMPNO ENAME 8001 Tom 8002 8003 Harry
See the discussion in "Using the FOR Clause" for restrictions and cautions.
The macro option MODE (See "MODE") sets ANSI compatibility characteristics and controls a number of functions. It can have the values ANSI or ORACLE. For individual functions there are micro options that override the MODE setting.
The precompiler micro option DYNAMIC specifies the descriptor behavior in dynamic SQL. The precompiler micro option TYPE_CODE specifies whether ANSI or Oracle datatype codes are to be used.
When the macro option MODE is set to ANSI, the micro option DYNAMIC becomes ANSI automatically. When MODE is set to ORACLE, DYNAMIC becomes ORACLE.
DYNAMIC and TYPE_CODE cannot be used inline.
The following table describes functionality and how the DYNAMIC setting affects them:
The micro option TYPE_CODE is set by the precompiler to the same setting as the macro option MODE. TYPE_CODE can only equal ANSI if DYNAMIC equals ANSI.
Here is the functionality corresponding to the TYPE_CODE settings:
For more details on all these statements, see the alphabetical listing in the appendix Appendix F, "Embedded SQL Statements and Precompiler Directives".
Use this statement to allocate a SQL descriptor area. Supply a descriptor and the maximum number of occurrences of host bind items, and an array size. This statement is only for the ANSI dynamic SQL.
EXEC SQL [FOR [:]array_size] ALLOCATE DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} [WITH MAX occurrences] END-EXEC.
array_size
This is in an optional clause (it is an Oracle extension) that supports table processing. It tells the precompiler that the descriptor is usable for table processing.
GLOBAL | LOCAL
The optional scope clause defaults to LOCAL if not entered. A local descriptor can be accessed only in the file in which it is allocated. A global descriptor can be used in any module in the compilation unit.
desc_nam
Local descriptors must be unique in the module. A runtime error is generated if the descriptor has been allocated, but not deallocated, previously. A global descriptor must be unique for the application, or a runtime error results.
occurrences
The maximum number of host variables possible in the descriptor. It must be an integer constant between 0 and 64K, or an error is returned. Its default is 100. The clause is optional. A precompiler error results if it does not conform to these rules.
EXEC SQL ALLOCATE DESCRIPTOR 'SELDES' WITH MAX 50 END-EXEC. EXEC SQL FOR :batch ALLOCATE DESCRIPTOR GLOBAL :BINDDES WITH MAX 25 END-EXEC.
Use this statement to deallocate a SQL descriptor area that has been previously allocated, to free memory. This statement is only used for the ANSI dynamic SQL.
EXEC SQL DEALLOCATE DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} END-EXEC.
desc_nam
Descriptor name. A runtime error results when a descriptor with the same name and scope has not been allocated, or has been allocated and deallocated already.
EXEC SQL DEALLOCATE DESCRIPTOR GLOBAL 'SELDES' END-EXEC. EXEC SQL DEALLOCATE DESCRIPTOR :BINDDES END-EXEC.
Use to obtain information from a SQL descriptor area.
EXEC SQL [FOR [:]array_size] GET DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} {:hv0 = COUNT | VALUE item_number :hv1 = item_name1 [{, :hvN = item_nameN }]} END-EXEC.
array_size
The FOR array_size
is an optional Oracle extension. array_size
has to be equal to the array_size
field in the FETCH statement.
desc_nam
The descriptor name.
GLOBAL | LOCAL
GLOBAL means that the descriptor name is known to all program files. LOCAL means that it is known only in the file in which it is allocated. LOCAL is the default.
COUNT
The total number of bind variables.
VALUE item_number
The position of the item in the SQL statement. item_number
can be a variable or a constant. If item_number
is greater than COUNT
, the "no data found" condition is returned. item_number
must be greater than 0.
hv1 .. hvN
These are host variables to which values are transferred.
item_name1 .. item_nameN
The descriptor item names corresponding to the host variables. The possible ANSI descriptor item names
are:
Descriptor Item Name | Meaning |
|
See Table 10-1 for the ANSI type codes. See Table 11-2 for the Oracle type codes. Use the negative value of the Oracle code if the ANSI datatype is not in the table, and TYPE_CODE = ANSI. |
|
Length of data in the column. In characters for NCHAR, in bytes otherwise. Set by the DESCRIBE OUTPUT. |
|
Length of data in bytes. |
|
The actual data length after a FETCH. |
|
Length of the returned data in bytes. |
|
The number of digits. |
|
For exact numeric types, the number of digits to the right of the decimal point. |
|
If 1, the column can have NULL values. If 0, the column cannot have NULL values. |
|
The associated indicator value. |
|
The data value. |
|
Column name. |
|
Column's character set. |
The Oracle additional descriptor item names are:
Descriptor Item Name | Meaning |
|
If 2, NCHAR or NVARCHAR2. If 1, character. If 0, non-character. |
|
The internal length, in bytes. |
Use the FOR clause in GET DESCRIPTOR statements which contain DATA, INDICATOR, and RETURNED_LENGTH items only.
The internal type is provided by the DESCRIBE OUTPUT statement. For both input and output, you must set the type to be the external type of your host variable. TYPE is the Oracle or ANSI code in Table 10-1 . Use the negative value of the Oracle type if the ANSI type is not in the table.
LENGTH contains the column length in characters for fields that have fixed-width National Language character sets. It is in bytes for other character columns. It is set in DESCRIBE OUTPUT.
RETURNED_LENGTH is the actual data length set by the FETCH statement. It is in bytes or characters as described for LENGTH. The fields OCTET_LENGTH and RETURNED_OCTET_LENGTH are the lengths in bytes.
NULLABLE = 1 means that the column can have NULLS; NULLABLE = 0 means it cannot.
CHARACTER_SET_NAME only has meaning for character columns. For other types, it is undefined. The DESCRIBE OUTPUT statement obtains the value.
DATA and INDICATOR are the data value and the indicator status for that column. If data = NULL, but the indicator was not requested, an error is generated at runtime ("DATA EXCEPTION, NULL VALUE, NO INDICATOR PARAMETER").
NATIONAL_CHARACTER = 2 if the column is an NCHAR or NVARCHAR2 column. If the column is a character (but not National Character) column, this item is set to 1. If a non-character column, this item becomes 0 after DESCRIBE OUTPUT is executed.
INTERNAL_LENGTH is for compatibility with Oracle dynamic Method 4. It has the same value as the length member of the Oracle descriptor area. See "Oracle Dynamic SQL: Method 4" .
EXEC SQL GET DESCRIPTOR :BINDDES :COUNT = COUNT END-EXEC. EXEC SQL GET DESCRIPTOR 'SELDES' VALUE 1 :TYP = TYPE, :LEN = LENGTH END-EXEC. EXEC SQL FOR :batch GET DESCRIPTOR LOCAL 'SELDES' VALUE :SEL-ITEM-NO :IND = INDICATOR, :DAT = DATA END-EXEC.
Use this statement to set information in the descriptor area from host variables. The SET DESCRIPTOR statement supports only host variables for the item names.
EXEC SQL [FOR [:]array_size] SET DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} {COUNT = :hv0 | VALUE item_number [REF] item_name1 = :hv1 [{, [REF] item_nameN = :hvN}]} END-EXEC.
array_size
This optional Oracle clause permits using arrays when setting the descriptor items DATA, INDICATOR, and RETURNED_LENGTH only. You cannot use other items in a SET DESCRIPTOR that contains the FOR clause. All host variable table sizes must match. Use the same array size for the SET statement that you use for the FETCH statement.
desc_nam
The descriptor name. It follows the rules in ALLOCATE DESCRIPTOR.
COUNT
The number of bind (input) or define (output) variables.
VALUE item_number
Position in the dynamic SQL statement of a host variable.
hv1 .. hvN
The host variables (not constants) that you set.
item_name1 .. item_nameN
In a similar way to the GET DESCRIPTOR syntax (see "GET DESCRIPTOR"), item_name
can take on these values:
Descriptor Item Name | Meaning |
TYPE |
See Table 10-1 for the ANSI type codes. See Table 11-2 for the Oracle type codes. Use the negative value of the Oracle type code if the Oracle type is not in the table, and TYPE_CODE = ANSI. |
LENGTH |
Maximum length of data in the column. |
PRECISION |
The number of digits. |
SCALE |
For exact numeric types, the number of bytes to the right of the decimal point. |
Descriptor Item Name | Meaning |
INDICATOR |
The associated indicator value. Set for reference semantics. |
DATA |
Value of the data to be set. Set for reference semantics. |
CHARACTER_SET_NAME |
Column's character set. |
The Oracle extensions to the descriptor item names are:
Reference semantics is another optional Oracle extension that speeds performance. Use the keyword REF before these descriptor items names only: DATA, INDICATOR, RETURNED_LENGTH. When you use the REF keyword you do not need to use a GET statement. Complex data types (DML returning) require the REF form of SET DESCRIPTOR. See "DML Returning Clause".
When REF is used the associated host variable itself is used in the SET. The GET is not needed in this case. The RETURNED_LENGTH can only be set when you use the REF semantics, not the value semantics.
Use the same array size for the SET or GET statements that you use in the FETCH.
Set the NATIONAL_CHAR field to 2 for NCHAR host input values.
When setting an object type's characteristics, you must set USER_DEFINED_TYPE_NAME and USER_DEFINED_TYPE_NAME_LENGTH.
If omitted, USER_DEFINED_TYPE_SCHEMA and USER_DEFINED_TYPE_SCHEMA_LENGTH default to the current connection.
Bulk table examples are found in "Using Tables for Bulk Operations".
... O1 BINDNO PIC S9(9) COMP VALUE 2. 01 INDI PIC S9(4) COMP VALUE -1. 01 DATA PIC X(6) COMP VALUE "ignore". 01 BATCH PIC S9(9) COMP VALUE 1. ... EXEC SQL FOR :batch ALLOCATE DESCRIPTOR :BINDDES END-EXEC. EXEC SQL SET DESCRIPTOR GLOBAL :BINDDES COUNT = 3 END-EXEC. EXEC SQL FOR :batch SET DESCRIPTOR :BINDDES VALUE :BINDNO INDICATOR = :INDI, DATA = :DATA END-EXEC. ...
The PREPARE statement used in this method is the same as the PREPARE statement used in the Oracle dynamic SQL methods. An Oracle extension allows a quoted string for the SQL statement, as well as a variable.
EXEC SQL PREPARE statement_id FROM :sql_statement END-EXEC.
statement_id
This must not be declared; it is an undeclared SQL identifier associated with the prepared SQL statement.
sql_statement
A character string (a constant or a variable) holding the embedded SQL statement.
... 01 STATEMENT PIC X(255) VALUE "SELECT ENAME FROM emp WHERE deptno = :d". ... EXEC SQL PREPARE S1 FROM :STATEMENT END-EXEC.
This statement returns information about the input bind variables.
EXEC SQL DESCRIBE INPUT statement_id USING [SQL] DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} END-EXEC.
statement_id
The same as used in PREPARE and DESCRIBE OUTPUT. This must not be declared; it is a SQL identifier.
GLOBAL | LOCAL
GLOBAL means that the descriptor name is known to all program files. LOCAL means that it is known only in the file in which it is allocated. LOCAL is the default.
desc_nam
The descriptor name.
Only COUNT and NAME are implemented for bind variables in this version.
EXEC SQL DESCRIBE INPUT S1 USING SQL DESCRIPTOR GLOBAL :BINDDES END-EXEC. EXEC SQL DESCRIBE INPUT S2 USING DESCRIPTOR 'input' END-EXEC.
Use this statement to obtain information about the columns in a PREPARE statement. The ANSI syntax differs from the older syntax. The information which is stored in the SQL descriptor area is the number of values returned and associated information such as type, length, and name.
EXEC SQL DESCRIBE [OUTPUT] statement_id USING [SQL] DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} END-EXEC.
statement_id
The same as used in PREPARE. This must not be declared; it is a SQL identifier.
GLOBAL | LOCAL
GLOBAL means that the descriptor name is known to all program files. LOCAL means that it is known only in the file in which it is allocated. LOCAL is the default.
desc_nam
The descriptor name. Either a host variable preceded by a ":", or a single-quoted string.
OUTPUT is the default and can be omitted.
... 01 DESNAME PIC X(10) VALUE "SELDES". ... EXEC SQL DESCRIBE S1 USING SQL DESCRIPTOR 'SELDES' END-EXEC. * Or: EXEC SQL DESCRIBE OUTPUT S1 USING DESCRIPTOR :DESNAME END-EXEC.
EXECUTE matches input and output variables in a prepared SQL statement and then executes the statement. This ANSI version of EXECUTE differs from the older EXECUTE statement by allowing two descriptors in one statement to support DML RETURNING.
EXEC SQL [FOR [:]array_size] EXECUTE statement_id [USING [SQL] DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal}] [INTO [SQL] DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal}] END-EXEC.
array_size
The number of rows the statement will process.
statement_id
The same as used in PREPARE. This must not be declared; it is a SQL identifier. It can be a literal.
GLOBAL | LOCAL
GLOBAL means that the descriptor name is known to all program files. LOCAL means that it is known only in the file in which it is allocated. LOCAL is the default.
desc_nam
The descriptor name. Either a host variable preceded by a ":", or a single-quoted string.
The INTO clause implements the RETURNING clause for INSERT, UPDATE and DELETE (See "Inserting Rows" and succeeding pages).
EXEC SQL EXECUTE S1 USING SQL DESCRIPTOR GLOBAL :BINDDES END-EXEC. EXEC SQL EXECUTE S2 USING DESCRIPTOR :bv1 INTO DESCRIPTOR 'SELDES' END-EXEC.
Executes a literal or host variable character string containing the SQL statement.The ANSI SQL form of this statement is the same as in the older dynamic SQL:
EXEC SQL EXECUTE IMMEDIATE [:]sql_statement END-EXEC.
sql_statement
The SQL statement or PL/SQL block in a character string. Can be a host variable or a literal.
EXEC SQL EXECUTE IMMEDIATE :statement END-EXEC.
Declares a cursor that is associated with a statement which is a query. This is a form of the generic Declare Cursor statement.
EXEC SQL DECLARE cursor_name CURSOR FOR statement_id END-EXEC.
cursor_name
A cursor variable (a SQL identifier, not a host variable).
statement_id
An undeclared SQL identifier (the same as the one used in the PREPARE statement).
EXEC SQL DECLARE C1 CURSOR FOR S1 END-EXEC.
The OPEN statement associates input parameters with a cursor and then opens the cursor.
EXEC SQL [FOR [:]array_size] OPEN dyn_cursor [[USING [SQL] DESCRIPTOR [GLOBAL | LOCAL] desc_nam1] [INTO [SQL] DESCRIPTOR [GLOBAL | LOCAL] desc_nam2] ] END-EXEC.
array_size
This limit is less than or equal to number specified when the descriptor was allocated.
GLOBAL | LOCAL
GLOBAL means that the descriptor name is known to all program files. LOCAL means that it is known only in the file in which it is allocated. LOCAL is the default.
dyn_cursor
The cursor variable.
desc_nam1, desc_nam2
The optional descriptor names.
If the prepared statement associated with the cursor contains colons or question marks, a USING clause must be specified, or an error results at runtime. The INTO clause supports DML RETURNING (See "Inserting Rows" and succeeding sections on DELETE and UPDATE).
EXEC SQL OPEN C1 USING SQL DESCRIPTOR :BINDDES END-EXEC. EXEC SQL FOR :limit OPEN C2 USING DESCRIPTOR :b1, :b2 INTO SQL DESCRIPTOR :seldes END-EXEC.
Fetches a row for a cursor declared with a dynamic DECLARE statement.
EXEC SQL [FOR [:]array_size] FETCH cursor INTO [SQL] DESCRIPTOR [GLOBAL | LOCAL] {:desc_nam | string_literal} END-EXEC.
array_size
The number of rows the statement will process.
cursor
The dynamic cursor that was previously declared.
GLOBAL | LOCAL
GLOBAL means that the descriptor name is known to all program files. LOCAL means that it is known only in the file in which it is allocated. LOCAL is the default.
desc_nam
Descriptor name.
The optional array_size
in the FOR clause must be less than or equal to the number specified in the ALLOCATE DESCRIPTOR statement.
EXEC SQL FETCH FROM C1 INTO DESCRIPTOR 'SELDES' END-EXEC. EXEC SQL FOR :arsz FETCH C2 INTO DESCRIPTOR :DESC END-EXEC.
Closes a dynamic cursor. Syntax has not changed from the Oracle Method 4:
EXEC SQL CLOSE cursor END-EXEC.
cursor
The dynamic cursor that was previously declared.
EXEC SQL CLOSE C1 END-EXEC.
The ANSI dynamic SQL interface supports all the features supported by the Oracle dynamic Method 4, with these additions:
Restrictions in effect on ANSI dynamic SQL are:
The following ANSI SQL dynamic Method 4 program, SAMPLE12.PCO, is found in the demo directory. SAMPLE12 mimics SQL*Plus by prompting for SQL statements to be input by the user. Read the comments at the beginning for details of the program flow.
****************************************************************** * Sample Program 12: Dynamic SQL Method 4 using ANSI Dynamic SQL * * * * This program shows the basic steps required to use dynamic * * SQL Method 4 with ANSI Dynamic SQL. After logging on to * * ORACLE, the program prompts the user for a SQL statement, * * PREPAREs the statement, DECLAREs a cursor, checks for any * * bind variables using DESCRIBE INPUT, OPENs the cursor, and * * DESCRIBEs any select-list variables. If the input SQL * * statement is a query, the program FETCHes each row of data, * * then CLOSEs the cursor. * * use option dynamic=ansi when precompiling this sample. * ****************************************************************** IDENTIFICATION DIVISION. PROGRAM-ID. ANSIDYNSQL4. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. 01 USERNAME PIC X(20). 01 PASSWD PIC X(20). 01 BDSC PIC X(6) VALUE "BNDDSC". 01 SDSC PIC X(6) VALUE "SELDSC". 01 BNDCNT PIC S9(9) COMP. 01 SELCNT PIC S9(9) COMP. 01 BNDNAME PIC X(80). 01 BNDVAL PIC X(80). 01 SELNAME PIC X(80) VARYING. 01 SELDATA PIC X(80). 01 SELTYP PIC S9(4) COMP. 01 SELPREC PIC S9(4) COMP. 01 SELLEN PIC S9(4) COMP. 01 SELIND PIC S9(4) COMP. 01 DYN-STATEMENT PIC X(80). 01 BND-INDEX PIC S9(9) COMP. 01 SEL-INDEX PIC S9(9) COMP. 01 VARCHAR2-TYP PIC S9(4) COMP VALUE 1. 01 VAR-COUNT PIC 9(2). 01 ROW-COUNT PIC 9(4). 01 NO-MORE-DATA PIC X(1) VALUE "N". 01 TMPLEN PIC S9(9) COMP. 01 MAX-LENGTH PIC S9(9) COMP VALUE 80. EXEC SQL INCLUDE SQLCA END-EXEC. PROCEDURE DIVISION. START-MAIN. EXEC SQL WHENEVER SQLERROR GOTO SQL-ERROR END-EXEC. DISPLAY "USERNAME: " WITH NO ADVANCING. ACCEPT USERNAME. DISPLAY "PASSWORD: " WITH NO ADVANCING. ACCEPT PASSWD. EXEC SQL CONNECT :USERNAME IDENTIFIED BY :PASSWD END-EXEC. DISPLAY "CONNECTED TO ORACLE AS USER: ", USERNAME. * ALLOCATE THE BIND AND SELECT DESCRIPTORS. EXEC SQL ALLOCATE DESCRIPTOR :BDSC WITH MAX 20 END-EXEC. EXEC SQL ALLOCATE DESCRIPTOR :SDSC WITH MAX 20 END-EXEC. * GET A SQL STATEMENT FROM THE OPERATOR. DISPLAY "ENTER SQL STATEMENT WITHOUT TERMINATOR:". DISPLAY ">" WITH NO ADVANCING. ACCEPT DYN-STATEMENT. DISPLAY " ". * PREPARE THE SQL STATEMENT AND DECLARE A CURSOR. EXEC SQL PREPARE S1 FROM :DYN-STATEMENT END-EXEC. EXEC SQL DECLARE C1 CURSOR FOR S1 END-EXEC. * DESCRIBE BIND VARIABLES. EXEC SQL DESCRIBE INPUT S1 USING DESCRIPTOR :BDSC END-EXEC. EXEC SQL GET DESCRIPTOR :BDSC :BNDCNT = COUNT END-EXEC. IF BNDCNT < 0 DISPLAY "TOO MANY BIND VARIABLES." GO TO END-SQL ELSE DISPLAY "NUMBER OF BIND VARIABLES: " WITH NO ADVANCING MOVE BNDCNT TO VAR-COUNT DISPLAY VAR-COUNT * EXEC SQL SET DESCRIPTOR :BDSC COUNT = :BNDCNT END-EXEC END-IF. IF BNDCNT = 0 GO TO DESCRIBE-ITEMS. PERFORM SET-BND-DSC VARYING BND-INDEX FROM 1 BY 1 UNTIL BND-INDEX > BNDCNT. * OPEN THE CURSOR AND DESCRIBE THE SELECT-LIST ITEMS. DESCRIBE-ITEMS. EXEC SQL OPEN C1 USING DESCRIPTOR :BDSC END-EXEC. EXEC SQL DESCRIBE OUTPUT S1 USING DESCRIPTOR :SDSC END-EXEC. EXEC SQL GET DESCRIPTOR :SDSC :SELCNT = COUNT END-EXEC. IF SELCNT < 0 DISPLAY "TOO MANY SELECT-LIST ITEMS." GO TO END-SQL ELSE DISPLAY "NUMBER OF SELECT-LIST ITEMS: " WITH NO ADVANCING MOVE SELCNT TO VAR-COUNT DISPLAY VAR-COUNT DISPLAY " " * EXEC SQL SET DESCRIPTOR :SDSC COUNT = :SELCNT END-EXEC END-IF. * SET THE INPUT DESCRIPTOR IF SELCNT > 0 PERFORM SET-SEL-DSC VARYING SEL-INDEX FROM 1 BY 1 UNTIL SEL-INDEX > SELCNT DISPLAY " ". * FETCH EACH ROW AND PRINT EACH SELECT-LIST VALUE. IF SELCNT > 0 PERFORM FETCH-ROWS UNTIL NO-MORE-DATA = "Y". DISPLAY " " DISPLAY "NUMBER OF ROWS PROCESSED: " WITH NO ADVANCING. MOVE SQLERRD(3) TO ROW-COUNT. DISPLAY ROW-COUNT. * CLEAN UP AND TERMINATE. EXEC SQL CLOSE C1 END-EXEC. EXEC SQL DEALLOCATE DESCRIPTOR :BDSC END-EXEC. EXEC SQL DEALLOCATE DESCRIPTOR :SDSC END-EXEC. EXEC SQL ROLLBACK WORK RELEASE END-EXEC. DISPLAY " ". DISPLAY "HAVE A GOOD DAY!". DISPLAY " ". STOP RUN. * DISPLAY ORACLE ERROR MESSAGE AND CODE. SQL-ERROR. DISPLAY " ". DISPLAY SQLERRMC. END-SQL. EXEC SQL WHENEVER SQLERROR CONTINUE END-EXEC. EXEC SQL ROLLBACK WORK RELEASE END-EXEC. STOP RUN. * PERFORMED SUBROUTINES BEGIN HERE: * SET A BIND-LIST ELEMENT'S ATTRIBUTE * LET THE USER FILL IN THE BIND VARIABLES AND * REPLACE THE 0S DESCRIBED INTO THE DATATYPE FIELDS OF THE * BIND DESCRIPTOR WITH 1S TO AVOID AN "INVALID DATATYPE" * ORACLE ERROR SET-BND-DSC. EXEC SQL GET DESCRIPTOR :BDSC VALUE :BND-INDEX :BNDNAME = NAME END-EXEC. DISPLAY "ENTER VALUE FOR ", BNDNAME. ACCEPT BNDVAL. EXEC SQL SET DESCRIPTOR :BDSC VALUE :BND-INDEX TYPE = :VARCHAR2-TYP, LENGTH = :MAX-LENGTH, DATA = :BNDVAL END-EXEC. * SET A SELECT-LIST ELEMENT'S ATTRIBUTES SET-SEL-DSC. MOVE SPACES TO SELNAME-ARR. EXEC SQL GET DESCRIPTOR :SDSC VALUE :SEL-INDEX :SELNAME = NAME, :SELTYP = TYPE, :SELPREC = PRECISION, :SELLEN = LENGTH END-EXEC. * DISPLAY COLUMN HEADING. DISPLAY SELNAME-ARR(1:SELNAME-LEN), " " WITH NO ADVANCING. * IF DATATYPE IS DATE, LENGTHEN TO 9 CHARACTERS. IF SELTYP = 12 MOVE 9 TO SELLEN. * IF DATATYPE IS NUMBER, SET LENGTH TO PRECISION. MOVE 0 TO TMPLEN. IF SELTYP = 2 AND SELPREC = 0 MOVE 40 TO TMPLEN. IF SELTYP = 2 AND SELPREC > 0 ADD 2 TO SELPREC MOVE SELPREC TO TMPLEN. IF SELTYP = 2 IF TMPLEN > MAX-LENGTH DISPLAY "COLUMN VALUE TOO LARGE FOR DATA BUFFER." GO TO END-SQL ELSE MOVE TMPLEN TO SELLEN. * COERCE DATATYPES TO VARCHAR2. MOVE 1 TO SELTYP. EXEC SQL SET DESCRIPTOR :SDSC VALUE :SEL-INDEX TYPE = :SELTYP, LENGTH = :SELLEN END-EXEC. * FETCH A ROW AND PRINT THE SELECT-LIST VALUE. FETCH-ROWS. EXEC SQL FETCH C1 INTO DESCRIPTOR :SDSC END-EXEC. IF SQLCODE NOT = 0 MOVE "Y" TO NO-MORE-DATA. IF SQLCODE = 0 PERFORM PRINT-COLUMN-VALUES VARYING SEL-INDEX FROM 1 BY 1 UNTIL SEL-INDEX > SELCNT DISPLAY " ". * PRINT A SELECT-LIST VALUE. PRINT-COLUMN-VALUES. MOVE SPACES TO SELDATA. EXEC SQL GET DESCRIPTOR :SDSC VALUE :SEL-INDEX :SELDATA = DATA, :SELIND = INDICATOR, :SELLEN = RETURNED_LENGTH END-EXEC. IF (SELIND = -1) DISPLAY "NULL " WITH NO ADVANCING ELSE DISPLAY SELDATA(1:SELLEN), " " WITH NO ADVANCING.