Descriptor manipulation with descriptor handles in CLI applications

You can manipulate descriptors by using descriptor handles. If your descriptor does not use descriptor handles, you can use CLI functions instead.

The handle of an explicitly allocated descriptor is returned in the OutputHandlePtr argument when the application calls SQLAllocHandle() to allocate the descriptor. The handle of an implicitly allocated descriptor is obtained by calling SQLGetStmtAttr() with either SQL_ATTR_IMP_PARAM_DESC or SQL_ATTR_IMP_ROW_DESC.

Retrieval of descriptor field values

The CLI function SQLGetDescField() can be used to obtain a single field of a descriptor record. SQLGetDescRec() retrieves the settings of multiple descriptor fields that affect the data type and storage of column or parameter data.

Setting of descriptor field values

Two methods are available for setting descriptor fields: one field at a time or multiple fields at once.

Setting of individual fields

Some fields of a descriptor are read-only, but others can be set using the function SQLSetDescField(). Refer to the list of header and record fields in the descriptor FieldIdentifier values documentation.

Record and header fields are set differently using SQLSetDescField() as follows:
Header fields
The call to SQLSetDescField() passes the header field to be set and a record number of 0. The record number is ignored since there is only one header field per descriptor. In this case the record number of 0 does not indicate the bookmark field.
Record fields
The call to SQLSetDescField() passes the record field to be set and a record number of 1 or higher, or 0 to indicate the bookmark field.

The application must follow the sequence of setting descriptor fields described in the SQLSetDescField() documentation when setting individual fields of a descriptor. Setting some fields will cause CLI to automatically set other fields. A consistency check will take place after the application follows the defined steps. This will ensure that the values in the descriptor fields are consistent.

If a function call that would set a descriptor fails, the content of the descriptor fields are undefined after the failed function call.

Setting of multiple fields

A predefined set of descriptor fields can be set with one call rather than setting individual fields one at a time. SQLSetDescRec() sets the following fields for a single column or parameter:
  • SQL_DESC_TYPE
  • SQL_DESC_OCTET_LENGTH
  • SQL_DESC_PRECISION
  • SQL_DESC_SCALE
  • SQL_DESC_DATA_PTR
  • SQL_DESC_OCTET_LENGTH_PTR
  • SQL_DESC_INDICATOR_PTR
(SQL_DESC_DATETIME_INTERVAL_CODE is also defined by ODBC but is not supported by CLI.)
For example, all of the descriptor fields are set with the following call:
    /* dbuse.c */
    /* ... */
    rc = SQLSetDescRec(hARD, 1, type, 0,
                     length, 0, 0, &id_no, &datalen, NULL);

Copying of descriptors

One benefit of descriptors is the fact that a single descriptor can be used for multiple purposes. For instance, an ARD on one statement handle can be used as an APD on another statement handle.

There will be other instances, however, where the application will want to make a copy of the original descriptor, then modify certain fields. In this case SQLCopyDesc() is used to overwrite the fields of an existing descriptor with the values from another descriptor. Only fields that are defined for both the source and target descriptors are copied (with the exception of the SQL_DESC_ALLOC_TYPE field which cannot be changed).

Fields can be copied from any type of descriptor, but can only be copied to an application descriptor (APD or ARD) or an IPD. Fields cannot be copied to an IRD. The descriptor's allocation type will not be changed by the copy procedure (again, the SQL_DESC_ALLOC_TYPE field cannot be changed).