Descriptor allocation and freeing

Descriptors can be allocated implicitly or explicitly. The implicitly allocated descriptors are freed implicitly when an object, such as statement handle, is freed. The descriptors can be explicitly allocated only after database connection is established.
Descriptors are allocated in one of two ways:
Implicitly allocated descriptors
When a statement handle is allocated, a set of four descriptors are implicitly allocated. When the statement handle is freed, all implicitly allocated descriptors on that handle are freed as well.
To obtain handles to these implicitly allocated descriptors an application can call SQLGetStmtAttr(), passing the statement handle and an Attribute value of:
  • SQL_ATTR_APP_PARAM_DESC (APD)
  • SQL_ATTR_APP_ROW_DESC (ARD)
  • SQL_ATTR_IMP_PARAM_DESC (IPD)
  • SQL_ATTR_IMP_ROW_DESC (IRD)
The following example gives access to the statement's implicitly allocated implementation parameter descriptor:
    /* dbuse. c */
    /* ... */
    sqlrc = SQLGetStmtAttr ( hstmt,
                             SQL_ATTR_IMP_PARAM_DESC,
                             &hIPD,
                             SQL_IS_POINTER,
                             NULL);
Note: The descriptors whose handles are obtained in this manner will still be freed when the statement for which they were allocated is freed.
Explicitly allocated descriptors
An application can explicitly allocate application descriptors. It is not possible, however, to allocate implementation descriptors.
An application descriptor can be explicitly allocated any time the application is connected to the database. To explicitly allocate the application descriptor, call SQLAllocHandle() with a HandleType of SQL_HANDLE_DESC. The following example explicitly allocates an application row descriptor:
    rc = SQLAllocHandle( SQL_HANDLE_DESC, hdbc, &hARD ) ;
To use an explicitly allocated application descriptor instead of a statement's implicitly allocated descriptor, call SQLSetStmtAttr(), and pass the statement handle, the descriptor handle, and an Attribute value of either:
  • SQL_ATTR_APP_PARAM_DESC (APD), or
  • SQL_ATTR_APP_ROW_DESC (ARD)
When there are explicitly and implicitly allocated descriptors, the explicitly specified one is used. An explicitly allocated descriptor can be associated with more than one statement.

Field initialization

When an application row descriptor is allocated, its fields are initialized to the values listed in the descriptor header and record field initialization values documentation. The SQL_DESC_TYPE field is set to SQL_DEFAULT which provides for a standard treatment of database data for presentation to the application. The application may specify different treatment of the data by setting fields of the descriptor record.

The initial value of the SQL_DESC_ARRAY_SIZE header field is 1. To enable multirow fetch, the application can set this value in an ARD to the number of rows in a rowset.

There are no default values for the fields of an IRD. The fields are set when there is a prepared or executed statement.

The following fields of an IPD are undefined until a call to SQLPrepare() automatically populates them:
  • SQL_DESC_CASE_SENSITIVE
  • SQL_DESC_FIXED_PREC_SCALE
  • SQL_DESC_TYPE_NAME
  • SQL_DESC_DESC_UNSIGNED
  • SQL_DESC_LOCAL_TYPE_NAME

Automatic population of the IPD

There are times when the application will need to discover information about the parameters of a prepared SQL statement. A good example is when a dynamically generated query is prepared; the application will not know anything about the parameters in advance. If the application enables automatic population of the IPD, by setting the SQL_ATTR_ENABLE_AUTO_IPD statement attribute to SQL_TRUE (using SQLSetStmtAttr()), then the fields of the IPD are automatically populated to describe the parameter. This includes the data type, precision, scale, and so on (the same information that SQLDescribeParam() returns). The application can use this information to determine if data conversion is required, and which application buffer is the most appropriate to bind the parameter to.

Automatic population of the IPD involves increased resource usage. If it is not necessary for this information to be automatically gathered by the CLI driver then the SQL_ATTR_ENABLE_AUTO_IPD statement attribute should be set to SQL_FALSE.

When automatic population of the IPD is active, each call to SQLPrepare() causes the fields of the IPD to be updated. The resulting descriptor information can be retrieved by calling the following functions:
  • SQLGetDescField()
  • SQLGetDescRec()
  • SQLDescribeParam()

Freeing of descriptors

Explicitly allocated descriptors
When an explicitly allocated descriptor is freed, all statement handles to which the freed descriptor applied automatically revert to the original descriptors implicitly allocated for them.
Explicitly allocated descriptors can be freed in one of two ways:
  • by calling SQLFreeHandle()with a HandleType of SQL_HANDLE_DESC
  • by freeing the connection handle that the descriptor is associated with
Implicitly allocated descriptors
An implicitly allocated descriptor can be freed in one of the following ways:
  • by calling SQLDisconnect() which drops any statements or descriptors open on the connection
  • by calling SQLFreeHandle() with a HandleType of SQL_HANDLE_STMT to free the statement handle and all of the implicitly allocated descriptors associated with the statement
An implicitly allocated descriptor cannot be freed by calling SQLFreeHandle() with a HandleType of SQL_HANDLE_DESC.