Microsoft ODBC SDK 2.01a Release Notes
Microsoft ODBC SDK 2.10 Release Notes

This file contains the most up-to-date information about the Microsoft ODBC Software Development Kit (SDK), version 2.10.

Installing and Using the ODBC SDK

Contents of the ODBC SDK

What's New Since ODBC 1.0

Summary of Changes Made After ODBC 2.0

Known Problems and Additional Information


Installing and Using the ODBC SDK

Installing the ODBC SDK

Configuring Data Sources

Redistributing ODBC Components


Installing the ODBC SDK

To install the ODBC SDK, run the SETUP.EXE program. For more information, see Chapter 2 of the ODBC SDK Guide.


Configuring Data Sources

To configure data sources, run the ODBC Administrator from the Control Panel or the ODBC Administrator item in the ODBC SDK 2.10 program group. For more information, see Chapter 3 of the ODBC SDK Guide. If you choose to install the drivers included in the SDK, the Setup program will automatically create sample data sources for you.


Redistributing ODBC Components

All redistributable 16-bit components are copied to the \ODBCSDK\REDIST16 directory. All redistributable 32-bit components are copied to the \ODBCSDK\REDIST32 directory.

In addition, the \ODBCSDK\DRVSETUP.KIT\SETUP16 and the \ODBCSDK\DRVSETUP.KIT\SETUP32 directories contain sample DRVSETUP.EXE, DRVSTP32.EXE, _BOOTSTP.EXE, SETUP.LST and ODBC.INF files that you can customize for your drivers and use together with the Microsoft SDK setup tools.


Contents of the ODBC SDK

To view a list of all materials shipped with the ODBC SDK, see PACKLIST.TXT, located in the \ODBCSDK directory. (Note: \ODBCSDK is the directory where the Setup program has installed the ODBC SDK; you may specify a different directory name during installation.)

Redistributable Components

32-Bit Components

Cursor Library

Installer DLL

Tools

Driver Setup Toolkit

ODBC Spy

ODBC Test

Drivers

ODBC Drivers

Samples

Sample Drivers

Sample Programs

Documentation

Documentation


32-Bit Components

The ODBC SDK provides complete 32-bit components. In addition, ODBC thunking layers allow 16-bit applications to use 32-bit drivers on Windows NT. Separate thunks also allow 32-bit applications to use existing 16-bit drivers on Win32s. (Note that ODBC SDK 2.10 has not been tested on Win32s. ODBC 2.0 should be used on Win32s.) See the ODBC SDK Guide for complete details.


Cursor Library

The ODBC SDK provides scrollable result set support to all level 1 drivers. This support is provided through an additional ODBC component, the cursor library. The library is provided in 16-bit (ODBCCURS.DLL) and 32-bit (ODBCCR32.DLL) binary form. For details on the cursor library and its supported functionality, see Appendix G of the ODBC 2.0 Programmer's Reference.


Installer DLL

The ODBC installer DLL now supports high-level installation functions to allow simple and easy administration of ODBC drivers. For more information, see Chapters 19 and 20 of the ODBC 2.0 Programmer's Reference.


Driver Setup Toolkit

The \ODBCSDK\DRVSETUP.KIT directory contains source code for programs that install and configure ODBC drivers using the installer DLL. The SETUP16 and SETUP32 subdirectories contain the compiled versions of these programs. For more information, see Chapter 6 of the ODBC SDK Guide.


ODBC Spy

ODBC Spy is a utility you can use to debug your drivers and applications. To run ODBC Spy, double click the ODBC Spy icon in the ODBC SDK 2.10 program group. For more information, see Chapter 5 of the ODBC SDK Guide or online Help.


ODBC Test

ODBC Test is a Windows-based application for running quality assurance tests against ODBC drivers. To run ODBC Test, double click the ODBC Test icon in the ODBC SDK 2.10 program group. For more information, see Chapter 4 of the ODBC SDK Guide or online Help.


ODBC Drivers

The ODBC SDK includes a number of ODBC drivers that application writers can use to test their applications against a working set of drivers. These drivers are provided under a single-user SDK license for development purposes only. See the licensing agreement for details.

The ODBC SDK provides the following 16-bit and 32-bit drivers:

Access driver

Btrieve driver (16-bit only)

dBase driver

Excel driver

Fox driver

Paradox driver

Text driver

Sample Driver template

The 16-bit drivers are located in the \ODBCSDK\BIN directory, and the 32-bit drivers are located in the \ODBCSDK\BIN32 directory.

The Btrieve driver requires WBTRCALL.DLL to retrieve Btrieve data. This DLL is not shipped in the ODBC SDK; please contact Novell to get this DLL.

To install individual drivers, use the ODBC Administrator in the Control Panel or the ODBC SDK 2.10 program group.

If you are writing 32-bit applications, you can use the 16-bit drivers on Win32s (Intel only). The ODBC SDK installs thunking versions of the Driver Manager and the installer DLL in the Windows SYSTEM directory. You must have Win32s installed for this to work correctly. See the ODBC SDK Guide for more details.


Sample Drivers

The ODBC SDK 2.10 includes 16- and 32-bit sample drivers, complete with source code, to assist driver writers in building drivers. Do not use the sample drivers for application testing, as they have no functionality. For more information on these drivers, see the Samples help file in the \ODBCSDK\HELP directory.


Sample Programs

Several code samples are included with the ODBC SDK to help both application and driver writers. These include sample applications that use ODBC functions to access databases , a sample driver that provides a template for writing ODBC drivers, and a sample translation tool that provides stubs for writing a translation DLL and acts as a translation spy. The samples included with the ODBC SDK are 16-bit executables.  However, the sample source code may be compiled into either 16- or 32-bit excutables. The ODBC SDK contains the following sample programs:

Sample program	Location
Visual Basic application	\ODBCSDK\SAMPLES\VBDEMO
Sample C++ application	\ODBCSDK\SAMPLES\CPPDEMO
SQL Query Sample application	\ODBCSDK\SAMPLES\QURYDEMO
Cursor Library Sample application	\ODBCSDK\SAMPLES\CRSRDEMO
ODBC System Administration tool	\ODBCSDK\SAMPLES\ADMNDEMO
Sample Driver template	\ODBCSDK\SAMPLES\SMPLDRVR
Auto Test template	\ODBCSDK\SAMPLES\QUIKTEST
DLL Viewer/Translation Spy	\ODBCSDK\SAMPLES\TRNSLCHK
For more information, see the ODBCSMPL.HLP Help file in \ODBCSDK\HELP.


Documentation

Documentation for the ODBC SDK is available online (on the MSDN Developer Library CD and in Help files located in the \ODBCSDK\HELP directory) and in printed format (available from Microsoft Press).

Further assistance is available through the Microsoft Connection on CompuServe and other support plans. For more information, see the "Getting Help" section of Chapter 1 of the ODBC SDK Guide and Introduction to "Whats New".


Whats New Since ODBC 1.0

These topics list all significant changes (new features, bug fixes, and clarifications ) made to the ODBC 2.0 Programmer's Reference since ODBC 1.0. They are not intended to completely describe each change. For complete information, see the chapter and section of the ODBC 2.0 Programmer's Reference listed in brackets ([]).

Introduction to "What's New"

General Changes

ODBC Functions

Appendix B: ODBC State Transition Tables

Appendix C: SQL Grammar

Appendix D: Data Types

Appendix F: Scalar Functions

Installation and Configuration

Translation DLLs


"What's New" topics list all significant changes (new features, bug fixes, and clarifications ) made to the ODBC 2.0 Programmer's Reference since ODBC 1.0. They are not intended to completely describe each change. For complete information, see the chapter and section of the ODBC 2.0 Programmer's Reference listed in brackets ([]).


Introduction to "What's New"

Based on feedback from developers, a number of features were added to the ODBC 1.0 specification to create the ODBC 2.0 and later specifications. Furthermore, many items in the ODBC 1.0 specification have been clarified.

The ODBC 2.0 Programmer's Reference contains the ODBC 2.0 specification. All later changes to the specification, as well as notes about bugs, are contained in this file.

For details on	See
The latest ODBC specification	The ODBC 2.0 Programmer's Reference, as modified by Known Problems and Additional Information
All changes made since ODBC 1.0	Whats New Since ODBC 1.0
Changes made after ODBC 2.0	Summary of Changes Made After ODBC 2.0
Changes made between the ODBC 2.0 beta and ODBC 2.0	The change document posted on CompuServe.
ODBC 2.10 was designed to be backwards compatible with ODBC 1.0. The following table shows the compatibility of ODBC 1.0 and 2.x applications and drivers:

Application	Driver	Driver Mgr	Compatible?
1.0	1.0	2.0	Yes
1.0	2.x	2.0 *	Yes
2.x	1.0	1.0	Yes, except for ODBC 2.x functionality.
2.x	1.0	2.0	Yes, except for ODBC 2.x functionality.
* ODBC 2.x drivers require the ODBC 2.0 Driver Manager.


General Changes (What's New)

Asynchronous Execution

Bookmarks

Buffers

Compiling for Specific ODBC Versions

Conformance Levels

Default Procedure Parameters

#defines

Driver Manager

Driver-Specific Data Types, Descriptor Types, Information Types, and Options

ODBC Cursor Library

ODBC Cursor Model

Procedures

Sending Long Data

Transactions

Windows 3.0 and Windows NT Support


Asynchronous Execution (What's New)

1) If a function is called while it is executing asynchronously, the driver ignores all arguments except the hstmt argument.  [Chapter 6, Executing Functions Asynchronously; Chapter 14, Supporting Asynchronous Execution]

2) If an hstmt is being executed in an asynchronous state, and an application calls a different function with that hstmt, the driver (not the Driver Manager) returns an error.  [Chapter 14, Supporting Asynchronous Execution]


Bookmarks (What's New)

Before using bookmarks, an application sets the SQL_USE_BOOKMARK statement option. To request a bookmark that it can use to return to a row, an application positions the cursor on that row and calls SQLGetStmtOption with the SQL_GET_BOOKMARK statement option or retrieves the bookmark from column 0 of the result set with fCType set to SQL_C_BOOKMARK. To return to a row using a bookmark, the application calls SQLExtendedFetch with the SQL_FETCH_BOOKMARK fetch type and passes the bookmark in the irow argument.  [Chapter 7, Using Bookmarks; Chapter 22, SQLExtendedFetch and SQLGetStmtOption; Appendix D, Bookmark C Data Type]


Buffers (What's New)

Null Termination of Character Data

An application must null terminate character data it sends to the driver in an input buffer only if the corresponding length is SQL_NTS. The driver must always null terminate character data it returns to the application in an output buffer.  [Chapter 3, Input Buffers and Output Buffers]

Output Buffers

Unless explicitly prohibited, an application can pass a null pointer to a driver instead of the address of an output buffer. In this case, the driver ignores the information normally returned in the output buffer.  [Chapter 3, Output Buffers]

Segments

On Windows 3.1, buffers should not cross segment boundaries.  [Chapters 3 and 11, Buffers]


Compiling for Specific ODBC Versions (What's New)

An application or driver can be compiled with only ODBC 1.0 #defines and function prototypes by setting the ODBCVER #define.  [Chapter 10, Testing and Debugging and Application; Chapter 18; Testing and Debugging a Driver]


Conformance Levels (What's New)

Many ODBC applications require that drivers support all of the functions in the Level 1 API conformance level. To ensure that their driver works with most ODBC applications, driver developers should implement all Level 1 functions.  [Chapter 1, API Conformance Levels]


Default Procedure Parameters (What's New)

To specify that a procedure uses the default value for a parameter, an application constructs an SQL statement with a parameter marker for the procedure. It then calls SQLSetParam for the parameter and specifies SQL_DEFAULT_PARAM or SQL_DATA_AT_EXEC for the pcbValue argument. If it specifies SQL_DATA_AT_EXEC, it later calls SQLPutData and specifies SQL_DEFAULT_PARAM for the cbValue argument. The application can also construct an SQL statement with no value for the parameter. For example, {call AddEmployee('Smith',,{d '1968-06-28'},)} will use a default value for the second and fourth parameters.  [Chapter 22, SQLPutData and SQLSetParam; Appendix C, procedure-parameter]


#defines (What's New)

The names of some #defines have been changed to clarify their meaning. So that these changes are backwards compatible, the old and new #define names have the same value and the old #defines are still defined in the ODBC include files.

As an aid to programming, a number of #defines have been added to ODBC. These replace numbers that previously had to be hard coded in an application or driver.

See Also:

Changed #defines

Additional #defines


Changed #defines (What's New)

Function	Old #define	New #define
SQLExtendedFetch	SQL_FETCH_PREV	SQL_FETCH_PRIOR
SQLGetInfo	For SQL_FETCH_DIRECTION: SQL_FD_FETCH_PREV For SQL_SCROLL_CONCURRENCY: SQL_SCCO_OPT_TIMESTAMP	SQL_FD_FETCH_PRIOR SQL_SCCO_OPT_ROWVER
SQLSetPos	For fOption (formerly fRefresh): FALSE TRUE For fLock: FALSE TRUE	SQL_POSITION SQL_REFRESH SQL_LOCK_NO_CHANGE SQL_LOCK_EXCLUSIVE
SQLSetScrollOptions	SQL_CONCUR_TIMESTAMP	SQL_CONCUR_ROWVER
[Chapter 22, SQLExtendedFetch, SQLGetInfo, SQLSetPos, and SQLSetScrollOptions]


Additional #defines (What's New)

Function	#define	Value
SQLGetConnectOption	SQL_MAX_OPTION_STRING_LENGTH	256
SQLGetInfo	For SQL_ODBC_API_CONFORMANCE: SQL_OAC_NONE SQL_OAC_LEVEL1 SQL_OAC_LEVEL2 For SQL_ODBC_SAG_CLI_CONFORMANCE: SQL_OSCC_NOT_COMPLIANT SQL_OSCC_COMPLIANT For SQL_ODBC_SQL_CONFORMANCE: SQL_OSC_MINIMUM SQL_OSC_CORE SQL_OSC_EXTENDED For SQL_CONCAT_NULL_BEHAVIOR: SQL_CB_NULL SQL_CB_NON_NULL For SQL_CURSOR_COMMIT_BEHAVIOR: SQL_CB_DELETE SQL_CB_CLOSE SQL_CB_PRESERVE For SQL_CURSOR_ROLLBACK_BEHAVIOR: SQL_CB_DELETE SQL_CB_CLOSE SQL_CB_PRESERVE For SQL_IDENTIFIER_CASE: SQL_IC_UPPER SQL_IC_LOWER SQL_IC_SENSITIVE SQL_IC_MIXED For SQL_TXN_CAPABLE: SQL_TC_NONE SQL_TC_DML SQL_TC_ALL	0 1 2 0 1 0 1 2 0 1 0 1 2 0 1 2 1 2 3 4 0 1 2
SQLGetStmtOption	SQL_MAX_OPTION_STRING_LENGTH	256
SQLSetConnectOption	SQL_MAX_OPTION_STRING_LENGTH For SQL_AUTOCOMMIT: SQL_AUTOCOMMIT_OFF SQL_AUTOCOMMIT_ON For SQL_OPT_TRACE: SQL_OPT_TRACE_OFF SQL_OPT_TRACE_ON	256 0 1 0 1
SQLSetStmtOption	SQL_MAX_OPTION_STRING_LENGTH For SQL_ASYNC_ENABLE: SQL_ASYNC_ENABLE_OFF SQL_ASYNC_ENABLE_ON For SQL_NOSCAN: SQL_NOSCAN_OFF SQL_NOSCAN_ON	256 0 1 0 1
[Chapter 22, SQLGetConnectOption, SQLGetInfo, SQLGetStmtOption, SQLSetConnectOption, and SQLSetStmtOption]


Driver Manager (What's New)

Delayed Unloading of Drivers

To optimize performance for applications that continually connect and disconnect from data sources, the Driver Manager now does not unload a driver until the application calls SQLFreeConnect or connects to a different driver.

The Driver Manager does not call SQLAllocEnv or SQLFreeEnv during connection/disconnection if the driver is already loaded on the same henv.  [Chapter 22, SQLConnect]

Loading by Ordinal Value

To optimize performance when loading drivers, the Driver Manager checks if the driver exports a dummy function with the ordinal value 199. If so, it resolves the function addresses of the driver by ordinal, using the same ordinal values as the fFunction argument in SQLGetFunctions. If not, it resolves the function addresses by name, which is slower. Note that all non-ODBC functions must have ordinal values outside the range of 1-199 if loading by ordinal is used.  [Chapter 22, SQLConnect]

Specifying ODBC 2.x Argument Values to ODBC 1.0 Drivers

The Driver Manager returns an error if an application specifies an ODBC 2.x argument value to an ODBC 1.0 driver. For example, the Driver Manager returns an error if an application calls SQLGetInfo with an fInfoType of SQL_GROUP_BY in an ODBC 1.0 driver.  [Chapter 11, Validating Arguments]

Tracing

The Driver Manager checks function calls for errors before recording them in the trace file; if there are any errors, the call is not recorded.  [Chapter 11, Role of the Driver Manager]


Driver-Specific Data Types, Descriptor Types, Information Types, and Options (What's New)

1) Driver developers may request blocks of numbers for driver-specific data types, descriptor types, information types, statement options, and connection options. To do so, driver developers post a request to the section lead of the ODBC section of the WINEXT forum on CompuServe or email odbcwish@microsoft.com.  [Chapter 11, Driver-Specific Data Types, Descriptor Types, Information Types, and Options]

2) Data types, descriptor types, information types, and statement and connection options have two ranges: a range reserved for ODBC values and a range reserved for driver-specific values. The Driver Manager checks whether values in the ODBC range are valid; if not, it returns an error. (See the specific function for the SQLSTATE returned.) Drivers must check whether values in the driver range are valid; if not, such as when a driver-specific value for a different driver is specified, the driver returns SQLSTATE S1C00 (Driver not capable).  [Chapter 11, Driver-Specific Data Types, Descriptor Types, Information Types, and Options; Chapter 22, SQLBindParameter, SQLColAttributes, SQLGetConnectOption, SQLGetInfo,  SQLGetStmtOption, SQLGetTypeInfo, SQLSetConnectOption, and SQLSetStmtOption]


ODBC Cursor Library (What's New)

The ODBC Cursor Library supports block scrollable cursors for any driver that complies with the Level 1 API conformance level; it can be redistributed by developers with their applications or drivers. The cursor library also supports positioned update and delete statements for result sets generated by SELECT statements. Although it only supports static and forward-only cursors, the cursor library satisfies the needs of many applications. Furthermore, it provides good performance, especially for small- to medium-sized result sets.

An application calls SQLSetConnectOption with the SQL_ODBC_CURSORS option to specify whether to always use the cursor library, use it when the driver does not support scrollable cursors, or never use it. It calls SQLSetStmtOption to specify the cursor type, concurrency, and rowset size. Finally, it calls SQLExtendedFetch to use the cursor library.  [Chapter 22, SQLSetConnectOption and SQLSetStmtOption; Appendix G]


ODBC Cursor Model (What's New)

Keyset-Driven and Dynamic Cursors

Keyset-driven and dynamic cursors do not immediately detect changes to the underlying result set. Instead, they detect changes when data is next fetched.  [Chapter 7, Scrollable Cursors]

Optimistic Concurrency Control

1) In optimistic concurrency control, the driver does not necessarily lock the underlying row when the application executes an update or delete statement. Instead, the driver or data source checks if the row has changed and, if not, the driver or data source prevents other transactions from changing the row until the operation is complete.  [Chapter 7, Specifying Cursor Concurrency]

2) The phrase "optimistic concurrency control comparing timestamps" has been changed to "optimistic concurrency control comparing row versions" to reflect a wider range of possible implementations. In SQLGetInfo, the return value SQL_SCCO_OPT_TIMESTAMP is now SQL_SCCO_OPT_ROWVER. In SQLSetScrollOptions, SQL_CONCUR_TIMESTAMP is now SQL_CONCUR_ROWVER.  [Chapter 7, Specifying Cursor Concurrency; Chapter 22, SQLGetInfo and SQLSetScrollOptions]

Other Users

In the definition of static, dynamic, keyset-driven, and mixed cursors, "other users" includes other cursors in the same application.  [Chapters 7 and 15, Using Block and Scrollable Cursors]


Procedures (What's New)

1) The driver does not return an error if an application specifies a return value parameter for a procedure that does not return a value or if an application does not specify a return value parameter for a procedure that does return a value. In the first case, the driver sets pcbValue for the parameter to SQL_NULL_DATA. In the second case, the driver discards the return value.  [Chapters 6 and 14, Procedures]

2) The section describing procedure calls has been clarified.  [Chapters 6 and 14, Procedures]


Sending Long Data (What's New)

If more data was sent for a SQL_LONGVARCHAR or SQL_LONGVARBINARY parameter than was specified with the cbColDef argument in SQLBindParameter, SQLSTATE 22001 (String data right truncation) is returned. If less data was sent for a SQL_LONGVARCHAR or SQL_LONGVARBINARY parameter than was specified with the cbColDef argument in SQLBindParameter, SQLSTATE 22026 (String data, length mismatch) is returned. The following table shows the functions that return these SQLSTATEs in ODBC versions 1.0 and 2.x:

Function	ODBC 1.0 SQLSTATEs	ODBC 2.x SQLSTATEs
SQLExecDirect	22026	--
SQLExecute	--	--
SQLParamData	--	22026
SQLPutData	22001, 22026	22001
[Chapter 22, SQLExecDirect, SQLExecute, SQLParamData, SQLPutData, SQLBindParameter]


Transactions (What's New)

Cursors, Prepared Statements, and Transactions

Committing or rolling back a transaction can close cursors and delete access plans (return prepared statements to the unprepared state).  [Chapter 6, Performing Transactions; Chapter 14, Supporting Transactions]

Default Commit Mode

The default commit mode depends on whether the data source supports the SQL_AUTOCOMMIT connection option.  [Chapter 6, Performing Transactions; Chapter 14, Supporting Transactions]

Switching Connections

In "Connections and Transactions" in Chapter 1, the statement, "If the driver does not implement extended functionality, an application can switch connections only after it requests a commit or rollback operation for the transaction on the current connection." has been removed. This is not true for ODBC 1.0 or ODBC 2.x; applications can switch connections at any time.


Windows 3.0 and Windows NT Support (What's New)

1) ODBC 2.x does not support Windows 3.0; all references to Windows 3.0 have been removed from the ODBC 2.0 Programmer's Reference.  [Chapter 19, Installing ODBC Software]

2) ODBC supports Windows NT by:

Providing redistributable 32-bit Driver Manager, Installer, and Administrator program for use on Windows NT.  [Chapter 19, Redistributing ODBC Files]

Providing redistributable thunking layers for support of:

32-bit applications with 16-bit drivers on Win32s.

16-bit applications with 32-bit drivers on Windows NT.

[Chapter 19, Redistributing ODBC Files; For additional information, see Appendix A, Developing 16- and 32-Bit Applications and Drivers, in the ODBC SDK Guide]

Defining the following structures in the Windows NT registry:

HKEY_LOCAL_MACHINE
  Software
    ODBC
      ODBCINST.INI

HKEY_CURRENT_USER
  Software
    ODBC
      ODBC.INI

A driver calls SQLGetPrivateProfileString and SQLWritePrivateProfileString in the installer DLL to read and write entries in the ODBC.INI file and ODBC.INI subkey. In the 16-bit installer DLL, these are macros that call GetPrivateProfileString and WritePrivateProfileString in the Windows API. In the 32-bit installer DLL, these are functions that read and write entries in the ODBC.INI subkey of the Windows NT registry.  [Chapter 22, Structure of the ODBCINST.INI File; Chapter 20, Structure of the ODBC.INI File; Chapter 24, Installer DLL Function Reference]


ODBC Functions (What's New)

All Functions

Catalog Functions

SQLAllocConnect

SQLAllocEnv

SQLAllocStmt

SQLBindCol

SQLBindParameter (New Function)

SQLBrowseConnect and SQLDriverConnect

SQLBrowseConnect

SQLCancel

SQLColAttributes

SQLColumnPrivileges

SQLColumns

SQLConnect

SQLDataSources

SQLDescribeCol

SQLDescribeParam

SQLDisconnect

SQLDriverConnect

SQLDrivers (New Function)

SQLError

SQLExecDirect

SQLExecute

SQLExtendedFetch

SQLFetch

SQLForeignKeys

SQLFreeStmt

SQLGetConnectOption

SQLGetCursorName and SQLSetCursorName

SQLGetData

SQLGetFunctions

SQLGetInfo

SQLGetStmtOption

SQLGetTypeInfo

SQLMoreResults

SQLNativeSql

SQLNumParams

SQLNumResultCols

SQLParamData

SQLParamOptions

SQLPrepare

SQLPrimaryKeys

SQLProcedureColumns

SQLProcedures

SQLPutData

SQLRowCount

SQLSetConnectOption

SQLSetParam

SQLSetPos

SQLSetScrollOptions

SQLSetStmtOption

SQLSpecialColumns

SQLStatistics

SQLTablePrivileges

SQLTables

SQLTransact


All Functions (What's New)

The notation (DM) before the reason a function returns a SQLSTATE indicates that the Driver Manager performs the test for that reason.  [Chapter 22]


Catalog Functions (What's New)

1) If a driver supports qualifiers or owners for some tables but not for others, such as when the driver retrieves data from different DBMSs, an empty string ("") in the qualifier or owner argument denotes those tables that do not have qualifiers or owners. Similarly, an empty string is returned in the qualifier or owner column of the result set for those tables that do not have qualifiers or owners.  [Chapter 22, SQLColumnPrivileges, SQLColumns, SQLForeignKeys, SQLPrimaryKeys, SQLProcedureColumns, SQLProcedures, SQLSpecialColumns, SQLStatistics, SQLTablePrivileges, SQLTables]

2) Although driver developers should attempt to return all relevant information, application developers should be aware that catalog functions are not required to return all possible catalog information. For example, SQLColumnPrivileges might not return privileges for pseudo-columns, such as Oracle ROWID.  [Chapter 22, SQLColumnPrivileges, SQLColumns, SQLForeignKeys, SQLPrimaryKeys, SQLProcedureColumns, SQLProcedures, SQLSpecialColumns, SQLStatistics, SQLTablePrivileges, SQLTables]


SQLAllocConnect (What's New)

On operating systems that support multiple threads, applications can use the same hdbc on different threads; drivers must therefore support safe, multithreaded access to the hdbc information.  [Chapter 22, SQLAllocConnect]


SQLAllocEnv (What's New)

1) On operating systems that support multiple threads, applications can use the same henv on different threads; drivers must therefore support safe, multithreaded access to the henv information.  [Chapter 22, SQLAllocEnv]

2) In ODBC 1.0, the Driver Manager called SQLAllocEnv in the driver each time an application connected to a data source that used the driver. In ODBC 2.x, the Driver Manager only calls SQLAllocEnv when it loads the driver, that is, when the application first connects to a data source that uses the driver.  [Chapter 22, SQLAllocEnv and SQLConnect]


SQLAllocStmt (What's New)

On operating systems that support multiple threads, applications can use the same hstmt on different threads; drivers must therefore support safe, multithreaded access to the hstmt information.  [Chapter 22, SQLAllocStmt]


SQLBindCol (What's New)

1) The driver can only truncate data that has been converted to character or binary C data. Character data is truncated to cbValueMax-1 bytes; binary data is truncated to cbValueMax bytes. After truncation, character data is null terminated.  [Chapter 22, SQLBindCol]

2) To unbind a single bound column of the result set, an application calls SQLBindCol for that column and specifies a null pointer for the rgbValue argument. If an application specifies a null pointer for an unbound column, SQLBindCol returns SQL_SUCCESS.  [Chapter 22, SQLBindCol]

3) The number of bytes available to return before the data is fetched is returned in pcbValue. If this number cannot be determined, SQL_NO_TOTAL is returned. If pcbValue is a null pointer, no value is returned.  [Chapter 15, Assigning Storage for Results; Chapter 15, Assigning Blocks of Storage; Chapter 22, SQLBindCol]

4) SQLSTATE changes:

S1002: Returned if icol is 0 and the driver is an ODBC 1.0 driver.

S1003: Returned if icol is 0 and fCType is not SQL_C_BOOKMARK.

S1009: Returned if rgbValue is a null pointer and the driver is an ODBC 1.0 driver.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1C00: Returned if fCType is an ODBC 2.x integer data type and the driver is an ODBC 1.0 driver.

S1C00: Returned if icol is 0 and the driver doesn't support bookmarks.

[Chapter 22, SQLBindCol; Appendix B, Statement Transitions]


SQLBindParameter (New Function) (What's New)

The SQLBindParameter function replaces the SQLSetParam function. The major difference is that two arguments, fParamType and cbValueMax, have been added. The Driver Manager converts calls from ODBC 1.0 applications to SQLSetParam in ODBC 2.x drivers to calls to SQLBindParameter and calls from ODBC 2.x applications to SQLBindParameter in ODBC 1.0 drivers to calls to SQLSetParam. For backwards compatibility, SQLBindParameter must support any driver-specific semantics of SQLSetParam; cbValueMax is set to SQL_SETPARAM_VALUE_MAX when a call to SQLSetParam is converted to a call to SQLBindParameter.

In addition to these two arguments, the following changes have been made in changing SQLSetParam into SQLBindParameter:

1) If rgbValue and pcbValue are both null pointers for an output parameter, the driver discards the value.  [Chapter 22, SQLBindParameter]

2) If the number of bytes available to return cannot be determined for the output value of an input/output parameter or an output parameter, the driver sets pcbValue to SQL_NO_TOTAL.  [Chapter 22, SQLBindParameter]

3) To specify that data will be sent for a parameter with SQLPutData, the application sets pcbValue to the result of the SQL_LEN_DATA_AT_EXEC(length) macro, not SQL_DATA_AT_EXEC.  [Chapter 22, SQLBindParameter]

4) On output, pcbValue contains the length of the data available to return for the parameter, not the length of the data returned in rgbValue.  [Chapter 22, SQLBindParameter]

5) On input, an application can specify SQL_NTS for pcbValue.  [Chapter 22, SQLBindParameter]

6) If a procedure returns one or more result sets, the input/output and output procedure parameters might not be set until all results have been fetched. [Chapter 22, SQLBindParameter]

7) SQLBindParameter does not return errors due to preparing a statement.  [Chapter 22, SQLBindParameter]

8) SQLSTATE changes:

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1094: Returned if ibScale is outside the range of values supported by the data source, rather than less than 0.

S1104: Returned when cbColDef is outside the range of precision supported by the data source.

S1C00: Returned when fCType is an ODBC 2.x integer data type and the driver is an ODBC 1.0 driver.

[Chapter 22, SQLBindParameter; Appendix B, Statement Transitions]


SQLBrowseConnect and SQLDriverConnect (What's New)

1) To avoid problems parsing strings and using the ODBC.INI file, attribute values in connection strings (szConnStrIn and szConnStrOut in SQLBrowseConnect and SQLDriverConnect) should not contain the []{}(),;?*=!@ characters. Because of the grammar of the registry, keywords and the value of the DSN keyword cannot contain backslashes (\).  [Chapter 22, SQLBrowseConnect and SQLDriverConnect]

2) An application can connect directly to a driver by calling SQLDriverConnect or SQLBrowseConnect with the DRIVER keyword instead of the DSN keyword. The keywords used by SQLDriverConnect and SQLBrowseConnect must provide enough information for the driver to connect to an unnamed data source without retrieving information from the ODBC.INI file or the user.  [Chapter 22, SQLBrowseConnect and SQLDriverConnect]

3) Keywords in connection strings are case insensitive. Values in connection strings may be case sensitive.  [Chapter 22, SQLBrowseConnect and SQLDriverConnect]

4) The value of the DRIVER keyword must be surrounded in braces ({}).  [Chapter 22, SQLBrowseConnect and SQLDriverConnect]

5) To support the DRIVER keyword, the driver must provide enough keywords to connect to a data source without using information from the ODBC.INI file or the registry.  [Chapter 22, SQLBrowseConnect and SQLDriverConnect]

6) SQLSTATE changes:

IM010: Returned if the Driver Manager was unable to load the default translation DLL.

IM011: Returned if the value of the DRIVER keyword was too long.

IM012: Returned if the keyword-value pair for the DRIVER keyword contained a syntax error.

[Chapter 22, SQLBrowseConnect and SQLDriverConnect]


SQLBrowseConnect (What's New)

1) The browse result connection string cannot return the DRIVER or DSN keywords; these can only be used in the browse request connection string on the first time SQLBrowseConnect is called.  [Chapter 22, SQLBrowseConnect]

2) If duplicate keywords are specified in a browse request connection string, the driver uses the first keyword it encounters; the DSN and DRIVER keywords are considered to be the same for this purpose. Furthermore, a browse request connection string cannot contain keywords from previous levels.  [Chapter 22, SQLBrowseConnect]

3) Drivers that support SQLBrowseConnect must specify this in the ConnectFunctions keyword in the ODBC.INF file.  [Chapter 19, Driver Keyword Sections; Chapter 22, SQLBrowseConnect]

4) If the connection string contains the DSN keyword, the driver can retrieve data from the ODBC.INI file or the registry.  [Chapter 22, SQLBrowseConnect]

5) SQLSTATE changes:

01S00: Returned if a keyword applies to a different level.

[Chapter 22, SQLBrowseConnect]


SQLCancel (What's New)

1) Calling SQLCancel for a function executing asynchronously does not guarantee that that function will be canceled. Furthermore, a canceled function may continue to return SQL_STILL_EXECUTING even after SQLCancel is called.  [Chapters 9 and 17, Terminating Statement Processing; Chapter 22, SQLCancel]

2) SQLCancel can be called from one thread to cancel a function executing synchronously or asynchronously on a different thread.  [Chapter 22, SQLCancel]

3) The meaning has been clarified for the return code of SQLCancel and the canceled function when an asynchronous function is canceled.  [Chapter 22, SQLCancel]

4) SQLCancel can be called to cancel processing of data-at-execution parameters or columns.  [Chapter 22, SQLCancel; Appendix B, Statement Transitions]

5) Applications should NOT use SQLCancel to close and discard the results of an open cursor. SQLCancel should only be used in an attempt to cancel a function executing asynchronously or on a separate thread. Cursors should be closed using SQLFreeStmt with the SQL_CLOSE option.

If an ODBC 2.x driver treats SQLCancel as a closed cursor, it must return SQL_SUCCESS_WITH_INFO along with SQLSTATE 01S05 (Cancel treated as FreeStmt/Close). The Driver Manager and cursor library will require this value be returned in multithreaded environments to ensure the correct state checking.  [Chapter 22, SQLCancel]


SQLColAttributes (What's New)

1) Driver developers can create driver-specific descriptor types for SQLColAttributes. They must request a block of descriptor numbers from the lead of the ODBC section of the WINEXT forum on CompuServe; the numbers 0 to 999 are reserved by ODBC.  [Chapter 11, Driver-Specific Data Types, Descriptor Types, Information Types, and Options; Chapter 22, SQLColAttributes]

2) The value returned in rgbValue can only be truncated if it is character data.  [Chapter 22, SQLColAttributes]

3) Only 32-bit, signed integers are returned in pfDesc; all other values are returned in rgbValue.  [Chapter 22, SQLColAttributes]

4) Unless otherwise stated, SQLColAttributes returns 0 in pcbDesc or an empty string in rgbDesc if the value of a descriptor does not apply to a column or cannot be determined for a column.  [Chapter 22, SQLColAttributes]

5) The SQL_COLUMN_CASE_SENSITIVE descriptor applies to comparisons as well as collations.  [Chapter 22, SQLColAttributes]

6) New descriptors were added for SQL_COLUMN_LABEL, SQL_COLUMN_OWNER_NAME, SQL_COLUMN_QUALIFIER_NAME, and SQL_COLUMN_TABLE_NAME.  [Chapter 22, SQLColAttributes]

7) In the description of SQL_COLUMN_LENGTH, the words "transfer size" were changed to "length," as transfer size might have implied that the null termination byte should be counted for character data.  [Chapter 22, SQLColAttributes]

8) SQLSTATE changes:

01004: Returned when any character data, not just column names, is truncated.

S1002: Not returned if fDescType is SQL_COLUMN_COUNT.

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1C00: Returned instead of S1091 if a value of fDescType in the driver-specific range is not supported by the driver.

[Chapter 22, SQLColAttributes; Appendix B, Statement Transitions]


SQLColumnPrivileges (What's New)

SQLSTATE changes:

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1C00: Returned if the combination of the concurrency and the cursor type was not supported.

[Chapter 22, SQLColumnPrivileges; Appendix B, Statement Transitions]


SQLColumns (What's New)

1) In the description of LENGTH, the words "transfer size" were changed to "length," as transfer size might have implied that the null termination byte should be counted for character data.  [Chapter 22, SQLColumns]

2) SQLSTATE changes:

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1C00: Returned if the combination of the concurrency and the cursor type was not supported.

[Chapter 22, SQLColumns; Appendix B, Statement Transitions]


SQLConnect (What's New)

Drivers that support SQLConnect must specify this in the ConnectFunctions keyword in the ODBC.INF file.  [Chapter 19, Driver Keyword Sections; Chapter 22, SQLConnect]


SQLDataSources (What's New)

SQLDataSources returns the description of the driver associated with the data source, not the value of the Description keyword in the data source specification section of the ODBC.INI file.  [Chapter 22, SQLDataSources]


SQLDescribeCol (What's New)

1) SQLDescribeCol returns 0 in pfSqlType, pcbColDef, or pibScale or an empty string in szColName if the value of a descriptor does not apply to a column or cannot be determined for a column.  [Chapter 22, SQLDescribeCol]

2) SQLSTATE changes:

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

[Chapter 22, SQLDescribeCol; Appendix B; Appendix B, Statement Transitions]


SQLDescribeParam (What's New)

1) SQLDescribeParam does not return the parameter type. Except in calls to procedures, all parameters are input parameters. To determine the type of each parameter in a procedure call, an application calls SQLProcedureColumns.

2) SQLSTATE changes:

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state(see Appendix B).

S1010: Returned if SQLDescribeParam is called prior to SQLPrepare or SQLExecDirect.

[Chapter 22, SQLDescribeParam; Appendix B, Statement Transitions]


SQLDisconnect (What's New)

1) If an application calls SQLDisconnect after SQLBrowseConnect returns SQL_NEED_DATA and before it returns a different return code, the driver cancels the connection browsing process and returns the hdbc to an unconnected state.

2) SQLSTATE changes:

S1010: Returned if an hstmt associated with the hdbc was in a Need Data state (see Appendix B).

[Chapter 22, SQLDisconnect; Appendix B, Statement Transitions]


SQLDriverConnect (What's New)

1) If a keyword is repeated in a connection string, or if the keyword contains both the DRIVER and DSN keywords, the driver uses the value associated with the first occurrence of the keyword.  [Chapter 22, SQLDriverConnect]

2) If the value of the fDriverCompletion flag is SQL_DRIVER_COMPLETE or SQL_DRIVER_COMPLETE_REQUIRED and any information required to connect to the data source or driver is incorrect, the driver takes the same actions as if fDriverCompletion were SQL_DRIVER_PROMPT, except that if fDriverCompletion is SQL_DRIVER_COMPLETE_REQUIRED, the driver disables the controls for any information not required to connect to the data source.  [Chapter 22, SQLDriverConnect]

3) Drivers that support SQLDriverConnect must specify this in the ConnectFunctions keyword in the ODBC.INF file.  [Chapter 19, Driver Keyword Sections; Chapter 22, SQLDriverConnect]

4) SQLSTATE changes:

S1090: cbConnStrOut was changed to cbConnStrOutMax

[Chapter 22, SQLDriverConnect]


SQLDrivers (New Function) (What's New)

SQLDrivers is a new function that returns a list of driver descriptions and driver attributes. An application can pass a driver description to SQLDriverConnect with the DRIVER keyword (see SQLBrowseConnect and SQLDriverConnect). It can also use the driver attributes to determine information about a driver before connecting to a data source that uses the driver. SQLGetFunctions can return a new #define (SQL_API_SQLDRIVERS). [Chapter 22, SQLDrivers, SQLDriverConnect, and SQLGetFunctions]


SQLError (What's New)

1) The Driver Manager and the driver have separate error queues. The Driver Manager's error queue can hold up to 64 messages.  [Chapter 22, SQLError]

2) An error is removed from an error queue when the error is retrieved. All errors are removed from a queue when the handle associated with that queue is used in a subsequent function call.  [Chapter 22, SQLError]


SQLExecDirect (What's New)

1) Drivers must parse ODBC escape clauses in SQL statements before passing them to the data source for execution.  [Chapter 22, SQLExecDirect]

2) SQLSTATE changes:

01S03: Returned if a positioned update or delete statement did not affect any rows.

01S04: Returned if a positioned update or delete statement affected more than one row.

07006: Returned if the data value identified by fCType in SQLBindParameter cannot be converted to the data type identified by fSqlType. (see SQLBindParameter (Problems and Information))

24000: Returned if the cursor is positioned before the start or after the end of the result set and the statement is a positioned update or delete statement.

S0002: Returned if a nonexistent table is referenced in a constraint in a CREATE TABLE statement.

S0022: Returned if a nonexistent column is referenced in a constraint in a CREATE TABLE statement.

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1090: Returned if cbSqlStr is less than or equal to 0, but not SQL_NTS.

S1105: Returned if fParamType in SQLBindParameter was SQL_PARAM_OUTPUT and the parameter did not mark a procedure return value or output parameter.

S1105: Returned if fParamType in SQLBindParameter was SQL_PARAM_INPUT and the parameter marked a procedure return value or output parameter.

S1109: Returned if the cursor is positioned on a deleted or error row in a rowset and the statement is a positioned update or delete statement.

S1C00: Returned if the combination of the concurrency and the cursor type was not supported.

[Chapter 22, SQLExecDirect; Appendix B, Statement Transitions]


SQLExecute (What's New)

SQLSTATE changes:

01S03: Returned if a positioned update or delete statement did not affect any rows.

01S04: Returned if a positioned update or delete statement affected more than one row.

07006: Returned if the data value identified by fCType in SQLBindParameter cannot be converted to the data type identified by fSqlType. (see SQLBindParameter (Problems and Information))

24000: Returned if the cursor is positioned before the start or after the end of the result set and the statement is a positioned update or delete statement.

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1105: Returned if fParamType in SQLBindParameter was SQL_PARAM_OUTPUT and the parameter did not mark a procedure return value or output parameter.

S1105: Returned if fParamType in SQLBindParameter was SQL_PARAM_INPUT and the parameter marked a procedure return value or output parameter.

S1109: Returned if the cursor is positioned on a deleted or error row in a rowset and the statement is a positioned update or delete statement.

S1C00: Returned if the combination of the concurrency and the cursor type was not supported.

[Chapter 22, SQLExecute; Appendix B, Statement Transitions]


SQLExtendedFetch (What's New)

1) The pcrow argument returns the number of rows for which the value in the rgfRowStatus array is not SQL_ROW_NOROW.  [Chapter 22, SQLExtendedFetch]

2) SQLExtendedFetch can set the pcbValue argument specified in SQLBindCol to SQL_NULL_DATA or SQL_NO_TOTAL.  [Chapter 22, SQLExtendedFetch]

3) If the requested rowset is completely outside the result set, SQLExtendedFetch returns SQL_NO_DATA_FOUND. If it overlaps the start of the result set, SQLExtendedFetch returns the first rowset in the result set. If it overlaps the end of the result set, SQLExtendedFetch returns as many rows as possible and returns SQL_ROW_NOROW in the status array for those rows for which no data existed.  [Chapter 22, SQLExtendedFetch]

4) If fFetchType is SQL_FETCH_RELATIVE and irow is 0, SQLExtendedFetch refreshes the current rowset.  [Chapter 22, SQLExtendedFetch]

5) If fFetchType is SQL_FETCH_ABSOLUTE and irow is negative, the driver returns the rowset starting |irow-1| (absolute value) rows from the end of the result set. If fFetchType is SQL_FETCH_ABSOLUTE and irow is 0, the driver returns SQL_NO_DATA_FOUND; the driver no longer returns SQLSTATE S1107 (Row value out of range) in this case.  [Chapter 22, SQLExtendedFetch]

6) If SQLExtendedFetch encounters an error while retrieving a block of data, the driver returns one or more SQLSTATEs for the offending row, sets the value of the rgfRowStatus array to SQL_ROW_ERROR, and continues processing. The SQL_FETCH_RESUME fetch option is not supported in ODBC 2.x.  [Chapter 22, SQLExtendedFetch]

7) SQLSTATE changes:

01S01: Returned if one or more errors occurs while fetching rows.

24000: Returned if no result set has been created.

S1002: Returned if column 0 is bound and bookmarks have not been enabled.

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if calls to SQLExtendedFetch and SQLFetch are mixed for the same cursor.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1106: Returned if fOption is SQL_FETCH_BOOKMARK and the driver is an ODBC 1.0 driver.

S1106: Returned if fOption is not SQL_FETCH_NEXT and the cursor is a forward-only cursor.

S1107: Returned if the cursor is keyset-driven and the keyset size is greater than 0 but less than the rowset size.

S1C00: Returned if the driver cannot convert the data from a driver-specific SQL data type to the specified C data type.

[Chapter 22, SQLExecute; Appendix B, Statement Transitions]


SQLFetch (What's New)

1) SQLFetch can set the pcbValue argument specified in SQLBindCol to SQL_NULL_DATA or SQL_NO_TOTAL.  [Chapter 22, SQLFetch]

2) Before SQLFetch is called the first time, the cursor is positioned before the start of the result set. After SQLFetch returns SQL_NO_DATA_FOUND, the cursor is positioned after the end of the result set.  [Chapter 22, SQLFetch]

3) SQLSTATE changes:

24000: Returned if no result set was created.

S1002: Column 0 was bound; SQLFetch cannot be used to retrieve bookmarks.

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if an hstmt associated with the hdbc was in a Need Data state (see Appendix B).

S1010: Returned if calls to SQLExtendedFetch and SQLFetch are mixed for the same cursor.

S1C00: Returned if the driver cannot convert the data from a driver-specific SQL data type to the specified C data type.

[Chapter 22, SQLFetch; Appendix B, Statement Transitions]


SQLForeignKeys (What's New)

1) Foreign and primary keys are defined by SQL '92, not by the data source or driver, as stated in the ODBC 1.0 Programmer's Reference.  [Chapter 22, SQLForeignKeys]

2) The FK_NAME and PK_NAME columns were added to the result set.  [Chapter 22, SQLForeignKeys]

3) SQLSTATE changes:

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1C00: Returned if the combination of the concurrency and the cursor type was not supported.

[Chapter 22, SQLForeignKeys; Appendix B, Statement Transitions]


SQLFreeStmt (What's New)

SQLSTATE changes:

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

[Chapter 22, SQLFreeStmt; Appendix B, Statement Transitions]


SQLGetConnectOption (What's New)

SQLSTATE changes:

S1010: No longer returned if an hstmt on the hdbc is in a Need Data or asynchronous state.

S1010: Returned if the function was called after SQLBrowseConnect returned SQL_NEED_DATA and before SQLBrowseConnect returned a different return code.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

[Chapter 22, SQLGetConnectOption; Appendix B, Statement Transitions]


SQLGetCursorName and SQLSetCursorName (What's New)

SQLSTATE changes:

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1015: No longer returned if the SQL statement associated with the hstmt did not use a cursor; the cursor name is associated with the hstmt, not just with the SQL statement.

[Chapter 22, SQLGetCursorName and SQLSetCursorName; Appendix B, Statement Transitions]


SQLGetData (What's New)

1) An application can call SQLGetData to retrieve data in parts only when retrieving character or binary C data from a column whose type is character, binary, or data source specific.  [Chapter 22, SQLGetData]

2) The driver can only truncate data that has been converted to character or binary C data. Character data is truncated to cbValueMax-1 bytes; binary data is truncated to cbValueMax bytes. After truncation, character data is null terminated.  [Chapter 22, SQLGetData]

3) The cbValueMax argument is ignored unless the data type is character or binary.  [Chapter 22, SQLGetData]

4) The number of bytes available to return before the data is fetched is returned in pcbValue.  [Chapter 22, SQLGetData]

5) A driver can extend the capabilities of SQLGetData to allow an application to:

Retrieve data from columns in any order, rather than in left-to-right order.

Retrieve data from columns that occur before the last bound column.

Retrieve data from a rowset.

Retrieve data from a bound column.

To determine which of these extensions a driver and data source support, an application calls SQLGetInfo with the SQL_GETDATA_EXTENSIONS information type. [Chapter 22, SQLGetData and SQLGetInfo]

6) SQLSTATE changes:

24000: Returned if no result set was created.

24000: Returned if the cursor was positioned before the start or after the end of the result set.

S1002: Returned if icol is 0 and data was fetched with SQLFetch.

S1002: Returned if icol is 0 and bookmarks were not enabled.

S1002: Returned if icol is 0 and the driver is an ODBC 1.0 driver.

S1002: Returned if icol specifies a bound column.

S1003: Returned if icol is 0 and fCType is not SQL_C_BOOKMARK.

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1109: Returned if the cursor is positioned on a deleted or error row in a rowset.

S1C00: Returned if the driver cannot convert the data from a driver-specific SQL data type to the specified C data type.

S1C00: Returned if icol is 0 and the driver does not support bookmarks.

S1C00: Returned if fCType is an ODBC 2.x integer data type and the driver is an ODBC 1.0 driver.

[Chapter 22, SQLGetData; Appendix B, Statement Transitions]


SQLGetFunctions (What's New)

1) A driver can implement SQLGetFunctions. If the driver implements SQLGetFunctions, the Driver Manager calls SQLGetFunctions in the driver. Otherwise, it executes SQLGetFunctions itself.  [Chapter 22, SQLGetFunctions]

2) An application can now call SQLGetFunctions a single time and pass it an array, rather than calling it once for each ODBC function. In the elements of this array, SQLGetFunctions returns TRUE if the ODBC function is supported, FALSE if it is not.  [Chapter 22, SQLGetFunctions]

3) Added SQL_API_SQLBINDPARAMETER.  [Chapter 22, SQLGetFunctions]

4) SQLSTATE changes:

S1010: Returned if the function was called after SQLBrowseConnect returned SQL_NEED_DATA and before SQLBrowseConnect returned a different return code.

[Chapter 22, SQLGetFunctions]


SQLGetInfo (What's New)

1) Drivers are required to return a value for each information type listed in the ODBC 2.0 Programmer's Reference. If an information type does not apply to the driver or data source, the driver returns one of the following values:

Format of rgbInfoType	Returned Value
Character string ("Y" or "N")	"N"
Character string (not "Y" or "N")	""  (empty string)
16-bit integer	0
32-bit bitmask or 32-bit integer	0L
Drivers return SQLSTATE S1C00 (Driver not capable) only for unsupported values of fInfoType, such as driver-specific information types for other drivers. This change was made because of the following concerns in the ODBC developer community:

Returning SQL_ERROR and SQLSTATE S1C00 (Driver not capable) is ambiguous; it is not clear whether the driver is incapable of returning a value for the information type or the information type does not apply to the data source.

It is much slower for an application to call SQLError to find out that the information type does not apply to the data source than to have the driver return this information.

Application developers should be aware that ODBC 1.0 drivers can return either SQLSTATE S1C00 (Driver not capable) or one of the above values for information types that do not apply to the data source.  [Chapter 22, SQLGetInfo]

2) The value returned in rgbValue can only be truncated if it is character data.  [Chapter 22, SQLGetInfo]

3) SQL_DEFAULT_TXN_ISOLATION is a 32-bit integer, not a 32-bit bitmask.  [Chapter 22, SQLGetInfo]

4) Drivers that conform to the ODBC 2.01 or ODBC 2.01a specification return "02.01" for the SQL_DRIVER_ODBC_VER information type.  [SQLGetInfo (Problems and Information)]

5) SQL_OUTER_JOINS returns the same values it returned in ODBC 1.0.  [SQLGetInfo (Problems and Information)]

6) SQL_ROW_UPDATES returns whether a keyset-driven or a mixed cursor maintains row versions or values for all fetched rows and therefore can detect any changes made to a row since the row was last fetched.  [Chapter 22, SQLGetInfo]

7) Click here to see the values of fInfoType that have been added: New fInfoType Values.  [Chapter 22, SQLGetInfo; SQLGetInfo (Problems and Information)]

8) Click here to see the return values added to existing values of fInfoType: Added fInfoType Return Values.  [Chapter 22, SQLGetInfo]

9) SQLSTATE changes:

S1010: Not returned by SQLGetInfo in ODBC 2.x.


New fInfoType Values (What's New)

The following values of fInfoType in SQLGetInfo have been added:

SQL_ALTER_TABLE

SQL_COLUMN_ALIAS

SQL_DRIVER_HLIB

SQL_DRIVER_ODBC_VER

SQL_FILE_USAGE

SQL_GETDATA_EXTENSIONS

SQL_GROUP_BY

SQL_KEYWORDS

SQL_MAX_BINARY_LITERAL_LEN

SQL_MAX_CHAR_LITERAL_LEN

SQL_MAX_COLUMNS_IN_GROUP_BY

SQL_MAX_COLUMNS_IN_INDEX

SQL_MAX_COLUMNS_IN_ORDER_BY

SQL_MAX_COLUMNS_IN_SELECT

SQL_MAX_COLUMNS_IN_TABLE

SQL_MAX_INDEX_SIZE

SQL_MAX_ROW_SIZE

SQL_MAX_ROW_SIZE_INCLUDES_LONG

SQL_MAX_STATEMENT_LEN

SQL_MAX_TABLES_IN_SELECT

SQL_MAX_USER_NAME_LEN

SQL_NEED_LONG_DATA_LEN

SQL_NULL_COLLATION

SQL_OJ_CAPABILITIES (ODBC 2.01)

SQL_ORDER_BY_COLUMNS_IN_SELECT

SQL_OWNER_USAGE

SQL_POS_OPERATIONS

SQL_POSITIONED_STATEMENTS

SQL_QUALIFIER_LOCATION

SQL_QUALIFIER_USAGE

SQL_QUOTED_IDENTIFIER_CASE

SQL_SPECIAL_CHARACTERS

SQL_STATIC_SENSITIVITY

SQL_SUBQUERIES

SQL_TIMEDATE_ADD_INTERVALS

SQL_TIMEDATE_DIFF_INTERVALS

SQL_UNION


Added fInfoType Return Values (What's New)

The following return values have been added to existing fInfoType values in SQLGetInfo.

fInfoType	New Return Value
SQL_NUMERIC_FUNCTIONS	SQL_FN_NUM_DEGREES SQL_FN_NUM_LOG10 SQL_FN_NUM_POWER SQL_FN_NUM_RADIANS SQL_FN_NUM_ROUND SQL_FN_NUM_TRUNCATE
SQL_SCROLL_OPTIONS	SQL_SO_STATIC
SQL_STRING_FUNCTIONS	SQL_FN_STR_DIFFERENCE SQL_FN_STR_LOCATE_2 SQL_FN_STR_SOUNDEX SQL_FN_STR_SPACE
SQL_TIMEDATE_FUNCTIONS	SQL_FN_TD_DAYNAME SQL_FN_TD_MONTHNAME SQL_FN_TD_TIMESTAMPADD SQL_FN_TD_TIMESTAMPDIFF
SQL_TXN_CAPABLE	SQL_TC_DDL_COMMIT SQL_TC_DDL_IGNORE


SQLGetStmtOption (What's New)

1) The SQL_GET_BOOKMARK and SQL_ROW_NUMBER statement options have been added as options that can be retrieved but not set.  [Chapter 7, Using Bookmarks; Chapter 22, SQLGetStmtOption]

2) SQLSTATE changes:

24000: Returned if fOption is SQL_GET_BOOKMARK or SQL_ROW_NUMBER and the cursor was not open or the cursor was positioned before the start or after the end of the result set.

S1010: Returned if the hstmt was in a Need Data state(see Appendix B).

S1011: Returned if fOption is SQL_GET_BOOKMARK and bookmarks have not been enabled.

S1109: Returned if fOption is SQL_GET_BOOKMARK or SQL_ROW_NUMBER and the cursor is positioned on a deleted or error row.

[Chapter 22, SQLGetStmtOption; Appendix B, Statement Transitions]


SQLGetTypeInfo (What's New)

1) Two new columns (MINIMUM_SCALE and MAXIMUM_SCALE) were added to the end of the result set.  [Chapter 22, SQLGetTypeInfo]

2) The CASE_SENSITIVE column applies to comparisons as well as collations. [Chapter 22, SQLGetTypeInfo]

3) NULL is returned in the UNSIGNED_ATTRIBUTE column for columns with nonnumeric data types.  [Chapter 22, SQLGetTypeInfo]

4) The value returned in the TYPE_NAME column must be used in CREATE TABLE and ALTER TABLE statements.  [Chapter 22, SQLGetTypeInfo]

5) The value returned in the LOCAL_TYPE_NAME column is intended to be used only for display.  [Chapter 22, SQLGetTypeInfo]

6) SQLSTATE changes:

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1C00: Returned if the combination of the concurrency and the cursor type was not supported.

[Chapter 22, SQLGetTypeInfo; Appendix B, Statement Transitions]


SQLMoreResults (What's New)

SQLSTATE changes:

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

[Chapter 22, SQLMoreResults; Appendix B, Statement Transitions]


SQLNativeSql (What's New)

SQLSTATE changes:

S1090: Returned if cbSqlStrMax is less than 0 and szSqlStr is not a null pointer.

[Chapter 22, SQLNativeSql]


SQLNumParams (What's New)

1) SQLNumParams can be executed asynchronously.  [Chapter 22, SQLSetStmtOption]

2) SQLSTATE changes:

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1010: Returned if SQLNumParams is called prior to SQLPrepare or SQLExecDirect.

[Chapter 22, SQLNumParams; Appendix B, Statement Transitions]


SQLNumResultCols (What's New)

SQLSTATE changes:

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

[Chapter 22, SQLNumResultCols; Appendix B, Statement Transitions]


SQLParamData (What's New)

1) If SQLExecDirect or SQLExecute returns SQL_NEED_DATA, prgbValue returns the value passed in the rgbValue argument of SQLBindParameter. If SQLSetPos returns SQL_NEED_DATA, prgbValue returns the address of the row in the rgbValue buffer for which the corresponding pcbValue buffer contained the result of the SQL_LEN_DATA_AT_EXEC() macro.  [Chapter 22, SQLBindParameter and SQLSetPos]

2) Because SQLSetPos can return SQL_NEED_DATA, SQLParamData can return any SQLSTATE that SQLSetPos can return.  [Chapter 22, SQLParamData]

3) SQLSTATE changes:

22026: Returned if not enough data is sent for a long data-at-execution column.

S1008: Returned if the function is canceled from a different thread.

S1008: Returned if SQLCancel is called to cancel processing before all data was sent for all data-at-execution parameters.

S1010: Returned if the previous function call was not SQLExecDirect, SQLExecute, SQLPutData, or SQLSetPos or the return code was not SQL_NEED_DATA.

S1DE0: Not returned, since SQLParamData returns SQL_SUCCESS if there are no more data-at-execution parameters or SQL_NEED_DATA if there are.

[Chapter 22, SQLParamData]


SQLParamOptions (What's New)

SQLSTATE changes:

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

[Chapter 22, SQLParamOptions; Appendix B, Statement Transitions]


SQLPrepare (What's New)

1) Drivers must parse ODBC escape clauses in SQL statements before passing them to the data source for preparation.  [Chapter 22, SQLPrepare]

2) Parameter information can be checked at statement preparation or execution time. For maximum interoperability, applications should unbind parameters relating to an old SQL statement before preparing a new one.  [Chapter 22, SQLPrepare]

3) SQLSTATE changes:

S0002: Returned if a nonexistent table is referenced in a constraint in a CREATE TABLE statement.

S0022: Returned if a nonexistent column is referenced in a constraint in a CREATE TABLE statement.

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1090: Returned if cbSqlStr is less than or equal to 0, but not SQL_NTS.

[Chapter 22, SQLPrepare; Appendix B, Statement Transitions]


SQLPrimaryKeys (What's New)

1) Added PK_NAME columns to the result set.  [Chapter 22, SQLPrimaryKeys]

2) SQLSTATE changes:

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1C00: Returned if the combination of the concurrency and the cursor type was not supported.

[Chapter 22, SQLPrimaryKeys; Appendix B, Statement Transitions]


SQLProcedureColumns (What's New)

1) In the description of the LENGTH column, the words "transfer size" were changed to "length," as transfer size might have implied that the null termination byte should be counted for character data.  [Chapter 22, SQLProcedureColumns]

2) The COLUMN_TYPE column can return SQL_RETURN_VALUE.  [Chapter 22, SQLProcedureColumns]

3) SQLSTATE changes:

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1C00: Returned if the combination of the concurrency and the cursor type was not supported.

[Chapter 22, SQLProcedureColumns; Appendix B, Statement Transitions]


SQLProcedures (What's New)

1) Added the PROCEDURE_TYPE column to the result set.  [Chapter 22, SQLProcedures]

2) SQLSTATE changes:

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1C00: Returned if the combination of the concurrency and the cursor type was not supported.

[Chapter 22, SQLProcedures; Appendix B, Statement Transitions]


SQLPutData (What's New)

1) The cbValue argument is ignored except for binary or character data or when it is SQL_NULL_DATA, SQL_NTS, or SQL_DEFAULT_PARAM.  [Chapter 22, SQLPutData]

2) An application can call SQLPutData to send data in parts only when sending character or binary C data to a column whose type is character, binary, or data source specific.  [Chapter 22, SQLPutData]

3) The C data type of the data in rgbValue can be specified in SQLBindCol or SQLBindParameter.  [Chapter 22, SQLPutData]

4) SQLSTATE changes:

07006: Returned if the data value identified by fCType in SQLBindParameter cannot be converted to the data type identified by fSqlType.  (see SQLBindParameter (Problems and Information))

22001: Returned if too much data is sent for a long data-at-execution column.

22003: Returned if SQLPutData was called more than once and the C and SQL data types were not character or binary or data source-specific.

22005: Returned if data sent for a parameter is incompatible with the data type of the associated column.

S1008: Returned if the function was canceled from a different thread.

S1008: Returned if SQLCancel is called to cancel processing before all data was sent for all data-at-execution parameters.

S1009: Returned if rgbValue is a null pointer and cbValue is not 0, SQL_DEFAULT_PARAM, or SQL_NULL_DATA.

S1010: Returned if the previous function call was a call to SQLExecDirect, SQLExecute, or SQLSetPos that returned SQL_NEED_DATA.

S1DE0: Not returned, since SQLParamData, not SQLPutData detects whether there are remaining data-at-execution parameters.

[Chapter 22, SQLPutData]


SQLRowCount (What's New)

1) SQLRowCount can, in pcrow, return the number of rows affected by calling SQLSetPos with fOption set to SQL_ADD, SQL_DELETE, or SQL_UPDATE.  [Chapter 22, SQLRowCount]

2) Many data sources cannot return the number of rows in a result set before fetching them and interoperable applications should not depend on this behavior.  [Chapter 22, SQLRowCount]

3) SQLSTATE changes:

S1010: Returned if called prior to calling SQLExecDirect, SQLExecute, or SQLSetPos on the hstmt.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

[Chapter 22, SQLRowCount; Appendix B, Statement Transitions]


SQLSetConnectOption (What's New)

1) The default trace file is \SQL.LOG, not SQL.LOG. The Driver Manager used this file in ODBC 1.0; the ODBC 1.0 Programmer's Reference was incorrect.  [Chapter 22, SQLSetConnectOption]

2) The driver must maintain connection options as long as the hdbc is allocated.  [Chapter 22, SQLSetConnectOption]

3) In Windows 3.1, tracing affects all applications. When an application turns tracing on, the Driver Manager traces calls made by all applications; when an application turns tracing off, the Driver Manager doesn't trace calls by any applications.  [Chapter 22, SQLSetConnectOption]

4) Changing from manual-commit mode to auto-commit mode commits any open transactions on the connection.  [Chapter 22, SQLSetConnectOption]

5) The SQL_ODBC_CURSORS, SQL_PACKET_SIZE, and SQL_QUIET_MODE connection options have been added.  [Chapter 22, SQLSetConnectOption; Appendix G]

6) The default value of SQL_LOGIN_TIMEOUT is driver-dependent and must be nonzero.  [Chapter 22, SQLSetConnectOption]

7) If the driver or data source does not support the specified value for the SQL_LOGIN_TIMEOUT or SQL_PACKET_SIZE options, the driver can substitute a similar value and return SQL_SUCCESS_WITH_INFO.  [Chapter 22, SQLSetConnectOption]

8) If fOption is a statement option, SQLSetConnectOption can return any SQLSTATE that can be returned for that statement option by SQLSetStmtOption.  [Chapter 22, SQLSetConnectOption and SQLSetStmtOption]

9) SQLSTATE changes:

01S02: Returned if a similar value was substituted for vParam.

08002: Returned if fOption is SQL_ODBC_CURSORS and the hdbc is in a connected state.

IM013: Returned by any function if there is a tracing error.

S1010: Returned if the function was called after SQLBrowseConnect returned SQL_NEED_DATA and before SQLBrowseConnect returned a different return code.

S1010: Returned if an hstmt associated with the hdbc was in a Need Data state (see Appendix B).

S1011: Returned if fOption is SQL_TXN_ISOLATION and a transaction is open.

[Chapter 22, SQLSetConnectOption; Appendix B, Statement Transitions]


SQLSetParam (What's New)

This function has been replaced with SQLBindParameter. See SQLBindParameter for more information.


SQLSetPos (What's New)

1) The fRefresh argument has been changed from BOOL to UWORD and has been renamed fOption. The FALSE and TRUE values have been replaced with the SQL_POSITION and SQL_REFRESH #defines. Note that both BOOL and UWORD are defined as two byte integers, so these changes do not affect compiled code. [Chapter 22, SQLSetPos]

2) The fLock argument has been changed from BOOL to UWORD. The FALSE and TRUE values have been replaced with the SQL_LOCK_NO_CHANGE and SQL_LOCK_EXCLUSIVE #defines. Note that both BOOL and UWORD are defined as defined as two byte integers, so these changes do not affect compiled code. The purpose of this argument is to allow applications to simulate transactions.  [Chapter 22, SQLSetPos]

3) An application can call SQLSetPos with the SQL_UPDATE, SQL_DELETE, or SQL_ADD values of the fOption argument to add, update, delete, or undelete a row of data instead of executing an SQL statement to do so.  [Chapter 22, SQLSetPos]

4) If SQLSetPos encounters an error while performing a bulk operation (the irow argument is 0), the driver returns one or more SQLSTATEs for the offending row and continues processing.  [Chapter 22, SQLSetPos]

5) If irow is 0 and fOption is SQL_ADD, SQL_DELETE, SQL_REFRESH, or SQL_UPDATE, the current row after SQLSetPos is done is the same as it was before SQLSetPos was called. [SQLSetPos (Problems and Information)]

6) If the SQL_CONCURRENCY statement option is SQL_CONCUR_READ_ONLY, the cursor cannot be updated with SQLSetPos.  [Chapter 22, SQLSetPos]

7) SQLSTATE changes:

23000: Returned if fOption is SQL_ADD and an unbound column is defined as NOT NULL.

21S02: Returned if fOption is SQL_ADD and no columns were bound.

01S03: Returned if fOption is SQL_UPDATE or SQL_DELETE and no rows were affected.

01S04: Returned if fOption is SQL_UPDATE or SQL_DELETE and more than one row was affected.

24000: Returned if no result set was created.

24000: Returned if irow pointed to a row before the start or after the end of the result set.

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1109: Returned if irow points to a deleted or error row.

S1109: Returned if irow is 0 and fOption is SQL_POSITION.

[Chapter 22, SQLSetPos; Appendix B, Statement Transitions; SQLSetPos (Problems and Information)]


SQLSetScrollOptions (What's New)

SQLSTATE changes:

24000: No longer returned.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

[Chapter 22, SQLSetScrollOptions; Appendix B, Statement Transitions]


SQLSetStmtOption (What's New)

1) The SQL_CONCURRENCY, SQL_CURSOR_TYPE, SQL_KEYSET_SIZE, SQL_ROWSET_SIZE, and SQL_SIMULATE_CURSOR statement options have been added.  [Chapter 22, SQLSetStmtOption]

2) SQLSetScrollOptions has been superceded by the SQL_CURSOR_TYPE, SQL_CONCURRENCY, SQL_KEYSET_SIZE, and SQL_ROWSET_SIZE statement options. Although drivers must support SQLSetScrollOptions, applications should call it only in ODBC 1.0 drivers.  [Chapter 22, SQLSetConnectOption, SQLSetScrollOptions, and SQLSetStmtOption]

3) The SQL_MAX_LENGTH statement option applies to all character and binary columns, not just SQL_LONGVARCHAR and SQL_LONGVARBINARY columns. It was changed because some data sources have CHAR and VARCHAR data types up to 32K long and it was felt columns of these types should be covered by this statement option.

Application developers should be aware that if:

An ODBC 1.0 application uses this statement option, and

The application also retrieves SQL_CHAR, SQL_VARCHAR, or SQL_BINARYdata, and

The length of any buffer used to retrieve the SQL_CHAR, SQL_VARCHAR or SQL_BINARY data is greater than the value of this statement option

then that data will be truncated by an ODBC 2.x driver that supports this option.  [Chapter 22, SQLSetStmtOption]

4) The SQL_MAX_LENGTH statement option is intended to reduce network traffic and should only be supported when the data source (not the driver) can implement it. To guarantee data truncation, an application should specify the desired data size in the cbValueMax argument in SQLBindCol or SQLGetData.  [Chapter 22, SQLSetStmtOption]

5) If the driver or data source does not support the specified value for the SQL_CONCURRENCY, SQL_CURSOR_TYPE, SQL_KEYSET_SIZE, SQL_MAX_LENGTH, SQL_MAX_ROWS, SQL_QUERY_TIMEOUT, SQL_ROWSET_SIZE, or SQL_SIMULATE_CURSOR options, the driver can substitute a similar value and return SQL_SUCCESS_WITH_INFO.  [Chapter 22, SQLSetConnectOption]

6) SQL_MAX_ROWS is intended to reduce network traffic and is conceptually applied when the result set is created.  [Chapter 22, SQLSetStmtOption]

7) SQLSTATE changes:

01S02: Returned if the driver substituted a different value for vParam.

24000: Returned if the cursor is open and fOption is SQL_USE_BOOKMARKS, SQL_CURSOR_TYPE, SQL_CONCURRENCY, or SQL_SIMULATE_CURSOR.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1011: Returned if the statement has been prepared and fOption is SQL_USE_BOOKMARKS, SQL_CURSOR_TYPE, SQL_CONCURRENCY, or SQL_SIMULATE_CURSOR.

[Chapter 22, SQLSetStmtOption; Appendix B, Statement Transitions]


SQLSpecialColumns (What's New)

1) In the description of the LENGTH column, the words "transfer size" were changed to "length," as transfer size might have implied that the null termination byte should be counted for character data.  [Chapter 22, SQLSpecialColumns]

2) The PSEUDO_COLUMN column was added to the result set.  [Chapter 22, SQLSpecialColumns]

3) All columns returned by SQLSpecialColumns are searchable and selectable; they are not necessarily returned by SQLColumns.  [Chapter 22, SQLSpecialColumns]

4) The LENGTH column is the same as the PRECISION column for character or binary data.  [Chapter 22, SQLSpecialColumns]

5) SQLSTATE changes:

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1C00: Returned if the combination of the concurrency and the cursor type was not supported.

[Chapter 22, SQLSpecialColumns; Appendix B, Statement Transitions]


SQLStatistics (What's New)

1) If an index column is based on an expression or a filter condition, the expression or filter condition is returned in the COLUMN_NAME column. An empty string is returned if the expression or filter condition cannot be determined.  [Chapter 22, SQLStatistics]

2) SQLStatistics can return columns (such as expressions) that are not returned by SQLColumns.  [SQLStatistics (Problems and Information)]

3) A FILTER_CONDITION column was added to the result set.  [Chapter 22, SQLStatistics]

4) SQLSTATE changes:

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1C00: Returned if the combination of the concurrency and the cursor type was not supported.

[Chapter 22, SQLStatistics; Appendix B, Statement Transitions]


SQLTablePrivileges (What's New)

SQLSTATE changes:

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1C00: Returned if the combination of the concurrency and the cursor type was not supported.  [Chapter 22, SQLTablePrivileges; Appendix B, Statement Transitions]


SQLTables (What's New)

1) The szTableQualifier argument does not support search patterns.  [Chapter 22, SQLTables]

2) If szTableType is a percent sign (%) and szTableQualifier, szTableOwner, and szTableName are empty strings (""), SQLTables returns a result set of the table types supported by the data source.  [Chapter 22, SQLTables]

3) Table types in the szTableType argument can be unquoted or surrounded in single quotes.  [Chapter 22, SQLTables]

4) In addition to the types listed in ODBC 1.0, szTableType can be LOCAL TEMPORARY or GLOBAL TEMPORARY.  [Chapter 22, SQLTables]

5) SQLSTATE changes:

S1008: Returned if the function was canceled from a different thread.

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

S1C00: Returned if the combination of the concurrency and the cursor type was not supported.

[Chapter 22, SQLTables; Appendix B, Statement Transitions]


SQLTransact (What's New)

1) SQLTransact affects all statements on an hdbc, not just UPDATE, INSERT, and DELETE statements. For example, some data sources require that a SELECT statement be committed or rolled back in order to free table locks.  [Chapter 25, SQLTransact]

2) SQLSTATE changes:

S1010: Returned if the hstmt was in a Need Data state (see Appendix B).

[Chapter 22, SQLFetch; Appendix B, Statement Transitions]


Appendix B: ODBC State Transition Tables (What's New)

1) The state transition tables have been completely rewritten. These tables are consistent (except for bug fixes) with the tables in the ODBC 1.0 Programmer's Reference, but clarify many transitions. They also show which state transitions the Driver Manager checks.  [Appendix B]

2) The following bugs have been fixed in the state transition tables:

If the cursor is positioned and SQLExtendedFetch returns SQL_NO_DATA_FOUND, the statement does not return to the executed state. It remains in the cursor state.

From the allocated and prepared states, SQLMoreResults cannot go to the executed state.

If SQLParamData returns SQL_ERROR, the statement returns to the allocated or prepared state.

From the executed and cursor states, SQLTransact can go to the allocated, prepared, or executed states, depending on the cursor commit or rollback behavior.

SQLColAttributes and SQLDescribeCol cannot return SQLSTATE 24000 (Invalid cursor position) in the cursor states.

SQLSetScrollOptions returns S1010 if the statement is in the prepared, executed, or cursor states.

[Appendix B, Statement Transitions]


Appendix C: SQL Grammar (What's New)

Batch Statements

Character Data

Column Aliases

Core SQL Conformance Level

CREATE TABLE

CString Objects

Data Source-Specific Grammar

Data Types

Date and Time Data

DROP COLUMN Clause

Expressions in LIKE Predicates

LIKE Predicate Escape Character

Nested Outer Joins

ODBC Keywords

Outer Joins

Parameter Markers

Qualifiers and Owners

UNION ALL


Batch Statements (What's New)

The ODBC 1.0 Programmer's Reference stated that the return code of the function (SQLExecDirect or SQLExecute) used to execute a batch of statements depended on the success or failure of all statements in the batch. This statement was untrue.  [Chapter 7, Retrieving Multiple Results; Chapter 15, Returning Multiple Results]


Character Data (What's New)
!!!Character Data (What's New)

The minimum SQL conformance level requires at least one character data type; it can be SQL_CHAR, SQL_VARCHAR, or SQL_LONGVARCHAR.  [Chapter 1, SQL Conformance Levels; Appendix C, Elements Used in SQL Statements; Appendix D, SQL Data Types]


Column Aliases (What's New)

Column aliases are supported in select lists.  [Appendix C, column-alias and select-list]


Core SQL Conformance Level (What's New)

Positioned update and delete statements, the SELECT FOR UPDATE, and the UNION clause of the SELECT statement have been moved to the extended SQL grammar. This change was made because driver and application developers felt that the SQL conformance levels were unusable in their current form; drivers that supported all of the core SQL conformance level except these items were forced to report that they only supported the minimum SQL conformance level. The new conformance levels allow applications to distinguish between minimum and core drivers.

Application developers should be aware that, to an ODBC 1.0 application, the core conformance level means that a driver supports these items. This assumption is not valid for ODBC 2.x drivers.  [Chapter 1, SQL Conformance Levels; Chapter 7, Executing Positioned Update and Delete Statements; Appendix C, delete-statement-positioned, update-statement-positioned, select-statement, and select-for-update-statement]


CREATE TABLE (What's New)

The DEFAULT subclause of the column definition clause of the CREATE TABLE statement is optional.  [Appendix C, create-table-statement]


CString Objects (What's New)

Because objects of the CString class in Microsoft C++ are signed and string arguments in ODBC functions are unsigned, applications that pass CString objects to ODBC functions without casting them will receive compiler warnings.  [Appendix D, Core C Data Types]


Data SourceSpecific Grammar (What's New)
Data Source-Specific Grammar (What's New)

Drivers should support data source-specific extensions to the SQL language, although interoperable applications should not rely on those extensions.  [Chapter 1, SQL Conformance Levels]


Data Types (What's New)

All data types in the grammar are samples; applications must use the data types returned by SQLGetTypeInfo in CREATE TABLE and ALTER TABLE statements.  [Appendix C, approximate-numeric-type, binary-type, bit-type, character-type, date-type, exact-numeric-type, time-type, timestamp-type]


Date and Time Data (What's New)

If a data source supports the SQL_DATE, SQL_TIME, or SQL_TIMESTAMP data types, it must also support the corresponding extended SQL grammar for date, type, or timestamp literals.  [Chapter 6, Date, Time, and Timestamp Data; Appendix C]


DROP COLUMN Clause (What's New)

The extended grammar supports the DROP COLUMN clause of the ALTER TABLE statement.  [Appendix C, alter-table-statement]


Expressions in LIKE Predicates (What's New)

LIKE predicates can contain expressions.  [Appendix C, like-predicate]


LIKE Predicate Escape Character (What's New)

An escape character can be defined for a LIKE predicate with an ESCAPE clause. SQLGetInfo returns whether this is supported with SQL_LIKE_ESCAPE_CLAUSE.  [Chapters 6 and 4, LIKE Predicate Escape Characters; Chapter 22, SQLGetInfo; Appendix C, like-predicate and ODBC-like-escape-clause]


Nested Outer Joins (What's New)

Outer joins can be nested. A driver returns the supported level of outer joins through the SQL_OJ_CAPABILITIES information type in SQLGetInfo.  [Chapter 6, Outer Joins; Chapter 22, SQLGetInfo; Appendix C, outer-join]


ODBC Keywords (What's New)

The SQL_ODBC_KEYWORDS #define contains a comma-separated list of all ODBC keywords.  [Appendix C, List of Reserved Keywords]


Outer Joins (What's New)

The grammar in ODBC 1.0 only allowed a table reference list to consist of table names or an outer join. This was incorrect. A table reference list can contain table names, an outer join, or table names and a single outer join.  [Appendix C, table-reference]


Parameter Markers (What's New)

Parameter markers are not allowed as the argument of a set-function-reference.  [Appendix C, Parameter Markers]


Qualifiers and Owners (What's New)

Qualifiers and owners were added to the grammar.  [Appendix C, base-table-name, procedure-name, ref-table-name, table-name, and viewed-table-name]


UNION ALL (What's New)

ALL was added as an optional keyword in the UNION clause.  [Appendix C, select-statement]


Appendix D: Data Types (What's New)

Binary Data

Bit Data

cbColDef Argument

Converting Data

Date, Time, and Timestamp Data

Date, Time, and Timestamp Data, Character Format

Default C Data Types

Driver-Specific SQL Data Types

Floating-Point Data

Leading and Trailing Spaces

ODBC 1.0 Data Types

pcbValue Argument

Precision, Length, and Display Size

Significant Digits

Timestamp Data

Truncation of Parameter Data

Unsigned C Data Types


Binary Data (What's New)

When converting binary SQL data to character C data, the driver compares the length of the character buffer times two (not the length of the character buffer) with the length of the binary data. When converting character C data to binary SQL data, the driver compares the length of the character data divided by two (not the length of the character buffer) with the length of the binary column. When converting character C data to binary SQL data, the driver returns SQLSTATE 22005 (Error in assignment) if the data does not represent a binary value.  [Appendix D, SQL to C: Binary and C to SQL: Character]


Bit Data (What's New)

1) Since some data sources cannot perform numeric operations on bit data, and ANSI SQL '92 does not recognize numeric operations on bit data, the BIT data type was separated from the numeric data types.  [Appendix C, bit-literal and bit-type; Appendix D, Converting Data from SQL to C Data Types and Converting Data from C to SQL Data Types]

2) When converting character data to bit data, the driver returns SQLSTATE 01004 (Data truncated) if the number is a non-whole value between 0 and 2; it returns SQLSTATE 22005 (Error in assignment) if the character string is not a numeric literal.  [Appendix D, SQL to C: Character and C to SQL: Character]

3) When converting numeric data to bit data, the driver returns SQLSTATE 01004 (Data truncated) if the number is a non-whole value between 0 and 2. [Appendix D, SQL to C: Numeric and C to SQL: Numeric]


cbColDef Argument (What's New)

The cbColDef argument of SQLSetParam and SQLBindParameter must be the length of the data to be sent for a data-at-execution parameter only in ODBC 1.0.  [Chapter 22, SQLBindParameter; Appendix D, Precision]


Converting Data (What's New)

For each SQL data type they support, drivers must support all the conversions listed in Appendix D, "Data Types."  [Appendix D, Converting Data from SQL to C Data Types and Converting Data from C to SQL Data Types]


Date, Time, and Timestamp Data (What's New)

1) When converting character data representing a date to timestamp data, the time portion of the timestamp is set to 0. When converting time data or character data representing a time to timestamp data, the date portion of the timestamp is set to the current date (changed to comply with ANSI SQL '92). Application developers should be aware that this may cause sorting problems for applications that convert time data to timestamp data in an environment of ODBC 1.0 and ODBC 2.x drivers. [Appendix D, SQL to C: Character, SQL to C: Time, C to SQL: Character, and C to SQL: Time]

2) When converting C date, time, or timestamp data, the driver returns SQLSTATE 22008 (Datetime field overflow) if the data stored in the date, time, or timestamp structure is invalid.  [Appendix D, C to SQL: Date, C to SQL: Time, and C to SQL: Timestamp]

3) When converting data from a timestamp to a date, the driver returns SQLSTATE 01004 (Data truncated) only if the time portion of the timestamp is nonzero. When converting data from a timestamp to a time, the driver returns SQLSTATE 01004 (Data truncated) only if the fractional seconds portion of the timestamp is nonzero. When converting data from a timestamp to a timestamp, the driver returns SQLSTATE 01004 (Data truncated) only if the fractional seconds portion of the timestamp is nonzero.  [Appendix D, SQL to C: Character, SQL to C: Timestamp, C to SQL: Character, and C to SQL: Timestamp]


Date, Time, and Timestamp Data, Character Format (What's New)

1) When converting character SQL data to C date, time, or timestamp data, drivers must be able to convert data from the formats specified in the SQL grammar. Drivers may support additional, driver-specific formats.  [Appendix C, date-value, time-value, and timestamp-value; Appendix D, SQL to C: Character]

2) When converting character C data to SQL date, time, or timestamp data, the driver must be able to convert data from the ODBC date, time, and timestamp literal formats in the SQL grammar. Drivers may support additional, driver-specific formats.  [Appendix C, ODBC-date-literal, ODBC-time-literal, and ODBC-timestamp-literal; Appendix D, C to SQL: Character]

3) When converting date, time, or timestamp C data to character SQL data, the resulting character data uses the formats specified in the SQL grammar. [Appendix C, date-value, time-value, and timestamp-value; Appendix D, C to SQL: Date, C to SQL: Time, and C to SQL: Timestamp]


Default C Data Types (What's New)

For maximum interoperability, applications should specify a C data type other than SQL_C_DEFAULT.  [Appendix D, Default C Data Types]


Driver-Specific SQL Data Types (What's New)

A driver can support driver-specific SQL data types. These are accepted by SQLBindParameter and SQLGetTypeInfo and returned by SQLColAttributes, SQLColumns, SQLDescribeCol, SQLDescribeParam, SQLGetTypeInfo, SQLProcedureColumns, and SQLSpecialColumns.  [Chapter 11, Driver-Specific Data Types, Descriptor Types, Information Types, and Options; Appendix D, Data Types]


Floating-Point Data (What's New)

When converting character or numeric data to floating point data, the driver cannot return SQLSTATE 01004 (Data truncated), since floating point numbers, as stored on computers, do not have whole digits. (For example, the number known to an application as 100.2 might be stored by the computer as 1.002E2; it is impossible to determine which digits are fractional.)  [Appendix D, SQL to C: Character, SQL to C: Numeric, C to SQL: Character, and C to SQL: Numeric]


Leading and Trailing Spaces (What's New)

When converting character data to numeric, date, time, or timestamp data, leading and trailing spaces are ignored.  [Appendix D, SQL to C: Character and C to SQL: Character]


ODBC 1.0 Data Types (What's New)

ODBC 2.x applications must use ODBC 1.0 integer data types with ODBC 1.0 drivers.  [Appendix D, ODBC 1.0 C Data Types]


pcbValue Argument (What's New)

If SQLFetch, SQLExtendedFetch, or SQLGetData encounters an error while converting SQL data to C data, it does not modify the pcbValue argument specified in SQLBindCol or SQLGetData. This change was made in response to requests from many developers who felt that drivers should not be required to state how much data is available to return when they can't return that data due to an error. Application developers should be aware that an ODBC 1.0 application that used the pcbValue argument after an error occurred cannot do so with ODBC 2.x drivers.  [Appendix D, Converting Data From SQL to C Data Types]


Precision, Length, and Display Size (What's New)

If the driver cannot determine the precision, length, or display size of a column or parameter containing long data, the driver returns SQL_NO_TOTAL.  [Appendix D, Precision, Length, and Display Size]


Significant Digits (What's New)

The term "significant digits" was used incorrectly in Appendix D and has been replaced by the terms "whole digits" and "fractional digits".  [Appendix D, Converting Data from SQL to C Data Types and Converting Data from C to SQL Data Types]


Timestamp Data (What's New)

When converting timestamp SQL data to character C data, the driver checks if the character buffer length is 20, not 19. The extra byte is needed for the null termination byte.  [Appendix D, SQL to C: Timestamp]


Truncation of Parameter Data (What's New)

If C parameter data is truncated when it is sent to the data source, SQLExecDirect, SQLExecute, or SQLPutData returns SQLSTATE 01004 (Data truncated) instead of SQLSTATE 22001 (String data right truncation). This is to comply with ANSI SQL '92 and was previously published as part of the change document distributed with later copies of the ODBC SDK Version 1.0.  [Chapter 25, SQLExecDirect, SQLExecute, and SQLPutData; Appendix D, Converting Data from C to SQL Data Types]


Unsigned C Data Types (What's New)

Unsigned integer C data types were added so that applications no longer have to interpret integer data differently depending on whether it is signed or unsigned. Instead, applications now specify whether integer data is to be placed in a signed or unsigned C storage location and the driver converts the data accordingly. There are new #defines for integer C data types so an ODBC 2.x driver can distinguish between ODBC 1.0 and ODBC 2.x applications and support the data conversion models used by both. SQLBindCol, SQLGetData, and SQLSetParam accept the old and new #defines.  [Appendix D, C Data Types and ODBC 1.0 C Data Types; Chapter 22, SQLBindCol, SQLGetData, and SQLSetParam]


Appendix F: Scalar Functions (What's New)

CONVERT Function

The data type specified in the CONVERT scalar function is a text keyword.  [Appendix F, Explicit Data Type Conversion]

DATABASE Function

The DATABASE function returns the same value as the SQL_CURRENT_QUALIFIER connection option.  [Appendix F, System Functions]

DAYNAME and MONTHNAME Functions

The DAYNAME and MONTHNAME functions return data source-specific values.  [Appendix F, Time and Date Functions]

New Functions

The following scalar functions were added:

String functions:        DIFFERENCE, SOUNDEX, SPACE

Numeric functions:       DEGREES, LOG10, POWER, RADIANS, ROUND, TRUNCATE

Time and date functions: DAYNAME, MONTHNAME, TIMESTAMPADD, TIMESTAMPDIFF

[Chapter 22, SQLGetInfo; Appendix F]

QUARTER Function

The QUARTER function returns a number from 1 to 4, where 1 represents January 1 through March 31.  [Appendix F, Time and Date Functions]


Installation and Configuration (What's New)

Administration Program

ConfigDSN

Description Keyword

Driver-Specific Setup DLL

ODBC.INF File

ODBC.INI File

Setup Program

SQLCreateDataSource (New Installer Function)

SQLGetPrivateProfileString and SQLWritePrivateProfileString (New Installer Functions)

SQLGetTranslator (New Installer Function)

SQLInstallDriver

SQLInstallDriverManager

SQLInstallODBC (New Installer Function)

SQLManageDataSources (New Installer Function)

SQLRemoveDSNFromIni

Translator-Specific Setup DLL


Administration Program (What's New)

For a program to administer data sources, developers can either reship the Control Panel device shipped with the ODBC SDK or write their own program that calls the installer DLL. Developers should not confuse the administration program with the driver-specific setup program or the setup program used to install the ODBC SDK.  [Chapter 20, Configuring Data Sources. For more information, see Chapter 3 of the ODBC SDK Guide, Managing Data Sources and Drivers.]


ConfigDSN (What's New)

1) ConfigDSN uses the same keywords as SQLDriverConnect and SQLBrowseConnect, except that it doesn't accept the DRIVER keyword. The keywords and attribute values used by ConfigDSN have the same restrictions as in SQLDriverConnect and SQLBrowseConnect.  [Chapter 23, ConfigDSN]

2) ConfigDSN must validate data source names. If a data source by the same name already exists and hwndParent is not null, ConfigDSN prompts the user to overwrite the existing name; if hwndParent is null, ConfigDSN overwrites the existing name.  [Chapter 23, ConfigDSN]


Description Keyword (What's New)

The Description keyword in each data source specification section in the ODBC.INI file is no longer required.  [Chapter 20, Data Source Specification Sections]


Driver-Specific Setup DLL (What's New)

If a driver supports translators, its setup DLL must provide a way for users to specify a default translator and translation option. The setup DLL calls SQLGetTranslator in the ODBC installer DLL to display a dialog from which the user selects a translator. To get the default translation option, SQLGetTranslator calls ConfigTranslator in the translator-specific setup DLL. [Chapter 20, Specifying a Default Translator; Chapter 24, SQLGetTranslator]


ODBC.INF File (What's New)

1) The [Default File Settings] and [Files] sections have been removed. The [ODBC Administration Utility] section is now titled [ODBC Administrator]. The [ODBC Translators] section and translator specification sections were added. If an ODBC 1.0 ODBC.INF file is used with the ODBC 2.0 Installer, only the drivers will be installed, since the presence of the ODBC 2.0 Installer indicates that all existing ODBC components on the system comply with ODBC 2.x.  [Chapter 19, Structure of the ODBC.INF File]

2) Driver specification sections can contain driver attribute keywords. These are returned by SQLDrivers and an application uses them to determine information about a driver before connecting to a data source that uses the driver.  [Chapter 19, Driver Specification Sections]

3) Driver specification sections can contain the name of a data source that is to be created during installation. The information for the data source is contained in a data source specification section in the ODBC.INF file. [Chapter 19, Driver Specification Sections]

4) The ODBC.INF file cannot contain tabs.  [Chapter 19, Constructing the ODBC.INF File]

5) A blank date installation property means a date of 0. A blank size installation property means a size of 0. A blank version installation property means a version of 00.00.00.00.


ODBC.INI File (What's New)

The ODBC.INI file contains a section for general ODBC options. Currently, this section contains the Trace, TraceFile, and TraceAutoStop keywords. These keywords can be set through the ODBC control panel item and provide an easy way for users to control how the Driver Manager traces ODBC function calls. [Chapter 20, ODBC Options Section; Chapter 22, SQLAllocEnv, SQLFreeEnv, and SQLSetConnectOption]


Setup Program (What's New)

To create a program to install drivers, developers can either use the Driver Setup Toolkit or write their own program that calls the installer DLL. Developers should not confuse the driver-specific setup program with the setup program used to install the ODBC SDK.  [Chapter 19, Installing ODBC Software; For more information, see Chapter 6 of the ODBC SDK Guide, Using the Driver Setup Toolkit]


SQLCreateDataSource (New Installer Function) (What's New)

SQLCreateDataSource displays a dialog with which the user can add a data source.  [Chapter 24, SQLCreateDataSource]


SQLGetPrivateProfileString and SQLWritePrivateProfileString (New Installer Functions) (What's New)

Driver-specific setup DLLs should use these functions to get and write entries in the ODBC.INI file or Windows NT Registry. On Windows, they are macros that map to GetPrivateProfileString and WritePrivateProfileString in the Windows API. On Windows NT, they are functions that get and write entries in the ODBC.INI subkey of the Windows NT registry.  [Chapter 24, SQLGetPrivateProfileString and SQLWritePrivateProfileString]


SQLGetTranslator (New Installer Function) (What's New)

See Driver-Specific Setup DLL.  [Chapter 24, SQLGetTranslator]


SQLInstallDriver (What's New)

SQLInstallDriver now accepts a null pointer for the lpszInfFile argument. In this case, the lpszDriver argument must contain a list of keyword-value pairs describing the driver.  [Chapter 24, SQLInstallDriver]


SQLInstallDriverManager (What's New)

The lpszPath argument should be at least _MAX_PATH bytes.  [Chapter 24, SQLInstallDriverManager]


SQLInstallODBC (New Installer Function) (What's New)

SQLInstallODBC installs ODBC components. It can display a dialog from which the user selects drivers to install. It also can accept a list of drivers and silently install them.  [Chapter 24, SQLInstallODBC]


SQLManageDataSources (New Installer Function) (What's New)

SQLManageDataSources displays a dialog with which users can set up, add, and delete data sources, and add and delete drivers.  [Chapter 24, SQLManageDataSources]


SQLRemoveDSNFromIni (What's New)

SQLRemoveDSNFromIni returns TRUE if the lpszDSN argument specifies a data source not in the ODBC.INI file.  [Chapter 24, SQLRemoveDSNFromIni]


Translator-Specific Setup DLL (What's New)

Each translator must provide a translator-specific setup DLL with which the user specifies the default translation option for a data source. The setup DLL contains a single function, ConfigTranslator.  [Chapter 20, Specifying a Default Translator; Chapter 23, ConfigTranslator]


Translation DLLs (What's New)

SQLDataSourceToDriver

1) The fCType argument was changed to fSqlType and now accepts the SQL type of the data being passed from the data source. This change was made because the fCType argument does not provide sufficient information on how to translate the data returned by the data source. It is backwards compatible because the #defines used to define the ODBC SQL data types are a superset of the #defines used to define the ODBC C data types.  [Chapter 25, SQLDataSourceToDriver]

2) The translator never null terminates the value in the rgbValueOut buffer, even when it contains character data. This allows in-place translation of data, as is often done for character set translation. Because of this, character and binary data are truncated (if necessary) to cbValueMax bytes.  [Chapter 25, SQLDataSourceToDriver]

SQLDriverToDataSource

The translator never null terminates the value in the rgbValueOut buffer, even when it contains character data. This allows in-place translation of data, as is often done for character set translation. Because of this, character and binary data are truncated (if necessary) to cbValueMax bytes.  [Chapter 25, SQLDriverToDataSource]


Summary of Changes Made After ODBC 2.0

ODBC 2.01 Changes

ODBC 2.01a Changes

ODBC 2.10 Changes


ODBC 2.01 Changes

This topic summarizes the changes made in ODBC 2.01. Except for changes to the ODBC 2.0 README.WRI file, these are changes to the ODBC 2.0 Programmer's Reference.

SQLBindCol

1) Both reasons for S1003 are checked by the Driver Manager.

2) The description of S1009 is correct in the ODBC 2.0 Programmer's Reference, not as was stated in the ODBC 2.0 README.WRI file.

[SQLBindCol (Problems and Information)]

SQLBindParameter

1) SQLBindParameter does not enforce SQLSTATEs S1094 and S1104.

2) SQLBindParameter does not check parameter types, as indicated by the second and third reasons in SQLSTATE S1105. These are returned by SQLExecute and SQLExecDirect.

3) SQLBindParameter does not resolve the C and SQL data types as indicated by SQLSTATE 07006. This SQLSTATE is returned by SQLExecDirect, SQLExecute, and SQLPutData.

[SQLBindParameter (Problems and Information)]

SQLGetData

1) Both reasons for S1003 are checked by the Driver Manager.

2) The description of S1009 is correct in the ODBC 2.0 Programmer's Reference, not as was stated in the ODBC 2.0 README.WRI file.

[SQLGetData (Problems and Information)]

SQLGetInfo

1) SQL_OUTER_JOINS is the same in ODBC 2.01 as it was in ODBC 1.0, but the SQL_OJ_CAPABILITIES information type has been added in ODBC 2.01.

2) Drivers that conform to the ODBC 2.01 specification return "02.01" for the SQL_DRIVER_ODBC_VER information type.

[SQLGetInfo (Problems and Information)]

SQLNativeSql

SQLNativeSql might return SQLSTATE 24000 (Invalid cursor state) if the SQL string is a positioned update or delete statement and the cursor referred to in that statement is positioned before the first row of the result set or after the last row of the result set.

[SQLNativeSql (Problems and Information)]

SQLParamOptions

pirow indicates the number of parameters successfully processed. It does not indicate which result set is currently being processed by SQLMoreResults.

[SQLParamOptions (Problems and Information)]

SQLSetPos

1) In SQLSetPos, the third description of SQLSTATE S1009 duplicates that of SQLSTATE S1107 and should be removed. The fourth description of SQLSTATE S1009 is returned regardless of the value of the fLock argument.

2) After calling SQLSetPos with irow equal to 0, the current row is unchanged when fOption is SQL_ADD, SQL_DELETE, SQL_UPDATE, and SQL_REFRESH.

3) Calling SQLSetPos with irow equal to 0 and fOption equal to SQL_POSITION returns SQLSTATE S1109 (Invalid cursor position).

4) The third description of 24000 in ODBC 2.0 Programmer's Reference is correct. The bug listed in the ODBC 2.0 README.WRI file is a cursor library bug.

[SQLSetPos (Problems and Information)]

SQLStatistics

Filtered indexes are not treated differently by SQLStatistics than other indexes, except that the filter condition is returned in the FILTER_CONDITION column. The columns in the filter condition are not returned separately, as was incorrectly stated in the ODBC 2.0 Programmer's Reference. Also, SQLStatistics can return columns not returned by SQLColumns.

[SQLStatistics (Problems and Information)]

Installation and Configuration

The keywords for the thunking DLLs in the [Generic Thunk ODBC Driver Manager] and [Generic Thunk ODBC] sections of the 32-bit ODBC.INF file are Thunk1 and Thunk2. These were incorrectly stated in the ODBC 2.0 README.WRI file as Driver, Main, and Thunk.

[Installation and Configuration (Problems and Information)]

Header Files

The SQL_UB_DEFAULT, SQL_RETURN_VALUE, and SQL_PC_NOT_PSEUDO #defines have been fixed. These were incorrect in the ODBC 2.0 header files.


ODBC 2.01a Changes

This topic summarizes the changes made in ODBC 2.01a.

SQLGetInfo

Drivers that conform to the ODBC 2.01a specification return "02.01" for the SQL_DRIVER_ODBC_VER information type.

[SQLGetInfo (Problems and Information)]

ODBC Cursor Library

When changing the value of a column with a fixed-length data type to or from NULL, the cursor library now updates pcbValue for that column in its cache. It did not previously do this.


ODBC 2.10 Changes

This topic summarizes the changes made in ODBC 2.10.

Cross-Platform Support

The ODBC SDK 2.10 is a 32-bit release that supports Microsoft Windows NT Version 3.5 for Intel, Alpha, and MIPS platforms.

The 16-bit ODBC drivers in the ODBC SDK 2.10 may work on Windows on Windows (WOW) on Alpha and MIPS, but this use is not supported.

The ODBC SDK 2.10 has been tested on the version of the Windows 95 operating system available at the time of the release of the SDK 2.10. Since the final release of Windows 95 will occur after the release of SDK 2.10, the ODBC SDK will not have been fully tested against that final release.

ODBC SDK 2.10 has not been tested on Win32s. ODBC 2.0 should be used on Win32s.

Addition of Thunking Layers

The ODBC SDK 2.10 provides 16- to 32-bit thunks for Alpha and MIPS platforms in addition to existing thunks for Intel/x86 platform.

[ODBC 2.10 Thunking Layer]

Driver Manager

1) The 32-bit Driver Manager now stops tracing automatically when the option in the ODBC Administrator is chosen.

2) The DRIVER keyword is no longer duplicated in the connection string returned by SQLDriverConnect.

3) The Driver Manager no longer reads past the end of the buffer if a SQLDriverConnect connection string is not null-terminated and the connection string ends with "D", "DS", or "DSN".

4) SQLDriverConnect has been changed to connect to the appropriate driver if both 16-bit and 32-bit drivers are installed on Microsoft Windows NT, and both drivers have the same name.

5) The driver error flag is now set only if the error was returned by the driver.

6) The ODBC 2.01 release notes indicated that the Driver Manager does not properly return SQLSTATE S1108 (Concurrency option out of range), but instead, returns SQLSTATE S1000 (General error). This is no longer the case, and this statement has been removed from the release notes for ODBC 2.10.

7) Before ODBC 2.10, the driver, not the Driver Manager, would return an error when the cursor position became invalid after a successful SQLExtendedFetch. With the release of ODBC 2.10, the Driver Manager detects the invalid cursor position in this situation, and returns an error.

8) Before ODBC 2.10, the message text for SQLConnect and SQLDisconnect errors that were not generated by the Driver Manager was cached by the Driver Manager, but not cleared. This problem has been fixed by ODBC 2.10.

9) Before ODBC 2.10, calling SQLAllocConnect in a Windows NT console application under certain conditions could result in a General Protection Fault as a result of a problem with the Driver Manager. With the release of ODBC 2.10, this problem has been fixed.

10) When a 16-bit application connects to a data source through a 32-bit driver on Windows NT by calling SQLConnect, the Driver Manager changes the value of cbDSN passed by SQLConnect to a value of 14915. This value is then passed on to the driver, so the amount of memory allocated for the data source name does not correspond to the amount asked for.

[ODBC 2.10 Driver Manager]

Cursor Library

1)The cursor library is provided in 16-bit (ODBCCURS.DLL) and 32-bit (ODBCCR32.DLL) binary form.

2) The cursor library returns SQLSTATE S1C00 (Driver not capable) for SQLSetPos with irow=0.

3) If the cursor library is used, when data is retrieved with SQLExtendedFetch, SQLGetData supports the functionality specified with the SQL_GD_ANY_ORDER bitmask, as well as the SQL_GD_ANY_COLUMN and SQL_GD_BOUND bitmasks.

4) The cursor library creates temporary files on the current directory, rather than using a temporary directory. This can cause problems when running an application from a read-only share or a compact disk (such as a Microsoft Foundation Class Library sample).

[ODBC 2.10 Cursor Library]

ODBC Drivers

The ODBC SDK provides the following 16-bit and 32-bit drivers: Microsoft Access, Btrieve (16-bit only), dBASE, Microsoft Excel, Microsoft FoxPro, Paradox, and Text.

[ODBC 2.10 Drivers]

Header Files

1) All typedefs in the SQL*.H files have been #pragma packed.

2) Additional defines have been added to SQLEXT.H.

3) The #define in the SQLEXT.H file for the SQL_OJ_CAPABILITIES option in SQLGetInfo has been changed from 65002 to 65003.

[ODBC 2.10 Header Files]

ODBC Test

1) SQL_NULL_DATA and SQL_DEFAULT_PARAM have been added to the drop-down box for cbValue in the SQLPutData dialog box in ODBC Test.

2) Before ODBC 2.10, when SQLGetData was called in ODBC Test, cbValueMax was not ignored for fixed-length data types. This problem has been fixed in the version 2.10 ODBC Test.

3) ODBC Test has been fixed so SQLExtendedFetch can be performed on a bookmark column without error.

4) Before the version 2.10 ODBC Test, a crash was possible if repetitive calls to SQLSetStmtOption and SQLGetStmtOption were made with certain fOptions in ODBC Test. The same was also true for SQLSetConnectOption and SQLGetConnectOption. This has been fixed in the version 2.10 ODBC Test.

5) Font problems in a rowset displayed by SQLExtendedFetch in ODBC Test have been fixed in the version 2.10 ODBC Test.

6) The Always Use Cursor Library radio check box in the User Options dialog box in ODBC Test has been replaced with the following radio buttons: DEFAULT to specify that the DM uses the scrolling capabilities of the driver, rather than the cursor library; USE IF NEEDED to specify that the DM uses the cursor library only if it is needed; USE ODBC to specify that the Driver Manager (DM) uses the cursor library; and USE DRIVER to specify that the DM uses the scrolling capabilities of the driver, rather than the cursor library.

7) With the release of ODBC 2.10, the Cursor Library radio buttons that replaced the Always Use Cursor Library check box (see statement 6 above) are in effect only when a Full Connect is performed, not when explicit connection functions are called.

8) Before the version 2.10 ODBC Test, when a value of -128 was bound to SQL_C_TINYINT, the value was actually returned as 128. This problem has been fixed in the version 2.10 ODBC Test.

9) Before the version 2.10 ODBC Test, pcbValue in SQLBindParam could be improperly changed when called in ODBC Test. If the value for pcbValue returned by the SQL_LEN_DATA_AT_EXEC macro was greater than cbValueMax, pcbValue was changed to cbValueMax. This problem has been fixed in the version 2.10 ODBC Test.

10) Before the version 2.10 ODBC Test, pressing CTRL+F4 closed the output window. With the release of ODBC 2.10, pressing CTRL+F4 in ODBC Test has no effect.

11) Before the version 2.10 ODBC Test, performing an SQLSetPos in ODBC Test when no columns were bound caused a General Protection Fault. This problem has been fixed for the version 2.10 ODBC Test.

12) Before the version 2.10 ODBC Test, attempting to insert more than 64K of data into a single Text or Image field in ODBC Test caused a General Protection Fault. This problem has been fixed for the version 2.10 ODBC Test.

13) Before the version 2.10 ODBC Test, performing an SQLGetData with a pcbValue of NULL and a cbValueMax of 0 in ODBC Test caused a General Protection Fault. This problem has been fixed for the version 2.10 ODBC Test.

14) Before the version 2.10 ODBC Test, performing an SQLBindParameter with a numeric fcType and a number entered for rgbValue in ODBC Test caused a General Protection Fault on Windows on Windows (WOW) on Microsoft Windows NT. This problem has been fixed for the version 2.10 ODBC Test.

15) Problems with the pfNullable argument in SQLDescribeCol have been fixed for the version 2.10 ODBC Test.

16) Before the version 2.10 ODBC Test, the maximum number of columns that could be returned by the GetDataAll function was 153. This restriction has been removed for the version 2.10 ODBC Test.

17) Before the version 2.10 ODBC Test, the value returned for SQL_MAX_STATEMENT_LEN by SQLGetInfo in ODBC Test could be incorrect. This problem has been fixed in the version 2.10 ODBC Test.

18) Before the version 2.10 ODBC Test, once SQLParamData had returned SQL_SUCCESS in ODBC Test, calling SQLParamData again for the same parameter would not update prgbValue properly. This problem has been fixed in the version 2.10 ODBC Test.

[ODBC 2.10 Test]

ODBC Spy

1) When ODBC Spy is in capture mode, calling SQLSetStmtOption with SQL_RETRIEVE_DATA set to SQL_RD_ON returns a memory error.

[ODBC 2.10 Spy]

Sample Programs

1) The samples included with the ODBC SDK are 16-bit executables.  However, the sample source code may be compiled into either 16- or 32-bit executables.

2) CPU environment variables must be set in BUILD.BAT in order to build the sample files.

3) The cursor library sample application (CRSRDEMO) cannot be compiled on Alpha, so is unavailable for use on Alpha.

SQLBindCol

1) When SQLBindCol is called to bind a column to a new storage location, data is placed in the new storage location when SQLSetPos is called with an fOption of SQL_REFRESH, SQL_UPDATE, or SQL_ADD.

2) The description of pcbValue in the SQLBindCol section of the Programmer's Reference should include SQL_IGNORE as a possible value of pcbValue, and should indicate that SQLSetPos only updates those columns in a row that have been bound with SQLBindCol and do not have a pcbValue of SQL_IGNORE.

[SQLBindCol (Problems and Information)]

SQLBrowseConnect

1) The attribute value list returned in the browse result connection string can contain localized values.

[SQLBrowseConnect (Problems and Information)]

SQLColAttributes

1) An auto-increment value is unique, with an undefined increment that is DBMS-specific.

2) A MONEY data type has predefined fixed precision and scale (which are data source-specific).

3) The descriptor SQL_COLUMN_UPDATABLE describes the updatability of the base column, not the result set.

[SQLColAttributes (Problems and Information)]

SQLColumns

1) The order of the columns in the column list returned by SQLColumns is not necessarily the same as the order of the columns returned when the application performs a SELECT statement on all columns in that table.

[SQLColumns (Problems and Information)]

SQLConnect

1) SQLSTATE IM006 (Driver's SQLSetConnectOption failed) can be returned by either the driver or the Driver Manager.

2) SQLSTATE 01S02 (Option value changed) can be returned by the SQLConnect function when the driver does not support the specified value of the vParam argument in SQLSetConnectOption and substitutes a similar value. The function returns SQL_SUCCESS_WITH_INFO.

[SQLConnect (Problems and Information)]

SQLDriverConnect

1) A new data source can be added when making a connection with SQLDriverConnect.

2) SQLSTATE IM006 (Driver's SQLSetConnectOption failed) can be returned by either the driver or the Driver Manager.

3) Problems that occurred when SQLDriverConnect was called with the DRIVER keyword (without a DSN) on Windows on Windows (WOW) have been fixed for ODBC 2.10.

[SQLDriverConnect (Problems and Information)]

SQLExecDirect

1) SQLSTATE S1090 (Invalid string or buffer length) will be returned for SQLExecDirect if the parameter value bound by SQLBindParameter was a null pointer and the parameter length value was not set to SQL_DEFAULT_PARAM (or 0, SQL_NULL_DATA, SQL_DATA_AT_EXEC, or less than or equal to SQL_LEN_DATA_AT_EXEC_OFFSET).  SQLSTATE S1090 will be returned if the parameter value was not a null pointer, and the parameter value was less than 0 but was not SQL_DEFAULT_PARAM (or SQL_NTS, SQL_NULL_DATA, SQL_DATA_AT_EXEC, or less than or equal to SQL_LEN_DATA_AT_EXEC_OFFSET).

2) SQLSTATE S1090 (Invalid string or buffer length) will be returned if the parameter length value bound by SQLBindParameter was set to SQL_DATA_AT_EXEC; the SQL type was either SQL_LONGVARCHAR, SQL_LONGVARBINARY, or a long, data-source specific data type; and the SQL_NEED_LONG_DATA_LEN information type in SQLGetInfo was "Y".

3) SQLSTATE 01S02 (Option value changed) will be returned (with SQL_SUCCESS_WITH_INFO) if a statement option was invalid because of SQL constraints or requirements, so a similar value was substituted.

[SQLExecDirect (Problems and Information)]

SQLExecute

1) SQLSTATE S1090 (Invalid string or buffer length) will be returned for SQLExecute if the parameter value bound by SQLBindParameter was a null pointer and the parameter length value was not set to SQL_DEFAULT_PARAM  (or 0, SQL_NULL_DATA, SQL_DATA_AT_EXEC, or less than or equal to SQL_LEN_DATA_AT_EXEC_OFFSET).  SQLSTATE S1090 will be returned if the parameter value was not a null pointer, and the parameter value was less than 0 but was not SQL_DEFAULT_PARAM (or SQL_NTS, SQL_NULL_DATA, SQL_DATA_AT_EXEC, or less than or equal to SQL_LEN_DATA_AT_EXEC_OFFSET).

2) SQLSTATE S1090 (Invalid string or buffer length) will be returned if the parameter length value bound by SQLBindParameter was set to SQL_DATA_AT_EXEC; the SQL type was either SQL_LONGVARCHAR, SQL_LONGVARBINARY, or a long, data-source specific data type; and the SQL_NEED_LONG_DATA_LEN information type in SQLGetInfo was "Y".

3) SQLSTATE 01S02 (Option value changed) will be returned (with SQL_SUCCESS_WITH_INFO) if a statement option was invalid because of SQL constraints or requirements, so a similar value was substituted.

[SQLExecute (Problems and Information)]

SQLExtendedFetch

1) Using SQLExtendedFetch to return a rowset that starts before the result set when moving less than or equal to one rowset before the current position, will position to the first rowset and return SQL_SUCCESS_WITH_INFO and SQLSTATE 01S06 (Attempt to fetch before the result set returned the first rowset), not SQL_SUCCESS, if the cursor is not already positioned on or before the first row of the result set. Using SQLExtendedFetch to return a rowset that starts before the result set and is greater than one rowset before the current position always returns SQL_NO_DATA_FOUND, rather than returning SQL_SUCCESS and positioning on the first rowset.

2) For drivers that support packing, deleted rows are packed by any new fetch prior to calculating the new position.

3) An offset for an SQLExtendedFetch with an fFetchType of SQL_FETCH_RELATIVE is computed from the first row of the current rowset, even if that row has been deleted and in the case of the driver packing deleted records, no longer appears in the result set. If the cursor shows records at fetch time that have been inserted since the cursor was opened, the new rowset may show newly inserted rows including the first row of a rowset returned by an SQLExtendedFetch with an fFetchType of SQL_FETCH_NEXT and the last row of the rowset returned by an SQLExtendedFetch with an fFetchType of SQL_FETCH_PRIOR.

4) After a call to SQLExtendedFetch has returned a rowset, and rows are then added past the end of the rowset, the added rows may be fetched by a subsequent SQLExtendedFetch, and the added rows may affect the rowset returned by a relative fetch, if the cursor is able to detect new records.

5) The contents of the rgfRowStatus array are available for all rows for dynamic as well as static cursors.

6) The SQL_ROW_UPDATED flag in the rgbRowStatus array is changed back to SQL_SUCCESS when SQLExtendedFetch generates a new rowset. Note that this also occurs when an SQLExtendedFetch with an fFetchType of SQL_FETCH_RELATIVE and an irow of 0 is performed, which refreshes the current rowset.

7) The contents of the rgfRowStatus array should not be modified by the application. rgfRowStatus should only be modified by the driver. Modification by the application could result in the driver acting upon erroneous status information.

7) Changing the rowset size between fetches does not change the rowset size used to calculate the fetch destination when the second fetch is an SQLExtendedFetch with an fFetchType of SQL_FETCH_NEXT.

8) SQLSTATE S1002 (Invalid column number) will be returned when the SQL_CURSOR_TYPE statement option was SQL_CURSOR_FORWARD_ONLY and SQLBindCol was called with icol set to 0.

9) SQLSTATE 22002 (Indicator variable required but not supplied) is returned when NULL data is fetched into a column whose pcbValue set by SQLBindCol is a null pointer.

[SQLFetch and SQLExtendedFetch (Problems and Information)]

SQLFetch

1) SQLSTATE 22002 (Indicator variable required but not supplied) is returned when NULL data was fetched into a column whose pcbValue as set by SQLBindCol was a null pointer.

[SQLFetch and SQLExtendedFetch (Problems and Information)]

SQLGetData

1) SQLSTATE S1109 (Invalid cursor position) is returned when SQLGetData is called after SQLSetPos specified an irow of zero and fOption was not SQL_ADD, attempting to position the cursor on the entire rowset.

2) SQLSTATE S1109 (Invalid cursor position) is returned when SQLGetData is called on a forward-only cursor when the rowset is greater than one row.

3) SQLSTATE 22002 (Indicator variable required but not supplied) is returned if pcbValue is a null pointer and NULL data is retrieved.

4) When the following sequence is performed:

SQLGetData(icol=n), SQLGetData(icol=m), SQLGetData(icol=n),

the second call to SQLGetData(icol=n) retrieves data from the start of the n column. Any offset in the data in the column due to earlier calls to SQLGetData for the column is no longer valid.

If you reposition to a row by calling SQLSetPos, or refetch a row by calling SQLExtendedFetch (and the cursor is positioned on that row), SQLGetData(icol=n) retrieves data from the start of the n column in that row.

[SQLGetData (Problems and Information)]

SQLGetInfo

SQL_ROW_UPDATES indicates that the driver can return the SQL_ROW_UPDATED flag to the rgfRowStatus array when an SQLExtendedFetch is performed. The driver can detect and indicate that the data returned in a result set has been updated by another user. (This only applies to updates, not to deletions or insertions.)

[SQLGetInfo (Problems and Information)]

SQLGetTypeInfo

1) An auto-increment value is unique, with an undefined increment that is DBMS-specific.

2) A MONEY data type has predefined fixed precision and scale (which are DBMS-specific).

3) The data types returned by SQLGetTypeInfo are those supported by the DBMS.  They are intended for use in Data Definition Language (DDL) statements.  Drivers can return result set data using data types other than the types returned by SQLGetTypeInfo.  For example, in creating the result set for a catalog function, the driver might use a data type that is not supported by the DBMS.

4) SQLGetTypeInfo returns the results as a standard result set, ordered by DATA_TYPE and then by how closely the data type maps to the corresponding ODBC data type; data types defined by the DBMS taking precedence over user-defined data types.

[SQLGetTypeInfo (Problems and Information)]

SQLParamData

1) Before ODBC 2.10, when a 16-bit application was running on Windows NT and calling a 32-bit driver, an error was returned when a data-at-execution parameter was supplied to one column by calling SQLParamData and SQLPutData, then SQLParamData was called to supply a data-at-execution parameter for a second column. The data returned to rgbValue was not valid data. This problem, which was in the thunking layer, has been fixed for ODBC 2.10.

[SQLParamData (Problems and Information)]

SQLPrepare

1) SQLSTATE 01S02 (Option value changed) will be returned (with SQL_SUCCESS_WITH_INFO) if a statement option was invalid because of SQL constraints or requirements, so a similar value was substituted. This substitute value is temporary and will be returned to its explicitly set value when a statement is prepared that supports the option. Until that time, calling SQLGetStmtOption returns the temporary value.

[SQLPrepare (Problems and Information)]

SQLProcedureColumns

1) SQLProcedureColumns returns the results as a standard result set ordered by PROCEDURE_QUALIFIER, PROCEDURE_OWNER, PROCEDURE_NAME, and the order that the parameters appear in the procedure invocation. The Programmer's Reference incorrectly states that COLUMN_TYPE is used when ordering the result set.

[SQLProcedureColumns (Problems and Information)]

SQLPutData

1) When SQLExecute, SQLExecDirect, or SQLSetPos is called for an hstmt and returns SQL_NEED_DATA, and SQLCancel is called before data was sent for all data-at-execution parameters or columns, and then SQLPutData is called, SQLSTATE S1010 (Function Sequence Error) is returned, not SQLSTATE S1008 (Operation Cancelled).

[SQLPutData (Problems and Information)]

SQLSetConnectOption

1) SQLSTATE 08003 (Connection not open) for SQLSetConnectOption is returned by the Driver Manager.

2) The following description should be added for SQLSTATE S1011 (Operation invalid at this time) in the SQLSetConnectOption section of the Programmer's Reference: The argument fOption was SQL_PACKET_SIZE and the connection has already been established.

3) SQLSTATE 24000 (Invalid cursor state) is returned by SQLSetConnectOption when the argument fOption is SQL_CURRENT_QUALIFIER and a result set is pending.

[SQLSetConnectOption (Problems and Information)]

SQLSetPos

1) SQLSetPos updates, deletes, or adds (both single-row and bulk) that fail because of optimistic concurrency will return SQLSTATE 01S03 (no row updated/deleted).

2) SQLSetPos with an fOption of SQL_REFRESH does not change the membership of the rowset.

3) When SQLSetPos refreshes a row in a rowset, the row status changes to SQL_ROW_SUCCESS if the row has not changed since the last fetch or refresh, and if the row status is not SQL_ROW_DELETED or SQL_ROW_ERROR.

4) SQLSTATE S1090 (Invalid string or buffer length) will be returned if the column length value bound by SQLBindParameter was set to SQL_DATA_AT_EXEC while the SQL type was either SQL_LONGVARCHAR, SQL_LONGVARBINARY, or a long, data-source specific data type, and the SQL_NEED_LONG_DATA_LEN information type in SQLGetInfo was "Y".

5) SQLSetPos (SQL_ADD) can be successfully called even if the previous call to SQLExtendedFetch returned SQL_NO_DATA_FOUND.

6) SQLSetPos will return SQLSTATE S1C00 (Driver not capable) when irow=0 and the driver does not support bulk operations.

7) SQLSTATE 21S02 will be returned for SQLSetPos with an argument fOption of SQL_ADD or SQL_UPDATE if no columns were bound with SQLBindCol, or the bound columns were all read-only, or the bound columns had a pcbValue of SQL_IGNORE.

8) The description for SQLSTATE 01S04 for SQLSetPos should state that the argument fOption was SQL_UPDATE or SQL_DELETE and rows other than those indicated by the irow argument were update or deleted.

[SQLSetPos (Problems and Information)]

SQLSetStmtOption

1) If the data source provides native SQL support for a positioned update or delete statement, and the driver does not support simulated cursors, SQLSetStmtOption will reflect the data source support when SQL_SIMULATE_CURSOR is specified.

2) When a statement option supports substitution of a similar value, substitution is supported not only if the data source does not support the specified value of vParam, but also if vParam is invalid because of SQL constraints or requirements.

[SQLSetStmtOption (Problems and Information)]

SQLTransact

1) SQLTransact with SQL_ROLLBACK returns SQL_SUCCESS, not SQLSTATE S1C00 (Invalid cursor position), for drivers that do not support transactions.

[SQLTransact (Problems and Information)]

Installation and Configuration

1) Some, but not all, of the keywords used by the ConfigDSN function are also used by SQLBrowseConnect and SQLDriverConnect, and vice versa.

2) When a data source is added, a driver's ConfigDSN should call SQLValidDSN to check the length and validity of the data source name, and if the name is longer than SQL_MAX_DSN_LENGTH or contains invalid characters, then SQLValidDSN will return an error.

The function SQLValidDSN should be added to Chapter 23, "Installer DLL Function Reference".

3) When a 32-bit data source is added to Windows NT, the data source name is propagated to the 16-bit ODBC.INI file (under 32-bit drivers).

4) The ODBC.INF file must include the sections that describe the files shipped for thunking purposes, or the SQLInstallODBC function will fail. Although an ODBC.INF file has the same format as normal Windows INF files, the ODBC Installer does not look at all of the description fields that could be put there.

5) The ODBC Installer has been fixed to handle a GetDesktopWindow hwnd.

On Microsoft Windows for Workgroups, when the ODBC Installer calls GetDesktopWindow() to return a value for hwndParent in SQLConfigDataSource, mouse control is lost and the system has to be rebooted. To avoid this, the driver's ConfigDSN should call GetDesktopWindow() to return hwndParent for SQLConfigDataSource.

6) The ODBC Installer always installs ODBC components in the \WINDOWS\SYSTEM or \WINDOWS\SYSTEM32 directory, whether the Windows installation is local or shared. On previous versions, the ODBC Installer copied the components in the \WINDOWS directory for a shared installation.

7) Installation problems caused because the ODBC SDK 2.01 did not terminate the lpszAttributes string with double nulls, which could cause properly written installation programs to crash, have been corrected.

8) Use of the CTL3D library to provide 3D dialog boxes for Windows applications is discouraged, because future operating systems from Microsoft will provide default 3D user interface elements.

9) The message box returned if a null parent window handle is passed to SQLInstallODBC, and an error is returned, had a bad title.  It has been fixed to be entitled either "ODBC Administrator" or "32Bit ODBC Administrator".

10) The 16-bit components of the ODBC SDK can be installed on a platform other than its target platform.

11) New keywords WinSysNTnn and WinSys95nn have been defined for the ODBC.INF file. These keywords allow developers to install files selectively on either Windows NT or Windows 95.

12) Before ODBC 2.10, when installing a driver from a disk using the driver setup procedure in the Control Panel or Administrator, files on the disk could be deleted after installation. This problem, which was caused by a bad pointer in the installer function SQLInstallDriver that deleted the source path, has been fixed in ODBC 2.10.

13) When installing the ODBC SDK 2.10 over the ODBC SDK 1.0, the user may experience problems when using the dBASE driver that shipped with the SDK 1.0, and should install the dBASE driver that shipped with the SDK 2.10.

14) Before ODBC 2.10, the Ignore button displayed if the Installer attempted to install a file that was currently in use, did not work for 32-bit installations. With the release of ODBC 2.10, the Ignore button works for both 16- and 32-bit installations.

[Installation and Configuration (Problems and Information)]

Retrieving Results

1) The fInfoType SQL_STATIC_SENSITIVITY returned by SQLGetInfo indicates whether updated key values for a keyset-driven cursor are equivalent to the deletion of the existing row and insertion of a new row, as stated in chapter 7, Retrieving Results, in the Programmer's Reference.

[Retrieving Results]

Appendix A

1) SQLSTATE 22002 (Indicator variable required but not supplied) should be added to the list of error codes for SQLExtendedFetch, SQLFetch, and SQLGetData.

2) SQLSTATE 01S05 (Cancel treated as FreeStmt/CLOSE) should be added to the list of error codes for SQLCancel.

3) SQLSTATE 01S06 (Attempt to fetch before the result set returned the first rowset) should be added to the list of error codes for SQLExtendedFetch.

[Appendix A: ODBC Error Codes (Problems and Information)]

Appendix B

1) The row status values for the invalid row and valid row footnotes used in Appendix B tables should include the word "ROW", for example, SQL_ROW_SUCCESS, not SQL_SUCCESS.

2) "24000" should be added to the S5-S7 column of the SQLSetConnectOption statement transition table in Appendix B. A footnote referring to the "24000" entry should state: "The fOption argument was SQL_CURRENT_IDENTIFIER."

3) The Driver Manager cannot determine if a result set will be created (for prepared statements) or has been created (for executed statements).  Thus, when state transitions depend on whether a result set will be or has been created, the driver (not the Driver Manager) must check for state errors.

4) Currently, the state tables in Appendix B show the correct checks, except for SQLGetCursorName. The tables show that the Driver Manager checks state errors for SQLGetCursorName in states S4 and S5 and returns S1015 if that function is executed in S4 and a cursor name has not been set ("S1015" is enclosed by parentheses, indicating that it is generated by the Driver Manager). In fact, the Driver Manager cannot test this and the driver needs to do so.

[Appendix B: ODBC State Transition Tables (Problems and Information)]

Appendix C

1) The CASCADE | RESTRICT clauses of the ALTER TABLE, DROP TABLE, and DROP VIEW statements are not Integrity Enhancement Facility (IEF) grammar, but an optional enhancement added by the SQL Access Group (SAG).

[Appendix C: SQL Grammar (Problems and Information)]

Appendix D

1) SQLColAttributes, SQLColumns, and SQLDescribeCol each return attributes of a column in a table, but only SQLColAttributes returns all four of the precision, scale, length, and display size attributes of a column in a table.

[Appendix D: Data Types (Problems and Information)]

Appendix F

1) SQL_NUMERIC can be explicitly converted by the CONVERT function.

[Appendix F: Scalar Functions (Problems and Information)]

Appendix G

1) The note in the SQL_GETDATA_EXTENSIONS row of the table in the SQLGetInfo section of Appendix G states that when data is retrieved using SQLExtendedFetch, SQLGetData supports the functionality specified with the SQL_GD_ANY_COLUMN and SQL_GD_BOUND bitmasks. When data is retrieved with SQLExtendedFetch, SQLGetData supports the functionality specified with the SQL_GD_ANY_ORDER bitmask as well, so SQL_GD_ANY_ORDER should be added to the list of specified bitmasks in the note.

[Appendix G: ODBC Cursor Library (Problems and Information)]

SDK Guide, Using ODBC Test

1) The Always Use Cursor Library radio check box in the User Options dialog box in ODBC Test has been replaced with the following radio buttons: DEFAULT to specify that the DM uses the scrolling capabilities of the driver, rather than the cursor library; USE IF NEEDED to specify that the DM uses the cursor library only if it is needed; USE ODBC to specify that the Driver Manager (DM) uses the cursor library; and USE DRIVER to specify that the DM uses the scrolling capabilities of the driver, rather than the cursor library.

[Chapter 4: Using ODBC Test (Problems and Information)]


Known Problems and Additional Information

Although many ambiguities and problems in the ODBC specification have been resolved, some problems could not be resolved or were not addressed in time for printing. Furthermore, a few minor bugs have been found in software shipped with the ODBC SDK. The following topics describe these problems and provide additional information the software shipped with the ODBC SDK.

ODBC 2.0 Programmer's Reference

ODBC 2.0 SDK Guide

ODBC SDK 2.0 Software Components

ODBC SDK 2.10 Software Components

ODBC 2.x on Win32s

Notes to Driver Writers

Using the ODBC SDK With Visual C++


"Problems and Information" topics discuss problems that could not be resolved in time for printing; they should be considered more up-to-date than the ODBC 2.0 Programmer's Reference. These topics also provide additional information about the software shipped with the ODBC SDK.


ODBC 2.0 Programmer's Reference (Problems and Information)

General Problems

ODBC Functions

Appendix A: Error Codes

Appendix B: ODBC State Transition Tables

Appendix C: SQL Grammar

Appendix D: Data Types

Appendix F: Scalar Functions

Appendix G: ODBC Cursor Library

Installation and Configuration


General Problems (Problems and Information)

Catalog Functions

cbValueMax for Fixed-Length Data

Changing the Current Qualifier

Code Examples

Flushing the Error Queue

Resolving 16-Bit and 32-Bit Data Source Name Conflicts

Retrieving Results

SQL Standard

Trace Options


Catalog Functions (Problems and Information)

1) The rules for quoting identifiers in the catalog functions are identical to the rules for quoting identifiers anywhere else. The application is never required to quote identifiers as arguments to catalog functions and should only do so to distinguish a true column name from a pseudo-column of the same name (such as ROWID). Drivers should be prepared to handle quoted identifiers in the catalog functions.

2) To implement pattern matching against catalog functions that allow search characters, most drivers will use a LIKE predicate. The semantics of the LIKE predicate specify that trailing spaces are significant. To make sure  pattern matching is successful against identifiers stored in fixed-length columns, a percent sign (%) should be added to the end of the search string.

3) The column order in the result set should be the order that the column names are listed in each catalog function.

4) For the catalog functions, the description of SQLSTATE S1C00 states, "The combination of the current settings of the SQL_CONCURRENCY and SQL_CURSOR_TYPE statement options was not supported by the driver or data source." This is incorrect; in this case, the S1C00 error is returned by SQLFetch or SQLExtendedFetch.


cbValueMax for Fixed-Length Data (Problems and Information)

The cbValueMax argument for SQLBindCol is ignored for fixed-length data types. Several references in the ODBC specification suggest that it is used. For fixed-length C data types, the driver ignores the input cbValueMax and uses the length of the C data type. Specific sections are listed below.

The description for SQLExtendedFetch under "Column-Wise Binding" states that:

"For each bound column, the driver stores the data in the rgbValue buffer bound to the column. It stores the first row of data at the start of the buffer and each subsequent row of data at an offset of cbValueMax bytes from the data for the previous row."

This is true only for variable-length data types. If, for example, an application calls SQLBindCol with fCType set to SQL_C_SHORT and cbValueMax set to 5, the driver will write at 2-byte (sizeof(SWORD)) intervals, not every 5 bytes as the paragraph implies.

The above also applies to similar descriptions in "Column-Wise Binding" in Chapter 7, "Retrieving Results," as well as the same section of Chapter 15, "Returning Results."


Changing the Current Qualifier (Problems and Information)

Data sources that support multiple qualifiers allow an application to change the current qualifier by setting the SQL_CURRENT_QUALIFIER connection option. However, applications using this feature should be aware of the following limitations:

An application must not set this option while results are pending on an hstmt associated with the connection. The driver will return the SQLSTATE S1011 (Operation invalid at this time).

Prepared statements might not persist across changing qualifiers. Statements should be reprepared after changing qualifiers.

With data sources that allow connections to multiple qualifiers, the user can specify the current qualifier in a variety of ways. The following hierarchy describes which methods take precedence, if supported, in the order of highest to lowest precedence:

Qualifier interactively specified by user during connection (such as through a dialog box from SQLDriverConnect or specified in an SQLBrowseConnect string).

Connection option specified prior to connection.

Qualifier specified as part of connection string.

Qualifier used in previous connection.


Code Examples (Problems and Information)

In the second code example in Chapter 10, when printing column names *outlen should be outlen.


Flushing the Error Queue (Problems and Information)

In ODBC 1.0, if the application called another function on a handle with unretrieved errors, the Driver Manager called SQLError repeatedly to clear the errors prior to passing the call to the driver. For performance reasons, ODBC 2.x drivers must clear the errors themselves when another call is made on a handle with queued errors. The Driver Manager will continue to clear errors for 1.0 drivers only.


Resolving 16-Bit and 32-Bit Data Source Name Conflicts (Problems and Information)

If both a 16-bit and a 32-bit data source have the same name and this data source name is passed into SQLConnect, SQLDriverConnect, or SQLBrowseConnect, the Driver Manager will use the 32-bit data source and associated driver.


Retrieving Results (Problems and Information)

1) In the Keyset-Driven Cursors subsection of the Using Block and Scrollable Cursors section of chapter 7, "Retrieving Results," of the ODBC 2.0 Programmer's Reference, keyset-driven cursors are defined such that updating the key values in a row is considered to be deleting the existing row and inserting a new row. Note that the deleted rows are packed only if SQL_SS_DELETIONS is returned by SQLGetInfo for the fInfoType SQL_STATIC_SENSITIVITY, and that the added row will show only if SQL_SS_ADDITIONS is returned by SQLGetInfo for SQL_STATIC_SENSITIVITY.  A row whose key value has been updated may appear in the same position in the keyset until the next query.

For a row whose key value has not changed, updated values will show in the keyset if SQL_SS_UPDATES is returned by SQLGetInfo for SQL_STATIC_SENSITIVITY.


SQL Standard (Problems and Information)

The ODBC 2.0 Programmer's Reference refers to ANSI 1989 as the current SQL standard. Since the release of ODBC version 1.0, ANSI has published a new version of the SQL standard commonly referred to as SQL '92, as described later in the ODBC 2.0 Programmer's Reference. The following book provides additional information regarding the new standard:

Melton, Jim and Simon, Alan R.: Understanding the New SQL: A Complete Guide (Morgan Kaugmann, 1993).


Trace Options (Problems and Information)

1) ODBC 2.x allows the user to specify Driver Manager trace options in two ways. The user can specify tracing through the Options dialog box of the ODBC Control Panel device or Administrator or through the connection options described in SQLSetConnectOption. If the user specifies trace options through the Options dialog box, values are written as defaults to the [ODBC] section of the ODBC.INI file as described in Chapter 20, "Configuring Data Sources," of the ODBC 2.0 Programmer's Reference. Explicitly setting the value, either by calling SQLSetConnectOption or through the ODBC Administrator, overrides any default behavior specified in ODBC.INI.


ODBC Functions (Problems and Information)

SQLBindCol

SQLBindParameter

SQLBrowseConnect

SQLCancel

SQLColAttributes

SQLColumns

SQLConnect

SQLDriverConnect

SQLExecDirect

SQLExecute

SQLFetch and SQLExtendedFetch

SQLForeignKeys

SQLFreeStmt

SQLGetData

SQLGetInfo

SQLGetTypeInfo

SQLNativeSql

SQLParamData

SQLParamOptions

SQLPrepare

SQLProcedureColumns

SQLPutData

SQLRowCount

SQLSetConnectOption

SQLSetPos

SQLSetStmtOption

SQLSpecialColumns

SQLStatistics

SQLTables

SQLTransact


SQLBindCol (Problems and Information)

1) Both descriptions for SQLSTATE S1003 in SQLBindCol are checked by the Driver Manager.

2) Before ODBC 2.10, when SQLBindCol was called to bind a column to a new storage location, data was placed in the new storage location the next time that data was fetched. With the release of ODBC 2.10, the data is placed in the new storage location either the next time that data is fetched, or when SQLSetPos is called with an fOption of SQL_REFRESH, SQL_UPDATE, or SQL_ADD.

3) SQLSetPos only updates those columns in a row that have been bound with SQLBindCol and do not have a length (pcbValue in SQLBindCol) of SQL_IGNORE. The description of pcbValue in the SQLBindCol section of the Programmer's Reference should include SQL_IGNORE as a possible value of pcbValue, stating that pcbValue can be SQL_NULL_DATA, SQL_IGNORE (when used with SQLSetPos), the number of bytes (excluding the null termination byte for character data) available to return in rgbValue prior to calling SQLExtendedFetch or SQLFetch, or SQL_NO_TOTAL if the number of available bytes cannot be determined. Another statement (in both the syntax description and Comments sections of SQLBindCol) should indicate that if pcbValue is SQL_IGNORE, SQLSetPos will not update the icol column.


SQLBindParameter (Problems and Information)

1) SQLBindParameter contains arguments to indicate the maximum length and scale of the parameter column or expression. These arguments are provided to allow the driver to do client-side conversions between the fCType in the application buffer and the fSqlType sent to the server. These values must be less than the maximum length and scale for a column or expression of the SQL type (as opposed to the actual maximum length and scale of the underlying column) specified with the fSqlType parameter in SQLBindParameter.

Because this was not clear in earlier versions of the specification, ODBC 2.x drivers should not enforce this restriction and not return S1094 or S1104. However, applications must abide by this restriction as it will be enforced in the future.

2) The second two reasons for returning SQLSTATE S1105 (Invalid parameter type) cannot be returned by SQLBindParameter. This is because SQLBindParameter cannot always determine whether the underlying parameter marks an input parameter, an input/output parameter, an output parameter, or a return value. These SQLSTATEs can be returned by both SQLExecute and SQLExecDirect.

3) SQLSTATE 07006 (Restricted data type attribute violation) cannot be returned by SQLBindParameter, because SQLBindParameter ignores these arguments when pcbValue is SQL_DEFAULT_PARAM. This SQLSTATE can be returned by SQLExecute, SQLExecDirect, and SQLPutData.


SQLBrowseConnect (Problems and Information)

1) The syntax of the attribute value list returned in the szConnStrOut argument is as follows:

attribute-value-list ::= character-string [:localized-character string] | character-string [:localized-character-string], attribute value list


SQLCancel (Problems and Information)

1) Applications should NOT use SQLCancel to close and discard the results of an open cursor. SQLCancel should be used only in an attempt to cancel a function executing asynchronously or on a separate thread. Cursors should be closed using SQLFreeStmt with the SQL_CLOSE option.

2) If an ODBC 2.x driver treats a synchronous SQLCancel as a FreeStmt/Close, it must return SQL_SUCCESS_WITH_INFO along with SQLSTATE 01S05 (Cancel treated as FreeStmt/Close). The Driver Manager and cursor library will require this value be returned in multithreaded environments to ensure the correct state checking. Note that this error is returned for use by the Driver Manager; it will not be returned to an application.


SQLColAttributes (Problems and Information)

1) The description of the SQL_COLUMN_AUTO_INCREMENT descriptor type in the SQLColAttributes section of the Programmer's Reference should indicate that when an insert is made into an auto-increment column, a unique value is inserted into the column at insert time. The increment is not defined, but is DBMS-specific. An application should not assume that an auto-increment column starts at any particular point or increments by any particular value.

2) The description of the SQL_COLUMN_MONEY descriptor type in the SQLColAttributes section of the Programmer's Reference should indicate that a MONEY data type has predefined fixed precision and scale (which are DBMS-specific).

3) The descriptor SQL_COLUMN_UPDATABLE describes the updatability of the base column, not the result set. Whether the result set is updatable may depend upon the query used to generate it. The description of SQL_COLUMN_UPDATABLE in the SQLColAttributes section of the Programmer's Reference should be changed to indicate that this descriptor describes the updatability of the base column.


SQLColumns (Problems and Information)

1) SQLColumns retrieves data for all types of items returned by SQLTables. In addition to base tables, this may include (but is not limited to) views, synonyms, system tables, and so on.

2) Some columns that can be returned by SQLStatistics are not returned by SQLColumns. For example, SQLColumns does not return the columns in an index created over an expression or filter, such as SALARY + BENEFITS or DEPT = 0012.

3) The order of the columns in the column list returned by SQLColumns is not necessarily the same as the order of the columns returned when the application performs a SELECT statement on all columns in that table. This statement should be added to the Comments section of the SQLColumns section of the Programmer's Reference.


SQLConnect (Problems and Information)

1) SQLSTATE IM006 (Driver's SQLSetConnectOption failed) can be returned by either the driver or the Driver Manager.

2) SQLSTATE 01S02 (Option value changed) should be added to the Diagnostics section of the SQLConnect function in the Programmer's Reference, with the following description: "The driver did not support the specified value of the vParam argument in SQLSetConnectOption and substituted a similar value. (Function returns SQL_SUCCESS_WITH_INFO)."


SQLDriverConnect (Problems and Information)

1) A NEW button has been added to the SQL Data Sources dialog box that is displayed when SQLDriverConnect is called with either an empty string entered for the connection string, or the Driver Completion flag set to SQL_DRIVER_PROMPT. The New button allows you to add a new data source when making a connection with SQLDriverConnect. After you enter a data source name, you are prompted to select a driver, then to enter driver-specific setup information, the same process used to add a data source through the ODBC Administrator.

2) SQLSTATE IM006 (Driver's SQLSetConnectOption failed) can be returned by either the driver or the Driver Manager.

3) Before ODBC 2.10, problems could occur when SQLDriverConnect was called with the DRIVER keyword (without a data source name) on Windows on Windows (WOW). These problems have been fixed for ODBC 2.10.


SQLExecDirect (Problems and Information)

1) The second and third descriptions for SQLSTATE S1090 (Invalid string or buffer length) in the SQLExecDirect section of the Programmer's Reference should read as follows:

A parameter value, set with SQLBindParameter, was a null pointer and the parameter length value was not 0, SQL_NULL_DATA, SQL_DATA_AT_EXEC, SQL_DEFAULT_PARAM, or less than or equal to SQL_LEN_DATA_AT_EXEC_OFFSET.

A parameter value, set with SQLBindParameter, was not a null pointer and the parameter length value was less than 0, but was not SQL_NTS, SQL_NULL_DATA, SQL_DATA_AT_EXEC, SQL_DEFAULT_PARAM, or less than or equal to SQL_LEN_DATA_AT_EXEC_OFFSET.

2) Add a new description for SQLSTATE S1090 (Invalid string or buffer length) that reads:

A parameter length value bound by SQLBindParameter was set to SQL_DATA_AT_EXEC; the SQL type was either SQL_LONGVARCHAR, SQL_LONGVARBINARY, or a long, data-source specific data type; and the SQL_NEED_LONG_DATA_LEN information type in SQLGetInfo was "Y".

3) Add SQLSTATE 01S02 (Option value changed) to the SQLExecDirect diagnostics section, with the following description: A specified statement option was invalid because of SQL constraints or requirements, so a similar value was temporarily substituted. (Function returns SQL_SUCCESS_WITH_INFO.)


SQLExecute (Problems and Information)

1) The second and third descriptions for SQLSTATE S1090 (Invalid string or buffer length) in the SQLExecute section of the Programmer's Reference should read as follows:

A parameter value, set with SQLBindParameter, was a null pointer and the parameter length value was not 0, SQL_NULL_DATA, SQL_DATA_AT_EXEC, SQL_DEFAULT_PARAM, or less than or equal to SQL_LEN_DATA_AT_EXEC_OFFSET.

A parameter value, set with SQLBindParameter, was not a null pointer and the parameter length value was less than 0, but was not SQL_NTS, SQL_NULL_DATA, SQL_DATA_AT_EXEC, SQL_DEFAULT_PARAM, or less than or equal to SQL_LEN_DATA_AT_EXEC_OFFSET.

2) Add a new description for SQLSTATE S1090 (Invalid string or buffer length) that reads:

A parameter length value bound by SQLBindParameter was set to SQL_DATA_AT_EXEC; the SQL type was either SQL_LONGVARCHAR, SQL_LONGVARBINARY, or a long, data-source specific data type; and the SQL_NEED_LONG_DATA_LEN information type in SQLGetInfo was "Y".

3) Add SQLSTATE 01S02 (Option value changed) to the SQLExecute diagnostics section, with the following description: A specified statement option was invalid because of SQL constraints or requirements, so a similar value was substituted. (Function returns SQL_SUCCESS_WITH_INFO.)


SQLFetch and SQLExtendedFetch (Problems and Information)

1) The ODBC 2.0 Driver Manager prevents applications from intermixing SQLExtendedFetch and SQLFetch on the same result set. However, the descriptions of the resulting error for both functions require the following corrections:

a) The description for the last case of SQLSTATE S1010 (Function sequence error) for SQLFetch should read:

(DM) SQLFetch was called for an hstmt after SQLExtendedFetch was called and before SQLFreeStmt had been called with the SQL_CLOSE option.

b) The description for the last case of SQLSTATE S1010 (Function sequence error) for SQLExtendedFetch should read:

(DM) SQLExtendedFetch was called for an hstmt after SQLFetch was called and before SQLFreeStmt had been called with the SQL_CLOSE option.

2) Before ODBC 2.10, if you used SQLExtendedFetch to position the cursor such that the rowset started before the result set, but overlapped the result set, the returned rowset started with the first row of the result set and SQL_SUCCESS was returned. This was true for an fFetchType of SQL_ABSOLUTE (with a negative irow), SQL_RELATIVE (with a negative irow), or SQL_PRIOR.

With the release of ODBC 2.10, using SQLExtendedFetch returns SQL_NO_DATA_FOUND when fetching before the first row of the result set unless both of the following are true:

a) The current position is beyond the first row.

b) fFetchType is SQL_PRIOR, or fFetchType is SQL_RELATIVE or SQL_ABSOLUTE with a negative irow whose absolute value is less than or equal to the current set SQL_ROWSET_SIZE.

If both of these are true, SQL_SUCCESS_WITH_INFO is returned a SQLSTATE 01S06 (Attempt to fetch before the result set returned the first rowset).

3) Some drivers remove rows from the result set when deleted, such that subsequent fetches do not return those deleted rows. Such behavior is referred to as "packing". For drivers that do not support packing, deleted rows are removed from the cursor only when the cursor is closed. The following notes apply to fetch behavior for drivers that pack.

a) Deleted rows are packed only at Fetch time, such as when a refresh is accomplished by SQLExtendedFetch with SQL_FETCH_RELATIVE and irow=0, because a new rowset is retrieved in order to refresh the data. Note that packing does not occur in a refresh by SQLSetPos, which does not produce a new rowset.

b) When an SQLExtendedFetch with an fFetchType of SQL_FETCH_RELATIVE is performed by a driver that packs, the offset (as set by irow) is computed from the first row of the rowset, even if that row has been deleted. The new cursor position is computed by counting all non-deleted and newly inserted rows. If the first row has been deleted, a relative fetch with either an irow of 0 or an irow of 1 will return the same row (the first non-deleted row following the first row of the rowset).

c) When an SQLExtendedFetch with an fFetchType of SQL_FETCH_PRIOR is performed by a driver that packs, the rowset returned will end with the first non-deleted row preceding the first row of the previous rowset, even if the first row has been deleted. The last row of the returned rowset may be a newly inserted row.

d) When an SQLExtendedFetch with an fFetchType of SQL_FETCH_NEXT is performed by a driver that packs, the rowset will start with the first row following the last row of the previous rowset, even if the last row has been deleted. The last row of the previous rowset is used as a departure point even if new rows have been inserted or deleted prior to the last row, such that the number of rows from the first row to the last row is different than the original rowset size. The first row of the returned rowset will be the first non-deleted row, and may be a newly inserted row.

4) After a call to SQLExtendedFetch has returned SQL_NO_DATA_FOUND because it has read off the end of the result set, the cursor is positioned past the end of the result set.  Any SQLExtendedFetch with an fFetchType of SQL_FETCH_NEXT or SQL_FETCH_RELATIVE with a non-negative value of irow will return SQL_NO_DATA_FOUND.  Any negative relative fetch will return the rowset starting irow rows prior to the last row in the result set.  If the cursor is sensitive to added rows, this count includes rows that have been added to the end of the result set since the SQL_NO_DATA_FOUND.  This is equivalent to SQLExtendedFetch with an fFetchType of SQL_FETCH_ABSOLUTE with a negative value.  SQL_FETCH_PRIOR in this case will return the last complete rowset in the result set.

After a call to SQLExtendedFetch that has only partially filled the rowset because it has reached the end of the result set, the cursor is positioned on the first row of the rowset.  A Fetch Relative may specify a row past the last row in the rowset that is now valid if the cursor is able to detect new records which have been added to the result set since the previous fetch.  Such a fetch may show added rows even if the rowset overlaps the previous rowset in which the rows didn't exist.  A Fetch Next is not valid if the current rowset overlaps the end of the result set.

5) The rgfRowStatus Argument subsection of the SQLExtendedFetch section of the Programmer's Reference should specify that the contents of the rgfRowStatus array are available for all rows for a dynamic cursor, as well as a static cursor.  For keyset and mixed cursors, this information is only available for rows in the keyset.

6) The following statements should be added to the rgfRowStatus Argument subsection of the SQLExtendedFetch section of the Programmer's Reference: "The SQL_ROW_UPDATED flag in the rgbRowStatus array is changed back to SQL_SUCCESS when SQLExtendedFetch generates a new rowset. Note that this also occurs when an SQLExtendedFetch with an fFetchType of SQL_FETCH_RELATIVE and an irow of 0 is performed, which refreshes the current rowset."

7) The following note should be added to the rgfRowStatus Argument subsection of the SQLExtendedFetch section of the Programmer's Reference: "Note  The contents of the rgfRowStatus array should not be modified by the application. rgfRowStatus should only be modified by the driver. Modification by the application could result in the driver acting upon erroneous status information."

8) The rowset size used for an SQLExtendedFetch can be changed between fetches by changing the SQL_ROWSET_SIZE option in SQLSetStmtOption. Even when the rowset size is changed, however, the previous rowset size may have to be used to determine the fetch destination. When an fFetchType of SQL_FETCH_NEXT is used, SQLExtendedFetch uses the previous rowset size to compute the fetch destination, in order to ensure that the rowset starts at the appropriate row (the row immediately following the last row of the previous fetch). The rowset size used to determine the number of rows to fetch is (as always) the value set in the most recent call to SQLSetStmtOption.

When, on the other hand, an fFetchType of SQL_FETCH_PRIOR is used, SQLExtendedFetch uses the new rowset size to compute the fetch destination, in order to ensure that the rowset ends at the appropriate row (the row immediately preceding the first row of the previous rowset).

9) A statement should be added to the description for SQLSTATE S1002 (Invalid column number) stating that this error will be returned when the SQL_CURSOR_TYPE statement option was SQL_CURSOR_FORWARD_ONLY and SQLBindCol was called with icol set to 0.

10) SQLSTATE 22002 (Indicator variable required but not supplied) should be added to the Diagnostics sections of both SQLExtendedFetch and SQLFetch, with the following description: NULL data was fetched into a column whose pcbValue set by SQLBindCol was a null pointer.


SQLForeignKeys (Problems and Information)

In SQLForeignKeys, for UPDATE_RULE and DELETE_RULE columns, the possible actions are SQL_CASCADE, SQL_RESTRICT, and SQL_SET_NULL. These are not clearly defined.


SQLFreeStmt (Problems and Information)

The opening description of SQLFreeStmt should state "...discards pending results, or, optionally, frees all resources..." Currently it states "and" instead of "or".


SQLGetData (Problems and Information)

1) For drivers that support calling SQLGetData on columns in any order, calling SQLGetData on a column and then calling SQLGetData on a different column always starts with the first bytes of that column. This is true whether the column has previously been fetched in whole, in part, or not at all.

2) Both descriptions of SQLSTATE S1003 (Program type out of range) in SQLGetData are checked by the Driver Manager.

3) The following should be added to the description of SQLSTATE S1109 (Invalid cursor position) for SQLGetData in the Programmer's Reference: SQLSetPos specified an irow of zero and fOption was not SQL_ADD, attempting to position the cursor on the entire rowset.

4) SQLSTATE S1109 (Invalid cursor position) is returned when SQLGetData is called on a forward-only cursor when the rowset is greater than one row. This statement should be added to the description of SQLSTATE S1109 in the diagnostics section and to the comments section of SQLGetData in the Programmer's Reference.

5) SQLSTATE 22002 (Indicator variable required but not supplied) is returned if pcbValue is a null pointer and NULL data is retrieved.

6) The following statements should be added to the Comment subsection of the SQLGetData section in the Programmer's Reference:

When the following sequence is performed:

SQLGetData(icol=n), SQLGetData(icol=m), SQLGetData(icol=n),

the second call to SQLGetData(icol=n) retrieves data from the start of the n column. Any offset in the data in the column due to earlier calls to SQLGetData for the column is no longer valid.

If you reposition to a row by calling SQLSetPos, or refetch a row by calling SQLExtendedFetch (and the cursor is positioned on that row), SQLGetData(icol=n) retrieves data from the start of the n column in that row.


SQLGetInfo (Problems and Information)

1) The description of the pcbInfoValue argument for SQLGetInfo incorrectly states that "For all <noncharacter> types of data, the value of cbValueMax is ignored and the driver assumes the size of rgbValue is 32 bits." The length of data returned in rgbInfoValue depends on the fInfoType requested. The application must set cbValueMax to the defined size of the fInfoType requested, and the driver must return the data according to the size specified by cbValueMax.

2) The changes made to the SQL_OUTER_JOINS information type in ODBC 2.0 are not compatible with ODBC 1.0. To correct the incompatibility, SQL_OUTER_JOINS should revert to its original form in ODBC 1.0:

InfoType	Returns
SQL_OUTER_JOINS	A character string; "Y" if the data source supports outer joins and the driver supports the ODBC outer join escape clause. "N" otherwise.
3) A new information type, SQL_OJ_CAPABILITIES, describes the types of outer joins supported by the driver and data source:

InfoType	Returns
SQL_OJ_CAPABILITIES	A 32-bit bitmask enumerating the types of outer joins supported by the driver and data source. The following bitmasks are used to determine which types are supported: SQL_OJ_LEFT  = Left outer joins are supported. SQL_OJ_RIGHT = Right outer joins are supported. SQL_OJ_FULL  = Full outer joins are supported. SQL_OJ_NESTED = Nested outer joins are supported. SQL_OJ_NOT_ORDERED = The column names in the ON clause of the outer join do not have to be in the same order as their respective table names in the OUTER JOIN clause. SQL_OJ_INNER = The inner table (the right table in a left outer join or the left table in a right outer join) can also be used as in an inner join. This does not apply to full outer joins, which do not have an inner table. SQL_OJ_ALL_COMPARISON_OPS = The comparison operator in the ON clause can be any of the ODBC comparison operators. If this bit isn't set, only the equals (=) comparison operator can be used in outer joins.
4) Drivers that conform to the ODBC 2.01 or ODBC 2.01a specification return "02.01" for the SQL_DRIVER_ODBC_VER information type. Drivers that conform to the ODBC 2.10 specification return "02.10" for the SQL_DRIVER_ODBC_VER information type.

5) The following statements should be added to the Returns column for SQL_ROW_UPDATES in the SQLGetInfo section of the Programmer's Reference: "SQL_ROW_UPDATES indicates that the driver can return the SQL_ROW_UPDATED flag to the rgfRowStatus array when an SQLExtendedFetch is performed. The driver can detect and indicate that the data returned in a result set has been updated by another user. (This only applies to updates, not to deletions or insertions.)"


SQLGetTypeInfo (Problems and Information)

1) The description of the AUTO_INCREMENT descriptor type in the SQLGetTypeInfo section of the Programmer's Reference should indicate that when an insert is made into an auto-increment column, a unique value is inserted into the column at insert time. The increment is not defined, but is DBMS-specific. An application should not assume that an auto-increment column starts at any particular point or increments by any particular value.

2) The description of the MONEY descriptor type in the SQLGetTypeInfo section of the Programmer's Reference should indicate that a MONEY data type has predefined fixed precision and scale (which are DBMS-specific).

3) The data types returned by SQLGetTypeInfo are those supported by the DBMS.  They are intended for use in Data Definition Language (DDL) statements.  Drivers can return result set data using data types other than the types returned by SQLGetTypeInfo.  For example, in creating the result set for a catalog function, the driver might use a data type that is not supported by the DBMS.

4) SQLGetTypeInfo returns the results as a standard result set, ordered by DATA_TYPE and then by how closely the data type maps to the corresponding ODBC data type; data types defined by the DBMS taking precedence over user-defined data types.  For example, suppose that a DBMS defines INTEGER and COUNTER data types, where COUNTER is auto-incrementing, and that a user-defined data type WHOLENUM has also been defined.  These would be returned in the order INTEGER, WHOLENUM, COUNTER. The Programmer's Reference incorrectly states that SQLGetTypeInfo returns the result set ordered by the TYPE_NAME.


SQLNativeSql (Problems and Information)

For drivers that simulate scrollable cursors, SQLNativeSql might return the following SQLSTATEs when the SQL string is a positioned update or delete statement:

SQLSTATE S1109 (Invalid cursor position). For the current row of the cursor referred to in the statement, the value of the rgfStatus array is SQL_ERROR or SQL_DELETED.

SQLSTATE 24000 (Invalid cursor state). The cursor referred to in the statement is positioned before the start of the result set or after the end of the result set.


SQLParamData (Problems and Information)

1) Before ODBC 2.10, when a 16-bit application was running on Windows NT and calling a 32-bit driver, an error was returned when a data-at-execution parameter was supplied to one column by calling SQLParamData and SQLPutData, then SQLParamData was called to supply a data-at-execution parameter for a second column. The data returned to rgbValue was not valid data. This problem, which was in the thunking layer, has been fixed for ODBC 2.10.


SQLParamOptions (Problems and Information)

The pirow parameter indicates how many parameters were successfully processed. It does not indicate the current result set being processed with SQLMoreResults. That is, pirow is set at execute time (when SQLExecute, SQLExecDirect, or, in the case of data-at-execution parameters, SQLParamData returns SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, or SQL_ERROR). It is not incremented each time SQLMoreResults is called.

For example, suppose an array of 10 parameters is passed to a SELECT statement and that statement is executed successfully. pirow is set to 10 and is not affected by calls to SQLMoreResults to retrieve each result set.


SQLPrepare (Problems and Information)

1) Add SQLSTATE 01S02 (Option value changed) to the SQLExecute diagnostics section, with the following description: A specified statement option was invalid because of SQL constraints or requirements, so a similar value was temporarily substituted. (Function returns SQL_SUCCESS_WITH_INFO.)


SQLProcedureColumns (Problems and Information)

1) SQLProcedureColumns returns the results as a standard result set ordered by PROCEDURE_QUALIFIER, PROCEDURE_OWNER, PROCEDURE_NAME, and the order that the parameters appear in the procedure invocation. The Programmer's Reference incorrectly states that COLUMN_TYPE is used when ordering the result set.


SQLPPutData (Problems and Information)
SQLPutData (Problems and Information)

1) Before ODBC 2.10, when SQLExecute, SQLExecDirect, or SQLSetPos was called for an hstmt and returned SQL_NEED_DATA, and SQLCancel was called before data was sent for all data-at-execution parameters or columns, and then SQLPutData was called, SQLSTATE S1008 (Operation Cancelled) was returned. With the release of ODBC 2.10, SQLSTATE S1010 (Function Sequence Error) is returned for SQLPutData because after SQLCancel is called, and the hstmt is moved out of the SQL_NEED_DATA state, so SQLPutData was called out of sequence.


SQLRowCount (Problems and Information)

Some drivers support determining the number of rows returned from a SELECT by calling SQLRowCount. Note that, after the application has executed a SQL_UPDATE, SQL_ADD, or SQL_DELETE operation on the same hstmt, the number of rows returned by calling SQLRowCount will be the number of rows affected by the update operation, not the number of rows in the rowset.

2) The following description should be added for SQLSTATE 1011 (Operation invalid at this time) in the SQLSetConnectOption section of the Programmer's Reference: The argument fOption was SQL_PACKET_SIZE and the connection has already been established.


SQLSetConnectOption (Problems and Information)

1) The description for SQLSTATE 08003 (Connection not open) in the SQLSetConnectOption section of the Programmer's Reference should be designated with (DM), since the warning is returned by the Driver Manager, not the driver.

2) The following description should be added for SQLSTATE S1011 (Operation invalid at this time) in the SQLSetConnectOption section of the Programmer's Reference: "The argument fOption was SQL_PACKET_SIZE and the connection has already been established."

3) SQLSTATE 24000 (Invalid cursor state) should be added to the Diagnostics section of SQLSetConnectOption in the Programmer's Reference, with the following description: "The argument fOption was SQL_CURRENT_QUALIFIER and a result set was pending."


SQLSetPos (Problems and Information)

1) Contrary to what is stated in the discussion of the irow Argument in the Comments section of the SQLSetPos description, it is illegal to position the cursor on the entire rowset. An additional description should be added to SQLSTATE S1109 (Invalid cursor position), "The irow argument was 0 and the fOption argument was SQL_POSITION."

2) The third description of SQLSTATE S1009 (Invalid argument value), "irow was greater than the number of rows in the rowset and fOption was not SQL_ADD", should be removed. Instead, this error condition is returned by SQLSTATE S1107 (Row value out of range).

3) The fourth description of SQLSTATE S1009 (Invalid argument value) should be, "The value specified for the argument fOption was SQL_ADD, SQL_UPDATE, or SQL_DELETE and the SQL_CONCURRENCY statement option was SQL_CONCUR_READ_ONLY."

4) If irow is 0 and fOption is SQL_ADD, SQL_DELETE, SQL_REFRESH, or SQL_UPDATE, the current row after the operation is the same as the current row before the operation.

5) SQLSetPos updates, deletes, or adds (both single-row and bulk) that fail because of optimistic concurrency will return SQLSTATE 01S03 (No rows updated/deleted) for that row, after returning a rgfRowStatus of SQL_ROW_ERROR and SQLSTATE 01S01 (Error in row) for each row that failed. A call to SQLRowCount will return the number of rows successfully updated, added, or deleted.

An additional description should be added to SQLSTATE 01S03 (No rows updated/deleted): "The argument fOption was SQL_ADD, SQL_DELETE, or SQL_UPDATE, and the operation failed because of optimistic concurrency."

6) SQLSetPos with an fOption of SQL_REFRESH simply updates the status and content of the rows within the current fetched rowset. Deleted rows within the rowset appear as deleted rows until the next fetch, at which time the rows may disappear if the cursor supports packing (in which a subsequent SQLExtendedFetch does not return deleted rows). Added rows do not appear until the next fetch. Note that this behavior is different from SQLExtendedFetch with an fFetchType of SQL_FETCH_RELATIVE and irow=0, which also refreshes the current rowset, but will show added records or pack deleted records if these operations are supported by the cursor.

7) If a SQLSetPos update is performed, the status on the updated row is changed to SQL_ROW_UPDATED. A SQLSetPos refresh will change the status to SQL_ROW_SUCCESS if there are no errors on the refresh.

If a SQLSetPos deletion is performed, the row status is changed to SQL_ROW_DELETED. The status is not changed by any subsequent SQLSetPos refresh, and will remain until new data is retrieved from the data source. For drivers that support packing, the row is then deleted.

If an error occurs in a SQLSetPos operation on a row, the row status is set to SQL_ROW_ERROR. This status is not changed by any subsequent SQLSetPos refresh, and will remain until new data is retrieved from the data source.

8) Add a new SQLSTATE S1090 description that reads:

A column length value bound by SQLBindParameter was set to SQL_DATA_AT_EXEC; the SQL type was either SQL_LONGVARCHAR, SQL_LONGVARBINARY, or a long, data-source specific data type; and the SQL_NEED_LONG_DATA_LEN information type in SQLGetInfo was "Y".

9) SQLSetPos with an fOption of SQL_ADD can be performed even after SQLExtendedFetch has returned SQL_NO_DATA_FOUND.

10) The cursor library returns SQLSTATE S1C00 (Driver not capable) for SQLSetPos with irow=0 when the driver does not support bulk operations. A driver can return this error, but this is not recommended, since support of irow=0 will be required in the future.

11) The SQLSTATE 21S02 description should be changed to read: The argument fOption was SQL_ADD or SQL_UPDATE and either no columns were bound with SQLBindCol, the bound columns were all read-only, or the bound columns had a pcbValue of SQL_IGNORE.

12) The description contained in the Programmer's Reference for SQLSTATE 01S04 for SQLSetPos does not accurately describe the errors that can occur. The description states that SQLSTATE 01S04 is returned if the argument fOption was SQL_UPDATE or SQL_DELETE and more than one row was update or deleted. This is not an accurate description of the update or delete that occurs when irow=0, in which case more than one row is update or deleted by design. The description for SQLSTATE 01S04 should state that the argument fOption was SQL_UPDATE or SQL_DELETE and rows other than those indicated by the irow argument were update or deleted.


SQLSetStmtOption (Problems and Information)

1) If the data source provides native SQL support for a positioned update or delete statement, and the driver does not support simulated cursors, SQL_SUCCESS is returned when SQL_SC_UNIQUE is requested for SQL_SIMULATE_CURSOR. SQL_SUCCESS_WITH_INFO is returned if SQL_SC_TRY_UNIQUE or SQL_SC_NON_UNIQUE is requested. If the data source provides the SQL_SC_TRY_UNIQUE level of support, and the driver does not, SQL_SUCCESS is returned for SQL_SC_TRY_UNIQUE and SQL_SUCCESS_WITH_INFO is returned for SQL_SC_NON_UNIQUE.

2) The Programmer's Reference states that some statement options support substitution of a similar value if the data source does not support the specified option of vParam, with the result that the driver returns SQL_SUCCESS_WITH_INFO and SQLSTATE 01S02 (Options value changed). Substitution also occurs when the statement option is supported by the data source, but the option is invalid because of SQL constraints or requirements.

The description of SQLSTATE 01S02 (Option value changed) for SQLSetStmtOption should be changed to state that the driver did not support the specified value of the vParam argument, or the vParam argument was invalid because of SQL constraints or requirements, so a similar value was substituted.


SQLSpecialColumns (Problems and Information)

1) Some drivers cannot support the SQL_NO_NULLS value for fNullable in SQLSpecialColumns. Such drivers return SQLSTATE S1C00 (Driver not capable) if it is specified. Applications should be prepared for this case and  request SQL_NO_NULLS only if it is absolutely required.

2) The description of the PRECISION column returned from SQLSpecialColumns indicates that NULL is returned for data types where precision is not applicable. Note that, for the columns returned from SQLSpecialColumns, precision is always applicable and this column should never be NULL.


SQLStatistics (Problems and Information)

1) The ODBC 2.0 Programmer's Reference states that, for filtered indexes, each column in the filter condition is returned. This is incorrect. Filtered indexes are returned in the same manner as other indexes, except that the filter condition is returned in the FILTER_CONDITION column.

For example, if a filtered index is created on column A where the value of column B is greater than 10, 'A' is returned in the COLUMN_NAME column and 'B > 10' is returned in the FILTER_CONDITION column. If a filtered index is created on the expression B > 10, 'B > 10' is returned in both the COLUMN_NAME column the FILTER_CONDITION column.

2) Some columns returned by SQLStatistics are not returned by SQLColumns. For example, SQLColumns does not return the columns in an index created over an expression or filter, such as SALARY + BENEFITS or DEPT = 0012.


SQLTables (Problems and Information)

The description of the szQualifier argument in SQLTables does not describe the use of search patterns. Note that many drivers support enumerating tables across qualifiers by interpreting the percent sign (%) and the underscore character (_) as metacharacters in the szQualifier argument. Applications should escape metacharacters in the qualifier if they are to be interpreted literally against such drivers.


SQLTransact (Problems and Information)

For drivers that do not support transactions (SQLGetInfo fOption SQL_TXN_CAPABLE is 0), which are effectively always in autocommit mode, calling SQLTransact with an fType of either SQL_COMMIT or SQL_ROLLBACK will return SQL_SUCCESS. The Programmer's Reference states that in this instance calling SQL_COMMIT will return SQL_SUCCESS, but calling SQL_ROLLBACK will return SQLSTATE S1C00 (Driver not capable), which is not the case. The Driver Manager does not actually call SQLTransact with SQL_ROLLBACK when the driver is in autocommit mode, so SQLSTATE S1C00 is no longer returned.


Appendix A: ODBC Error Codes (Problems and Information)

1) SQLSTATE 22002 should be added to the list of error codes, with an error text of "Indicator variable required but not supplied", and the following returning functions: SQLExtendedFetch, SQLFetch, and SQLGetData.

2) SQLSTATE 01S05 should be added to the list of error codes, with an error text of "Cancel treated as FreeStmt/CLOSE", and the following returning function: SQLCancel.

3) SQLSTATE 01S06 should be added to the list of error codes, with an error text of "Attempt to fetch before the result set returned the first rowset", and the following returning function: SQLExtendedFetch.


Appendix B: ODBC State Transition Tables (Problems and Information)

1) If one or more calls to SQLPutData for a single parameter result in SQL_SUCCESS, attempting to call SQLPutData with cbValue set to SQL_NULL_DATA for the same parameter results in an error with SQLSTATE S1011 (Operation invalid at this time). This error does not result in a change of state; the hstmt is still in a Need Data state and the application can continue sending parameter data.

2) In "Connection Transitions" for SQLTransact, the entry in the second row for state C2 (Allocated) should be no change (that is, marked as "--") rather than SQLSTATE 08003.

3) The following should be added to the first footnote under SQLCancel: "If the driver treats the call to SQLCancel as SQLFreeStmt with the SQL_CLOSE option, then the driver returns SQL_SUCCESS_WITH_INFO and SQLSTATE 01S05 (Cancel treated as FreeStmt/Close), and the state changes as shown in the table for SQLFreeStmt with the SQL_CLOSE option."

4) The status codes in the footnote table of Appendix B should be SQL_ROW_DELETED and SQL_ROW_ERROR for footnote i (not SQL_DELETED and SQL_ERROR) and SQL_ROW_ADDED, SQL_ROW_SUCCESS, and SQL_ROW_UPDATED for footnote v (not SQL_ADDED, SQL_SUCCESS, and SQL_UPDATED).

5) "24000" should be added to the S5-S7 column of the SQLSetConnectOption statement transition table in Appendix B. A footnote referring to the "24000" entry should state: "The fOption argument was SQL_CURRENT_IDENTIFIER."

6) The Driver Manager cannot determine if a result set will be created (for prepared statements) or has been created (for executed statements).  Thus, when state transitions depend on whether a result set will be or has been created, the driver (not the Driver Manager) must check for state errors.  In particular, the driver must check for state errors for the following functions in the following states:

SQLColAttributes: S2/S3, S4/S5
catalog functions: S4/S5
SQLDescribeCol: S2/S3, S4/S5
SQLExecDirect: S4/S5
SQLExecute: S4/S5
SQLExtendedFetch: S4/S5
SQLFetch: S4/S5
SQLGetCursorName: S4/S5
SQLPrepare: S4/S5

Currently, the state tables in Appendix B show these correctly, except for SQLGetCursorName.  The tables show that the Driver Manager checks state errors for SQLGetCursorName in states S4 and S5 and returns S1015 if that function is executed in S4 and a cursor name has not been set ("S1015" is enclosed by parentheses, indicating that it is generated by the Driver Manager).  In fact, the Driver Manager cannot test this and the driver needs to do so.


Appendix C: SQL Grammar (Problems and Information)

1) The following should be removed from the list of keywords in Appendix C: DICTIONARY, DISPLACEMENT, IGNORE, OFF, and SYSTEM.

The following should be added to the list of keywords in Appendix C: ACTION, BOTH, CROSS, CURRENT_USER, DEFAULT, LEADING, NATURAL, NO, PAD, REFERENCES, RELATIVE, SESSION, SESSION_USER, SPACE, SYSTEM_USER, TRAILING, and TRIM.

These changes are made to align with international standards.

2) The outer join grammar should be changed to:

outer-join ::= table-name [correlation-name] {LEFT | RIGHT | FULL} OUTER JOIN
                   {table-name [correlation-name] | outer-join} ON search-condition

To determine which parts of this statement are supported, an application calls SQLGetInfo with the SQL_OJ_CAPABILITIES information type.

3) The CASCADE | RESTRICT clauses of the ALTER TABLE, DROP TABLE, and DROP VIEW SQL statements are not Integrity Enhancement Facility (IEF) grammar, but an optional enhancement added by the SQL Access Group (SAG). The font of these clauses in the SQL Statements section of Appendix C should not be distinct from the rest of the grammar.


Appendix D: Data Types (Problems and Information)

1) In "Converting Data from C to SQL Data Types," in Appendix D, the term "column length" is defined to be the length defined earlier in  Appendix D. This is incorrect. The column length here is the back end size, while the earlier definition refers to the number of bytes returned to the application in default C form.

2) We have allocated an implementation-defined range for extended SQL types. The Driver Manager allows an fSqlType less than or equal to SQL_TYPE_DRIVER_START to be passed to ODBC 2.x drivers. The driver values decrease (from -80) to reserve positive values of fSqlType for SQL 2. If the driver is 1.0 and the fSqlType is in the driver range, the Driver Manager issues an SQLSTATE S1004 error (SQLBindParameter and SQLGetTypeInfo). For an ODBC 2.x driver, the driver must issue a S1C00 error if it doesn't support the type, or, in the case of SQLGetTypeInfo, return an empty result set.

To improve interoperability, ODBC has predefined a set of extended fSqlTypes to handle ANSI INTERVAL types and double-byte UNICODE characters. Not all drivers are required to support these values, but drivers that support INTERVAL or UNICODE data types should use the defined values and follow the described behavior.

fSqlType	Description
SQL_INTERVAL_YEAR (-80)	Number of years between two dates. precision = max digits in year field length = precision display size = length
SQL_INTERVAL_MONTH (-81)	Number of months between two dates. precision = max digits in month field length = precision display size = length
SQL_INTERVAL_ YEAR_TO_MONTH (-82)	Number of years and months between two dates. precision = max digits in year field length = precision + 3 (year digits + two months digits + separator) display size = length
SQL_INTERVAL_DAY (-83)	Number of days between two dates. precision = max digits in day field length = precision display size = length
SQL_INTERVAL_HOUR (-84)	Number of hours between two date/times. precision = max digits in hour field length = precision display size = length
SQL_INTERVAL_MINUTE (-85)	Number of minutes between two date/times. precision = max digits in minute field length = precision display size = length
SQL_INTERVAL_ SECOND (-86)	Number of seconds between two date/times. precision = max digits in second scale = fractional seconds digits length = precison + scale (+ 1 if scale > 0 for decimal point) display size = length
SQL_INTERVAL_ DAY_TO_HOUR (-87)	Number of days/hours between two date/times. precision = max digits in day field length = precision + 3 (day digits + two hour digits + separator) display size = length
SQL_INTERVAL_ DAY_TO_MINUTE (-88)	Number of days/hours/minutes between two date/times. precision = max digits in day field length = precision + 6 (day digits + two hour digits+ two minutes digits + two separators) display size = length
SQL_INTERVAL_ DAY_TO_SECOND (-89)	Number of days/hours/minutes/seconds between two date/times. precision = max digits in day field scale = fractional digits of seconds length = precision + 9 + scale (+ 1 if scale > 0) (day digits + two hour digits + two minutes digits + two seconds digits + three separators + fractional second digits (+ decimal point if scale > 0)) display size = length
SQL_INTERVAL_ HOUR_TO_MINUTE (-90)	Number of hours/minutes between two date/times. precision = max digits in hour field length = precision + 3 (hour digits + two minutes digits +  separator) display size = length
SQL_INTERVAL_ HOUR_TO_SECOND (-91)	Number of hours/minutes/seconds between two date/times. precision = max digits in hour field scale = fractional digits of seconds length = precision + 6 + scale (+ 1 if scale > 0) (hour digits + two minutes digits + two seconds digits + two separators + fractional scale digits (+ decimal point if scale > 0)) display size = length
SQL_INTERVAL_ MINUTE_TO_SECOND (-92)	Number of minutes/seconds between two date/times precision = max digits in minute scale = fractional digits of seconds length = precision + scale + 3 (+ 1 if scale > 0) (minute digits + two seconds digits+ separator + fractional seconds digits (+ decimal point if scale >0)) display size = length
SQL_UNICODE (-95)	UNICODE string with 2 bytes/char. precision = max characters in string length = max number of bytes in string (precision times two) display size = max characters in string
Note that all of the INTERVAL types have a default C type of SQL_C_CHAR.

SQL_UNICODE has a default C type of SQL_C_BINARY. The application specifies the actual number of bytes when specifying the buffer size of a double-byte character string. The driver returns the maximum number of characters as the precision and the number of bytes as the length.

3) The Precision, Scale, Length, and Display Size section of Appendix D should be changed to indicate that SQLColAttributes, SQLColumns, and SQLDescribeCol return attributes of a column in a table, but that all three functions do not return the precision, scale, length, and display size of a column in a table. SQLDescribeCol returns the precision and scale. SQLColumns returns the precision, scale, and length. Only SQLColAttributes returns the precision, scale, length, and display size of a column.


Appendix F: Scalar Functions (Problems and Information)

1) The description for the scalar function USER is incorrect. Instead of returning the authorization (login) name, it should return the user name in the DBMS, which may be different from the login name. The function is identical to the SQLGetInfo SQL_USER_NAME option as to what it returns.

2) ODBC does not mandate a data type for return values from scalar functions as these are often back end-specific functions. Applications should use the CONVERT scalar function whenever possible to force data type conversion.

3) SQL_NUMERIC should be added to the list of keywords supported for the data_type argument of the CONVERT function.


Appendix G: ODBC Cursor Library (Problems and Information)

1) The cursor library documentation recommends that, when executing a positioned update statement, you should bind parameters in your update to the bound column buffers for your rowset and place the new values in the rowset buffers. This is so that the data source will be updated (using the parameters) with the same values as the cursor library's cache (from the rowset row). However, if you use SQL_DATA_AT_EXEC in any of the parameters of your update, then in order to make sure the cache and data source are updated with the same values, you should pass the corresponding bound column buffers for your rowset to SQLPutData rather than binding those parameters to the rowset buffers.

2) The cursor library specification should explain some end cases as to what happens when the cache gets updated, as follows:

If the pcbValue for the bound column is set to SQL_DATA_AT_EXEC, the cache is untouched.

If the column's C type is SQL_C_CHAR or SQL_C_BINARY and the pcbValue is SQL_NTS, the strlen of the data is put into the cache pcbValue.

The new data in the rowset is assumed to be of the same type as the bound column; that is, if the column is bound to SQL_C_CHAR and the user calls SQLBindParameter specifying that the parameter C type is SQL_C_SLONG and puts a LONG value into the rowset, the cursor libary won't convert data when moving the data to the cache. It simply moves cbValueMax bytes of data.

3) For forward-only cursors, SQLGetStmtOption with an fOption of SQL_ROW_NUMBER does not return SQLSTATE S1109 (Invalid cursor position) when the value in the rgfRowStatus array in SQLExtendedFetch for the current row is SQL_ROW_DELETED or SQL_ROW_ERROR; instead, it returns SQL_SUCCESS. This is incorrect behavior on the part of the cursor library.

4) The note in the SQL_GETDATA_EXTENSIONS row of the table in the SQLGetInfo section of Appendix G states that when data is retrieved using SQLExtendedFetch, SQLGetData supports the functionality specified with the SQL_GD_ANY_COLUMN and SQL_GD_BOUND bitmasks. When data is retrieved with SQLExtendedFetch, SQLGetData supports the functionality specified with the SQL_GD_ANY_ORDER bitmask as well, so SQL_GD_ANY_ORDER should be added to the list of specified bitmasks in the note.


Installation and Configuration (Problems and Information)

1) SQLGetAvailableDrivers might return true with zero buffer length, if the specified path for the .INF file is invalid or the file does not contain valid information. Applications must not rely solely upon the return value of this function.

2) Errors are returned for the following situations:

SQLGetInstalledDrivers returns an error if a NULL pointer is passed in as lpszBuf.

SQLGetTranslator returns an error if a NULL pointer is passed in as lpszPath.

SQLConfigDataSource returns an error if lpszDriver is invalid.

SQLInstallODBC returns an error if the path to the .INF file is invalid.

SQLConfigDataSource returns an error if the user cancels the dialog box.

3) In the SQLDrivers section, driver attributes (DriverODBCVer, FileUsage, and so on) are required for all ODBC 2.x drivers.

4) Please note the following new sections to facilitate automatic installation of thunking components on appropriate operating environments:

The 16-bit ODBC.INF file has the following new sections. (The following components are installed ONLY on Win32s machines. These allow a 32-bit application to use a 16-bit ODBC Driver.)

[Win32s ODBC Driver Manager]
Driver=odbc32.dll,...
Thunk=odbc16ut.dll,...

[Win32s ODBC]
Main=odbccp32.dll,...
Thunk=cpn16ut.dll,...

The 32-bit ODBC.INF file has the following new sections. (The following components are installed ONLY on Windows NT machines. These allow a 16-bit WOW application to use a 32-bit ODBC Driver.)

[Generic Thunk ODBC Driver Manager]
Thunk1=odbc32gt.dll,...
Thunk2=odbc16gt.dll,...

[Generic Thunk ODBC]
Thunk1=ds32gt.dll,...
Thunk2=ds16gt.dll,...

5) The formal parameter UINT in the setup and installer functions has been changed to WORD. This is to avoid byte size mismatches between function calls when thunking from a 32-bit application to a 16-bit driver. This change will not affect an existing 16-bit driver.

6) To properly utilize WOW thunking components, the 16-bit ODBC Administrator program item (ODBCADM.EXE) must be installed in the \WINDOWS (not \WINDOWS\SYSTEM) directory. Therefore, the ODBC.INF entry for the [ODBC Administrator] section must contain the Windows00 keyword.

7) For Windows NT, driver configuration information is stored in the HKEY_LOCAL_MACHINE tree of the registry; therefore, drivers are available to all users of the machine. The data source configuration information is stored in the HKEY_CURRENT_USER tree of the registry; therefore, data sources are available only to the user who created the data source. This is consistent with Windows NT system design guidelines.

8) ConfigDSN can accept keywords that are not valid keywords for the connection functions. ConfigDSN does not necessarily support all keywords that are valid keywords for the connection functions. The keywords used by the ConfigDSN function must support all the options required to re-create the data source using the AUTO setup feature of the installer. When the uses of the ConfigDSN values and the connection string values are the same, the same keywords should be used.

9) Before ODBC 2.10, if the data source name was longer than SQL_MAX_DSN_LENGTH, as defined in SQL.H, the installer would connect to the default data source or if no default was specified, the installer would return a message that no data source was available. There was no clear indication that the error was due to an invalid data source name.

With the release of ODBC 2.10, the driver's ConfigDSN should call SQLValidDSN to check the length of the data source name, and to verify that no invalid characters are included in the name. If the data source name is longer than SQL_MAX_DSN_LENGTH, or includes invalid characters, then SQLValidDSN will return an error. (Note that the length of the data source name is also checked by SQLWriteDSNToIni.)

A section on SQLValidDSN should be added to Chapter 23, "Installer DLL Function Reference".

10) Before ODBC 2.10, when a 32-bit data source was added on Windows NT, the data source name was placed in the registration database, but was not propagated to the 16-bit ODBC.INI file under 32-bit drivers. This problem has been fixed for ODBC 2.10.

11) The ODBC.INF file must include the sections that describe the files shipped for thunking purposes: [Win32s ODBC] and [Win32s ODBC Driver Manager] for 16-bit drivers or [Generic Thunk ODBC] and [Generic Thunk ODBC Driver Manager] for 32-bit drivers. The SQLInstallODBC function will fail if these sections are not included in ODBC.INF.

Although an ODBC.INF file has the same format as normal Windows INF files, the ODBC Installer does not look at all of the description fields that could be put there. The following information is included in ODBC.INF:

  Disk number                   [image]  Overwrite
  File name                       [image]  Shared
  Date                               [image]  Version

The following information is not included in ODBC.INF. The ODBC Installer will silently ignore these fields. Note that commas need to be included in the ODBC.INF file to account for the unused keywords.

  Append (append or overwrite)
  Backup (backup old files)
  Copy (copy/don't copy the file)
  Decompress (decompress/don't decompress the file)
  Destination (destination directory)
  ReadOnly (mark file as read-only)
  Remove (remove file or copy using other properties)
  Rename (rename destination file)
  Root (strip subdirectories from the filename when copied)
  SetTimeStamp (use DATE setting or use real time)
  Size (size of the file in bytes)
  System (copy file when system reboots)
  TimeToCopy (for status indicator)
  Reserved (not used)
  Vital (abort/don't abort if this file doesn't copy)

12) Before ODBC 2.10, the ODBC Installer did not check for the GetDesktopWindow hwnd, so if an application used an hwnd of GetDesktopWindow, dialog boxes called by some installer functions would either prompt a fatal error (with an invalid-hwnd error message) or be positioned improperly. The installer functions for which this was true were SQLConfigDataSource, SQLCreateDataSource, SQLGetTranslator, SQLInstallODBC, and SQLManageDataSources. With the release of ODBC 2.10, the ODBC installer handles the GetDesktopWindow hwnd.

On Microsoft Windows for Workgroups, when the ODBC Installer calls GetDesktopWindow() to return a value for hwndParent in SQLConfigDataSource, mouse control is lost and the system has to be rebooted. To avoid this, the driver's ConfigDSN should call GetDesktopWindow() to return hwndParent for SQLConfigDataSource on Windows for Workgroups.

13) Before ODBC 2.10, the ODBC Installer installed ODBC components in the \WINDOWS\SYSTEM or \WINDOWS\SYSTEM32 directory for a local system, and in the \WINDOWS directory for a shared system. The components were installed in the \WINDOWS directory for a shared system so that one user's installation of ODBC would not affect another user's installation of ODBC.

With the release of ODBC 2.10, the ODBC Installer always installs ODBC components in the \WINDOWS\SYSTEM or \WINDOWS\SYSTEM32 directory, whether the Windows installation is local or shared. This allows a network administrator to maintain one installation for all users on the shared system.

14) The ODBC SDK 2.01 did not terminate the lpszAttributes string with double nulls, which could cause properly written installation programs to crash. With the release of ODBC 2.10, the attribute string is properly double-null terminated.

15) Use of the CTL3D library is discouraged. Future operating systems, such as Windows 95 and future versions of Windows NT, will provide this functionality natively, so will provide inherent support for 3D dialog boxes.

16) Before ODBC 2.10, if a null parent window handle was passed to SQLInstallODBC, and an error was returned, the message box that was returned had a bad title. With the release of ODBC 2.10, the error message box is entitled either "ODBC Administrator" or "32Bit ODBC Administrator".

17) Before ODBC 2.10, the ODBC SDK could not be installed if its target platform was other than the native platform of the machine. For example, an Intel SDK could not be installed on an Alpha Windows NT platform. With the release of ODBC 2.10, the 16-bit components of the SDK can be installed on a platform other than the target platform, but the 32-bit components cannot.

18) New keywords WinSysNTnn and WinSys95nn (where 00=<n<=99) have been defined for the ODBC.INF file. The files specified by these keywords will be installed on either Windows NT or Windows 95, but not on both. These keywords allow developers to install files selectively. For example, CTL3D32.DLL has the same name, but a different binary, for Windows NT (unicode version) and Windows 95 (ASCII version).

19) Before ODBC 2.10, when installing a driver from a disk using the driver setup procedure in the Control Panel or Administrator, files on the disk could be deleted after installation. This problem, which was caused by a bad pointer in the installer function SQLInstallDriver that deleted the source path, has been fixed in ODBC 2.10.

20) When installing the ODBC SDK 2.10 over the ODBC SDK 1.0, the user may experience problems when using the dBASE driver that shipped with the SDK 1.0, and should install the dBASE driver that shipped with the SDK 2.10.

21) ODBC SDK 2.0 added an Ignore button to the dialog box displayed if the Installer attempted to install a file that was currently in use. The dialog box previously had a Retry button to retry the operation, and a Cancel button to cancel the installation, but needed an Ignore button to allow the Installer to bypass installation of a file that was used by the operating system.

Before ODBC 2.10, the Ignore button worked for installation of 16-bit components, but did not work for installation of 32-bit components. With the release of ODBC 2.10, the Ignore button works for both 16- and 32-bit installations.


SQLValidDSN (Problems and Information)

The following information should be entered in Chapter 23, "Installer DLL Function Reference", of the Programmer's Reference:

Purpose

SQLValidDSN checks the length and validity of the data source name before the name is added to the ODBC.INI file (or registry).

Syntax

BOOL SQLValidDSN (lpszDSN)

The SQLValidDSN function accepts the following arguments:

Type	Argument	Use	Description
LPCSTR	lpszDSN	Input	Name of the data source whose validity should be checked.

Returns

The function returns TRUE if the data source name is valid. It returns FALSE if the data source name is invalid.

Comments

SQLValidDSN is called by a driver's ConfigDSN to check the length of the data source name, and the validity of the individual characters in the data source name.  It checks whether the length of the name is greater than SQL_MAX_DSN_LENGTH, as defined in SQL.H. (Note that the length of the data source name is also checked by SQLWriteDSNToIni.) SQLValidDSN checks whether any of the following invalid characters are included in the data source name:

[ ] { } < > , ; ? * = ! @ \

Related Functions

For information about	See
Adding, modifying, or removing a data source	ConfigDSN
Adding, modifying, or removing a data source	SQLConfigDataSource
Writing a data source name to ODBC.INI (or registry)	SQLWriteDSNToIni


ODBC 2.0 SDK Guide (Problems and Information)

Chapter 1: Overview of the ODBC SDK

Chapter 4: Using ODBC Test

Chapter 5: Using ODBC Spy

Chapter 6: Using the Driver Setup Toolkit

Appendix A: Developing 16-Bit and 32-Bit Applications and Drivers


Chapter 1: Overview of the ODBC SDK (Problems and Information)

The minimum graphics card requirement for the ODBC SDK 2.x is VGA gray scale.

Note that on an IBM Model 70 VGA gray scale display, the ODBC SDK Setup program has display problems such as improper display of three-dimensional dialog boxes and missing frames.


Chapter 4: Using ODBC Test (Problems and Information)

1) A batched query can contain selects, create tables, inserts, updates, and deletes. The Fetch All and Get Data All tools support this with code similar to the following simplified version:

SQLGetFunctions(hstmt, SQL_API_SQLMORERESULTS, &fExists);

do {

    SQLNumResultCols(hstmt, &ccol);

    if (ccol == 0)  //The next entry is a row count:

        <Call SQLRowCount; display the number of rows affected>

    else {        //The next entry is a result set:

        if (fGetDataAll)

            //Call SQLDescribeCol for each column;

            //display the column names>

        while(SQLFetch(hstmt) != SQL_SUCCESS)

            if (fGetDataAll)

                //Call SQLGetData for each column;

                //display the output

    }

} while (fExists && SQLMoreResults(hstmt) == SQL_SUCCESS);

if (ccol != 0 && !fExists)

    SQLFreeStmt(hstmt, SQL_CLOSE);

The Fetch All and Get Data All tools always empty all the result sets. If SQLMoreResults is not supported, both tools call SQLFreeStmt with fOption set to SQL_CLOSE to clear the result set.

The Fetch All section doesn't mention the calls to SQLNumResultCols, SQLRowCount, or SQLFreeStmt; the Get Data All section doesn't mention SQLRowCount. These functions are called similarly to the above example.

2) The Always Use Cursor Library entry in the Tool Reference section of Chapter 4, Using ODBC Test, has been replaced with a Cursor Library section for ODBC Test 2.10. The Always Use Cursor Library radio check box in the User Options dialog box in ODBC Test has been replaced with the following radio buttons: DEFAULT to specify that the DM uses the scrolling capabilities of the driver, rather than the cursor library; USE IF NEEDED to specify that the DM uses the cursor library only if it is needed; USE ODBC to specify that the Driver Manager (DM) uses the cursor library; and USE DRIVER to specify that the DM uses the scrolling capabilities of the driver, rather than the cursor library.


Chapter 5: Using ODBC Spy (Problems and Information)

The capture example in "Spying on an Application-Driver Connection" lists after step 6:

"The SQL Data Sources dialog box disappears, and ODBC Test sends the functions needed to connect to the data source. It sends SQLAllocEnv, SQLAllocConnect, SQLConnect, six SQLGetInfo statements, and one SQLAllocStmt request ..."

While this was correct at one time, several more functions are now logged during a Full Connect and many are dependent upon which driver they connect to.


Chapter 6: Using the Driver Setup Toolkit (Problems and Information)

Setup /AUTO works on Windows NT as well. However, on Windows NT, you cannot configure a standalone system first and get a copy of the ODBC.INI and ODBCINST.INI files, as the information for 32-bit setup is in the registry. (See step 4 in "To configure a system for automatic setup, the network administrator.") You must manually create these files for network installation on Windows NT workstations. The file format for ODBC.INI is described in the ODBC 2.0 Programmer's Reference. The file format for the ODBCINST.INI file is the same for both 16-bit and 32-bit drivers.


Appendix A: Developing 16-Bit and 32-Bit Applications and Drivers (Problems and Information)

1) For Windows on Windows (16- to 32-bit thunking), there is an additional thunking DLL named DS32GT.DLL that converts 16-bit argument values passed through a 32-bit setup DLL back to 16-bit.

2) An additional C run-time library, MSVCRT10.DLL (provided with the ODBC SDK), is used by 32-bit components.


ODBC SDK 2.0 Software Components (Problems and Information)

ODBC Setup

During ODBC SDK Setup, files that are copied to the \WINDOWS\SYSTEM and SYSTEM32 directories are also copied to the \BIN,\BIN32, \REDIST16,and \REDIST32 directories. You can safely delete these duplicates after a complete install.

ODBC Drivers

1) The ODBC drivers shipped with the SDK conform to ODBC version 1.0.

2) The MS-DOS SHARE utility must be preinstalled and configured for ODBC drivers to work properly.

ODBC Administrator

1) The ODBC Administrator Help file topic for the Install Drivers dialog box specifies that you must select one or more drivers and then choose the OK button. You can install without selecting any drivers. This option installs the Driver Manager, control panel device, and other ODBC components.

2) If you try to add a driver with the 32-bit ODBC Administrator while CTL3D32.DLL is in use by another program, the ODBC Administrator will attempt to copy this file and fail. To install the driver, close all applications using CTL3D32.DLL and run the ODBC Administrator again.

Cursor Library

The cursor library returns SQL_SUCCESS if these conditions are true:

SQLSetPos is called with fOption set to SQL_POSITION

A cursor is open

SQLExtendedFetch has been called

The cursor is positioned before the start of the result set or after the end of the result set

This is a bug. The cursor library should return SQLSTATE 24000 (Invalid cursor position).

ODBC Test

1) The ODBC Test Tools/Trace dialog box will not dismiss itself when running under older versions of Win32s. This is a known bug in Win32s with common dialog box functions and hook procedures. Version 1.2 of Win32s fixes this problem. A similar problem exists with the Log File button on the Tools/Run Auto Test dialog box.

2) If you have an entry in the Update Cell dialog box's rgbValue control that has a pcbValue of SQL_NTS, or any of the other defined constants, the calculated length of the rgbValue string in the pcbValue drop-down combo box will not be the correct string length.

3) A function sequence error occurs if a fetch operation is called after the Fetch All function tool has been called on an open rowset window.

4) ODBC Test does not close the rowset window after a call to SQLTransact with the cursor library loaded. This is inconsistent with the behavior for SQLTransact as described in Appendix G, "ODBC Cursor Library," in the ODBC 2.0 Programmer's Reference.

5) When a log file specified in the ODBC Test Trace dialog box already exists, it is not replaced; the new tracing information is always appended to the existing log file. To replace the existing file, you must delete this file before running your test.

ODBC Spy

1) The 32-bit ODBC Spy does not support debugging of multithreaded applications.

2) ODBC Spy must preallocate memory for the rgbValue buffer of SQLBindParameter or SQLSetParam. For large values of the cbColDef argument (of magnitude 1.0E+08 or greater), ODBC Spy fails to allocate enough memory and displays a replay error dialog box.

3) The Enter Debugger feature of 32-bit ODBC Spy does not work and should not be used. The functionality required to support this feature is not available in 32-bit debuggers.

4) ODBC Spy does not replay driver-specific information type, statement, and connection options.

5) ODBC Spy may experience problems playing back log files containing functions which execute asynchronously. To correct this, disable asynchronous execution and record a new log file.

6) For SQLBindParameter with an invalid argument value in pcbValue (for example, a negative number) and a null rgbValue, ODBC Spy posts a replay error in Emulate App mode.

7) During replays, ODBC Spy allocates a temporary buffer for character strings that is based upon the string as read from the log file and not by the actual buffer length specified (usually the next parameter). However, it still passes the specified actual buffer length. If these two values do not match, some drivers may behave in an uncertain fashion. Applications should use SQL_NTS as the buffer length in such cases.

8) ODBC Spy may experience memory problems for long captures and replays.

9) The following arguments are returned by ODBC Spy as #define numbers, not #define names: SQLGetInfo (return values SQL_NC_START and SQL_NC_END for fInfoType of SQL_NULL_COLLATION), SQLExtendedFetch (fFetchType of SQL_FETCH_BOOKMARK), and SQLExtendedFetch (rgfRowStatus of SQL_ROW_ADDED or SQL_ROW_ERROR).

10) When SQLNativeSql is called in Emulate App mode, ODBC Spy posts a replay error.

Sample Programs

The ODBC SDK provides several code samples. No known major problems exist, but one issue is still outstanding: The VB Demo sample does not run on ATI MACH32 displays. It terminates on a query of an empty table, it terminates on low RAM (2MB) with Smart Drive loaded, and it quits on Print Error. Also, the sample doesn't properly display text with Italic fonts.


ODBC SDK 2.10 Software Components (Problems and Information)

The following sections contain information about ODBC SDK 2.10 software components:

   Driver Manager

   Cursor Library

   ODBC Drivers

   Header Files

   Redistributable Components

   ODBC Test

   ODBC Spy

   Sample Programs

   Thunking Layer


ODBC 2.10 Driver Manager (Problems and Information)

1) Before ODBC 2.10, the Stop Tracing Automatically option in the ODBC Administrator would not work properly for the 32-bit Driver Manager.  To stop tracing, the ODBC Administrator had to be opened and the Trace ODBC Calls box had to be unchecked. With the release of ODBC 2.10, the 32-bit Driver Manager will stop tracing automatically.

2) Before ODBC 2.10, the DRIVER keyword was duplicated in the connection string returned to the driver.  Drivers used the value of the leftmost DRIVER keyword. With the release of ODBC 2.10, the DRIVER keyword is no longer duplicated in the connection string returned by SQLDriverConnect.

3) Before ODBC 2.10, if a SQLDriverConnect connection string was not null-terminated (for example, it was stored in a memory allocation buffer with a valid cbConnStrIn value) and the connection string ended with "D", "DS", or "DSN", the Driver Manager would read past the end of the buffer, which caused an error. With the release of ODBC 2.10, the Driver Manager will not read past the end of the buffer.

4) Before ODBC 2.10, if both 16-bit and 32-bit drivers were installed on Microsoft Windows NT, and both drivers had the same name, the Driver Manager attempted to connect to a 32-bit data source using the 16-bit driver when SQLDriverConnect was called. The Driver Manager selected the wrong driver name in ODBCINST.INI. This problem has been fixed in ODBC 2.10.

5) Before ODBC 2.10, if no connection had been made and SQLGetInfo was called, SQLGetInfo set a driver error flag. When SQLBrowseConnect was then called, a general protection fault would occur because SQLBrowseConnect tried to call SQLError in the driver that wasn't loaded yet. With the release of ODBC 2.10, the driver error flag is set only if the error was returned by the driver.

6) The ODBC 2.01 release notes indicated that the Driver Manager does not properly return SQLSTATE S1108 (Concurrency option out of range), but instead, returns SQLSTATE S1000 (General error). This is no longer the case, and this statement has been removed from the release notes for ODBC 2.10.

7) Before ODBC 2.10, the Driver Manager would not detect when the cursor position became invalid after a successful SQLExtendedFetch. As a result, the driver, not the Driver Manager, would return an error when this occurred. If no successful SQLExtendedFetch had been performed, the Driver Manager would return an error. For example, the driver, not the Driver Manager, would return an error when a successful SQLExtendedFetch was performed, a SQLExtendedFetch positioned the cursor off the result set, then a SQLSetPos (SQL_UPDATE) was attempted. The driver, not the Driver Manager, would return an error if a successful SQLExtendedFetch was performed, a SQLExtendedFetch positioned the cursor off the result set, then a SQLGetStmtOption (SQL_ROW_NUMBER) was attempted.

With the release of ODBC 2.10, the Driver Manager detects the invalid cursor position in this situation, and returns an error.

8) Before ODBC 2.10, the message text for SQLConnect and SQLDisconnect errors that were not generated by the Driver Manager was cached by the Driver Manager, but not cleared. This problem has been fixed by ODBC 2.10.

9) Before ODBC 2.10, calling SQLAllocConnect in a Windows NT console application under certain conditions could result in a General Protection Fault as a result of a problem with the Driver Manager. With the release of ODBC 2.10, this problem has been fixed.

10) When a 16-bit application connects to a data source through a 32-bit driver on Windows NT by calling SQLConnect, the Driver Manager changes the value of cbDSN passed by SQLConnect to a value of 14915. This value is then passed on to the driver, so the amount of memory allocated for the data source name does not correspond to the amount asked for.


ODBC 2.10 Cursor Library (Problems and Information)

1) The cursor library is provided in 16-bit (ODBCCURS.DLL) and 32-bit (ODBCCR32.DLL) binary form.

2) The cursor library returns SQLSTATE S1C00 (Driver not capable) for SQLSetPos with irow=0.

3) If the cursor library is used, when data is retrieved with SQLExtendedFetch, SQLGetData supports the functionality specified with the SQL_GD_ANY_ORDER bitmask, as well as the SQL_GD_ANY_COLUMN and SQL_GD_BOUND bitmasks.

4) The cursor library creates temporary files on the current directory, rather than using a temporary directory. This can cause problems when running an application from a read-only share or a compact disk (such as a Microsoft Foundation Class Library sample).


ODBC 2.10 ODBC Drivers (Problems and Information)
ODBC 2.10 Drivers (Problems and Information)

The ODBC SDK provides the following 16-bit and 32-bit drivers: Microsoft Access, Btrieve (16-bit only), dBASE, Microsoft Excel, Microsoft FoxPro, Paradox, and Text.

Last-minute readme notes for the ODBC drivers included information on setup, connection, and data access, data type problems and updates, and documentation.


ODBC 2.10 Header Files (Problems and Information)

1) All typedefs in the SQL*.H files have been #pragma packed to ensure that all structure elements are correctly aligned. Two-byte packing (n=2) has been performed for the Intel, MIPS, and Alpha platforms.

2) The following defines have been added to SQLEXT.H: SQL_BIND_TYPE_DEFAULT, SQL_CONCUR_DEFAULT, and SQL_CURSOR_TYPE_DEFAULT.

3) In ODBC 2.01, a #define of 65002 was added to the SQLEXT.H file for the SQL_OJ_CAPABILITIES option in SQLGetInfo. In ODBC 2.10, the #define for SQL_OJ_CAPABILITIES was changed to 65003 to avoid contention with the bitmask used for the SQL_FILE_USAGE option in the ODBC Desktop Database Drivers 1.0. (Note that this change was not made in the ODBC 2.01a release.)


ODBC 2.10 Redistributable Components (Problems and Information)

The \ODBCSDK\DRVSETUP.KIT\SETUP16 and \ODBCSDK\DRVSETUP.KIT\SETUP32 directories contain sample files SETUP.LST, ODBC.INF, DRVSETUP.EXE (and its source code), and_BOOTSTP.EXE (and its source code) that you can customize for your drivers and use with the Driver Setup Toolkit.


ODBC 2.10 ODBC Test (Problems and Information)
ODBC 2.10 Test (Problems and Information)

1) Before ODBC 2.10, the values shown in the drop-down box for cbValue in the SQLPutData dialog box in ODBC Test were the length (default 0) and SQL_NTS. With the release of ODBC 2.10, SQL_NULL_DATA and SQL_DEFAULT_PARAM, which are also valid values for cbValue, have been added to the drop-down box.

2) Before ODBC 2.10, when SQLGetData was called in ODBC Test, cbValueMax was not ignored for fixed-length data types. As a result, if pcbValue was greater than cbValueMax, rgbValue was unmodified. When the version 2.10 ODBC Test is used, cbValueMax is ignored for fixed-length data types, so the converted data is placed in rgbValue.

3) Before ODBC 2.10, if you attempted in ODBC Test to perform SQLExtendedFetch on a bookmark column, SQLSTATE S1002 (Invalid column number) was returned because SQLDescribeCol was being called with icol=0 (a bookmark column), which is not supported. With the release of ODBC 2.10, ODBC Test has been fixed so SQLExtendedFetch can be performed on a bookmark column without error.

4) Before the version 2.10 ODBC Test, a crash was possible if repetitive calls to SQLSetStmtOption and SQLGetStmtOption were made with certain fOptions in ODBC Test. The same was also true for SQLSetConnectOption and SQLGetConnectOption. This has been fixed in the version 2.10 ODBC Test.

5) Before the version 2.10 ODBC Test, when a row in a rowset displayed by SQLExtendedFetch in ODBC Test was changed by a positioned operation, the font of the row could be inconsistent. This problem has been fixed for the version 2.10 ODBC Test.

6) The Always Use Cursor Library radio check box in the User Options dialog box in ODBC Test has been replaced with the following radio buttons: DEFAULT to specify that the DM uses the scrolling capabilities of the driver, rather than the cursor library; USE IF NEEDED to specify that the DM uses the cursor library only if it is needed; USE ODBC to specify that the Driver Manager (DM) uses the cursor library; and USE DRIVER to specify that the DM uses the scrolling capabilities of the driver, rather than the cursor library.

7) The version 2.0 ODBC Test added the Always Use Cursor Library option to the User Options dialog box displayed from the Tools menu. This option was added to call SQLSetConnectOption automatically (after SQLAllocConnect), with SQL_ODBC_CURSORS set to SQL_CUR_USE_ODBC, when the Full Connect command was chosen. This option was also in effect when a connection was performed by explicitly calling the connect function, so that if the Always Use Cursor Library option was chosen, SQLSetConnectOption would automatically be called after SQLAllocConnect was called manually. This was undesirable because explicit functions calls in ODBC Test should not be accompanied by unannounced calls.

With the release of ODBC 2.10, the Always Use Cursor Library option has been replaced by a series of radio buttons (see statement 16 above), and the radio buttons are only in effect when a Full Connect is performed, not when explicit connection functions are called.

8) Before the version 2.10 ODBC Test, when a value of -128 was bound to SQL_C_TINYINT in ODBC Test, the value was actually returned as 128. This problem has been fixed in the version 2.10 ODBC Test.

9) Before the version 2.10 ODBC Test, pcbValue in SQLBindParam could be improperly changed when called in ODBC Test. If the value for pcbValue returned by the SQL_LEN_DATA_AT_EXEC macro was greater than cbValueMax, pcbValue was changed to cbValueMax. This problem has been fixed in the version 2.10 ODBC Test.

10) Before the version 2.10 ODBC Test, pressing CTRL+F4 closed the output window. With the release of ODBC 2.10, pressing CTRL+F4 in ODBC Test has no effect.

11) Before the version 2.10 ODBC Test, performing an SQLSetPos in ODBC Test when no columns were bound caused a General Protection Fault. This problem has been fixed for the version 2.10 ODBC Test.

12) Before the version 2.10 ODBC Test, attempting to insert more than 64K of data into a single Text or Image field in ODBC Test caused a General Protection Fault. This problem has been fixed for the version 2.10 ODBC Test.

13) Before the version 2.10 ODBC Test, performing an SQLGetData with a pcbValue of NULL and a cbValueMax of 0 in ODBC Test caused a General Protection Fault. This problem has been fixed for the version 2.10 ODBC Test.

14) Before the version 2.10 ODBC Test, performing an SQLBindParameter with a numeric fcType and a number entered for rgbValue in ODBC Test caused a General Protection Fault on Windows on Windows (WOW) on Microsoft Windows NT. This problem has been fixed for the version 2.10 ODBC Test.

15) Before the version 2.10 ODBC Test, the value displayed for the pfNullable argument after a call to SQLDescribeCol was not always correct. This problem has been fixed for the version 2.10 ODBC Test.

16) Before the version 2.10 ODBC Test, the maximum number of columns that could be returned by the GetDataAll function was 153. This restriction has been removed for the version 2.10 ODBC Test.

17) Before the version 2.10 ODBC Test, the value returned for SQL_MAX_STATEMENT_LEN by SQLGetInfo in ODBC Test could be incorrect. This problem has been fixed in the version 2.10 ODBC Test.

18) Before the version 2.10 ODBC Test, once SQLParamData had returned SQL_SUCCESS in ODBC Test, calling SQLParamData again for the same parameter would not update prgbValue properly. This problem has been fixed in the version 2.10 ODBC Test.


ODBC 2.10 Spy (Problems and Information)

1) When ODBC Spy is in capture mode, calling SQLSetStmtOption with SQL_RETRIEVE_DATA set to SQL_RD_ON returns a memory error.


ODBC 2.10 Sample Programs (Problems and Information)

1) The samples included with the ODBC SDK are 16-bit executables.  However, the sample source code may be compiled into either 16- or 32-bit executables.

2) CPU environment variables must be set in BUILD.BAT in order to build the sample files.

3) The cursor library sample application (CRSRDEMO) cannot be compiled on Alpha, so is unavailable for use on Alpha.


ODBC 2.10 Thunking Layer (Problems and Information)

The ODBC SDK 2.10 provides 16- to 32-bit thunks for existing 16-bit applications and drivers.  These thunks are fully supported on the Windows 95 and Microsoft Windows NT 3.5 platforms, and are binary compatible (Intel versions).

ODBC SDK 2.10 handles 16- to 32-bit thunking by having the Driver Manager call a thunking DLL to call the driver, rather than calling the driver directly.  The Driver Manager resides in the first environment; the driver resides in the second.  The process employs two thunking components, one in each environment.

The Driver Manager determines whether the driver is a 16- or 32-bit driver before the connection is made.  If the driver is 32-bit, the Driver Manager loads the thunking DLL in the first environment.  The DM calls a special entry point in the thunking DLL (InitThunks) that tells the thunk component to load the 32-bit driver.

From this point on, the DM calls the thunking DLL as if it were the driver.  The first thunking DLL calls the actual 32-bit driver.  The second thunking component exposes a Dispatch routine that allows the first thunking component to call ODBC functions in the real driver, and to pass the results back to the Driver Manager.

Note that the same process occurs if the calling ODBC component is the Installer rather than the Driver Manager.


Setup and Connection Information--ODBC SDK Drivers (Problems and Information)
Setup, Connection, and Data Access Information--ODBC SDK Drivers (Problems and Information)

Naming of Oracle Drivers

When adding an Oracle 6 data source, select the Oracle driver.  When adding an Oracle 7 data source, select the Oracle 7 driver.

System Database Setup (Microsoft Access Driver)

When the system database is set to None in the Microsoft Access Setup dialog box, the system database cannot be changed in the Set Advanced Options dialog box.

SQLSetStmtOption (SQL_NOSCAN)

SQLSetStmtOption (SQL_NOSCAN, SQL_NOSCAN_ON) is silently ignored.

Attaching a Table from within Microsoft Access

The ODBC drivers should not be used to attach a table to another table from within the Microsoft Access database management system.  The table should be attached directly.  The <SQL Database> command, which uses the ODBC driver selected, should not be used.

Outer Join Capabilities

The SQL_OJ_CAPABILITIES information type in SQL GetInfo is not supported.

Quoted Identifier Support Problems in Outer Joins (Btrieve Driver Only)

When the Btrieve driver is used, quoted identifiers as defined in SQL_IDENTIFIER_QUOTE_CHAR in SQLGetInfo (backquotes used to allow reserved words, spaces, or special symbols to be used in names) are not supported with table names in outer join expressions. Quoted identifiers using backquotes are supported for column names. For table names, square brackets can be used instead of backquotes to quote identifiers.

Multithreading

The 32-bit drivers are thread-safe, but are not effectively multithreaded.  A second thread will block until the first thread completes.

16-Bit Drivers on Alpha and MIPS

The 16-bit drivers in the ODBC Database Drivers 2.0 may work on Windows on Windows (WOW) on Alpha and MIPs, but this use is not supported.


Data Type Problems and Updates--ODBC SDK Drivers (Problems and Information)

Bit Data Types

Bit columns will display as 0 or 1 when a SELECT is performed, but a query making a direct comparison of a Bit data value to the number 1 will not succeed. If a direct comparison must be made, the comparison should be made to TRUE or <>0.  Note that a Bit data value will compare correctly to the number 1 when it is used with parameters. In other words, "WHERE x = ?" will work correctly for Bit data values, but "WHERE x = 1" will not work correctly. This is true for the BIT data type in Microsoft Access; LOGICAL1 in Btrieve; and LOGICAL in dBASE, Microsoft Excel, and Microsoft FoxPro.

Memo Data Type (Paradox Driver)

The Paradox driver does not support the Memo data type.

DateTime Precision (Text Driver)

The Text driver reports a precision of 16 for the DATETIME data type (SQL_TIMESTAMP). The precision should be 19. This affects the SQLGetTypeInfo and SQLColAttributes functions.

Zero-Length Strings (Microsoft Access Driver)

Support for zero-length strings through the Microsoft Access drivers is inconsistent.  If a table is created in Microsoft Access with the default of No for the AllowZeroLength property of a field, zero-length strings can be inserted into the field through ODBC. If, however, that table is subsequently opened in Microsoft Access, and then saved, zero-length strings cannot be inserted into that field.


Documentation--ODBC SDK Drivers (Problems and Information)

Help Files

The following help files are included in the Microsoft ODBC Database Drivers 2.0. These files are included in the \\windows\system directory for 16-bit drivers and the \\windows\system32 directory for 32-bit drivers.

ODBCDRV.HLP    	16-Bit ODBC Drivers Help File

ODBCDR32.HLP       	32-Bit ODBC Drivers Help File

ODBCJET.HLP        	ODBC Desktop Database Drivers Help File
(includes Btrieve, dBASE, Microsoft Access,Microsoft Excel,
Microsoft FoxPro, Paradox, and Text drivers)

ODBCJTNW.HLP       	ODBC Desktop Database DriversWhats New Help File

DRVORACL.HLP       	Oracle6 Driver Help File

DRVORA7.HLP        	Oracle7 Driver Help File

DRVSSRVR.HLP       	SQL Server Driver Help File

Oracle Readme Files

The following readme files are included in the Microsoft ODBC Database Drivers 2.0:

ORACLE.TXT         	Oracle6 Readme

ORA7NOTE.TXT       	Oracle7 Readme

File Lists in Getting Started Manual

The file lists in the ODBC Component Files section of Appendix B of the Getting Started manual should be changed as follows:

1.	Add OLE2PROX.DLL and OLE2CONV.DLL to the list of files required for each driver.

2.	Delete SCP.DLL, VAEN2.DLL, and VAEN232.DLL from the list of files required for each driver.

3.	Delete WINHELP.EXE and WINHELP.HLP from the list of files required for the ODBC Installer/Control Panel Device.

Note that ODBC.INF has been renamed to ODBCJT.INF.


ODBC 2.x on Win 32S (Problems and Information)

1) The Win32s files shipped with Microsoft Visual C++ for Windows NT do not contain the necessary .NLS files. These files are needed for the ANSI to UNICODE conversion (MultiByteToWideChar). These files are, however, available on Windows NT under the SYSTEM32 directory. You need at least unicode.nls, c_437.nls and c_1252.nls. More files might be needed for different code pages. Please note that the XXX in the filename (C_XXX.NLS) is the code page you use. If you use an OEM code page other than the default 437 or your Windows is localized and uses an ANSI code page other than 1252, then you need the matching C_XXX.NLS files. Make sure that in the WIN32S.INI file (in \windows\system) you have the right ANSI code page entry. (The default is 1252.)

2) Because ODBC components use three-dimensional controls, you may experience problems running multiple instances on Win32s.


Notes to Driver Writers (Problems and Information)

1) As described in the ODBC 2.0 Programmer's Reference, the ODBC 2.0 Driver Manager uses ordinal number 199 to determine whether or not to load functions by ordinal or by name. If a driver doesn't define its functions in the ordinal order defined by ODBC, it MUST not define ordinal number 199. Note that by default, the Microsoft C/C++ compiler defines ordinal values for all far functions, not only exported functions. This can cause ordinal 199 to be defined even if there is no function explicitly mapped to that ordinal.

To make sure  the compiler doesn't assign ordinal values for non-exported functions, include the "PROTMODE" statement in the definition (.DEF) file that describes the dynamic-link library. For more information, see "Building Drivers: Use of PROTMODE Line in .DEF Files" in the ODBC SDK Knowledge Base Help file.

2) An application might occasionally invoke a driver connection while responding to a DDE Initiate request from another application. If the driver displays a connect dialog box and yields to Windows, it may cause unpredictable system behavior. Therefore, drivers must call InSendMessage before displaying any dialog or message boxes to see if they are being called while the application is in SendMessage processing. If so, only SYSTEM MODAL dialogs are permitted so that Windows can block additional messages being sent to the applications.

Drivers that support the asynchronous mode of ODBC operations MUST not rely upon windows PeekMessage functionality to emulate such support. This also applies to ALL underlying components (network libraries, any asynchronous DDEML based drivers, underlying data access components, and so on). Any ODBC application that implements asynchronous ODBC operations may show unexpected behavior and cause the entire Windows system to become unstable, if such a driver was used. Therefore, driver writers must make sure that implementation of asynchronous mode does not yield control to Windows.

3) For driver-specific options (>999), the thunking layer checks to see if vParam is a valid pointer. If it is not, vParam is passed unchanged as a 32-bit integer. In the case where an application expects vParam to be an integer, and the value for vParam happened to be a valid pointer, the driver will receive an invalid 32-bit integer value.

In addition, if a driver tries to return a pointer in the pvParam argument of SQLGetStmtOption for a driver-specific option, it will not be translated. Instead of passing back a pointer, the driver should copy the associated value back into the calling application's buffer.


Using the ODBC SDK with Visual C++ (Problems and Information)

Microsoft Visual C++ version 1.5 includes a set of ODBC header and library files. These files are from an earlier version of the ODBC SDK and may cause compiler and linker problems when used in conjunction with the ODBC SDK 2.x.

If you are using Visual C++ 1.5 to work with ODBC SDK 2.x software, make sure that the INCLUDE and LIB environment variables are set up correctly. The ODBC SDK INCLUDE directory (\ODBCSDK\INCLUDE) must appear before the compiler INCLUDE directory (<MSVC>\INCLUDE). The ODBC SDK LIB (or LIB32) directory (\ODBCSDK\LIB) must appear before the compiler LIB directory (<MSVC>\LIB).