MDAC 2.5 SDK - ODBC Programmer's Reference
Chapter 21: ODBC API Reference


 

SQLAllocHandle

Conformance

Version Introduced: ODBC 3.0
Standards Compliance: ISO 92

Summary

SQLAllocHandle allocates an environment, connection, statement, or descriptor handle.

Note   This function is a generic function for allocating handles that replaces the ODBC 2.0 functions SQLAllocConnect, SQLAllocEnv, and SQLAllocStmt. To allow applications calling SQLAllocHandle to work with ODBC 2.x drivers, a call to SQLAllocHandle is mapped in the Driver Manager to SQLAllocConnect, SQLAllocEnv, or SQLAllocStmt, as appropriate. For more information, see "Comments." For more information about what the Driver Manager maps this function to when an ODBC 3.x application is working with an ODBC 2.x driver, see "Mapping Replacement Functions for Backward Compatibility of Applications" in Chapter 17, "Programming Considerations."

Syntax

SQLRETURN SQLAllocHandle(
     SQLSMALLINT     HandleType,
     SQLHANDLE     InputHandle,
     SQLHANDLE *     OutputHandlePtr);

Arguments

HandleType

[Input]
The type of handle to be allocated by SQLAllocHandle. Must be one of the following values:

SQL_HANDLE_ENV
SQL_HANDLE_DBC
SQL_HANDLE_STMT
SQL_HANDLE_DESC

InputHandle

[Input]
The input handle in whose context the new handle is to be allocated. If HandleType is SQL_HANDLE_ENV, this is SQL_NULL_HANDLE. If HandleType is SQL_HANDLE_DBC, this must be an environment handle, and if it is SQL_HANDLE_STMT or SQL_HANDLE_DESC, it must be a connection handle.

OutputHandlePtr

[Output]
Pointer to a buffer in which to return the handle to the newly allocated data structure.

Returns

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_INVALID_HANDLE, or SQL_ERROR.

When allocating a handle other than an environment handle, if SQLAllocHandle returns SQL_ERROR, it sets OutputHandlePtr to SQL_NULL_HDBC, SQL_NULL_HSTMT, or SQL_NULL_HDESC, depending on the value of HandleType, unless the output argument is a null pointer. The application can then obtain additional information from the diagnostic data structure associated with the handle in the InputHandle argument.

Environment Handle Allocation Errors

Environment allocation occurs both within the Driver Manager and within each driver. The error returned by SQLAllocHandle with a HandleType of SQL_HANDLE_ENV depends on the level in which the error occurred.

If the Driver Manager cannot allocate memory for *OutputHandlePtr when SQLAllocHandle with a HandleType of SQL_HANDLE_ENV is called, or the application provides a null pointer for OutputHandlePtr, SQLAllocHandle returns SQL_ERROR. The Driver Manager sets *OutputHandlePtr to SQL_NULL_HENV (unless the application provided a null pointer, which returns SQL_ERROR). There is no handle with which to associate additional diagnostic information. (If the driver has additional diagnostic information, it will put the information on a skeletal handle that it allocates; the Driver Manager will read the information from the diagnostic structure associated with this handle.)

The Driver Manager does not call the driver-level environment handle allocation function until the application calls SQLConnect, SQLBrowseConnect, or SQLDriverConnect. If an error occurs in the driver-level SQLAllocHandle function, then the Driver Manager–level SQLConnect, SQLBrowseConnect, or SQLDriverConnect function returns SQL_ERROR. The diagnostic data structure contains SQLSTATE IM004 (Driver's SQLAllocHandle failed), followed by a driver-specific SQLSTATE value from the driver. For example, SQLSTATE HY001 (Memory allocation error) indicates that the Driver Manager's call to the driver-level SQLAllocHandle returned SQL_ERROR. The error is returned on a connection handle.

For additional information about the flow of function calls between the Driver Manager and a driver, see SQLConnect.

Diagnostics

When SQLAllocHandle returns SQL_ERROR or SQL_SUCCESS_WITH_INFO, an associated SQLSTATE value may be obtained by calling SQLGetDiagRec with the appropriate HandleType and Handle set to the value of InputHandle. SQL_SUCCESS_WITH_INFO (but not SQL_ERROR) can be returned for the OutputHandle argument. The following table lists the SQLSTATE values commonly returned by SQLAllocHandle and explains each one in the context of this function; the notation "(DM)" precedes the descriptions of SQLSTATEs returned by the Driver Manager. The return code associated with each SQLSTATE value is SQL_ERROR, unless noted otherwise.

SQLSTATE Error Description
01000 General warning Driver-specific informational message. (Function returns SQL_SUCCESS_WITH_INFO.)
08003 Connection does not exist (DM) The HandleType argument was SQL_HANDLE_STMT or SQL_HANDLE_DESC, but the connection specified by the InputHandle argument was not open. The connection process must be completed successfully (and the connection must be open) for the driver to allocate a statement or descriptor handle.
HY000 General error An error occurred for which there was no specific SQLSTATE and for which no implementation-specific SQLSTATE was defined. The error message returned by SQLGetDiagRec in the *MessageText buffer describes the error and its cause.
HY001 Memory allocation
error
(DM) The Driver Manager was unable to allocate memory for the specified handle.

The driver was unable to allocate memory for the specified handle.

HY009 Invalid use of null pointer (DM) The OutputHandlePtr argument was a null pointer.
HY010 Function sequence
error
(DM) The HandleType argument was SQL_HANDLE_DBC, and SQLSetEnvAttr has not been called to set the SQL_ODBC_VERSION environment attribute.
HY013 Memory management error The HandleType argument was SQL_HANDLE_DBC, SQL_HANDLE_STMT, or SQL_HANDLE_DESC; and the function call could not be processed because the underlying memory objects could not be accessed, possibly because of low memory conditions.
HY014 Limit on the number of handles exceeded The driver-defined limit for the number of handles that can be allocated for the type of handle indicated by the HandleType argument has been reached.
HY092 Invalid attribute/option identifier (DM) The HandleType argument was not: SQL_HANDLE_ENV, SQL_HANDLE_DBC, SQL_HANDLE_STMT, or SQL_HANDLE_DESC.
HYC00 Optional feature not implemented The HandleType argument was SQL_HANDLE_DESC and the driver was an ODBC 2.x driver.
HYT01 Connection timeout expired The connection timeout period expired before the data source responded to the request. The connection timeout period is set through SQLSetConnectAttr, SQL_ATTR_CONNECTION_TIMEOUT.
IM001 Driver does not support this function (DM) The HandleType argument was SQL_HANDLE_STMT, and the driver was not a valid ODBC driver.

(DM) The HandleType argument was SQL_HANDLE_DESC, and the driver does not support allocating a descriptor handle.


Comments

SQLAllocHandle is used to allocate handles for environments, connections, statements, and descriptors, as described in the following sections. For general information about handles, see "Handles" in Chapter 4, "ODBC Fundamentals."

More than one environment, connection, or statement handle can be allocated by an application at a time if multiple allocations are supported by the driver. In ODBC, no limit is defined on the number of environment, connection, statement, or descriptor handles that can be allocated at any one time. Drivers may impose a limit on the number of a certain type of handle that can be allocated at a time; for more information, see the driver documentation.

If the application calls SQLAllocHandle with *OutputHandlePtr set to an environment, connection, statement, or descriptor handle that already exists, the driver overwrites the information associated with the handle, unless the application is using connection pooling (see "Allocating an Environment Attribute for Connection Pooling" later in this section). The Driver Manager does not check to see whether the handle entered in *OutputHandlePtr is already in use, nor does it check the previous contents of a handle before overwriting them.

Note   It is incorrect ODBC application programming to call SQLAllocHandle twice with the same application variable defined for *OutputHandlePtr without calling SQLFreeHandle to free the handle before reallocating it. Overwriting ODBC handles in such a manner can lead to inconsistent behavior or errors on the part of ODBC drivers.

On operating systems that support multiple threads, applications can use the same environment, connection, statement, or descriptor handle on different threads. Drivers must therefore support safe, multithread access to this information; one way of achieving this, for example, is through the use of a critical section or a semaphore. For more information about threading, see "Multithreading" in Chapter 17, "Programming Considerations."

SQLAllocHandle does not set the SQL_ATTR_ODBC_VERSION environment attribute when it is called to allocate an environment handle; the environment attribute must be set by the application, or SQLSTATE HY010 (Function sequence error) will be returned when SQLAllocHandle is called to allocate a connection handle.

For standards-compliant applications, SQLAllocHandle is mapped to SQLAllocHandleStd at compile time. The difference between these two functions is that SQLAllocHandleStd sets the SQL_ATTR_ODBC_VERSION environment attribute to SQL_OV_ODBC3 when it is called with the HandleType argument set to SQL_HANDLE_ENV. This is done because standards-compliant applications are always ODBC 3.x applications. Moreover, the standards do not require the application version to be registered. This is the only difference between these two functions; otherwise, they are identical.

Allocating an Environment Handle

An environment handle provides access to global information such as valid connection handles and active connection handles. For general information about environment handles, see "Environment Handles" in Chapter 4, "ODBC Fundamentals."

To request an environment handle, an application calls SQLAllocHandle with a HandleType of SQL_HANDLE_ENV and an InputHandle of SQL_NULL_HANDLE. The driver allocates memory for the environment information and passes the value of the associated handle back in the *OutputHandlePtr argument. The application passes the *OutputHandle value in all subsequent calls that require an environment handle argument. For more information, see "Allocating the Environment Handle" in Chapter 6, "Connecting to a Data Source or Driver."

Under a Driver Manager's environment handle, if there already exists a driver's environment handle, then SQLAllocHandle with a HandleType of SQL_HANDLE_ENV is not called in that driver when a connection is made, only SQLAllocHandle with a HandleType of SQL_HANDLE_DBC. If a driver's environment handle does not exist under the Driver Manager's environment handle, then both SQLAllocHandle with a HandleType of SQL_HANDLE_ENV and SQLAllocHandle with a HandleType of SQL_HANDLE_DBC are called in the driver when the first connection handle of the environment is connected to the driver.

When the Driver Manager processes the SQLAllocHandle function with a HandleType of SQL_HANDLE_ENV, it checks the Trace keyword in the [ODBC] section of the system information. If it is set to 1, the Driver Manager enables tracing for the current application on a computer running Microsoft® Windows® 95/98, Microsoft Windows NT® Server/Windows 2000 Server, or Microsoft Windows NT Workstation/Windows 2000 Professional. If the trace flag is set, tracing starts when the first environment handle is allocated and ends when the last environment handle is freed. For more information, see Chapter 19, "Configuring Data Sources."

After allocating an environment handle, an application must call SQLSetEnvAttr on the environment handle to set the SQL_ATTR_ODBC_VERSION environment attribute. If this attribute is not set before SQLAllocHandle is called to allocate a connection handle on the environment, the call to allocate the connection will return SQLSTATE HY010 (Function sequence error). For more information, see "Declaring the Application's ODBC Version" in Chapter 6, "Connecting to a Data Source or Driver."

Allocating Shared Environments for Connection Pooling

Environments can be shared among multiple components on a single process. A shared environment can be used by more than one component simultaneously. When a component uses a shared environment, it can use pooled connections, which allow it to allocate and use an existing connection without re-creating that connection.

Before allocating a shared environment to be used for connection pooling, an application must call SQLSetEnvAttr to set the SQL_ATTR_CONNECTION_POOLING environment attribute to SQL_CP_ONE_PER_DRIVER or SQL_CP_ONE_PER_HENV. SQLSetEnvAttr in this case is called with EnvironmentHandle set to null, which makes the attribute a process-level attribute.

After connection pooling has been enabled, an application calls SQLAllocHandle with the HandleType argument set to SQL_HANDLE_ENV. The environment allocated by this call will be an implicit shared environment because connection pooling has been enabled. (For more information about connection pooling, see SQLConnect.)

When a shared environment is allocated, the environment to be used is not determined until SQLAllocHandle with a HandleType of SQL_HANDLE_DBC is called. At that point, the Driver Manager attempts to find an existing environment that matches the environment attributes requested by the application. If no such environment exists, one is created as a shared environment. The Driver Manager maintains a reference count for each shared environment; the count is set to 1 when the environment is first created. If a matching environment is found, the handle of that environment is returned to the application and the reference count is incremented. An environment handle allocated this way can be used in any ODBC function that accepts an environment handle as an input argument.

Allocating a Connection Handle

A connection handle provides access to information such as the valid statement and descriptor handles on the connection and whether a transaction is currently open. For general information about connection handles, see "Connection Handles" in Chapter 4, "ODBC Fundamentals."

To request a connection handle, an application calls SQLAllocHandle with a HandleType of SQL_HANDLE_DBC. The InputHandle argument is set to the environment handle that was returned by the call to SQLAllocHandle that allocated that handle. The driver allocates memory for the connection information and passes the value of the associated handle back in *OutputHandlePtr. The application passes the *OutputHandlePtr value in all subsequent calls that require a connection handle. For more information, see "Allocating a Connection Handle" in Chapter 6, "Connecting to a Data Source or Driver."

The Driver Manager processes the SQLAllocHandle function and calls the driver's SQLAllocHandle function when the application calls SQLConnect, SQLBrowseConnect, or SQLDriverConnect. (For more information, see SQLConnect.)

If the SQL_ATTR_ODBC_VERSION environment attribute is not set before SQLAllocHandle is called to allocate a connection handle on the environment, the call to allocate the connection will return SQLSTATE HY010 (Function sequence error).

When an application calls SQLAllocHandle with the InputHandle argument set to SQL_HANDLE_DBC and also set to a shared environment handle, the Driver Manager attempts to find an existing shared environment that matches the environment attributes set by the application. If no such environment exists, one is created, with a reference count (maintained by the Driver Manager) of 1. If a matching shared environment is found, that handle is returned to the application and its reference count is incremented.

The actual connection to be used is not determined by the Driver Manager until SQLConnect or SQLDriverConnect is called. The Driver Manager uses the connection options in the call to SQLConnect (or the connection keywords in the call to SQLDriverConnect) and the connection attributes set after connection allocation to determine which connection in the pool should be used. For more information, see SQLConnect.

Allocating a Statement Handle

A statement handle provides access to statement information, such as error messages, the cursor name, and status information for SQL statement processing. For general information about statement handles, see "Statement Handles" in Chapter 4, "ODBC Fundamentals."

To request a statement handle, an application connects to a data source and then calls SQLAllocHandle prior to submitting SQL statements. In this call, HandleType should be set to SQL_HANDLE_STMT and InputHandle should be set to the connection handle that was returned by the call to SQLAllocHandle that allocated that handle. The driver allocates memory for the statement information, associates the statement handle with the specified connection, and passes the value of the associated handle back in *OutputHandlePtr. The application passes the *OutputHandlePtr value in all subsequent calls that require a statement handle. For more information, see "Allocating a Statement Handle" in Chapter 9, "Executing Statements."

When the statement handle is allocated, the driver automatically allocates a set of four descriptors and assigns the handles for these descriptors to the SQL_ATTR_APP_ROW_DESC, SQL_ATTR_APP_PARAM_DESC, SQL_ATTR_IMP_ROW_DESC, and SQL_ATTR_IMP_PARAM_DESC statement attributes. These are called implicitly allocated descriptors. To allocate an application descriptor explicitly, see the following section, "Allocating a Descriptor Handle."

Allocating a Descriptor Handle

When an application calls SQLAllocHandle with a HandleType of SQL_HANDLE_DESC, the driver allocates an application descriptor. These are called explicitly allocated descriptors. The application directs a driver to use an explicitly allocated application descriptor in place of an automatically allocated one for a given statement handle by calling the SQLSetStmtAttr function with the SQL_ATTR_APP_ROW_DESC or SQL_ATTR_APP_PARAM_DESC attribute. An implementation descriptor cannot be allocated explicitly, nor can an implementation descriptor be specified in an SQLSetStmtAttr function call.

Explicitly allocated descriptors are associated with a connection handle rather than a statement handle (as automatically allocated descriptors are). Descriptors remain allocated only when an application is actually connected to the database. Because explicitly allocated descriptors are associated with a connection handle, an application can associate an explicitly allocated descriptor with more than one statement within a connection. An implicitly allocated application descriptor, on the other hand, cannot be associated with more than one statement handle. (It cannot be associated with any statement handle other than the one that it was allocated for.) Explicitly allocated descriptor handles can be freed explicitly either by the application or by calling SQLFreeHandle with a HandleType of SQL_HANDLE_DESC, or implicitly when the connection is closed.

When the explicitly allocated descriptor is freed, the implicitly allocated descriptor is once again associated with the statement. (The SQL_ATTR_APP_ROW_DESC or SQL_ATTR_APP_PARAM_DESC attribute for that statement is once again set to the implicitly allocated descriptor handle.) This is true for all statements that were associated with the explicitly allocated descriptor on the connection.

For more information about descriptors, see Chapter 13, "Descriptors."

Code Example

See SQLBrowseConnect, SQLConnect, and SQLSetCursorName.

Related Functions

For information about See
Executing an SQL statement SQLExecDirect
Executing a prepared SQL statement SQLExecute
Freeing an environment, connection, statement, or descriptor handle SQLFreeHandle
Preparing a statement for execution SQLPrepare
Setting a connection attribute SQLSetConnectAttr
Setting a descriptor field SQLSetDescField
Setting an environment attribute SQLSetEnvAttr
Setting a statement attribute SQLSetStmtAttr