This chapter describes the general characteristics of ODBC functions, determining driver conformance levels, the role of the Driver Manager, ODBC function arguments, and the values ODBC functions return.
Each SOLID SQL API and ODBC function name starts with the prefix "SQL." Each function accepts one or more arguments. Arguments are defined as input (to the driver) or output (from the the driver).
C programs that call ODBC functions must include the SQL.H, SQLEXT.H, and WINDOWS.H header files. These files define Windows and ODBC constants and types and provide function prototypes for all ODBC functions.
C programs that call SOLID SQL API functions must include the CLI0CORE.H, CLI0DEFS.H, CLI0ENV.H and CLI01EXT1.H header files. These files define constants and types and provide function prototypes for all SOLID SQL API functions.
ODBC defines conformance levels for drivers in two areas: the ODBC API and the ODBC SQL grammar (which includes the ODBC SQL data types). These levels establish standard sets of functionality. By inquiring the conformance levels supported by a driver, an application can easily determine if the driver provides the necessary functionality. For a complete discussion of ODBC conformance levels, see "ODBC Conformance Levels" in Chapter 1, "ODBC Theory of Operation."
Note The following sections refer to SQLGetInfo and SQLGetTypeInfo, which are part of the Level 1 API conformance level. Although it is strongly recommended that drivers support this conformance level, drivers are not required to do so. If these functions are not supported, an application developer must consult the driver documentation to determine its conformance levels.
Determining API Conformance Levels
ODBC functions are divided into core functions, which are defined in the X/Open and SQL Access Group Call Level Interface specification, and two levels of extension functions, with which ODBC extends this specification. To determine the function conformance level of a driver, an application calls SQLGetInfo with the SQL_ODBC_SAG_CLI_CONFORMANCE and SQL_ODBC_API_CONFORMANCE flags. Note that a driver can support one or more extension functions but not conform to ODBC extension Level 1 or 2. To determine if a driver supports a particular function, an application calls SQLGetFunctions. Note that SQLGetFunctions is implemented by the Driver Manager and can be called for any driver, regardless of its level.
Determining SQL Conformance Levels
The ODBC SQL grammar, which includes SQL data types, is divided into a minimum grammar, a core grammar, which corresponds to the X/Open and SQL Access Group SQL CAE specification (1992), and an extended grammar, which provides common extensions to SQL. To determine the SQL conformance level of a driver, an application calls SQLGetInfo with the SQL_ODBC_SQL_CONFORMANCE flag. To determine whether a driver supports a specific SQL extension, an application calls SQLGetInfo with a flag for that extension. For more information, see Appendix C, "SQL Grammar." To determine whether a driver supports a specific SQL data type, an application calls SQLGetTypeInfo.
The Driver Manager is a DLL that provides access to ODBC drivers. An application typically links with the Driver Manager import library (ODBC.LIB) to gain access to the Driver Manager.
Application accessing SOLID SQL API directly bypass the Driver Manager and cannot therefore use ODBC functions that are implemented in the Driver Manager.
Whenever an application calls an ODBC function, the Driver Manager performs one of the following actions:
- For SQLDataSources and SQLDrivers, the Driver Manager processes the call. It does not pass the call to the driver.
- For SQLGetFunctions, the Driver Manager passes the call to the driver associated with the connection. If the driver does not support SQLGetFunctions, the Driver Manager processes the call.
- For SQLAllocEnv, SQLAllocConnect, SQLSetConnectOption, SQLFreeConnect, and SQLFreeEnv, the Driver Manager processes the call. The Driver Manager calls SQLAllocEnv, SQLAllocConnect, and SQLSetConnectOption in the driver when the application calls a function to connect to the data source (SQLConnect, SQLDriverConnect, or SQLBrowseConnect). The Driver Manager calls SQLFreeConnect and SQLFreeEnv in the driver when the application calls SQLDisconnect.
- For SQLConnect, SQLDriverConnect, SQLBrowseConnect, and SQLError, the Driver Manager performs initial processing then passes the call to the driver associated with the connection.
- For any other ODBC function, the Driver Manager passes the call to the driver associated with the connection.
If requested, the Driver Manager records each called function in a trace file. The name of each function is recorded, along with the values of the input arguments and the names of the output arguments (as listed in the function definitions).
The following paragraphs describe general characteristics of ODBC functions.
An application passes data to a driver in an input buffer. The driver returns data to an application in an output buffer. The application must allocate memory for both input and output buffers. (If the application will use the buffer to retrieve string data, the buffer must contain space for the null termination byte.)
Note that some functions accept pointers to buffers that are later used by other functions. The application must ensure that these pointers remain valid until all applicable functions have used them. For example, the argument rgbValue in SQLBindCol points to an output buffer in which SQLFetch returns the data for a column.
Caution ODBC does not require drivers to correctly manage buffers that cross segment boundaries in Windows 3.1. The Driver Manager supports the use of such buffers, since it passes buffer addresses to drivers and does not operate on buffer contents. If a driver supports buffers that cross segment boundaries, the documentation for the driver should clearly state this.
For maximum interoperability, applications that use buffers that cross segment boundaries should pass them in pieces to ODBC functions. None of these pieces can cross a segment boundary. For example, suppose a data source contains 100 kilobytes of bitmap data. A Windows 3.1 application can safely allocate 100K of memory (beginning at a segment boundary) and retrieve the data in two pieces (64K and 36K), each of which begins on a segment boundary.
Input Buffers
An application passes the address and length of an input buffer to a driver. The length of the buffer must be one of the following values:
- A length greater than or equal to zero. This is the actual length of the data in the input buffer. For character data, a length of zero indicates that the data is an empty (zero length) string. Note that this is different from a null pointer. If the application specifies the length of character data, the character data does not need to be null-terminated.
- SQL_NTS. This specifies that a character data value is null-terminated.
- SQL_NULL_DATA. This tells the driver to ignore the value in the input buffer and use a NULL data value instead. It is only valid when the input buffer is used to provide the value of a parameter in an SQL statement.
The operation of ODBC functions on character data containing embedded null characters is undefined, and is not recommended for maximum interoperability.
Unless it is specifically prohibited in a function description, the address of an input buffer may be a null pointer. When the address of an input buffer is a null pointer, the value of the corresponding buffer length argument is ignored.
For more information about input buffers, see "Converting Data from C to SQL Data Types" in Appendix D, "Data Types."
Output Buffers
An application passes the following arguments to a driver, so that it can return data in an output buffer:
- The address of the buffer in which the driver returns the data (the output buffer). Unless it is specifically prohibited in a function description, the address of an output buffer can be a null pointer. In this case, the driver does not return anything in the buffer and, in the absence of other errors, returns SQL_SUCCESS.
- If necessary, the driver converts data before returning it. The driver always null-terminates character data before returning it.
- The length of the buffer. This is ignored by the driver if the returned data has a fixed length in C, such as an integer, real number, or date structure.
- The address of a variable in which the driver returns the length of the data (the length buffer). The returned length of the data is SQL_NULL_DATA if the data is a NULL value in a result set. Otherwise, it is the number of bytes of data available to return. If the driver converts the data, it is the number of bytes after the conversion. For character data, it does not include the null termination byte added by the driver.
If the output buffer is too small, the driver attempts to truncate the data. If the truncation does not cause a loss of significant data, the driver returns the truncated data in the output buffer, returns the length of the available data (as opposed to the length of the truncated data) in the length buffer, and returns SQL_SUCCESS_WITH_INFO. If the truncation causes a loss of significant data, the driver leaves the output and length buffers untouched and returns SQL_ERROR. The application calls SQLError to retrieve information about the truncation or the error.
For more information about output buffers, see "Converting Data from SQL to C Data Types" in Appendix D, "Data Types."
When so requested by an application, the Driver Manager and each driver allocate storage for information about the ODBC environment, each connection, and each SQL statement. The handles to these storage areas are returned to the application. The application then uses one or more of them in each call to an ODBC function.
- The environment handle identifies memory storage for global information, including the valid connection handles and the current active connection handle. ODBC defines the environment handle as a variable of type HENV. An application uses a single environment handle; it must request this handle prior to connecting to a data source.
- Connection handles identify memory storage for information about a particular connection. ODBC defines connection handles as variables of type HDBC. An application must request a connection handle prior to connecting to a data source. Each connection handle is associated with the environment handle. The environment handle can, however, have multiple connection handles associated with it.
- Statement handles identify memory storage for information about an SQL statement. ODBC defines statement handles as variables of type HSTMT. An application must request a statement handle prior to submitting SQL requests. Each statement handle is associated with exactly one connection handle. Each connection handle can, however, have multiple statement handles associated with it.
For more information about requesting a connection handle, see Chapter 5, "Connecting to a Data Source." For more information about requesting a statement handle, see Chapter 6, "Executing SQL Statements."
Data stored on a data source has an SQL data type, which may be specific to that data source. A driver maps data sourcespecific SQL data types to ODBC SQL data types, which are defined in the ODBC SQL grammar, and driver-specific SQL data types. (A driver returns these mappings through SQLGetTypeInfo. It also uses the ODBC SQL data types to describe the data types of columns and parameters in SQLColAttributes, SQLDescribeCol, and SQLDescribeParam.)
Each SQL data type corresponds to an ODBC C data type. By default, the driver assumes that the C data type of a storage location corresponds to the SQL data type of the column or parameter to which the location is bound. If the C data type of a storage location is not the default C data type, the application can specify the correct C data type with the fCType argument in SQLBindCol, SQLGetData, or SQLBindParameter. Before returning data from the data source, the driver converts it to the specified C data type. Before sending data to the data source, the driver converts it from the specified C data type.
For more information about data types, see Appendix D, "Data Types." The C data types are defined in SQL.H and SQLEXT.H.
The C data types of SOLID SQL API and defined in CLI0DEFS.H.
When an application calls an ODBC function, the driver executes the function and returns a predefined code. These return codes indicate success, warning, or failure status. The return codes are:
SQL_SUCCESS
SQL_SUCCESS_WITH_INFO
SQL_NO_DATA_FOUND
SQL_ERROR
SQL_INVALID_HANDLE
SQL_STILL_EXECUTING
If the function returns SQL_SUCCESS_WITH_INFO or SQL_ERROR, the application can call SQLError to retrieve additional information about the error. For a complete description of return codes and error handling, see Chapter 8, "Retrieving Status and Error Information."
Copyright © 1992-1997 Solid Information Technology Ltd All rights reserved.