|
Your ESQL/C program can manipulate a system-descriptor area with the SQL statements that Figure 16-1 summarizes.
Figure 16-1
To allocate memory for a system-descriptor area, use the ALLOCATE DESCRIPTOR statement. This statement performs the following tasks:
Important: ALLOCATE DESCRIPTOR does not allocate memory for column data (DATA field). This memory is allocated by the DESCRIBE statement on an as-needed basis. For more information, refer to the next section.
The DESCRIBE...USING SQL DESCRIPTOR statement initializes the system-descriptor area with information about the prepared statement. This statement takes the following actions:
As noted earlier, the DESCRIBE statement provides information about the columns of a column list. Therefore, you usually use this statement after a SELECT (without an INTO TEMP clause), INSERT, or EXECUTE FUNCTION statement was prepared.
When you use the system-descriptor area to hold an input parameter, you cannot use DESCRIBE to initialize the system-descriptor area. Your code must define the input parameters with the SET DESCRIPTOR statement to explicitly set the appropriate fields of the system-descriptor area. For more information, see Specifying Input Parameter Values.
When you use a system-descriptor area to hold columns of prepared SQL statements, the ALLOCATE DESCRIPTOR statement allocates memory for the item descriptors of each column and the DESCRIBE...USING SQL DESCRIPTOR statement allocates memory for the DATA field of each item descriptor.
However, the DESCRIBE...USING SQL DESCRIPTOR statement does not allocate memory for the DATA field of a system-descriptor area when you describe a prepared SELECT statement that fetches data from a column into a host variable of type lvarchar.
Before you fetch lvarchar data into the system-descriptor area, you must explicitly assign memory to the DATA field to hold the column value, as follows:
The following code fragment shows the basic steps to allocate memory for an LVARCHAR column called lvarch_col in the table1 table:
The preceding code fragment does not perform exception handling.
The following SQL statements allow your program to access the fields of the system-descriptor area:
To assign values to the system-descriptor-area fields, use the SET DESCRIPTOR statement. You can use the SET DESCRIPTOR statement to:
Informix provides data-type constants in the sqltypes.h header file to identify the data type of a column in the TYPE field (and optionally the ITYPE field) of a system-descriptor area. However, you cannot assign a data-type constant directly in a SET DESCRIPTOR statement. Instead, assign the constant value to an integer host variable and specify this variable in the SET DESCRIPTOR statement, as follows:
For more information on the data-type constants, see Determining the Data Type of a Column. For more information about how to set individual system-descriptor fields, see the entry for the SET DESCRIPTOR statement in the Informix Guide to SQL: Syntax.
Using an lvarchar Pointer Host Variable with a DescriptorIf you use an lvarchar pointer host variable with a FETCH or PUT statement that uses a system descriptor area, you must explicitly set the type to 124 (CLVCHARPTRTYPE from incl/esql/sqltypes.h) in the SET DESCRIPTOR statement. The following example illustrates:
The GET DESCRIPTOR statement obtains values from the system-descriptor-area fields. You can use the GET DESCRIPTOR statement to:
The data type of the host variable must be compatible with the type of the associated system-descriptor area field. When you interpret the TYPE field, make sure that you use the data type values that match your environment. For some data types, X/Open values differ from Informix values. For more information, see Determining the Data Type of a Column.
For more information about how to get individual system-descriptor fields, see the entry for the GET DESCRIPTOR statement in the Informix Guide to SQL: Syntax.
Because the DESCRIBE...USING SQL DESCRIPTOR statement does not analyze a WHERE clause, your program must store the number, data types, and values of the input parameters in the fields of the system-descriptor area to explicitly describe these parameters. For general information on how to define input parameters dynamically, see page 15-28.
When you execute a parameterized statement, you must specify the system-descriptor area as the location of input parameter values with the USING SQL DESCRIPTOR clause, as follows:
When you create a SELECT statement dynamically, you cannot use the INTO host_var clause of FETCH because you cannot name the host variables in the prepared statement. To fetch column values into a system-descriptor area, use the USING SQL DESCRIPTOR clause of FETCH instead of the INTO clause. The FETCH...USING SQL DESCRIPTOR statement puts each column value into the DATA field of its item descriptor.
Use of the FETCH...USING SQL DESCRIPTOR statement assumes the existence of a cursor associated with the prepared statement. You must always use a cursor for SELECT statements and cursory functions (EXECUTE FUNCTION statements that return multiple rows). However, if the SELECT (or EXECUTE FUNCTION) returns only one row, you can omit the cursor and retrieve the column values into a system-descriptor area with the EXECUTE...INTO SQL DESCRIPTOR statement.
Warning: If you execute a SELECT statement or user-defined function that returns more than one row and do not associate the statement with a cursor, your program generates a runtime error. When you associate a singleton SELECT (or EXECUTE FUNCTION) statement with a cursor, ESQL/C does not generate an error. Therefore, it is a good practice to always associate a dynamic SELECT or EXECUTE FUNCTION statement with a cursor and to use a FETCH...USING SQL DESCRIPTOR statement to retrieve the column values from this cursor into the system-descriptor area.
Once the column values are in the system-descriptor area, you can use the GET DESCRIPTOR statement to transfer these values from their DATA fields to the appropriate host variables. You must use the LENGTH and TYPE fields to determine, at runtime, the data types for these host variables. You might need to perform data type or length conversions between the SQL data types in the TYPE fields and the ESQL/C data types that are needed for host variables that hold the return value.
For more information on how to execute SELECT statements dynamically, see Handling an Unknown Select List. For more information on how to execute user-defined functions dynamically, see Handling Unknown Return Values.
The DEALLOCATE DESCRIPTOR statement deallocates, or frees, memory that the specified system-descriptor area uses. The freed memory includes memory used by the item descriptors to hold data (in the DATA fields). Make sure you deallocate a system-descriptor area only after you no longer have need of it. A deallocated system-descriptor area cannot be reused.
For information about how to free other program resources, see Freeing Resources. For more information about DEALLOCATE DESCRIPTOR, see the Informix Guide to SQL: Syntax.