ODBC SQL Microsoft
ODBC SQL Microsoft
ODBC Appendixes
Appendixes
Appendix A: ODBC Error Codes
Appendix B: ODBC State Transition Tables
Appendix C: SQL Grammar
Appendix D: Data Types
Appendix E: Scalar Functions
Appendix F: ODBC Cursor Library
Appendix G: Driver Guidelines for Backward Compatibility
Backward Compatibility of C Data Types
Behavioral Changes and ODBC 3.x Drivers
Block Cursors, Scrollable Cursors, and Backward Compatibility
Bookmark C Data Type
C Data Types
Retrieve numeric data with SQL_NUMERIC_STRUCT in C
C Interval Structure
Converting Data from C to SQL Data Types
C to SQL Data Conversion Examples
C to SQL: Binary
C to SQL: Bit
C to SQL: Character
C to SQL: Date
C to SQL: Day-Time Intervals
C to SQL: GUID
C to SQL: Numeric
C to SQL: Timestamp
C to SQL: Time
C to SQL: Year-Month Intervals
Calling SQLSetPos to Insert Data
Column Data
Column Size, Decimal Digits, Transfer Octet Length, and Display Size
Column Size
Connection Transitions
Constraints of the Gregorian Calendar
Constructing Searched Statements
Cursor Library Cache
Cursor Library Code Example
Data Type Identifiers and Descriptors
Data Type Support
Date, Time, and Timestamp Escape Sequences
Datetime Data Types
Decimal Digits
Default C Data Types
Descriptor Transitions
Display Size
Elements Used in SQL Statements
Environment Transitions
Example SQLGetTypeInfo Result Set
Executing Positioned Update and Delete Statements
Explicit Data Type Conversion Function
Fixed-Length Bookmarks
GUID Escape Sequences
Guidelines for Interval and Numeric Data Types
Implementation Notes
Interval Data Type Length
Interval Data Type Precision
Interval Data Types
Interval Escape Sequences
Interval Literal Syntax
Interval Literals
Length of Column Data
LIKE Escape Sequence
Literals in ODBC
Loading by Ordinal
Location of Cache
Mapping Deprecated Functions
SQLAllocConnect Mapping
SQLAllocEnv Mapping
SQLAllocStmt Mapping
SQLBindParam Mapping
SQLColAttributes Mapping
SQLError Mapping
SQLFreeConnect Mapping
SQLFreeEnv Mapping
SQLFreeStmt Mapping
SQLGetConnectOption Mapping
SQLGetStmtOption Mapping
SQLInstallTranslator Mapping
SQLParamOptions Mapping
SQLSetConnectOption Mapping
SQLSetParam Mapping
SQLSetScrollOptions Mapping
SQLSetStmtOption Mapping
SQLTransact Mapping
Numeric Functions
Numeric Literal Syntax
Numeric Literals
ODBC Escape Sequences
ODBC Functions and the Cursor Library
ODBC Functions Executed by the Cursor Library
ODBC Functions Not Executed by the Cursor Library
SQLBindCol (Cursor Library)
SQLBindParameter (Cursor Library)
SQLBulkOperations and the Cursor Library
SQLCloseCursor_ODBC
SQLEndTran (Cursor Library)
SQLExtendedFetch (Cursor Library)
SQLFetch (Cursor Library)
SQLFetchScroll (Cursor Library)
SQLFreeStmt (Cursor Library)
SQLGetData (Cursor Library)
SQLGetDescField and SQLGetDescRec (Cursor Library)
SQLGetFunctions (Cursor Library)
SQLGetInfo (Cursor Library)
SQLGetInfo Support
SQLGetStmtAttr (Cursor Library)
SQLGetStmtOption (Cursor Library)
SQLNativeSql (Cursor Library)
SQLRowCount (Cursor Library)
SQLSetConnectAttr (Cursor Library)
SQLSetDescField and SQLSetDescRec (Cursor Library)
SQLSetEnvAttr and the Cursor Library
SQLSetPos (Cursor Library)
SQLSetScrollOptions (Cursor Library)
SQLSetStmtAttr (Cursor Library)
ODBC Cursor Library Error Codes
Outer Join Escape Sequence
Overriding Default Leading and Seconds Precision for Interval Data Types
Overriding Default Precision and Scale for Numeric Data Types
Parameter Data Types
Parameter Markers
Procedure Call Escape Sequence
Processing Batches of SQL Statements
Processing Positioned Update and Delete Statements
Processing SELECT FOR UPDATE Statements
Processing SQL Statements
Pseudo-Type Identifiers
Reserved Keywords
Returning SQL_NO_DATA
Row Status
Rules for Conversions
Scalar Function Escape Sequence
SQL Data Types
SQL Minimum Grammar
Converting Data from SQL to C Data Types
SQL to C Data Conversion Examples
SQL to C: Binary
SQL to C: Bit
SQL to C: Character
SQL to C: Date
SQL to C: Day-Time Intervals
SQL to C: GUID
SQL to C: Numeric
SQL to C: Timestamp
SQL to C: Time
SQL to C: Year-Month Intervals
SQL-92 CAST Function
SQL_ARD_TYPE
SQL_C_TCHAR
Statement Transitions
String Functions
System Functions
Time, Date, and Interval Functions
Transfer Octet Length
Transferring Data in Its Binary Form
Using Data Type Identifiers
Using the ODBC Cursor Library
What the Driver Does
What the Driver Manager Does
64-Bit Integer Structures
ODBC Appendixes
12/20/2017 • 1 min to read • Edit Online
Technical details relating to the Microsoft ODBC interface are contained in the following appendixes:
Appendix A: ODBC Error Codes
Appendix B: ODBC State Transition Tables
Appendix C: SQL Grammar
Appendix D: Data Types
Appendix E: Scalar Functions
Appendix F: ODBC Cursor Library
Appendix G: Driver Guidelines for Backward Compatibility
Appendix A: ODBC Error Codes
12/20/2017 • 7 min to read • Edit Online
This topic discusses SQLSTATE values for ODBC 3.x. For more information on ODBC 3.x SQLSTATE values, see
SQLSTATE Mappings.
SQLGetDiagRec or SQLGetDiagField returns SQLSTATE values as defined by Open Group Data Management:
Structured Query Language (SQL), Version 2 (March 1995). SQLSTATE values are strings that contain five
characters. The following table lists SQLSTATE values that a driver can return for SQLGetDiagRec.
The character string value returned for an SQLSTATE consists of a two-character class value followed by a three-
character subclass value. A class value of "01" indicates a warning and is accompanied by a return code of
SQL_SUCCESS_WITH_INFO. Class values other than "01," except for the class "IM," indicate an error and are
accompanied by a return value of SQL_ERROR. The class "IM" is specific to warnings and errors that derive from
the implementation of ODBC itself. The subclass value "000" in any class indicates that there is no subclass for that
SQLSTATE. The assignment of class and subclass values is defined by SQL-92.
NOTE
Although successful execution of a function is normally indicated by a return value of SQL_SUCCESS, the SQLSTATE 00000
also indicates success.
SQLError
SQLGetDiagField
SQLGetDiagRec
SQLExecute
SQLParamData
SQLSetPos
SQLExecute
SQLParamData
SQLSTATE ERROR CAN BE RETURNED FROM
SQLBulkOperations
SQLColAttribute
SQLDataSources
SQLDescribeCol
SQLDriverConnect
SQLDrivers
SQLExecDirect
SQLExecute
SQLExtendedFetch
SQLFetch
SQLFetchScroll
SQLGetConnectAttr
SQLGetCursorName
SQLGetData
SQLGetDescField
SQLGetDescRec
SQLGetEnvAttr
SQLGetInfo
SQLGetStmtAttr
SQLNative
Sql SQLParamData
SQLPutData
SQLSetCursorName
SQLExecute
SQLParamData
SQLExecute
SQLParamData
SQLSTATE ERROR CAN BE RETURNED FROM
SQLDriverConnec
SQLExtendedFetch
SQLSetPos
SQLConnect
SQLDriverConnect
SQLExecDirect
SQLExecute
SQLParamData
SQLPrepare
SQLSetConnectAttr
SQLSetDescField
SQLSetEnvAttr
SQLSetStmtAttr
SQLExecDirect
SQLExecute
SQLExtendedFetch
SQLFetch
SQLFetchScroll
SQLGetData
SQLParamData
SQLSetPos
SQLExecute
SQLExecute
SQLParamData
SQLBindParameter
SQLBulkOperations
SQLExecDirect
SQLExecute
SQLExtendedFetch
SQLFetch
SQLFetchScroll
SQLGetData
SQLParamData
SQLPutData
SQLSetPos
SQLSTATE ERROR CAN BE RETURNED FROM
SQLBindParameter
SQLBulkOperations
SQLColAttribute
SQLDescribeCol
SQLDescribeParam
SQLFetch
SQLFetchScroll
SQLGetData
SQLGetDescField
SQLGetDescRec
SQLParamData
SQLSetDescField
SQLSetDescRecSQLSetPos
SQLExecute
SQLParamData
SQLPutData
SQLConnect
SQLDriverConnect
SQLConnect
SQLDriverConnect
SQLSetConnectAttr
SQLSTATE ERROR CAN BE RETURNED FROM
SQLDisconnect
SQLEndTran
SQLGetConnectAttr
SQLGetInfo
SQLNativeSql
SQLSetConnectAttr
SQLConnect
SQLDriverConnect
SQLColumnPrivileges
SQLColumns
SQLConnect
SQLCopyDesc
SQLDescribeCol
SQLDescribeParam
SQLDriverConnect
SQLExecDirect
SQLExecute
SQLExtendedFetch
SQLFetch
SQLFetchScroll
SQLForeignKeys
SQLGetConnectAttr
SQLGetData
SQLGetDescField
SQLGetDescRec
SQLGetFunctions
SQLGetInfo
SQLSTATE ERROR CAN BE RETURNED FROM
SQLGetTypeInfo
SQLMoreResults
SQLNativeSql
SQLNumParams
SQLNumResultCols
SQLParamData
SQLPrepare
SQLPrimaryKeys
SQLProcedureColumns
SQLProcedures
SQLPutData
SQLSetConnectAttr
SQLSetDescField
SQLSetDescRec
SQLSetEnvAttr
SQLSetStmtAttr
SQLSpecialColumns
SQLStatistics
SQLTablePrivileges
SQLTables
SQLExecute
SQLParamData
SQLPrepare
SQLSetPos
SQLSTATE ERROR CAN BE RETURNED FROM
SQLExecDirect
SQLExecute
SQLFetch
SQLFetchScroll
SQLParamData
SQLPutData
SQLSetDescField
SQLSetPos
SQLExtendedFetch
SQLFetch
SQLFetchScroll
SQLGetData
SQLParamData
SQLExecDirect
SQLExecute
SQLExtendedFetch
SQLFetch
SQLFetchScroll
SQLGetData
SQLGetInfo
SQLParamData
SQLPutData
SQLSetPos
SQLSTATE ERROR CAN BE RETURNED FROM
SQLExecDirect
SQLExecute
SQLExtendedFetch
SQLFetch
SQLFetchScroll
SQLGetData
SQLParamData
SQLPutData
SQLSetPos
SQLExecDirect
QLParamData
SQLPutData
SQLExecute
SQLExtendedFetch
SQLFetch
SQLFetchScroll
SQLGetData
SQLPutData
SQLSTATE ERROR CAN BE RETURNED FROM
SQLExecDirect
SQLExecute
SQLExtendedFetch
SQLFetch
SQLFetchScroll
SQLGetData
SQLParamData
SQLPutData
SQLSetPos
SQLExecute
SQLExtendedFetch
SQLFetch
SQLFetchScroll
SQLGetData
SQLParamData
SQLPutData
SQLSetPos
SQLExecute
SQLPrepare
SQLExecute
SQLPrepare
SQLExecDirect
SQLExecute
SQLParamData
SQLSetPos
SQLCloseCursor
SQLColumnPrivileges
SQLColumns
SQLExecDirect
SQLExecute
SQLExtendedFetch
SQLFetch
SQLFetchScroll
SQLForeignKeys
SQLGetData
SQLGetStmtAttr
SQLGetTypeInfo
SQLNativeSql
SQLPrepare
SQLPrimaryKeys
SQLProcedureColumns
SQLProcedures
SQLSetConnectAttr
SQLSetCursorName
SQLSetPos
SQLSetStmtAttr
SQLSpecialColumns
SQLStatistics
SQLTablePrivileges
SQLTables
SQLSTATE ERROR CAN BE RETURNED FROM
SQLConnect
SQLDriverConnect
SQLPrepare
SQLSetCursorName
SQLPrepare
SQLSetConnectAttr
SQLPrepare
SQLSTATE ERROR CAN BE RETURNED FROM
SQLColumnPrivileges
SQLColumns
SQLEndTran
SQLExecDirect
SQLExecute
SQLFetch
SQLFetchScroll
SQLForeignKeys
SQLGetTypeInfo
SQLMoreResults
SQLParamData
SQLPrimaryKeys
SQLProcedureColumns
SQLProcedures
SQLSetPos
SQLSpecialColumns
SQLStatistics
SQLTablePrivileges
SQLTables
SQLColumnPrivileges
SQLColumns
SQLExecDirect
SQLExecute
SQLFetch
SQLFetchScroll
SQLForeignKeys
SQLGetTypeInfo
SQLMoreResults
SQLPrimaryKeys
SQLProcedureColumns
SQLProcedures
SQLParamData
SQLSetPos
SQLSpecialColumns
SQLStatistics
SQLTablePrivileges
SQLTables
SQLExecDirect
SQLExecute
SQLParamData
SQLPrepare
SQLSetPos
SQLPrepare
SQLPrepare
SQLSTATE ERROR CAN BE RETURNED FROM
SQLPrepare
SQLPrepare
SQLPrepare
SQLPrepare
SQLExecDirect
SQLExecute
SQLParamData
SQLSetPos
SQLError
SQLGetDiagField
SQLGetDiagRec
SQLError
SQLGetDiagField
SQLGetDiagRec
SQLBindParameter
SQLGetData
SQLGetTypeInfo
SQLGetDescField
SQLGetDescRec
HY008 Operation canceled All ODBC functions that can be
SQLSTATE ERROR CAN BE RETURNED FROM
processed asynchronously:
SQLBrowseConnect
SQLBulkOperations
SQLColAttribute
SQLColumnPrivileges
SQLColumns
SQLConnect
SQLDescribeCol
SQLDescribeParam
SQLDisconnect
SQLDriverConnect
SQLEndTran
SQLExecDirect
SQLExecute
SQLExtendedFetch
SQLFetch
SQLFetchScroll
SQLForeignKeys
SQLGetData
SQLGetTypeInfo
SQLMoreResults
SQLNumParams
SQLNumResultCols
SQLParamData
SQLPrepare
SQLPrimaryKeys
SQLProcedureColumns
SQLProcedures
SQLPutData
SQLSetConnectAttr
SQLSetPos
SQLSpecialColumns
SQLStatistics
SQLStatistics
SQLSTATE ERROR CAN BE RETURNED FROM
SQLTablePrivileges
SQLTables
SQLBindParameter
SQLBulkOperations
SQLColumnPrivileges
SQLColumns
SQLExecDirect
SQLForeignKeys
SQLGetCursorName
SQLGetData
SQLGetFunctions
SQLNativeSql
SQLPrepare
SQLPrimaryKeys
SQLProcedureColumns
SQLProcedures
SQLPutData
SQLSetConnectAttr
SQLSetCursorName
SQLSetEnvAttr
SQLSetStmtAttr
SQLSpecialColumns
SQLStatistics
SQLTablePrivileges
SQLTables
SQLBindCol
SQLBindParameter
SQLBulkOperations
SQLCloseCursor
SQLColAttribute
SQLColAttribute
SQLSTATE ERROR CAN BE RETURNED FROM
SQLColumnPrivileges
SQLColumns
SQLCopyDesc
SQLDescribeCol
SQLDescribeParam
SQLDisconnect
SQLEndTran
SQLExecDirect
SQLExecute
SQLExtendedFetch
SQLFetch
SQLFetchScroll
SQLForeignKeys
SQLFreeHandle
SQLFreeStmt
SQLGetConnectAttr
SQLGetCursorName
SQLGetData
SQLGetDescField
SQLGetDescRec
SQLGetFunctions
SQLGetStmtAttr
SQLGetTypeInfo
SQLMoreResults
SQLNumParams
SQLNumResultCols
SQLParamData
SQLPrepare
SQLPrimaryKeys
SQLProcedureColumns
SQLProcedures
SQLPutData
SQLRowCount
SQLRowCount
SQLSTATE ERROR CAN BE RETURNED FROM
SQLSetConnectAttr
SQLSetCursorName
SQLSetDescField
SQLSetEnvAttr
SQLSetDescRec
SQLSetPos
SQLSetStmtAttr
SQLSpecialColumns
SQLStatistics
SQLTablePrivileges
SQLTables
SQLParamData
QLSetPos
SQLSetStmtAttr
SQLGetDiagField
SQLGetDiagRec
SQLSetDescRec
SQLCopyDesc
SQLGetDescField
SQLSetDescField
SQLSetDescRec
SQLSetEnvAttr
SQLSetStmtAttr
SQLBindParameter
SQLBrowseConnect
SQLBulkOperations
SQLColAttribute
SQLColumnPrivileges
SQLColumns
SQLConnect
SQLDataSources
SQLDescribeCol
SQLDriverConnect
SQLDrivers
SQLExecDirect
SQLExecute
SQLFetch
SQLFetchScroll
SQLForeignKeys
SQLGetConnectAttr
SQLGetCursorName
SQLGetData
SQLGetDescField
SQLGetInfo
SQLSTATE ERROR CAN BE RETURNED FROM
SQLGetStmtAttr
SQLNativeSql
SQLParamData
SQLPrepare
SQLPrimaryKeys
SQLProcedureColumns
SQLProcedures
SQLPutData
SQLSetConnectAttr
SQLSetCursorName
SQLSetDescField
SQLSetDescRec
SQLSetEnvAttr
SQLSetStmtAttr
SQLSetPos
SQLSpecialColumns
SQLStatistics
SQLTablePrivileges
SQLTables
SQLGetDescField
SQLSetDescField
SQLSTATE ERROR CAN BE RETURNED FROM
QLBulkOperations
SQLCopyDesc
SQLDriverConnect
SQLEndTran
SQLFreeStmt
SQLGetConnectAttr
SQLGetEnvAttr
QLParamData
SQLSetConnectAttr
SQLSetDescField
SQLSetEnvAttr
SQLSetPos
SQLSetStmtAttr
SQLDrivers
SQLExecDirect
SQLExecute
SQLParamData
SQLSetDescField
SQLSTATE ERROR CAN BE RETURNED FROM
SQLFetchScroll
SQLFetch
SQLFetchScroll
SQLSetPos
SQLExecute
SQLGetData
SQLGetStmtAttr
SQLNativeSql
SQLParamData
SQLSetPos
SQLFetchScroll
SQLBindParameter
SQLBulkOperations
SQLColAttribute
SQLColumnPrivileges
SQLColumns
SQLDriverConnect
SQLEndTran
SQLExecDirect
SQLExecute
SQLExtendedFetch
SQLFetch
SQLFetchScroll
SQLForeignKeys
SQLGetConnectAttr
SQLGetConnectAttr
SQLSTATE ERROR CAN BE RETURNED FROM
SQLGetData
SQLGetEnvAttr
SQLGetInfo
SQLGetStmtAttr
SQLGetTypeInfo
SQLParamData
SQLPrepare
SQLPrimaryKeys
SQLProcedureColumns
SQLProcedures
SQLSetConnectAttr
SQLSetEnvAttr
SQLSetPos
SQLSetStmtAttr
SQLSpecialColumns
SQLStatistics
SQLTablePrivileges
SQLTables
SQLSTATE ERROR CAN BE RETURNED FROM
SQLBulkOperations
SQLColumnPrivileges
SQLColumns
SQLConnect
SQLDriverConnect
SQLExecDirect
SQLExecute
SQLExtendedFetch
SQLForeignKeys
SQLGetTypeInfo
SQLParamData
SQLPrepare
SQLPrimaryKeys
SQLProcedureColumns
SQLProcedures
SQLSetPos
SQLSpecialColumns
SQLStatistics
SQLTablePrivileges
SQLTables
SQLDrivers
SQLDataSources
SQLGetEnvAttr
SQLSetEnvAttr
SQLSTATE ERROR CAN BE RETURNED FROM
IM001 Driver does not support this function All ODBC functions except:
SQLAllocHandle
SQLDataSources
SQLDrivers
SQLFreeHandle
SQLGetFunctions
SQLDriverConnect
SQLConnect
SQLDriverConnect
SQLDriverConnect
SQLDriverConnect
SQLConnect
SQLDriverConnect
SQLConnect
SQLDriverConnect
SQLSetConnectAttr
SQLSTATE ERROR CAN BE RETURNED FROM
SQLConnect
SQLDriverConnect
SQLDriverConnect
SQLDriverConnect
The tables in this appendix show how ODBC functions cause transitions of the environment, connection, statement,
and descriptor states. The state of the environment, connection, statement, or descriptor usually dictates when
functions that use the corresponding type of handle (environment, connection, statement, or descriptor) can be
called. The environment, connection, statement, and descriptor states overlap roughly as shown in the following
illustrations. For example, the exact overlap of connection states C5 and C6 and statement states S1 through S12 is
data source–dependent, since transactions begin at different times on different data sources, and descriptor state
D1i (implicitly allocated descriptor) depends on the state of the statement with which the descriptor is associated,
while state D1e (explicitly allocated descriptor) is independent of the state of any statement. For a description of
each state, see Environment Transitions, Connection Transitions, Statement Transitions, and Descriptor Transitions,
later in this appendix.
The environment and connection states overlap as follows:
NOTE
The tables do not show errors unrelated to the transition tables that do not change the state. For example, when
SQLAllocHandle is called in environment state E1 and returns SQLSTATE HY001 (Memory allocation error), the environment
remains in state E1; this is not shown in the environment transition table for SQLAllocHandle.
If the environment, connection, statement, or descriptor can move to more than one state, each possible state is
shown and one or more footnotes explain the conditions under which each transition takes place. The following
footnotes may appear in any table.
FOOTNOTE MEANING
v Valid row. The cursor was positioned on a row in the result set,
and the row had been successfully inserted, successfully
updated, or another operation on the row had been
successfully completed. If the row status array existed, the
value in the row status array for the row was
SQL_ROW_ADDED, SQL_ROW_SUCCESS, or
SQL_ROW_UPDATED. (The row status array is pointed to by
the SQL_ATTR_ROW_STATUS_PTR statement attribute.)
SQLFreeHandle
In this example, the row in the environment state transition table for SQLFreeHandle when HandleType is
SQL_HANDLE_ENV is as follows.
E0 E1 E2
(IH) E0 (HY010)
If SQLFreeHandle is called in environment state E0 with HandleType set to SQL_HANDLE_ENV, the Driver
Manager returns SQL_INVALID_HANDLE. If it is called in state E1 with HandleType set to SQL_HANDLE_ENV, the
environment moves to state E0 if the function succeeds and remains in state E1 if the function fails. If it is called in
state E2 with HandleType set to SQL_HANDLE_ENV, the Driver Manager always returns SQL_ERROR and
SQLSTATE HY010 (Function sequence error) and the environment remains in state E2.
To understand the state transition tables, it is necessary to understand which item (environment, connection,
statement, or descriptor) they refer to. Suppose a function accepts the handle of an item of type X. The X state
transition table for that function describes how calling the function, with the handle of an item of type X, affects that
item. For example, SQLDisconnect accepts a connection handle. The connection state transition table for
SQLDisconnect describes how SQLDisconnect affects the state of the connection for which it is called.
Suppose a function accepts the handle of an item of type Y, where Y is not equal to X. The X state transition table for
that function describes how calling the function, with a handle of type X that is associated with the item of type Y,
affects the item of type Y. For example, the statement state transition table for SQLDisconnect describes how
SQLDisconnect affects the state of a statement when called with the handle of the connection with which the
statement is associated.
This appendix contains the following topics.
Environment Transitions
Connection Transitions
Statement Transitions
Descriptor Transitions
Appendix C: SQL Grammar
12/20/2017 • 1 min to read • Edit Online
ODBC defines two sets of data types: SQL data types and C data types. SQL data types indicate the data type of data
stored at the data source. C data types indicate the data type of data stored in application buffers.
SQL data types are defined by each DBMS in accordance with the SQL-92 standard. For each SQL data type
specified in the SQL-92 standard, ODBC defines a type identifier, which is a #define value that is passed as an
argument in ODBC functions or returned in the metadata of a result set. The only SQL-92 data types not supported
by ODBC are BIT (the ODBC SQL_BIT type has different characteristics), BIT_VARYING, TIME_WITH_TIMEZONE,
TIMESTAMP_WITH_TIMEZONE, and NATIONAL_CHARACTER. Drivers are responsible for mapping data source–
specific SQL data types to ODBC SQL data type identifiers and driver-specific SQL data type identifiers. The SQL
data type is specified in the SQL_DESC_CONCISE_TYPE field of an implementation descriptor.
ODBC defines the C data types and their corresponding ODBC type identifiers. An application specifies the C data
type of the buffer that will receive result set data by passing the appropriate C type identifier in the TargetType
argument in a call to SQLBindCol or SQLGetData. It specifies the C type of the buffer containing a statement
parameter by passing the appropriate C type identifier in the ValueType argument in a call to SQLBindParameter.
The C data type is specified in the SQL_DESC_CONCISE_TYPE field of an application descriptor.
NOTE
There are no driver-specific C data types.
Each SQL data type corresponds to an ODBC C data type. Before returning data from the data source, the driver
converts it to the specified C data type. Before sending data to the data source, the driver converts it from the
specified C data type.
This appendix contains the following topics.
Using Data Type Identifiers
SQL Data Types
C Data Types
Data Type Identifiers and Descriptors
Pseudo-Type Identifiers
Transferring Data in Its Binary Form
Guidelines for Interval and Numeric Data Types
Constraints of the Gregorian Calendar
Column Size, Decimal Digits, Transfer Octet Length, and Display Size
Converting Data from SQL to C Data Types
Converting Data from C to SQL Data Types
For an explanation of ODBC data types, see Data Types in ODBC. For information about driver-specific SQL
data types, see the driver's documentation.
Appendix E: Scalar Functions
12/20/2017 • 1 min to read • Edit Online
ODBC specifies the following types of scalar functions, with detailed information about each of these function types
provided in the corresponding sections of this appendix. The function descriptions include associated syntax.
This appendix contains the following topics.
String Functions
Numeric Functions
Time, Date, and Interval Functions
System Functions
Explicit Data Type Conversion Function
SQL-92 CAST Function
ODBC does not mandate a data type for return values from scalar functions because the functions are often
data source–specific. Applications should use the CONVERT scalar function whenever possible to force data
type conversion.
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
The ODBC cursor library (Odbccr32.dll) supports block scrollable cursors for any driver that complies with the Level
1 API conformance level and 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
supports only static and forward-only cursors, the cursor library satisfies the needs of many applications.
Furthermore, it can provide good performance, especially for small-sized to medium-sized result sets, and for
applications that do not have good cursor support.
The cursor library is a dynamic-link library (DLL) that resides between the Driver Manager and the driver. When an
application calls a function, the Driver Manager calls the function in the cursor library, which either executes the
function or calls it in the specified driver. For a given connection, an application specifies whether the cursor library
is always used, used if the driver does not support scrollable cursors, or never used.
The cursor library appears as a driver to the Driver Manager. If the cursor library resides between the Driver
Manager and an ODBC 2.x driver, the cursor library appears as an ODBC 2.x driver. If the cursor library resides
between the Driver Manager and an ODBC 3.x driver, the cursor library appears as an ODBC 3.x driver. The
behavior exhibited by the cursor library depends upon the version of the driver it is working with, with the
exception of binding offsets, which is supported for both ODBC 2.x and ODBC 3.x drivers.
To implement block cursors in SQLFetch and SQLFetchScroll, the cursor library repeatedly calls SQLFetch in the
driver. To implement scrolling, it caches the data it has retrieved in memory and in disk files. When an application
requests a new rowset, the cursor library retrieves it as necessary from the driver or the cache.
To implement positioned update and delete statements, the cursor library constructs an UPDATE or DELETE
statement with a WHERE clause that specifies the cached value of each bound column in the row. When it executes
a positioned update statement, the cursor library updates its cache from the values in the rowset buffers.
For more information about the ODBC cursor library, see the following sections of this appendix:
Using the ODBC Cursor Library
Executing Positioned Update and Delete Statements
Cursor Library Code Example
Implementation Notes
ODBC Cursor Library Error Codes
Appendix G: Driver Guidelines for Backward
Compatibility
12/20/2017 • 1 min to read • Edit Online
This appendix provides information for driver writers working on ODBC 3.x drivers that need to support ODBC 2.x
applications. For more information about backward compatibility, see Backward Compatibility and Standards
Compliance.
This section contains the following topics.
Block Cursors, Scrollable Cursors, and Backward Compatibility for ODBC 3.x Drivers — New features are
features that exist in ODBC 3.x and not in ODBC 2.x. ODBC 3.x drivers generally do not have to worry about
backward compatibility with new features because ODBC 2.x applications never use them. The sole
exceptions to this are features related to SQLFetch, SQLFetchScroll, SQLSetPos, and SQLExtendedFetch;
for more information, see , later in this appendix.
Mapping Deprecated Functions — Duplicated features are features that are implemented differently in
ODBC 3.x and ODBC 2.x. ODBC 3.x drivers do not have to worry about backward compatibility with
duplicated features because the Driver Manager always maps ODBC 2.x features to ODBC 3.x features when
calling an ODBC 3.x driver. Thus, an ODBC 3.x driver sees only ODBC 3.x features. For more information
about these mappings, see , later in this appendix.
Behavioral Changes and ODBC 3.x Drivers — Behavior changes are features that are handled differently in
ODBC 3.x and ODBC 2.x. ODBC 3.x drivers have to worry about behavior changes and act in response to the
SQL_ATTR_ODBC_VERSION environment attribute set by the application.
Backward Compatibility of C Data Types
12/20/2017 • 1 min to read • Edit Online
SQL_C_SHORT, SQL_C_LONG, and SQL_C_TINYINT have been replaced in ODBC by signed and unsigned types:
SQL_C_SSHORT and SQL_C_USHORT, SQL_C_SLONG and SQL_C_ULONG, and SQL_C_STINYINT and
SQL_C_UTINYINT. An ODBC 3.x driver that should work with ODBC 2.x applications should support SQL_C_SHORT,
SQL_C_LONG, and SQL_C_TINYINT, because when they are called, the Driver Manager passes them through to the
driver.
Behavioral Changes and ODBC 3.x Drivers
12/20/2017 • 2 min to read • Edit Online
The environment attribute SQL_ATTR_ODBC_VERSION indicates to the driver whether it needs to exhibit ODBC 2.x
behavior or ODBC 3.x behavior. How the SQL_ATTR_ODBC_VERSION environment attribute is set depends on the
application. ODBC 3.x applications must call SQLSetEnvAttr to set this attribute after they call SQLAllocHandle to
allocate an environment handle and before they call SQLAllocHandle to allocate a connection handle. If they fail
to do this, the Driver Manager returns SQLSTATE HY010 (Function sequence error) on the latter call to
SQLAllocHandle.
NOTE
For more information on behavioral changes and how an application acts, see Behavioral Changes.
ODBC 2.x applications and ODBC 2.x applications recompiled with the ODBC 3.x header files do not call
SQLSetEnvAttr. However, they call SQLAllocEnv instead of SQLAllocHandle to allocate an environment handle.
Therefore, when the application calls SQLAllocEnv in the Driver Manager, the Driver Manager calls
SQLAllocHandle and SQLSetEnvAttr in the driver. Thus, ODBC 3.x drivers can always count on this attribute
being set.
If a standards-compliant application compiled with the ODBC_STD compile flag calls SQLAllocEnv (which may
occur because SQLAllocEnv is not deprecated in ISO), the call is mapped to SQLAllocHandleStd at compile time.
At run time, the application calls SQLAllocHandleStd. The Driver Manager sets the SQL_ATTR_ODBC_VERSION
environment attribute to SQL_OV_ODBC3. A call to SQLAllocHandleStd is equivalent to a call to
SQLAllocHandle with a HandleType of SQL_HANDLE_ENV and a call to SQLSetEnvAttr to set
SQL_ATTR_ODBC_VERSION to SQL_OV_ODBC3.
In certain driver architectures, there is a need for the driver to appear as either an ODBC 2.x driver or an ODBC 3.x
driver, depending on the connection. The driver in this case might not actually be a driver but a layer that resides
between the Driver Manager and another driver. For example, it might mimic a driver, like ODBC Spy. In another
example, it might act as a gateway, like EDA/SQL. To appear as an ODBC 3.x driver, such a driver must be able to
export SQLAllocHandle, and to appear as an ODBC 2.x driver, must be able to export SQLAllocConnect,
SQLAllocEnv, and SQLAllocStmt. When an environment, connection, or statement is to be allocated, the Driver
Manager checks to see if this driver exports SQLAllocHandle. Since the driver does, the Driver Manager calls
SQLAllocHandle in the driver. If the driver is working with an ODBC 2.x driver, the driver must map the call to
SQLAllocHandle to SQLAllocConnect, SQLAllocEnv, or SQLAllocStmt, as appropriate. It must also do nothing
with the SQLSetEnvAttr call when behaving as an ODBC 2.x driver.
This section contains the following topics.
Datetime Data Types
Backward Compatibility of C Data Types
Fixed-Length Bookmarks
SQLGetInfo Support
Returning SQL_NO_DATA
Calling SQLSetPos to Insert Data
Loading by Ordinal
Block Cursors, Scrollable Cursors, and Backward
Compatibility
12/20/2017 • 1 min to read • Edit Online
The existence of both SQLFetchScroll and SQLExtendedFetch represents the first clear split in ODBC between the
Application Programming Interface (API), which is the set of functions the application calls, and the Service Provider
Interface (SPI), which is the set of functions the driver implements. This split is necessary so that ODBC 3.x, which
uses SQLFetchScroll,bealigned with the standards and also be compatible with ODBC 2.x, which uses
SQLExtendedFetch.
The ODBC 3.x API, which is the set of functions the application calls, includes SQLFetchScroll and related
statement attributes. The ODBC 3.x SPI, which is the set of functions the driver implements, includes
SQLFetchScroll, SQLExtendedFetch, and related statement attributes. Because ODBC does not formally enforce
this split between the API and the SPI, it is possible for ODBC 3.x applications to call SQLExtendedFetch and
related statement attributes. However, there is no reason for ODBC 3.x application to do this. For more information
about APIs and SPIs, see the introduction to ODBC Architecture.
For information about what functions and statement attributes an ODBC 3.x application should use with block and
scrollable cursors, see Block Cursors, Scrollable Cursors, and Backward Compatibility for ODBC 3.x Applications.
This section contains the following topics.
What the Driver Manager Does
What the Driver Does
Bookmark C Data Type
12/20/2017 • 1 min to read • Edit Online
The bookmark C data type allows an application to retrieve a bookmark. The bookmark C types are used only to
retrieve bookmark values that can be variable in length; they should not be converted to other data types. An
application retrieves a bookmark either from column 0 of the result set with SQLBulkOperations (with an
operation of SQL_ADD), SQLFetch, SQLFetchScroll, or SQLGetData. For more information, see Bookmarks.
The following table lists the value of CType for the bookmark C data type, the ODBC C data type that implements
the bookmark C data type, and the definition of this data type from SQL.H.
NOTE
The SQL_C_BOOKMARK data type has been deprecated. ODBC 3.x applications should not use SQL_C_BOOKMARK. ODBC
3.x drivers need to support SQL_C_BOOKMARK only if they want to work with ODBC 2.x applications that use it. The Driver
Manager maps SQL_C_VARBOOKMARK to SQL_C_BOOKMARK when an application works with an ODBC 2.x driver.
ODBC C data types indicate the data type of C buffers used to store data in the application.
All drivers must support all C data types. This is required because all drivers must support all C types to which SQL
types that they support can be converted, and all drivers support at least one character SQL type. Because the
character SQL type can be converted to and from all C types, all drivers must support all C types.
The C data type is specified in the SQLBindCol and SQLGetData functions with the TargetType argument and in
the SQLBindParameter function with the ValueType argument. It can also be specified by calling
SQLSetDescField to set the SQL_DESC_CONCISE_TYPE field of an ARD or APD, or by calling SQLSetDescRec
with the Type argument (and the SubType argument if needed) and the DescriptorHandle argument set to the
handle of an ARD or APD.
The following tables lists valid type identifiers for the C data types. The table also lists the ODBC C data type that
corresponds to each identifier and the definition of this data type.
All C interval data types SQL_INTERVAL_STRUCT See the C Interval Structure section,
later in this appendix.
struct tagDATE_STRUCT {
SQLSMALLINT year;
SQLUSMALLINT month;
SQLUSMALLINT day;
} DATE_STRUCT;[a]
struct tagTIME_STRUCT {
SQLUSMALLINT hour;
SQLUSMALLINT minute;
SQLUSMALLINT second;
} TIME_STRUCT;[a]
struct tagTIMESTAMP_STRUCT {
SQLSMALLINT year;
SQLUSMALLINT month;
SQLUSMALLINT day;
SQLUSMALLINT hour;
SQLUSMALLINT minute;
SQLUSMALLINT second;
SQLUINTEGER fraction;[b]
} TIMESTAMP_STRUCT;[a]
struct tagSQLGUID {
DWORD Data1;
WORD Data2;
WORD Data3;
BYTE Data4[8];
} SQLGUID;[k]
[a] The values of the year, month, day, hour, minute, and second fields in the datetime C data types must conform
to the constraints of the Gregorian calendar. (See Constraints of the Gregorian Calendar later in this appendix.)
[b] The value of the fraction field is the number of billionths of a second and ranges from 0 through 999,999,999
(1 less than 1 billion). For example, the value of the fraction field for a half-second is 500,000,000, for a
thousandth of a second (one millisecond) is 1,000,000, for a millionth of a second (one microsecond) is 1,000, and
for a billionth of a second (one nanosecond) is 1.
[c] In ODBC 2.x, the C date, time, and timestamp data types are SQL_C_DATE, SQL_C_TIME, and
SQL_C_TIMESTAMP.
[d] ODBC 3.x applications should use SQL_C_VARBOOKMARK, not SQL_C_BOOKMARK. When an ODBC 3.x
application works with an ODBC 2.x driver, the ODBC 3.x Driver Manager will map SQL_C_VARBOOKMARK to
SQL_C_BOOKMARK.
[e] A number is stored in the val field of the SQL_NUMERIC_STRUCT structure as a scaled integer, in little endian
mode (the leftmost byte being the least-significant byte). For example, the number 10.001 base 10, with a scale of
4, is scaled to an integer of 100010. Because this is 186AA in hexadecimal format, the value in
SQL_NUMERIC_STRUCT would be "AA 86 01 00 00 ... 00", with the number of bytes defined by the
SQL_MAX_NUMERIC_LEN #define.
For more information about SQL_NUMERIC_STRUCT, see HOWTO: Retrieving Numeric Data with
SQL_NUMERIC_STRUCT.
[f] The precision and scale fields of the SQL_C_NUMERIC data type areused for input from an application and for
output from the driver to the application. When the driver writes a numeric value into the
SQL_NUMERIC_STRUCT, it will use its own driver-specific default as the value for the precision field, and it will use
the value in the SQL_DESC_SCALE field of the application descriptor (which defaults to 0) for the scale field. An
application can provide its own values for precision and scale by setting the SQL_DESC_PRECISION and
SQL_DESC_SCALE fields of the application descriptor.
[g] The sign field is 1 if positive, 0 if negative.
[h] _int64 might not be supplied by some compilers.
[i] _SQL_C_BOOKMARK has been deprecated in ODBC 3.x.
[j] _SQL_C_SHORT, SQL_C_LONG, and SQL_C_TINYINT have been replaced in ODBC by signed and unsigned
types: SQL_C_SSHORT and SQL_C_USHORT, SQL_C_SLONG and SQL_C_ULONG, and SQL_C_STINYINT and
SQL_C_UTINYINT. An ODBC 3.x driver that should work with ODBC 2.x applications should support
SQL_C_SHORT, SQL_C_LONG, and SQL_C_TINYINT, because when they are called, the Driver Manager passes
them through to the driver.
[k] SQL_C_GUID can be converted only to SQL_CHAR or SQL_WCHAR.
This section contains the following topic.
64-Bit Integer Structures
See Also
C Data Types in ODBC
Retrieve numeric data with SQL_NUMERIC_STRUCT
12/20/2017 • 7 min to read • Edit Online
This article describes how to retrieve numeric data from the SQL Server ODBC driver into a numeric structure. It
also describes how to get the correct values using specific precision and scale values.
This data type allows applications to directly handle numeric data. Around the year 2003, ODBC 3.0 introduced a
new ODBC C data type, identified by SQL_C_NUMERIC. This data type is still relevant as of 2017.
The C buffer that is used has the type definition of SQL_NUMERIC_STRUCT. This structure has fields for storing
the precision, scale, sign, and value of the numeric data. The value itself is stored as a scaled integer with the least
significant byte beginning in the leftmost position.
The article C Data Types provides more information about the format and use of SQL_NUMERIC_STRUCT.
Generally the Appendix D of the ODBC 3.0 Programmer's Reference discusses data types.
SQL_NUMERIC_STRUCT overview
The SQL_NUMERIC_STRUCT is defined in the sqltypes.h header file as follows:
#define SQL_MAX_NUMERIC_LEN 16
typedef struct tagSQL_NUMERIC_STRUCT
{
SQLCHAR precision;
SQLSCHAR scale;
SQLCHAR sign; /* 1 if positive, 0 if negative */
SQLCHAR val[SQL_MAX_NUMERIC_LEN];
} SQL_NUMERIC_STRUCT;
The precision and scale fields of the numeric structure are never used for input from an application, only for output
from the driver to the application.
The driver uses the default precision (driver-defined) and default scale (0) whenever returning data to the
application. Unless the application specifies values for precision and scale, the driver assumes the default and
truncates the decimal portion of the numeric data.
NOTE
ANY USE BY YOU OF THE CODE PROVIDED IN THIS ARTICLE IS AT YOUR OWN RISK.
Microsoft provides these code samples "as is" without warranty of any kind, either expressed or implied, including but not
limited to the implied warranties of merchantability and/or fitness for a particular purpose.
#include <stdio.h>
#include <string.h>
#include <string.h>
#include <conio.h>
#include <stdlib.h>
#include <ctype.h>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#define MAXDSN 25
#define MAXUID 25
#define MAXAUTHSTR 25
#define MAXBUFLEN 255
SQL_NUMERIC_STRUCT NumStr;
int main()
{
RETCODE retcode;
// Allocate the Environment handle. Set the Env attribute, allocate the
//connection handle, connect to the database and allocate the statement //handle.
// Use SQLBindCol to bind the NumStr to the column that is being retrieved.
retcode = SQLBindCol(hstmt1,1,SQL_C_NUMERIC,&NumStr,19,&strlen1);
// Get the application row descriptor for the statement handle using
//SQLGetStmtAttr.
// In this case, the table contains only one column, hence the second
//parameter contains one. Zero applies to bookmark columns. Please check
//the programmers guide for more information.
//retcode=SQLSetDescRec(hdesc,1,SQL_NUMERIC,NULL,sizeof(NumStr),5,3,&NumStr,&a,&b);
memset(NumStr.val,0,16);
if ( SQL_NULL_DATA == a )
{
printf( "The final value: NULL\n" );
continue;
}
// Call to convert the little endian mode data into numeric data.
myvalue = strtohextoval();
// The returned value in the above code is scaled to the value specified
//in the scale field of the numeric structure. For example 25.212 would
//be returned as 25212. The scale in this case is 3 hence the integer
//value needs to be divided by 1000.
divisor = 1;
if(NumStr.scale > 0)
{
for (i=0;i< NumStr.scale; i++)
divisor = divisor * 10;
}
final_val = (float) myvalue /(float) divisor;
// Examine the sign value returned in the sign field for the numeric
//structure.
//NOTE: The ODBC 3.0 spec required drivers to return the sign as
//1 for positive numbers and 2 for negative number. This was changed in the
//ODBC 3.5 spec to return 0 for negative instead of 2.
final_val *= sign;
printf("The final value: %f\n",final_val);
}
Interim results:
// C ==> 12 * 1 = 12
// 7 ==> 07 * 16 = 112
// 2 ==> 02 * 256 = 512
// 6 ==> 06 * 4096 = 24576
===============================
Sum = 25212
In the numeric structure, the val field is a character array of 16 elements. For example, 25.212 is scaled to 25212
and the scale is 3. In hexadecimal format this number would be 627C.
The driver returns the following items:
The equivalent character of 7C, which is '|'(pipe) in the first element of the character array.
The equivalent of 62, which is 'b' in the second element.
The remainders of the array elements contain zeroes, so the buffer contains '|b\0'.
Now the challenge is to construct the scaled integer out of this string array. Each character in the string
corresponds to two hexadecimal digits, say least significant digit (LSD) and most significant digit (MSD). The scaled
integer value could be generated by multiplying each digit (LSD & MSD) with a multiple of 16, starting with 1.
Code that implements the conversion from little endian mode to the scaled integer. It is up to the application
developer to implement this functionality. The following code example is just one of the many possible ways.
long strtohextoval()
{
long val=0,value=0;
int i=1,last=1,current;
int a=0,b=0;
for(i=0;i<=15;i++)
{
current = (int) NumStr.val[i];
a= current % 16; //Obtain LSD
b= current / 16; //Obtain MSD
value += last* a;
last = last * 16;
value += last* b;
last = last * 16;
}
return value;
}
Applies to versions
The preceding information about SQL_NUMERIC_STRUCT applies to the following product versions:
Microsoft ODBC Driver for Microsoft SQL Server 3.7
Microsoft Data Access Components 2.1
Microsoft Data Access Components 2.5
Microsoft Data Access Components 2.6
Microsoft Data Access Components 2.7
SQL_C_NUMERIC overview
The following sample program illustrates the use of SQL_C_NUMERIC, by inserting 123.45 into a table. In the table,
the column is defined as a numeric or a decimal, with precision 5, and with scale 2.
The ODBC driver you use to run this program must support ODBC 3.0 functionality.
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
void main() {
SQL_NUMERIC_STRUCT NumStr;
SQLINTEGER cbNumStr = sizeof (NumStr);
/*
Set up the SQL_NUMERIC_STRUCT, NumStr, to hold "123.45".
The precision and scale fields are not used for input to the driver,
only for output from the driver. The precision and scale will be set
in the application parameter descriptor later.
*/
SQLExecDirect(hstmt,
(SQLCHAR *) "INSERT INTO table (numeric_column) VALUES (?)",
SQL_NTS);
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
SQLDisconnect (hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
C Interval Structure
12/20/2017 • 1 min to read • Edit Online
Each of the C interval data types listed in the C Data Types section uses the same structure to contain the interval
data. When SQLFetch, SQLFetchScroll, or SQLGetData is called, the driver returns data into the
SQL_INTERVAL_STRUCT structure, uses the value that was specified by the application for the C data types (in the
call to SQLBindCol, SQLGetData, or SQLBindParameter) to interpret the contents of SQL_INTERVAL_STRUCT,
and populates the interval_type field of the structure with the enum value corresponding to the C type. Note that
drivers do not read the interval_type field to determine the type of the interval; they retrieve the value of the
SQL_DESC_CONCISE_TYPE descriptor field. When the structure is used for parameter data, the driver uses the
value specified by the application in the SQL_DESC_CONCISE_TYPE field of the APD to interpret the contents of
SQL_INTERVAL_STRUCT, even if the application sets the value of the interval_type field to a different value.
This structure is defined as follows:
The interval_type field of the SQL_INTERVAL_STRUCT indicates to the application what structure is held in the
union and also what members of the structure are relevant. The interval_sign field has the value SQL_FALSE if the
interval leading field is unsigned; if it is SQL_TRUE, the leading field is negative. The value in the leading field itself
is always unsigned, regardless of the value of interval_sign. The interval_sign field acts as a sign bit.
Converting Data from C to SQL Data Types
12/20/2017 • 3 min to read • Edit Online
When an application calls SQLExecute or SQLExecDirect, the driver retrieves the data for any parameters bound
with SQLBindParameter from storage locations in the application. When an application calls SQLSetPos, the
driver retrieves the data for an update or add operation from columns bound with SQLBindCol. For data-at-
execution parameters, the application sends the parameter data with SQLPutData. If necessary, the driver
converts the data from the data type specified by the ValueType argument in SQLBindParameter to the data
type specified by the ParameterType argument in SQLBindParameter,and then sends the data to the data
source.
The following table shows the supported conversions from ODBC C data types to ODBC SQL data types. A filled
circle indicates the default conversion for an SQL data type (the C data type from which the data will be converted
when the value of ValueType or the SQL_DESC_CONCISE_TYPE descriptor field is SQL_C_DEFAULT). A hollow
circle indicates a supported conversion.
The format of the converted data is not affected by the Windows® country setting.
The tables in the following sections describe how the driver or data source converts data sent to the data source;
drivers are required to support conversions from all ODBC C data types to the ODBC SQL data types that they
support. For a given ODBC C data type, the first column of the table lists the legal input values of the
ParameterType argument in SQLBindParameter. The second column lists the outcomes of a test that the driver
performs to determine if it can convert the data. The third column lists the SQLSTATE returned for each outcome
by SQLExecDirect, SQLExecute, SQLBulkOperations, SQLSetPos, or SQLPutData. Data is sent to the data
source only if SQL_SUCCESS is returned.
If the ParameterType argument in SQLBindParameter contains the identifier of an ODBC SQL data type that is
not shown in the table for a given C data type, SQLBindParameter returns SQLSTATE 07006 (Restricted data
type attribute violation). If the ParameterType argument contains a driver-specific identifier and the driver does
not support the conversion from the specific ODBC C data type to that driver-specific SQL data type,
SQLBindParameter returns SQLSTATE HYC00 (Optional feature not implemented).
If the ParameterValuePtr and StrLen_or_IndPtr arguments specified in SQLBindParameter are both null pointers,
that function returns SQLSTATE HY009 (Invalid use of null pointer). Although it is not shown in the tables, an
application sets the value of the length/indicator buffer pointed to by the StrLen_or_IndPtr argument of
SQLBindParameter or the value of the StrLen_or_IndPtr argument of SQLPutData to SQL_NULL_DATA to
specify a NULL SQL data value. (The StrLen_or_IndPtr argument corresponds to the
SQL_DESC_OCTET_LENGTH_PTR field of the APD.) The application sets these values to SQL_NTS to specify that
the value in *ParameterValuePtr in SQLBindParameter or *DataPtr in SQLPutData (pointed to by the
SQL_DESC_DATA_PTR field of the APD) is a null-terminated string.
The following terms are used in the tables:
Byte length of data — Number of bytes of SQL data available to send to the data source, whether or not
the data will be truncated before it is sent to the data source. For string data, this does not include space for
the null-termination character.
Column byte length — Number of bytes required to store the data at the data source.
Character byte length — Maximum number of bytes needed to display data in character form. This is as
defined for each SQL data type in Display Size, except character byte length is in bytes, while the display
size is in characters.
Number of digits — Number of characters used to represent a number, including the minus sign, decimal
point, and exponent (if needed).
Words in
italics — Elements of the SQL grammar. For the syntax of grammar elements, see Appendix C: SQL
Grammar.
This section contains the following topics.
C to SQL: Character
C to SQL: Numeric
C to SQL: Bit
C to SQL: Binary
C to SQL: Date
C to SQL: GUID
C to SQL: Time
C to SQL: Timestamp
C to SQL: Year-Month Intervals
C to SQL: Day-Time Intervals
C to SQL Data Conversion Examples
C to SQL Data Conversion Examples
12/20/2017 • 1 min to read • Edit Online
The following examples illustrate how the driver converts C data to SQL data :
[a] "\0" represents a null-termination byte. The null-termination byte is required only if the length of the data is
SQL_NTS.
[b] In addition to bytes for numbers, one byte is required for a sign and another byte is required for the decimal
point.
[c] The numbers in this list are the numbers stored in the fields of the SQL_DATE_STRUCT structure.
[d] The numbers in this list are the numbers stored in the fields of the SQL_TIMESTAMP_STRUCT structure.
C to SQL: Binary
12/20/2017 • 1 min to read • Edit Online
SQL_TINYINT
SQL_SMALLINT
SQL_INTEGER
SQL_BIGINT
SQL_REAL
SQL_FLOAT
SQL_DOUBLE
SQL_BIT SQL_TYPE_DATE
SQL_TYPE_TIME
SQL_TYPE_TIMESTAMP
SQL_LONGVARBINARY
C to SQL: Bit
12/20/2017 • 1 min to read • Edit Online
SQL_LONGVARCHAR
SQL_WCHAR SQL_WVARCHAR
SQL_WLONGVARCHAR
SQL_TINYINT SQL_SMALLINT
SQL_INTEGER SQL_BIGINT
SQL_REAL SQL_FLOAT
SQL_DOUBLE
The driver ignores the length/indicator value when converting data from the bit C data type and assumes that the
size of the data buffer is the size of the bit C data type. The length/indicator value is passed in the StrLen_or_Ind
argument in SQLPutData and in the buffer specified with the StrLen_or_IndPtr argument in SQLBindParameter.
The data buffer is specified with the DataPtr argument in SQLPutData and the ParameterValuePtr argument in
SQLBindParameter.
C to SQL: Character
12/20/2017 • 3 min to read • Edit Online
NOTE
When character C data is converted to Unicode SQL data, the length of the Unicode data must be an even number.
SQL_LONGVARCHAR
All SQL interval types Data value is a valid interval value; no n/a
truncation occurs
22015
Data value is a valid interval value; the
value in one of the fields is truncated 22018
NOTE
Application developers are discouraged from binding character C data to a binary SQL data type. This conversion is usually
inefficient and slow.
C to SQL: Date
12/20/2017 • 1 min to read • Edit Online
The identifiers for the day-time interval ODBC C data types are:
SQL_C_INTERVAL_DAY
SQL_C_INTERVAL_HOUR
SQL_C_INTERVAL_MINUTE
SQL_C_INTERVAL_SECOND
SQL_C_INTERVAL_DAY_TO_HOUR
SQL_C_INTERVAL_DAY_TO_MINUTE
SQL_C_INTERVAL_DAY_TO_SECOND
SQL_C_INTERVAL_HOUR_TO_MINUTE
SQL_C_INTERVAL_HOUR_TO_SECOND
SQL_C_INTERVAL_MINUTE_TO_SECOND
The following table shows the ODBC SQL data types to which interval C data may be converted. For an explanation
of the columns and terms in the table, see Converting Data from C to SQL Data Types.
SQL_DECIMAL[b]
SQL TYPE IDENTIFIER TEST SQLSTATE
SQL_INTERVAL_SECOND
SQL_INTERVAL_DAY_TO_HOUR
SQL_INTERVAL_DAY_TO_MINUTE
SQL_INTERVAL_DAY_TO_SECOND
SQL_INTERVAL_HOUR_TO_MINUTE
SQL_INTERVAL_HOUR_TO_SECOND
SQL_INTERVAL_MINUTE_TO_SECOND
[a] All C interval data types can be converted to a character data type.
[b] If the type field in the interval structure is such that the interval is a single field (SQL_DAY, SQL_HOUR,
SQL_MINUTE, or SQL_SECOND), the interval C type can be converted to any exact numeric (SQL_TINYINT,
SQL_SMALLINT, SQL_INTEGER, SQL_BIGINT, SQL_DECIMAL, or SQL_NUMERIC).
The default conversion of an interval C type is to the corresponding day-time interval SQL type.
The driver ignores the length/indicator value when converting data from the interval C data type and assumes that
the size of the data buffer is the size of the interval C data type. The length/indicator value is passed in the
StrLen_or_Ind argument in SQLPutData and in the buffer specified with the StrLen_or_IndPtr argument in
SQLBindParameter. The data buffer is specified with the DataPtr argument in SQLPutData and the
ParameterValuePtr argument in SQLBindParameter.
The following example demonstrates how to send interval C data stored in the SQL_INTERVAL_STRUCT structure
into a database column. The interval structure contains a DAY_TO_SECOND interval; it will be stored in a database
column of type SQL_INTERVAL_DAY_TO_MINUTE.
SQL_INTERVAL_STRUCT is;
SQLINTEGER cbValue;
SQL_SMALLINT[b]
SQL_INTEGER[b]
SQL_BIGINT[b]
SQL_INTERVAL_DAY[a]
SQL_INTERVAL_HOUR[a]
SQL_INTERVAL_MINUTE[a]
SQL_INTERVAL_SECOND[a]
[a] These conversions are supported only for the exact numeric data types (SQL_C_STINYINT, SQL_C_UTINYINT,
SQL_C_SSHORT, SQL_C_USHORT, SQL_C_SLONG, SQL_C_ULONG, or SQL_C_NUMERIC). They are not supported
for the approximate numeric data types (SQL_C_FLOAT or SQL_C_DOUBLE). Exact numeric C data types cannot be
converted to an interval SQL type whose interval precision is not a single field.
[b] For the "n/a" case, a driver may optionally return SQL_SUCCESS_WITH_INFO and 01S07 when there is a
fractional truncation.
The driver ignores the length/indicator value when converting data from the numeric C data types and assumes
that the size of the data buffer is the size of the numeric C data type. The length/indicator value is passed in the
StrLen_or_Ind argument in SQLPutData and in the buffer specified with the StrLen_or_IndPtr argument in
SQLBindParameter. The data buffer is specified with the DataPtr argument in SQLPutData and the
ParameterValuePtr argument in SQLBindParameter.
C to SQL: Timestamp
12/20/2017 • 1 min to read • Edit Online
[a] The date portion of the timestamp is set to the current date, and the fractional seconds portion of the timestamp
is set to zero.
For information about what values are valid in a SQL_C_TYPE_TIME structure, see C Data Types, earlier in this
appendix.
When time C data is converted to character SQL data, the resulting character data is in the "hh:mm:ss" format.
The driver ignores the length/indicator value when converting data from the time C data type and assumes that the
size of the data buffer is the size of the time C data type. The length/indicator value is passed in the StrLen_or_Ind
argument in SQLPutData and in the buffer specified with the StrLen_or_IndPtr argument in SQLBindParameter.
The data buffer is specified with the DataPtr argument in SQLPutData and the ParameterValuePtr argument in
SQLBindParameter.
C to SQL: Year-Month Intervals
12/20/2017 • 1 min to read • Edit Online
The identifiers for the year-month interval ODBC C data types are:
SQL_C_INTERVAL_MONTH SQL_C_INTERVAL_YEAR SQL_C_INTERVAL_YEAR_TO_MONTH
The following table shows the ODBC SQL data types to which year-month interval C data may be converted. For an
explanation of the columns and terms in the table, see Converting Data from C to SQL Data Types.
SQL_BIGINT[b]
SQL_NUMERIC[b]
SQL_DECIMAL[b]
[a] All C interval data types can be converted to a character data type.
[b] If the type field in the interval structure is such that the interval is a single field (SQL_YEAR or SQL_MONTH), the
interval C type can be converted to any exact numeric (SQL_TINYINT, SQL_SMALLINT, SQL_INTEGER, SQL_BIGINT,
SQL_DECIMAL, or SQL_NUMERIC).
The default conversion of an interval C type is to the corresponding year-month interval SQL type.
The driver ignores the length/indicator value when converting data from the interval C data type and assumes that
the size of the data buffer is the size of the interval C data type. The length/indicator value is passed in the
StrLen_or_Ind argument in SQLPutData and in the buffer specified with the StrLen_or_IndPtr argument in
SQLBindParameter. The data buffer is specified with the DataPtr argument in SQLPutData and the
ParameterValuePtr argument in SQLBindParameter.
Calling SQLSetPos to Insert Data
12/20/2017 • 1 min to read • Edit Online
When an ODBC 2.x application working with an ODBC 3.x driver calls SQLSetPos with an Operation argument of
SQL_ADD, the Driver Manager does not map this call to SQLBulkOperations. If an ODBC 3.x driver should work
with an application that calls SQLSetPos with SQL_ADD, the driver should support that operation.
One major difference in behavior when SQLSetPos is called with SQL_ADD occurs when it is called in state S6. In
ODBC 2.x, the driver returned S1010 when SQLSetPos was called with SQL_ADD in state S6 (after the cursor has
been positioned with SQLFetch). In ODBC 3.x, SQLBulkOperations with an Operation of SQL_ADD can be called
in state S6. A second major difference in behavior is that SQLBulkOperations with an Operation of SQL_ADD can
be called in state S5, while SQLSetPos with an Operation of SQL_ADD cannot. For the statement transitions that
can occur for the same call in ODBC 3.x, see Appendix B: ODBC State Transition Tables.
Column Data
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
The cursor library creates a buffer in the cache for each data buffer bound to the result set with SQLBindCol. It
uses the values in these buffers to construct a WHERE clause when it emulates a positioned update or delete
statement. It updates these buffers from the rowset buffers when it fetches data from the data source and when it
executes positioned update statements.
When the cursor library updates its cache from the rowset buffers, it transfers the data according to the C data type
specified in SQLBindCol. For example, if the C data type of a rowset buffer is SQL_C_SLONG, the cursor library
transfers four bytes of data; if it is SQL_C_CHAR and BufferLength is 10, the cursor library transfers 10 bytes of
data. The cursor library does not perform any type checking or conversions on the data it transfers.
NOTE
The cursor library does not update its cache for a column if *StrLen_or_IndPtr in the corresponding rowset buffer is
SQL_DATA_AT_EXEC or the result of the SQL_LEN_DATA_AT_EXEC macro.
When it updates a column, a data source blank-pads fixed-length character data and zero-pads fixed-length binary
data as necessary. For example, a data source stores "Smith" in a CHAR(10) column as "Smith ". The cursor library
does not blank-pad or zero-pad data in the rowset buffers when it copies this data to its cache after executing a
positioned update statement. Therefore, if an application requires that the values in the cursor library's cache are
blank-padded or zero-padded, it must blank-pad or zero-pad the values in the rowset buffers before executing a
positioned update statement.
Column Size, Decimal Digits, Transfer Octet Length,
and Display Size - ODBC
12/20/2017 • 2 min to read • Edit Online
Data types are characterized by their column (or parameter) size, decimal digits, length, and display size. The
following ODBC functions return these attributes for a parameter in an SQL statement or for an SQL data type on a
data source. Each ODBC function returns a different set of these attributes, as follows:
SQLDescribeCol returns the column size and decimal digits of the columns it describes.
SQLDescribeParam returns the parameter size and decimal digits of the parameters it describes.
SQLBindParameter sets the parameter size and decimal digits for a parameter in an SQL statement.
The catalog functions SQLColumns, SQLProcedureColumns, and SQLGetTypeInfo return attributes for a
column in a table, result set, or a procedure parameter and the catalog attributes of the data types in the
data source. SQLColumns returns the column size, decimal digits, and length of a column in specified tables
(such as the base table, view, or a system table). SQLProcedureColumns returns the column size, decimal
digits, and length of a column in a procedure. SQLGetTypeInfo returns the maximum column size and the
minimum and maximum decimal digits of an SQL data type on a data source.
The values returned by these functions for the column or parameter size correspond to "precision" as
defined in ODBC 2.x. However, the values do not necessarily correspond to the values returned in
SQL_DESC_PRECISION or any other one descriptor field. The same is true for decimal digits, which
correspond to "scale" as defined in ODBC 2.x. It does not necessarily correspond to the values returned in
SQL_DESC_SCALE or any other one descriptor field, but comes from different descriptor fields depending
on the data type. For further information, see Column Size and Decimal Digits.
Similarly, the values for transfer octet length do not come from SQL_DESC_LENGTH. They come from the
SQL_DESC_OCTET_LENGTH of a field of a descriptor for all character and binary types. There is no
descriptor field that holds this information for other types.
The display size value for all data types corresponds to the value in a single descriptor field,
SQL_DESC_DISPLAY_SIZE.
Descriptor fields describe the characteristics of a result set. Descriptor fields do not contain valid values
about data before statement execution. The values for column size, decimal digits, and display size returned
by SQLColumns, SQLProcedureColumns, and SQLGetTypeInfo,on the other hand, return characteristics
of database objects, such as table columns and data types, that exist in the data source's catalog. Likewise, in
its result set, SQLColAttribute returns the column size, decimal digits, and transfer octet length of columns
at the data source; these values are not necessarily the same as the values in the SQL_DESC_PRECISION,
SQL_DESC_SCALE, and SQL_DESC_OCTET_LENGTH descriptor fields.
For more information about these descriptor fields, see SQLSetDescField.
Related topics:
Column Size
Decimal Digits
Transfer Octet Length
Display Size
Column Size
12/20/2017 • 3 min to read • Edit Online
The column (or parameter) size of numeric data types is defined as the maximum number of digits used by the
data type of the column or parameter, or the precision of the data. For character types, this is the length in
characters of the data; for binary data types, column size is defined as the length in bytes of the data. For the time,
timestamp, and all interval data types, this is the number of characters in the character representation of this data.
The column size defined for each concise SQL data type is shown in the following table.
All character types[a],[b] The defined or maximum column size in characters of the
column or parameter (as contained in the SQL_DESC_LENGTH
descriptor field). For example, the column size of a single-byte
character column defined as CHAR(10) is 10.
SQL_DECIMAL SQL_NUMERIC The defined number of digits. For example, the precision of a
column defined as NUMERIC(10,3) is 10.
SQL_BIT[c] 1
SQL_TINYINT[c] 3
SQL_SMALLINT[c] 5
SQL_INTEGER[c] 10
SQL_REAL[c] 7
SQL_FLOAT[c] 15
SQL_DOUBLE[c] 15
All binary types[a],[b] The defined or maximum length in bytes of the column or
parameter. For example, the length of a column defined as
BINARY(10) is 10.
or
[a] For an ODBC 1.0 application calling SQLSetParam in an ODBC 2.0 driver, and for an ODBC 2.0 application
calling SQLBindParameter in an ODBC 1.0 driver, when *StrLen_or_IndPtr is SQL_DATA_AT_EXEC for a
SQL_LONGVARCHAR or SQL_LONGVARBINARY type, ColumnSize must be set to the total length of the data to be
sent, not the precision as defined in this table.
[b] If the driver cannot determine the column or parameter length for a variable type, it returns SQL_NO_TOTAL.
[c] The ColumnSize argument of SQLBindParameter is ignored for this data type.
[d] For general rules about column length in interval data types, see Interval Data Type Length, earlier in this
appendix.
The values returned for the column (or parameter) size do not correspond to the values in any one descriptor field.
The values can come from either the SQL_DESC_PRECISION or the SQL_DESC_LENGTH field, depending on the
type of data, as shown in the following table.
DESCRIPTOR FIELD CORRESPONDING TO
SQL_BIT LENGTH
Connection Transitions
12/20/2017 • 8 min to read • Edit Online
STATE DESCRIPTION
C4 Connected connection
The following tables show how each ODBC function affects the connection state.
SQLAllocHandle
C0 C2 C3 C4 C5 C6
C1
NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION
SQLBrowseConnect
C0 C1 C2 C3 C4 C5 C6
SQLCloseCursor
C0 C1 C2 C3 C4 C5 C6
[1] The connection was in auto-commit mode, or the data source did not begin a transaction.
[2] The connection was in manual-commit mode, and the data source began a transaction.
SQLConnect
C0 C1 C2 C3 C4 C5 C6
[1] In this state, the only descriptors available to the application are explicitly allocated descriptors.
(IH) -- -- -- -- -- --
SQLDisconnect
C0 C1 C2 C3 C4 C5 C6
SQLDriverConnect
C0 C1 C2 C3 C4 C5 C6
SQLEndTran
C0 C1 C2 C3 C4 C5 C6
[1] The connection was in auto-commit mode, and the statement executed was not a cursor specification (such as a
SELECT statement); or the connection was in manual-commit mode, and the statement executed did not begin a
transaction.
[2] The connection was in auto-commit mode, and the statement executed was a cursor specification (such as a
SELECT statement).
[3] The connection was in manual-commit mode, and the data source began a transaction.
SQLFreeHandle
C0 C1 C2 C3 C4 C5 C6
SQLFreeStmt
C0 C1 C2 C3 C4 C5 C6
[1] This row shows transactions when the Option argument is SQL_CLOSE.
[2] This row shows transactions when the Option argument is SQL_UNBIND or SQL_RESET_PARAMS.
[3] The connection was in auto-commit mode, and no cursors were open on any statements except this one.
[4] The connection was in manual-commit mode, or it was in auto-commit mode and a cursor was open on at least
one other statement.
SQLGetConnectAttr
C0 C1 C2 C3 C4 C5 C6
(IH)[1] -- -- -- -- -- --
(IH)[2] (IH) -- -- -- -- --
SQLGetEnvAttr
C0 C1 C2 C3 C4 C5 C6
IH -- -- -- -- -- --
SQLGetFunctions
C0 C1 C2 C3 C4 C5 C6
IH IH HY010 HY010 -- -- --
SQLGetInfo
C0 C1 C2 C3 C4 C5 C6
SQLMoreResults
C0 C1 C2 C3 C4 C5 C6
[1] The connection was in auto-commit mode, and the call to SQLMoreResults has not initialized the processing
of a result set of a cursor specification.
[2] The connection was in auto-commit mode, and the call to SQLMoreResults has initialized the processing of a
result set of a cursor specification.
[3] The connection was in manual-commit mode.
SQLNativeSql
C0 C1 C2 C3 C4 C5 C6
[1] The connection was in auto-commit mode, or the data source did not begin a transaction.
[2] The connection was in manual–commit mode, and the data source began a transaction.
SQLSetConnectAttr
C0 C1 C2 C3 C4 C5 C6
IH IH --[1] 08003[2] HY010 --[3] 08002[4] --[3] 08002[4] --[3] and [6]
HY011[5] HY011[5] C5[8]
08002[4]
HY011[5] or
[7]
SQLSetEnvAttr
C0 C1 C2 C3 C4 C5 C6
(IH) -- -- (HY010) -- -- --
Date and datetime data types, and the trailing fields of interval data types, must conform to the constraints of the
Gregorian calendar. These constraints are as follows:
The value of the month field must be between 1 and 12, inclusive.
The value of the day field must be in the range from 1 through the number of days in the month. The
number of days in the month is determined from the values of the year and months fields and can be 28,
29, 30, or 31. (The number of days in the month can also depend on whether it is a leap year.)
The value of the hour field must be between 0 and 23, inclusive.
The value of the minute field must be between 0 and 59, inclusive.
For the trailing seconds field of interval data types, the value of the seconds field must be between 0 and
59.9(n), inclusive, where n is the number of digits in the fractional seconds precision.
For the trailing seconds field of datetime data types, the value of the seconds field must be between 0 and
61.9(n), inclusive, where n specifies the number of "9" digits and the value of n is the fractional seconds
precision. (The range of seconds allows as many as two leap seconds to maintain synchronization of
sidereal time.)
Constructing Searched Statements
12/20/2017 • 3 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
To support positioned update and delete statements, the cursor library constructs a searched UPDATE or DELETE
statement from the positioned statement. To support calls to SQLGetData in a block of data, the cursor library
constructs a searched SELECT statement to create a result set containing the current row of data. In each of these
statements, the WHERE clause enumerates the values stored in the cache for each bound column that returns
SQL_PRED_SEARCHABLE or SQL_PRED_BASIC for the SQL_DESC_SEARCHABLE field identifier in
SQLColAttribute.
Cau t i on
The WHERE clause constructed by the cursor library to identify the current row can fail to identify any rows,
identify a different row, or identify more than one row.
If a positioned update or delete statement affects more than one row, the cursor library updates the row status
array only for the row on which the cursor is positioned and returns SQL_SUCCESS_WITH_INFO and SQLSTATE
01001 (Cursor operation conflict). If the statement does not identify any rows, the cursor library does not update
the row status array and returns SQL_SUCCESS_WITH_INFO and SQLSTATE 01001 (Cursor operation conflict). An
application can call SQLRowCount to determine the number of rows that were updated or deleted.
If the SELECT clause used to position the cursor for a call to SQLGetData identifies more than one row,
SQLGetData is not guaranteed to return the correct data. If it does not identify any rows, SQLGetData returns
SQL_NO_DATA.
If an application conforms to the following guidelines, the WHERE clause constructed by the cursor library should
uniquely identify the current row, except when this is impossible, such as when the data source contains duplicate
rows.
Bind columns that uniquely identify the row. If the bound columns do not uniquely identify the row,
the WHERE clause constructed by the cursor library might identify more than one row. In a positioned
update or delete statement, such a clause might cause more than one row to be updated or deleted. In a call
to SQLGetData, such a clause might cause the driver to return data for the wrong row. Binding all the
columns in a unique key guarantees that each row is uniquely identified.
Allocate data buffers large enough that no truncation occurs. The cursor library's cache is a copy of
the values in the rowset buffers bound to the result set with SQLBindCol. If data is truncated when it is
placed in these buffers, it will also be truncated in the cache. A WHERE clause constructed from truncated
values might not correctly identify the underlying row in the data source.
Specify non-null length buffers for binary C data. The cursor library allocates length buffers in its cache
only if the StrLen_or_IndPtr argument in SQLBindCol is non-null. When the TargetType argument is
SQL_C_BINARY, the cursor library requires the length of the binary data to construct a WHERE clause from
the data. If there is no length buffer for a SQL_C_BINARY column and the application calls SQLGetData or
attempts to execute a positioned update or delete statement, the cursor library returns SQL_ERROR and
SQLSTATE SL014 (A positioned request was issued and not all column count fields were buffered).
Specify non-null length buffers for nullable columns. The cursor library allocates length buffers in its
cache only if the StrLen_or_IndPtr argument in SQLBindCol is non-null. Because SQL_NULL_DATA is stored
in the length buffer, the cursor library assumes that any column for which no length buffer is specified is
non-nullable. If no length column is specified for a nullable column, the cursor library constructs a WHERE
clause that uses the data value for the column. This clause will not correctly identify the row.
Cursor Library Cache
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
For each row of data in the result set, the cursor library caches the data for each bound column, the length of the
data in each bound column, and the status of the row. The cursor library uses the values in the cache both to return
through SQLFetch and SQLFetchScroll and to construct searched statements for positioned operations. For more
information, see Constructing Searched Statements.
This section contains the following topics.
Column Data
Length of Column Data
Row Status
Location of Cache
Cursor Library Code Example
12/20/2017 • 2 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
The following example uses the cursor library to retrieve each order's ID, open date, and status from the ORDERS
table. It then displays 20 rows of data. If the user updates this data, the code updates the rowset buffers and
executes a positioned update statement. Finally, it prompts the user for the direction to scroll and repeats the
process.
#define ROWS 20
#define STATUS_LEN 6
#define OPENDATE_LEN 11
#define DONE -1
SQLHENV henv;
SQLHDBC hdbc;
SQLHSTMT hstmt1, hstmt2;
SQLRETURN retcode;
SQLCHAR szStatus[ROWS][STATUS_LEN],
szOpenDate[ROWS][OPENDATE_LEN];
SQLCHAR szNewStatus[STATUS_LEN], szNewOpenDate[OPENDATE_LEN];
SQLSMALLINT sOrderID[ROWS], sNewOrderID[ROWS];
SQLINTEGER cbStatus[ROWS], cbOrderID[ROWS], cbOpenDate[ROWS];
SQLUINTEGER FetchOrientation, crow, FetchOffset, irowUpdt;
SQLUSMALLINT RowStatusArray[ROWS];
// Specify that the ODBC Cursor Library is always used, then connect.
/* Fetch the first block of data and display it. Prompt the user */
/* for new data values. If the user supplies new values, update */
/* the rowset buffers, bind them to the parameters in the update */
/* statement, and execute a positioned update on another hstmt. */
/* Prompt the user for how to scroll. Fetch and redisplay data as */
/* needed. */
FetchOrientation = SQL_FETCH_FIRST;
FetchOffset = 0;
do {
if (PromptUpdate(&irowUpdt,&sNewOrderID,szNewOpenDate,szNewStatus)==TRUE){
sOrderID[irowUpdt] = sNewOrderID;
cbOrderID[irowUpdt] = 0;
strcpy_s((char*)szOpenDate[irowUpdt], _countof(szOpenDate[irowUpdt]), szNewOpenData);
cbOpenDate[irowUpdt] = SQL_NTS;
strcpy_s((char*)szStatus[irowUpdt], _countof(szStatus[irowUpdt]), szNewStatus);
cbStatus[irowUpdt] = SQL_NTS;
SQLBindParameter(hstmt2, 1, SQL_PARAM_INPUT,
SQL_C_SSHORT, SQL_INTEGER, 0, 0,
&sOrderID[irowUpdt], 0, &cbOrderID[irowUpdt]);
SQLBindParameter(hstmt2, 2, SQL_PARAM_INPUT,
SQL_C_CHAR, SQL_TYPE_DATE, OPENDATE_LEN, 0,
szOpenDate[irowUpdt], OPENDATE_LEN, &cbOpenDate[irowUpdt]);
SQLBindParameter(hstmt2, 3, SQL_PARAM_INPUT,
SQL_C_CHAR, SQL_CHAR, STATUS_LEN, 0,
szStatus[irowUpdt], STATUS_LEN, &cbStatus[irowUpdt]);
SQLExecDirect(hstmt2,
"UPDATE EMPLOYEE SET ORDERID = ?, OPENDATE = ?, STATUS = ?"
"WHERE CURRENT OF EMPCURSOR",
SQL_NTS);
}
The data types listed in the SQL Data Types and C Data Types sections earlier in this appendix are "concise" data
types: Each identifier refers to a single data type. There is a one-to-one correspondence between the identifier and
the data type. Descriptors, however, do not in all cases use a single value to identify data types. In some cases, they
use a "verbose" data type and a type subcode. For all data types except datetime and interval data types, the
verbose type identifier is the same as the concise type identifier and the value in
SQL_DESC_DATETIME_INTERVAL_CODE is equal to 0. For datetime and interval data types, however, a verbose
type (SQL_DATETIME or SQL_INTERVAL) is stored in SQL_DESC_TYPE, a concise type is stored in
SQL_DESC_CONCISE_TYPE, and a subcode for each concise type is stored in
SQL_DESC_DATETIME_INTERVAL_CODE. Setting one of these fields affects the others. For more information about
these fields, see the SQLSetDescField function description.
When the SQL_DESC_TYPE or SQL_DESC_CONCISE_TYPE field is set for some data types, the
SQL_DESC_DATETIME_INTERVAL_PRECISION, SQL_DESC_LENGTH, SQL_DESC_PRECISION, and SQL_DESC_SCALE
fields are automatically set to default values, as applicable for the data type. For more information, see the
description of the SQL_DESC_TYPE field in SQLSetDescField. If any of the default values set is not appropriate, the
application should explicitly set the descriptor field through a call to SQLSetDescField.
The following table shows the concise type identifier, verbose type identifier, and type subcode for each datetime
and interval SQL and C type identifier. As this table indicates, for datetime and interval data types, the
SQL_DESC_TYPE and SQL_DESC_DATETIME_INTERVAL_CODE fields have the same manifest constants both for
SQL data types (in implementation descriptors) and for C data types (in application descriptors).
ODBC drivers must support at least one of SQL_CHAR and SQL_VARCHAR. Support for other data types is
determined by the driver's or data source's SQL-92 conformance level. An application should call SQLGetTypeInfo
to determine the data types supported by the driver.
For more information on data types, see Appendix D: Data Types.
Date, Time, and Timestamp Escape Sequences
12/20/2017 • 1 min to read • Edit Online
ODBC defines escape sequences for date, time, and timestamp literals. The syntax of these escape sequences is as
follows:
{d 'value'}
{t 'value'}
{ts 'value'}
ODBC-date-time-escape ::=
ODBC-date-escape
| ODBC-time-escape
| ODBC-timestamp-escapeODBC-date-escape ::=
ODBC-esc-initiator d 'date-value' ODBC-esc-terminatorODBC-time-escape ::=
ODBC-esc-initiator t 'time-value' ODBC-esc-terminatorODBC-timestamp-escape ::=
ODBC-esc-initiator ts 'timestamp-value' ODBC-esc-terminatorODBC-esc-initiator ::= {
ODBC-esc-terminator ::= }
date-value ::=
years-value date-separator months-value date-separator days-valuetime-value ::=
hours-value time-separator minutes-value time-separatorseconds-valuetimestamp-value ::= date-value
timestamp-separator time-valuedate-separator ::= -
time-separator ::= :
timestamp-separator ::=
(The blank character)years-value ::= digit digit digit digitmonths-value ::= digit digitdays-value ::=
digit digithours-value ::= digit digitminutes-value ::= digit digitseconds-value ::= digit digit[.digit...]
Remarks
The date, time, and timestamp literal escape sequences are supported if the date, time, and timestamp data types
are supported by the data source. An application should call SQLGetTypeInfo to determine whether these data
types are supported.
Datetime Data Types
12/20/2017 • 2 min to read • Edit Online
In ODBC 3.x, the identifiers for date, time, and timestamp SQL data types have changed from SQL_DATE, SQL_TIME,
and SQL_TIMESTAMP (with instances of #define in the header file of 9, 10, and 11) to SQL_TYPE_DATE,
SQL_TYPE_TIME, and SQL_TYPE_TIMESTAMP (with instances of #define in the header file of 91, 92, and 93),
respectively. The corresponding C type identifiers have changed from SQL_C_DATE, SQL_C_TIME, and
SQL_C_TIMESTAMP to SQL_C_TYPE_DATE, SQL_C_TYPE_TIME, and SQL_C_TYPE_TIMESTAMP, respectively, and the
instances of #define have changed accordingly.
The column size and decimal digits returned for the SQL datetime data types in ODBC 3.x are the same as the
precision and scale returned for them in ODBC 2.x. These values are different than the values in the
SQL_DESC_PRECISION and SQL_DESC_SCALE descriptor fields. (For more information, see Column Size, Decimal
Digits, Transfer Octet Length, and Display Size in Appendix D: Data Types.)
These changes affect SQLDescribeCol, SQLDescribeParam, and SQLColAttributes; SQLBindCol,
SQLBindParameter, and SQLGetData; and SQLColumns, SQLGetTypeInfo, SQLProcedureColumns,
SQLStatistics, and SQLSpecialColumns.
An ODBC 3.x driver processes the function calls listed in the previous paragraph according to the setting of the
SQL_ATTR_ODBC_VERSION environment attribute. For SQLColumns, SQLGetTypeInfo, SQLProcedureColumns,
SQLSpecialColumns, and SQLStatistics, if SQL_ATTR_ODBC_VERSION is set to SQL_OV_ODBC3, the functions
return SQL_TYPE_DATE, SQL_TYPE_TIME, and SQL_TYPE_TIMESTAMP in the DATA_TYPE field. The COLUMN_SIZE
column (in the result set returned by SQLColumns, SQLGetTypeInfo, SQLProcedureColumns, and
SQLSpecialColumns) contains the binary precision for the approximate numeric type. The NUM_PREC_RADIX
column (in the result set returned by SQLColumns, SQLGetTypeInfo, and SQLProcedureColumns) contains a
value of 2. If SQL_ATTR_ODBC_VERSION is set to SQL_OV_ODBC2, then the functions return SQL_DATE, SQL_TIME,
and SQL_TIMESTAMP in the DATA_TYPE field, the COLUMN_SIZE column contains the decimal precision for the
approximate numeric type, and the NUM_PREC_RADIX column contains a value of 10.
When all data types are requested in a call to SQLGetTypeInfo, the result set returned by the function will contain
both SQL_TYPE_DATE, SQL_TYPE_TIME, and SQL_TYPE_TIMESTAMP as defined in ODBC 3.x, and SQL_DATE,
SQL_TIME, and SQL_TIMESTAMP as defined in ODBC 2.x.
Because of how the ODBC 3.x Driver Manager performs mapping of the date, time, and timestamp data types,
ODBC 3.x drivers need only recognize #defines of 91, 92, and 93 for the date, time, and timestamp C data types
entered in the TargetType arguments of SQLBindCol and SQLGetData or the ValueType argument of
SQLBindParameter, and need only recognize #defines of 91, 92, and 93 for the date, time, and timestamp SQL
data types entered in the ParameterType argument of SQLBindParameter or the DataType argument of
SQLGetTypeInfo. For more information, see Datetime Data Type Changes.
Decimal Digits
12/20/2017 • 1 min to read • Edit Online
The decimal digits of decimal and numeric data types is defined as the maximum number of digits to the right of
the decimal point, or the scale of the data. For approximate floating-point number columns or parameters, the
scale is undefined because the number of digits to the right of the decimal point is not fixed. For datetime or
interval data that contains a seconds component, the decimal digits is defined as the number of digits to the right
of the decimal point in the seconds component of the data.
For the SQL_DECIMAL and SQL_NUMERIC data types, the maximum scale is usually the same as the maximum
precision. However, some data sources impose a separate limit on the maximum scale. To determine the minimum
and maximum scales allowed for a data type, an application calls SQLGetTypeInfo.
The decimal digits defined for each concise SQL data type is shown in the following table.
SQL_DECIMAL The defined number of digits to the right of the decimal point.
SQL_NUMERIC For example, the scale of a column defined as NUMERIC(10,3)
is 3. This can be a negative number to support storage of very
large numbers without using exponential notation; for
example, "12000" could be stored as "12" with a scale of –3.
All datetime types except SQL_TYPE_DATE, and all interval The number of digits to the right of the decimal point in the
types with a seconds component seconds part of the value (fractional seconds). This number
cannot be negative.
SQL_GUID n/a
[a] The DecimalDigits argument of SQLBindParameter is ignored for this data type.
The values returned for the decimal digits do not correspond to the values in any one descriptor field. The values
can come from either the SQL_DESC_SCALE or the SQL_DESC_PRECISION field, depending on the data type, as
shown in the following table.
SQL_BIT n/a
IMPORTANT
Interoperable applications should not use SQL_C_DEFAULT. Instead, they should always specify the C type of the buffer they
are using. This is because drivers cannot always correctly determine the default C type, for the following reasons:
If the DBMS promotes an SQL data type of a column or parameter, the driver cannot determine the original
SQL data type of a column or parameter. Therefore, it cannot determine the corresponding default C data
type.
If the driver cannot determine whether a particular column or parameter is signed, as is often the case when
this is handled by the DBMS, the driver cannot determine whether the corresponding default C data type
should be signed or unsigned.
Because SQL_C_DEFAULT is provided only as a programming convenience, the application does not lose any
functionality when it specifies the actual C data type.
A table showing the default C data type for each SQL data type is included in Converting Data from SQL to C
Data Types, later in this appendix.
Descriptor Transitions
12/20/2017 • 1 min to read • Edit Online
STATE DESCRIPTION
D0 Unallocated descriptor
The following tables show how each ODBC function affects the descriptor state.
SQLAllocHandle
D0 D1I D1E
D1i[1] -- --
D1e[2] -- --
SQLCopyDesc
D0 D1I D1E
(IH) -- --
SQLFreeHandle
D0 D1I D1E
--[1] D0 --
(IH)[2] (HY017) D0
(IH) -- --
(IH)[1] -- --
[1] This row shows transitions when DescriptorHandle was the handle of an ARD, APD, or IPD, or (for
SQLSetDescField) when DescriptorHandle was the handle of an IRD and FieldIdentifier was
SQL_DESC_ARRAY_STATUS_PTR or SQL_DESC_ROWS_PROCESSED_PTR.
-- -- --
Display Size
12/20/2017 • 1 min to read • Edit Online
The display size of a column is the maximum number of characters needed to display data in character form. The
following table defines the display size for each ODBC SQL data type.
All character types[a] The defined (for fixed types) or maximum (for variable types)
number of characters needed to display the data in character
form.
SQL_DECIMAL SQL_NUMERIC The precision of the column plus 2 (a sign, precision digits,
and a decimal point). For example, the display size of a column
defined as NUMERIC(10,3) is 12.
SQL_BIT 1 (1 digit).
SQL_FLOAT SQL_DOUBLE 24 (a sign, 15 digits, a decimal point, the letter E, a sign, and 3
digits).
All binary types[a] The defined or maximum (for variable types) length of the
column times 2. (Each binary byte is represented by a 2-digit
hexadecimal number.)
- or -
- or -
[a] If the driver cannot determine the column or parameter length of variable types, it returns SQL_NO_TOTAL.
Elements Used in SQL Statements
12/20/2017 • 1 min to read • Edit Online
The following elements are used in the SQL statements listed previously.
Element
base-table-identifier ::= user-defined-name
base-table-name ::= base-table-identifier
boolean-factor ::= [NOT] boolean-primary
boolean-primary ::= comparison-predicate | ( search-condition )
boolean-term ::= boolean-factor [AND boolean-term]
character-string-literal ::= ''{character}...'' (character is any character in the character set of the driver/data source.
To include a single literal quote character ('') in a character-string-literal, use two literal quote characters [''''].)
column-identifier ::= user-defined-name
column-name ::= [table-name.]column-identifier
comparison-operator ::= < | > | <= | >= | = | <>
comparison-predicate ::= expression comparison-operator expression
data-type ::= character-string-type (character-string-type is any data type for which the ""DATA_TYPE"" column in
the result set returned by SQLGetTypeInfo is either SQL_CHAR or SQL_VARCHAR.)
digit ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
dynamic-parameter ::= ?
expression ::= term | expression {+|–} term
factor ::= [+|–]primary
insert-value ::=
dynamic-parameter
| literal
| NULL
| USER
letter ::= lower-case-letter | upper-case-letter
literal ::= character-string-literal
lower-case-letter ::= a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z
order-by-clause ::= ORDER BY sort-specification [, sort-specification]...
primary ::= column-name
| dynamic-parameter
| literal
| ( expression )
search-condition ::= boolean-term [OR search-condition]
select-list ::= * | select-sublist [, select-sublist]... (select-list cannot contain parameters.)
select-sublist ::= expression
sort-specification ::= {unsigned-integer | column-name} [ASC | DESC]
table-identifier ::= user-defined-name
table-name ::= table-identifier
table-reference ::= table-name
table-reference-list ::= table-reference [,table-reference]...
term ::= factor | term {*|/} factor
unsigned-integer ::= {digit}
upper-case-letter ::= A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
user-defined-name ::= letter[digit | letter | _]...
Environment Transitions
12/20/2017 • 1 min to read • Edit Online
STATE DESCRIPTION
E0 Unallocated environment
The following tables show how each ODBC function affects the environment state.
SQLAllocHandle
E0 E1 E2
[1] The SQL_ATTR_ODBC_VERSION environment attribute had been set on the environment.
[2] The SQL_ATTR_ODBC_VERSION environment attribute had not been set on the environment.
SQLEndTran
E0 E1 E2
(IH)[2] (IH) --
SQLFreeHandle
E0 E1 E2
(IH)[1] E0 (HY010)
(IH)[3] (IH) --
(IH)[1] -- --
(IH)[2] (IH) --
SQLGetEnvAttr
E0 E1 E2
(IH) --[1] --
(HY010)[2]
[1] The SQL_ATTR_ODBC_VERSION environment attribute had been set on the environment.
[2] The SQL_ATTR_ODBC_VERSION environment attribute had not been set on the environment.
SQLSetEnvAttr
E0 E1 E2
[1] The SQL_ATTR_ODBC_VERSION environment attribute had been set on the environment.
[2] The Attribute argument was not SQL_ATTR_ODBC_VERSION, and the SQL_ATTR_ODBC_VERSION environment
attribute had not been set on the environment.
(IH) (IH) --
Example SQLGetTypeInfo Result Set
12/20/2017 • 1 min to read • Edit Online
An application calls SQLGetTypeInfo to determine which data types are supported by a data source and the
characteristics of those data types. The following tables show a sample result set returned by SQLGetTypeInfo for
a data source that supports SQL_CHAR, SQL_LONGVARCHAR, SQL_DECIMAL, SQL_REAL, SQL_DATETIME,
SQL_INTERVAL_YEAR, and SQL_INTERVAL_DAY_TO_SECOND.
LITERAL_SUFFI CREATE_PARAM
TYPE_NAME DATA_TYPE COLUMN_SIZE LITERAL_PREFIX X S NULLABLE
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
After an application has fetched a block of data with SQLFetchScroll, it can update or delete the data in the block.
To execute a positioned update or delete, the application:
1. Calls SQLSetPos to position the cursor on the row to be updated or deleted.
2. Constructs a positioned update or delete statement with the following syntax:
UPDATE table-name
SET column-identifier = {expression | NULL}
[, column-identifier = {expression | NULL}]
WHERE CURRENT OF cursor-name
DELETE FROM table-name WHERE CURRENT OF cursor-name
The easiest way to construct the SET clause in a positioned update statement is to use parameter markers
for each column to be updated and use SQLBindParameter to bind these to the rowset buffers for the row
to be updated. In this case, the C data type of the parameter will be the same as the C data type of the rowset
buffer.
3. Updates the rowset buffers for the current row if it will execute a positioned update statement. After
successfully executing a positioned update statement, the cursor library copies the values from each column
in the current row to its cache.
Cau t i on
If the application does not correctly update the rowset buffers before executing a positioned update
statement, the data in the cache will be incorrect after the statement is executed.
4. Executes the positioned update or delete statement using a different statement than the statement
associated with the cursor.
Cau t i on
The WHERE clause constructed by the cursor library to identify the current row can fail to identify any rows,
identify a different row, or identify more than one row. For more information, see Constructing Searched
Statements.
All positioned update and delete statements require a cursor name. To specify the cursor name, an
application calls SQLSetCursorName before the cursor is opened. To use the cursor name generated by the
driver, an application calls SQLGetCursorName after the cursor is opened.
After the cursor library executes a positioned update or delete statement, the status array, rowset buffers,
and cache maintained by the cursor library contain the values shown in the following table.
VALUES IN VALUES IN
STATEMENT USED VALUE IN ROW STATUS ARRAY ROWSET BUFFERS CACHE BUFFERS
[1] The application must update the values in the rowset buffers before executing the positioned update statement;
after executing the positioned update statement, the cursor library copies the values in the rowset buffers to its
cache.
Explicit Data Type Conversion Function
12/20/2017 • 2 min to read • Edit Online
Explicit data type conversion is specified in terms of SQL data type definitions.
The ODBC syntax for the explicit data type conversion function does not restrict conversions. The validity of specific
conversions of one data type to another data type will be determined by each driver-specific implementation. The
driver will, as it translates the ODBC syntax into the native syntax, reject those conversions that, although legal in
the ODBC syntax, are not supported by the data source. The ODBC function SQLGetInfo, with the conversion
options (such as SQL_CONVERT_BIGINT, SQL_CONVERT_BINARY, SQL_CONVERT_INTERVAL_YEAR_MONTH, and
so on), provides a way to inquire about conversions supported by the data source.
The format of the CONVERT function is:
CONVERT( value_exp, data_type)
The function returns the value specified by value_exp converted to the specified data_type, where data_type is one
of the following keywords:
SQL_BIGINT SQL_INTERVAL_HOUR_TO_MINUTE
SQL_BINARY SQL_INTERVAL_HOUR_TO_SECOND
SQL_BIT SQL_INTERVAL_MINUTE_TO_SECOND
SQL_CHAR SQL_LONGVARBINARY
SQL_DECIMAL SQL_LONGVARCHAR
SQL_DOUBLE SQL_NUMERIC
SQL_FLOAT SQL_REAL
SQL_GUID SQL_SMALLINT
SQL_INTEGER SQL_DATE
SQL_INTERVAL_MONTH SQL_TIME
SQL_INTERVAL_YEAR SQL_TIMESTAMP
SQL_INTERVAL_YEAR_TO_MONTH SQL_TINYINT
SQL_INTERVAL_DAY SQL_VARBINARY
SQL_INTERVAL_HOUR SQL_VARCHAR
SQL_INTERVAL_MINUTE SQL_WCHAR
SQL_INTERVAL_SECOND SQL_WLONGVARCHAR
SQL_INTERVAL_DAY_TO_HOUR SQL_WVARCHAR
SQL_INTERVAL_DAY_TO_MINUTE
SQL_INTERVAL_DAY_TO_SECOND
The ODBC syntax for the explicit data type conversion function does not support specification of conversion format.
If specification of explicit formats is supported by the underlying data source, a driver must specify a default value
or implement format specification.
The argument value_exp can be a column name, the result of another scalar function, or a numeric or string literal.
For example:
If an ODBC 3.x driver should work with an ODBC 2.x application that uses fixed-length bookmarks, the driver must
support the following:
SQL_UB_ON as a value for the SQL_USE_BOOKMARKS statement option. (SQL_UB_ON is deprecated in
ODBC 3.x.)
The SQL_GET_BOOKMARK statement option.
GUID Escape Sequences
12/20/2017 • 1 min to read • Edit Online
ODBC uses escape sequences for GUID literals. The syntax of this escape sequence is as follows:
{guid 'nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn'}
Remarks
In BNF notation, the syntax is as follows:
ODBC-guid-escape ::=
ODBC-esc-initiator guid 'guid-value' ODBC-esc-terminator
ODBC-esc-initiator ::= {
ODBC-esc-terminator ::= }
guid-value ::= clock-low-value guid-separator clock-middle-value guid-separator clock-high-value guid-separator
clock-seq-value guid-separator node-value
guid-separator ::= -
clock-low-value ::= hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit
clock-middle-value ::= hex_digit hex_digit hex_digit hex_digit
clock-high-value ::= hex_digit hex_digit hex_digit hex_digit
clock-seq-value ::= hex_digit hex_digit hex_digit hex_digit
clock-node-value ::= hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit hex_digit
hex_digit hex_digit hex_digit
hex_digit ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
The GUID literal escape sequence is supported if the GUID data type is supported by the data source. An application
should call SQLGetTypeInfo to determine whether this data type is supported.
Guidelines for Interval and Numeric Data Types
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This section describes how the ODBC cursor library is implemented. It describes how the cursor library maintains
its cache, executes SQL statements, and implements ODBC functions.
This section contains the following topics.
Cursor Library Cache
Processing SQL Statements
ODBC Functions and the Cursor Library
Interval Data Type Length
12/20/2017 • 1 min to read • Edit Online
The following rules are used to determine the length of an interval data type in characters. Length is expressed in
number of characters. The number of bytes depends upon the character set. The length includes the following
values added together:
Two characters for every field in the interval that is not the leading field.
For the leading field, the number of characters that is the express or implicit leading precision. If the leading
precision is not specified, the default value is 2.
One character for the separator between the fields.
One plus the express or implied seconds precision. If the seconds precision is not specified, the default value
is 6.
Specific column length values for each interval data type are contained in Column Size.
Interval Data Type Precision
12/20/2017 • 2 min to read • Edit Online
Precision for an interval data type includes interval leading precision, interval precision, and seconds precision.
The leading field of an interval is a signed numeric. The maximum number of digits for the leading field is
determined by a quantity called interval leading precision, which is a part of the data type declaration. For example,
the declaration: INTERVAL HOUR(5) TO MINUTE has an interval leading precision of 5; the HOUR field can take
values from –99999 through 99999. The interval leading precision is contained in the
SQL_DESC_DATETIME_INTERVAL_PRECISION field of the descriptor record.
The list of fields that an interval data type is made up of is called interval precision. It is not a numeric value, as the
term "precision" might imply. For example, the interval precision of the type INTERVAL DAY TO SECOND is the list
DAY, HOUR, MINUTE, SECOND. There is no descriptor field that holds this value; the interval precision can always
be determined by the interval data type.
Any interval data type that has a SECOND field has a seconds precision. This is the number of decimal digits
allowed in the fractional part of the seconds value. This is different than for other data types, where precision
indicates the number of digits before the decimal point. The seconds precision of an interval data type is the
number of digits after the decimal point. For example, if the seconds precision is set to 6, the number 123456 in the
fraction field would be interpreted as .123456 and the number 1230 would be interpreted as .001230. For other
data types, this is referred to as scale. Interval seconds precision is contained in the SQL_DESC_PRECISION field of
the descriptor. If the precision of the fractional seconds component of the SQL interval value is greater than what
can be held in the C interval structure, it is driver-defined whether the fractional seconds value in the SQL interval is
rounded or truncated when converted to the C interval structure.
When the SQL_DESC_CONCISE_TYPE field is set to an interval data type, the SQL_DESC_TYPE field is set to
SQL_INTERVAL and the SQL_DESC_DATETIME_INTERVAL_CODE is set to the code for the interval data type. The
SQL_DESC_DATETIME_INTERVAL_PRECISION field is automatically set to the default interval leading precision of 2,
and the SQL_DESC_PRECISION field is automatically set to the default interval seconds precision of 6. If either of
these values is not appropriate, the application should explicitly set the descriptor field through a call to
SQLSetDescField.
Interval Data Types
12/20/2017 • 2 min to read • Edit Online
An interval is defined as the difference between two dates and times. Intervals are expressed in one of two different
ways. One is a year-month interval that expresses intervals in terms of years and an integral number of months.
The other is a day-time interval that expresses intervals in terms of days, minutes, and seconds. These two types of
intervals are distinct and cannot be mixed, because months can have varying numbers of days.
An interval consists of a set of fields. There is an implied ordering among the fields. For example, in a year-to-
month interval, the year comes first, followed by the month. Similarly, in a day-to-minute interval, the fields are in
the order day, hour, and minute. The first field in an interval type is called the leading field, or the high-order field.
The last field is called the trailing field.
In all intervals, the leading field is not constrained by rules of the Gregorian calendar. For example, in an hour-to-
minute interval, the hour field is not constrained to be between 0 and 23 (inclusive), as it normally is. The trailing
fields subsequent to the leading field follow the usual constraints of the Gregorian calendar. For more information,
see Constraints of the Gregorian Calendar, later in this appendix.
There are 13 interval SQL data types and 13 interval C data types. Each of the interval C data types uses the same
structure, SQL_INTERVAL_STRUCT, to contain the interval data. (For more information, see the next section, C
Interval Structure.) For more information on the SQL data types, see SQL Data Types; for more information on the
C data types, see C Data Types.
ODBC uses escape sequences for interval literals. The syntax of this escape sequence is as follows:
{interval-literal}
For the BNF syntax of interval-literal, see the Interval Literal Syntax section later in this appendix.
The interval literal escape sequence is supported if the interval data types are supported by the data source. An
application should call SQLGetTypeInfo to determine whether these data types are supported.
Interval Literal Syntax
12/20/2017 • 1 min to read • Edit Online
ODBC requires that all drivers support conversion of the SQL_CHAR or SQL_VARCHAR data type to all C interval
data types. If the underlying data source does not support interval data types, however, the driver needs to know
the correct format of the value in the SQL_CHAR field in order to support these conversions. Similarly, ODBC
requires that any ODBC C type be convertible to SQL_CHAR or SQL_VARCHAR, so a driver needs to know what
format an interval stored in the character field should have. This section describes the syntax of interval literals,
which the driver writer needs to use to validate the SQL_CHAR fields during conversion either to or from C interval
data types.
NOTE
The complete BNF syntax for interval literals is shown in the section Interval Literal Syntax in Appendix C: SQL Grammar.
To pass interval literals as part of an SQL statement, an escape clause syntax is defined for interval literals. For
more information, see Date, Time, and Timestamp Literals.
An interval literal is of the form:
where "INTERVAL" indicates that the character literal is an interval. The sign can be either plus or minus; it is
outside the interval string and is optional.
The interval qualifier can either be a single datetime field or be composed of two datetime fields, in the form:
<leading field> TO <trailing field>.
When the interval is composed of a single field, the single field can be a non-second field that may be
accompanied by an optional leading precision in parentheses. The single datetime field can also be a second
field that may be accompanied by the optional leading precision, the optional fractional-seconds precision in
parentheses, or both. If both a leading precision and a fractional-seconds precision are present for a seconds
field, they are separated by commas. If the seconds field has a fractional-seconds precision, it must also have
a leading precision.
When the interval is composed of leading and trailing fields, the leading field is a non-second field that may
be accompanied by the interval leading field precision in parentheses. The trailing field can be either a non-
second field or a second field that may be accompanied by an interval fractional-seconds precision in
parentheses.
The interval string in value is enclosed in single quotation marks. It can be either a year-month literal or a
day-time literal. The format of the string in value is determined by the following rules:
The string contains a decimal value for every field that is implied by the <interval qualifier>.
If the interval precision includes the fields YEAR and MONTH, the values of these fields are separated by a
minus sign.
If the interval precision includes the fields DAY and HOUR, the values of these fields are separated by a
space.
If the interval precision includes the field HOUR and the lower order fields (MINUTE and SECOND), the
values of these fields are separated by a colon.
If the interval precision includes a SECOND field and the expressed or implied seconds precision is nonzero,
the character immediately before the first digit of the fractional part of the second is a period.
No field can be more than two digits long, except:
The value of the leading field can be as long as the expressed or implied interval leading precision.
The fractional part of the SECOND field can be as long as the expressed or implied seconds precision.
The trailing fields follow the usual constraints of the Gregorian calendar. (See Constraints of the
Gregorian Calendar.)
The following table lists examples of valid interval literals as included in the ODBC escape clause for
intervals. The syntax of the escape clause is as follows:
NOTE
{INTERVAL sign interval-string interval-qualifier}
{INTERVAL '326' YEAR(4)} Specifies an interval of 326 years. The interval leading
precision is 4.
{INTERVAL '326' MONTH(3)} Specifies an interval of 326 months. The interval leading
precision is 3.
{INTERVAL '3261' DAY(4)} Specifies an interval of 3261 days. The interval leading
precision is 4.
{INTERVAL '163' HOUR(3)} Specifies an interval of 163 days. The interval leading precision
is 3.
{INTERVAL '163' MINUTE(3)} Specifies an interval of 163 minutes. The interval leading
precision is 3.
{INTERVAL '223.16' SECOND(3,2)} Specifies an interval of 223.16 seconds. The interval leading
precision is 3, and the seconds precision is 2.
{INTERVAL '163-11' YEAR(3) TO MONTH} Specifies an interval of 163 years and 11 months. The interval
leading precision is 3.
{INTERVAL '163 12' DAY(3) TO HOUR} Specifies an interval of 163 days and 12 hours. The interval
leading precision is 3.
{INTERVAL '163 12:39' DAY(3) TO MINUTE} Specifies an interval of 163 days, 12 hours, and 39 minutes.
The interval leading precision is 3.
{INTERVAL '163 12:39:59.163' DAY(3) TO SECOND(3)} Specifies an interval of 163 days, 12 hours, 39 minutes, and
59.163 seconds. The interval leading precision is 3, and the
seconds precision is 3.
{INTERVAL '163:39' HOUR(3) TO MINUTE} Specifies an interval of 163 hours and 39 minutes. The interval
leading precision is 3.
LITERAL ESCAPE CLAUSE INTERVAL SPECIFIED
{INTERVAL '163:39:59.163' HOUR(3) TO SECOND(4)} Specifies an interval of 163 hours, 39 minutes, and 59.163
seconds. The interval leading precision is 3, and the seconds
precision is 4.
{INTERVAL '163:59.163' MINUTE(3) TO SECOND(5)} Specifies an interval of 163 minutes and 59.163 seconds. The
interval leading precision is 3, and the seconds precision is 5.
{INTERVAL -'16 23:39:56.23' DAY TO SECOND} Specifies an interval of minus 16 days, 23 hours, 39 minutes,
and 56.23 seconds. The implied leading precision is 2, and the
implied seconds precision is 6.
{INTERVAL '163' HOUR(2)} The interval leading precision is 2, but the value of the leading
field is 163.
{INTERVAL '223.16' SECOND(2,2)} In the first example, the leading precision is too small, and in
the second example, the seconds precision is too small.
{INTERVAL '223.16' SECOND(3,1)}
{INTERVAL '163-13' YEAR(3) TO MONTH} The trailing field does not follow the rules of the Gregorian
calendar.
{INTERVAL '163 65' DAY(3) TO HOUR}
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
The cursor library creates a buffer in the cache for each length/indicator buffer bound to the result set with
SQLBindCol. It uses the values in these buffers to construct a WHERE clause when it emulates positioned update
or delete statements. It updates these buffers from the rowset buffers when it fetches data from the data source
and when it executes positioned update statements.
If the C type of a data buffer is SQL_C_CHAR or SQL_C_BINARY, and the length/indicator value is SQL_NTS, the
string length of the data is put into the length/indicator buffer.
NOTE
The cursor library does not update its cache for a column if *StrLen_or_IndPtr in the corresponding rowset buffer is
SQL_DATA_AT_EXEC or the result of the SQL_LEN_DATA_AT_EXEC macro.
LIKE Escape Sequence
12/20/2017 • 1 min to read • Edit Online
ODBC uses escape sequences for the LIKE clause. The syntax of this escape sequence is as follows:
{'escape-character'}
Remarks
In BNF notation, the syntax is as follows:
ODBC-like-escape ::=
ODBC-esc-initiator escape 'escape-character' ODBC-esc-terminator
escape-character ::= character
ODBC-esc-initiator ::= {
ODBC-esc-terminator ::= }
To determine if the driver supports the LIKE escape sequence, an application can call SQLGetInfo with the
SQL_LIKE_ESCAPE_CLAUSE information type.
Literals in ODBC
12/20/2017 • 1 min to read • Edit Online
The syntax in the following sections is used for interval and numeric literals in ODBC. This syntax is provided here
as an aid to driver writers when conversions are performed from a character string type to a numeric or interval
type, or from a numeric or interval type to a character string type. For more information, see Interval Literals and
Numeric Literals in Appendix D: Data Types.
This appendix contains the following topics.
Interval Literal Syntax
Numeric Literal Syntax
Loading by Ordinal
12/20/2017 • 1 min to read • Edit Online
In ODBC 2.x, loading by ordinal could be performed to improve the performance of the connection process. An
ODBC 2.x driver exports a dummy function with the ordinal 199; when the Driver Manager detects it, it resolves the
addresses of the ODBC functions by ordinal, not by name. This functionality is still supported for ODBC 2.x drivers
but is not supported for ODBC 3.x drivers.
Location of Cache
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
The cursor library caches data in memory and in Windows® temporary files. This limits the size of the result set
that the cursor library can handle only by available disk space. A temporary file is used when the data to be cached
would cross the segment boundary if inserted at the end of the cursor library cache. Instead, the data to be cached
is added in place of the last-saved block of data in the cache. The last-saved block of data is saved in a temporary
file. If the cursor library terminates abnormally, such as when the power fails, it can leave Windows temporary files
on the disk. These are named ~CTTnnnn.tmp and are created in the current directory.
NOTE
If the cursor library in Microsoft® WindowsNT®/Windows2000 attempts to cache data in a temporary file on the current
directory while the application is running from a read-only share or a compact disk (such as a Microsoft Foundation Class
Library sample), SQLSTATE HY000 (General Error-Unable to create a file buffer) will be returned.
Mapping Deprecated Functions
12/20/2017 • 1 min to read • Edit Online
This section describes how deprecated functions are mapped by the ODBC 3.x Driver Manager to guarantee
backward compatibility of ODBC 3.x drivers that are used with ODBC 2.x applications. The Driver Manager
performs this mapping regardless of the version of the application. Because each of the ODBC 2.x functions in the
following list is mapped to the corresponding ODBC 3.x function when called in an ODBC 3.x driver, the ODBC 3.x
driver does not have to implement the ODBC 2.x functions.
The mapping in the list is triggered when the driver is an ODBC 3.x driver and the driver does not support the
function that is being mapped.
The following table lists all duplicated functionality that was introduced in ODBC 3.x.
SQLAllocConnect SQLAllocHandle
SQLAllocEnv SQLAllocHandle
SQLAllocStmt SQLAllocHandle
SQLBindParam[1] SQLBindParameter
SQLColAttributes SQLColAttribute
SQLError SQLGetDiagRec
SQLFreeConnect SQLFreeHandle
SQLFreeEnv SQLFreeHandle
SQLGetConnectOption SQLGetConnectAttr
SQLGetStmtOption SQLGetStmtAttr
SQLParamOptions SQLSetStmtAttr
SQLSetConnectOption SQLSetConnectAttr
SQLSetParam[2] SQLBindParameter
SQLSetScrollOption SQLSetStmtAttr
SQLSetStmtOption SQLSetStmtAttr
SQLTransact SQLEndTran
[1] Even though this function did not exist in ODBC 2.x, it is in the Open Group and ISO standards.
[2] This is an ODBC 1.0 function.
This section contains the following topics.
SQLAllocConnect Mapping
SQLAllocEnv Mapping
SQLAllocStmt Mapping
SQLBindParam Mapping
SQLColAttributes Mapping
SQLError Mapping
SQLFreeConnect Mapping
SQLFreeEnv Mapping
SQLFreeStmt Mapping
SQLGetConnectOption Mapping
SQLGetStmtOption Mapping
SQLInstallTranslator Mapping
SQLParamOptions Mapping
SQLSetConnectOption Mapping
SQLSetParam Mapping
SQLSetScrollOptions Mapping
SQLSetStmtOption Mapping
SQLTransact Mapping
SQLAllocConnect Mapping
12/20/2017 • 1 min to read • Edit Online
When an application calls SQLAllocConnect through an ODBC 3.x driver, the call to SQLAllocConnect(henv,
phdbc) is mapped to SQLAllocHandle as follows:
1. The Driver Manager allocates a connection and returns it to the application.
2. When the application establishes a connection, the Driver Manager calls
in the driver with InputHandle set to henv, and OutputHandlePtr set to phdbc.
SQLAllocEnv Mapping
12/20/2017 • 1 min to read • Edit Online
When an application calls SQLAllocEnv through an ODBC 3.x driver, the call to SQLAllocEnv(phenv) is mapped to
SQLAllocHandle as follows:
1. The Driver Manager allocates an environment handle and returns it to the application. The Driver Manager
calls SQLSetEnvAttr to set the SQL_ATTR_ODBC_VERSION environment attribute to SQL_OV_ODBC2.
2. When the application establishes the first connection to a driver, the Driver Manager calls
When an application calls SQLAllocStmt through an ODBC 3.x driver, the call to:
SQLAllocStmt(hdbc, phstmt)
SQLBindParam cannot truly be called deprecated because it was never there in ODBC; however, it still represents
duplicated functionality — the Driver Manager needs to export it because ISO and Open Group–compliant
applications will be using it. Because SQLBindParameter contains all the functionality of SQLBindParam,
SQLBindParam will be mapped on top of SQLBindParameter (when the underlying driver is an ODBC 3.x driver).
An ODBC 3.x driver does not need to implement SQLBindParam.
Remarks
When the following call to SQLBindParam is made:
See ODBC 64-Bit Information, if your application will run on a 64-bit operating system.
See Also
Mapping Deprecated Functions
SQLColAttributes Mapping
12/20/2017 • 1 min to read • Edit Online
When an application calls SQLColAttributes through an ODBC 3.x driver, the call to SQLColAttributes is mapped
to SQLColAttribute as follows:
NOTE
The prefix used in FieldIdentifier values in ODBC 3.x has been changed from that used in ODBC 2.x. The new prefix is
"SQL_DESC"; the old prefix was "SQL_COLUMN".
1. If the application is an ODBC 2.x application, fDescType is SQL_COLUMN_TYPE, and the returned type is a
concise DATETIME type, the Driver Manager maps the return values for date, time, and timestamp codes.
2. If fDescType is SQL_COLUMN_NAME, SQL_COLUMN_NULLABLE, or SQL_COLUMN_COUNT, the Driver
Manager calls SQLColAttribute in the driver with the FieldIdentifier argument mapped to
SQL_DESC_NAME, SQL_DESC_NULLABLE, or SQL_DESC_COUNT, as appropriate. All other values of
fDescType are passed through to the driver.
An ODBC 3.x driver must support all the ODBC 3.x FieldIdentifiers listed for SQLColAttribute.
An ODBC 3.x driver must support SQL_COLUMN_PRECISION and SQL_DESC_PRECISION,
SQL_COLUMN_SCALE and SQL_DESC_SCALE, and SQL_COLUMN_LENGTH and SQL_DESC_LENGTH. These
values are different because precision, scale, and length are defined differently in ODBC 3.x than they were
in ODBC 2.x. For more information, see Column Size, Decimal Digits, Transfer Octet Length, and Display Size
in Appendix D: Data Types.
SQLError Mapping
12/20/2017 • 1 min to read • Edit Online
When an application calls SQLError through an ODBC 3.x driver, the call to
is mapped to
with the HandleType argument set to the value SQL_HANDLE_ENV, SQL_HANDLE_DBC, or SQL_HANDLE_STMT, as
appropriate, and the Handle argument set to the value in henv, hdbc, or hstmt, as appropriate. The RecNumber
argument is determined by the Driver Manager.
SQLFreeConnect Mapping
12/20/2017 • 1 min to read • Edit Online
When an application calls SQLFreeConnect through an ODBC 3.x driver, the call to
SQLFreeConnect(hdbc)
is mapped to
SQLFreeHandle(SQL_HANDLE_DBC,Handle)
When an application calls SQLFreeEnv through an ODBC 3.x driver, the call to
SQLFreeEnv(henv)
is mapped to
SQLFreeHandle(SQL_HANDLE_ENV,Handle)
When an application calls SQLFreeStmt with an Option argument of SQL_DROP through an ODBC 3.x driver, the
call to
SQLFreeStmt(hstmt, SQL_DROP)
is mapped to
SQLFreeHandle(SQL_HANDLE_STMT,Handle)
When an application calls SQLGetConnectOption through an ODBC 3.x driver, the call to
is mapped as follows:
If fOption indicates an ODBC-defined connection option that returns a string, the Driver Manager calls
If fOption indicates an ODBC-defined connection option that returns a 32-bit integer value, the Driver
Manager calls
In the preceding three cases, the ConnectionHandle argument is set to the value in hdbc, the Attribute
argument is set to the value in fOption, and the ValuePtr argument is set to the same value as pvParam.
For ODBC-defined string connection options, the Driver Manager sets the BufferLength argument in the call
to SQLGetConnectAttr to the predefined maximum length (SQL_MAX_OPTION_STRING_LENGTH); for a
nonstring connection option, BufferLength is set to 0.
For an ODBC 3.x driver, the Driver Manager no longer checks to see if Option is in between
SQL_CONN_OPT_MIN and SQL_CONN_OPT_MAX, or is greater than SQL_CONNECT_OPT_DRVR_START.
The driver must check the validity of the option values.
SQLGetStmtOption Mapping
12/20/2017 • 1 min to read • Edit Online
When an application calls SQLGetStmtOption to an ODBC 3.x driver that does not support it, the call to
If fOption indicates an ODBC-defined statement option that returns a 32-bit integer value, the Driver
Manager calls
In the preceding three cases, the StatementHandle argument is set to the value in hstmt, the Attribute
argument is set to the value in fOption, and the ValuePtr argument is set to the same value as pvParam.
For ODBC-defined string connection options, the Driver Manager sets the BufferLength argument in the call
to SQLGetConnectAttr to the predefined maximum length (SQL_MAX_OPTION_STRING_LENGTH); for a
nonstring connection option, BufferLength is set to 0.
The SQL_GET_BOOKMARK statement option has been deprecated in ODBC 3.x. For an ODBC 3.x driver to
work with ODBC 2.x applications that use SQL_GET_BOOKMARK, it must support SQL_GET_BOOKMARK. For
an ODBC 3.x driver to work with ODBC 2.x applications, it must support setting SQL_USE_BOOKMARKS to
SQL_UB_ON and should expose fixed-length bookmarks. If an ODBC 3.x driver supports only variable-length
bookmarks, not fixed-length bookmarks, it must return SQLSTATE HYC00 (Optional feature not
implemented) if an ODBC 2.x application attempts to set SQL_USE_BOOKMARKS to SQL_UB_ON.
For an ODBC 3.x driver, the Driver Manager no longer checks to see whether Option is in between
SQL_STMT_OPT_MIN and SQL_STMT_OPT_MAX, or is greater than SQL_CONNECT_OPT_DRVR_START. The
driver must check this.
SQLInstallTranslator Mapping
12/20/2017 • 1 min to read • Edit Online
When an ODBC 2.x application calls SQLInstallTranslator through an ODBC 3.x driver, the Driver Manager maps
the call to SQLInstallTranslatorEx.An application should not call SQLInstallTranslator in the ODBC 3.x Driver
Manager with the lpszInfFile argument set to a value other than NULL. The ODBC.INF file used in ODBC 2.x is no
longer supported in ODBC 3.x, even for backward compatibility.
SQLParamOptions Mapping
12/20/2017 • 1 min to read • Edit Online
When an application calls SQLParamOptions through an ODBC 3.x driver, the call
When an ODBC 2.x application calls SQLSetConnectOption through an ODBC 3.x driver, the call to
If fOption indicates an ODBC-defined connection attribute that returns a 32-bit integer value, the Driver
Manager calls
In the preceding three cases, the ConnectionHandle argument is set to the value in hdbc, the Attribute
argument is set to the value in fOption, and the ValuePtr argument is set to the same value as vParam.
Because the Driver Manager does not know whether the driver-defined connection attribute needs a string
or 32-bit integer value, it has to pass in a valid value for the BufferLength argument of SQLSetConnectAttr.
If the driver has defined special semantics for driver-defined connect attributes and needs to be called using
SQLSetConnectOption, it must support SQLSetConnectOption.
If an ODBC 2.x application calls SQLSetConnectOption to set a driver-specific statement option in an ODBC
3.x driver, and the option was defined in an ODBC 2.x version of the driver, a new manifest constant should
be defined for the option in the ODBC 3.x driver. If the old manifest constant is used in the call to
SQLSetConnectOption, the Driver Manager will call SQLSetConnectAttr with the StringLength
argument set to 0.
For an ODBC 3.x driver, the Driver Manager no longer checks to see if fOption is in between
SQL_CONN_OPT_MIN and SQL_CONN_OPT_MAX, or is greater than SQL_CONNECT_OPT_DRVR_START.
When an application calls SQLSetScrollOptions through an ODBC 3.x driver and the driver does not support
SQLSetScrollOptions, the call to
with the InfoType argument set to one of the values in the following table, depending on the value of the
KeysetSize argument in SQLSetScrollOptions.
SQL_SCROLL_FORWARD_ONLY SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2
SQL_SCROLL_STATIC SQL_STATIC_CURSOR_ATTRIBUTES2
SQL_SCROLL_KEYSET_DRIVEN SQL_KEYSET_CURSOR_ATTRIBUTES2
SQL_SCROLL_DYNAMIC SQL_DYNAMIC_CURSOR_ATTRIBUTES2
If the value of the KeysetSize argument is not listed in the preceding table, the call to SQLSetScrollOptions
returns SQLSTATE S1107 (Row value out of range) and none of the following steps are performed.
The Driver Manager then verifies whether the appropriate bit is set in the InfoValuePtr* value returned
by the call to **SQLGetInfo, according to the value of the Concurrency argument in
SQLSetScrollOptions.
SQL_CONCUR_READ_ONLY SQL_CA2_READ_ONLY_CONCURRENCY
SQL_CONCUR_LOCK SQL_CA2_LOCK_CONCURRENCY
SQL_CONCUR_ROWVER SQL_CA2_ROWVER_CONCURRENCY
SQL_CONCUR_VALUES SQL_CA2_VALUES_CONCURRENCY
If the Concurrency argument is not one of the values in the preceding table, the call to
SQLSetScrollOptions returns SQLSTATE S1108 (Concurrency option out of range) and none of the
following steps are performed. If the appropriate bit (as indicated in the preceding table) is not set in
InfoValuePtr* to one of the values corresponding to the Concurrency argument, the call to
**SQLSetScrollOptions returns SQLSTATE S1C00 (Driver not capable) and none of the following steps are
performed.
A call to
with *ValuePtr set to one of the values in the following table, according to the value of the KeysetSize
argument in SQLSetScrollOptions.
SQL_SCROLL_FORWARD_ONLY SQL_CURSOR_FORWARD_ONLY
SQL_SCROLL_STATIC SQL_CURSOR_STATIC
SQL_SCROLL_KEYSET_DRIVEN SQL_CURSOR_KEYSET_DRIVEN
SQL_SCROLL_DYNAMIC SQL_CURSOR_DYNAMIC
A call to
NOTE
When the Driver Manager maps SQLSetScrollOptions for an application working with an ODBC 3.x driver that does
not support SQLSetScrollOptions, the Driver Manager sets the SQL_ROWSET_SIZE statement option, not the
SQL_ATTR_ROW_ARRAY_SIZE statement attribute, to the RowsetSize argument in SQLSetScrollOption. As a result,
SQLSetScrollOptions cannot be used by an application when fetching multiple rows by a call to SQLFetch or
SQLFetchScroll. It can be used only when fetching multiple rows by a call to SQLExtendedFetch.
SQLSetStmtOption Mapping
12/20/2017 • 1 min to read • Edit Online
When an application calls SQLSetStmtOption through an ODBC 3.x driver, the call to
If fOption indicates an ODBC-defined statement attribute that returns a 32-bit integer value, the Driver
Manager calls
In the preceding three cases, the StatementHandle argument is set to the value in hstmt, the Attribute
argument is set to the value in fOption, and the ValuePtr argument is set to the value as vParam.
Because the Driver Manager does not know whether the driver-defined statement attribute needs a string or
32-bit integer value, it has to pass in a valid value for the StringLength argument of SQLSetStmtAttr. If the
driver has defined special semantics for driver-defined statement attributes and needs to be called using
SQLSetStmtOption, it must support SQLSetStmtOption.
If an application calls SQLSetStmtOption to set a driver-specific statement option in an ODBC 3.x driver
and the option was defined in an ODBC 2.x version of the driver, a new manifest constant should be defined
for the option in the ODBC 3.x driver. If the old manifest constant is used in the call to SQLSetStmtOption,
the Driver Manager will call SQLSetStmtAttr with the StringLength argument set to 0.
When an application calls SQLSetStmtAttr to set SQL_ATTR_USE_BOOKMARKS to SQL_UB_ON in an ODBC
3.x driver, the SQL_ATTR_USE_BOOKMARKS statement attribute is set to SQL_UB_FIXED. SQL_UB_ON is the
same constant as SQL_UB_FIXED. The Driver Manager passes SQL_UB_FIXED through to the driver.
SQL_UB_FIXED has been deprecated in ODBC 3.x, but an ODBC 3.x driver must implement it to work with
ODBC 2.x applications that use fixed-length bookmarks.
For an ODBC 3.x driver, the Driver Manager no longer checks to see if Option is in between
SQL_STMT_OPT_MIN and SQL_STMT_OPT_MAX, or is greater than SQL_CONNECT_OPT_DRVR_START.
SQLTransact Mapping
12/20/2017 • 1 min to read • Edit Online
SQLTransact is now replaced by SQLEndTran. The major difference between the two functions is that
SQLEndTran contains an argument HandleType, which specifies the scope of the work to be done. The HandleType
argument can specify the environment or the connection handle. The following call to SQLTransact:
is mapped to
if ConnectionHandle is not equal to SQL_NULL_HDBC. The ConnectionHandle argument is set to the value of hdbc.
SQL_Transact is mapped to
if ConnectionHandle is equal to SQL_NULL_HDBC. The EnvironmentHandle argument is set to the value of henv.
In both of the preceding cases, the CompletionType argument is set to the same value as fType.
Numeric Functions
12/20/2017 • 3 min to read • Edit Online
The following table describes numeric functions that are included in the ODBC scalar function set. By calling
SQLGetInfo with an information type of SQL_NUMERIC_FUNCTIONS, an application can determine which numeric
functions are supported by a driver.
All numeric functions return values of data type SQL_FLOAT except for ABS, ROUND, TRUNCATE, SIGN, FLOOR,
and CEILING, which return values of the same data type as the input parameters.
Arguments denoted as numeric_exp can be the name of a column, the result of another scalar function, or a
numeric-literal, where the underlying data type could be represented as SQL_NUMERIC, SQL_DECIMAL,
SQL_TINYINT, SQL_SMALLINT, SQL_INTEGER, SQL_BIGINT, SQL_FLOAT, SQL_REAL, or SQL_DOUBLE.
Arguments denoted as float_exp can be the name of a column, the result of another scalar function, or a numeric-
literal, where the underlying data type can be represented as SQL_FLOAT.
Arguments denoted as integer_exp can be the name of a column, the result of another scalar function, or a
numeric-literal, where the underlying data type can be represented as SQL_TINYINT, SQL_SMALLINT,
SQL_INTEGER, or SQL_BIGINT.
The CURRENT_DATE, CURRENT_TIME, and CURRENT_TIMESTAMP scalar functions have been added in ODBC 3.0
to align with SQL-92.
FUNCTION DESCRIPTION
ACOS( float_exp ) (ODBC 1.0) Returns the arccosine of float_exp as an angle, expressed in
radians.
ASIN( float_exp ) (ODBC 1.0) Returns the arcsine of float_exp as an angle, expressed in
radians.
ATAN( float_exp ) (ODBC 1.0) Returns the arctangent of float_exp as an angle, expressed in
radians.
ATAN2( float_exp1, float_exp2) (ODBC 2.0) Returns the arctangent of the x and y coordinates, specified by
float_exp1 and float_exp2, respectively, as an angle, expressed
in radians.
CEILING( numeric_exp ) (ODBC 1.0) Returns the smallest integer greater than or equal to
numeric_exp. The return value is of the same data type as the
input parameter.
COS( float_exp ) (ODBC 1.0) Returns the cosine of float_exp, where float_exp is an angle
expressed in radians.
COT( float_exp ) (ODBC 1.0) Returns the cotangent of float_exp, where float_exp is an
angle expressed in radians.
DEGREES( numeric_exp ) (ODBC 2.0) Returns the number of degrees converted from numeric_exp
radians.
FUNCTION DESCRIPTION
FLOOR( numeric_exp ) (ODBC 1.0) Returns the largest integer less than or equal to numeric_exp.
The return value is of the same data type as the input
parameter.
MOD( integer_exp1, integer_exp2) (ODBC 1.0) Returns the remainder (modulus) of integer_exp1 divided by
integer_exp2.
POWER( numeric_exp, integer_exp) (ODBC 2.0) Returns the value of numeric_exp to the power of integer_exp.
RADIANS( numeric_exp ) (ODBC 2.0) Returns the number of radians converted from numeric_exp
degrees.
ROUND( numeric_exp, integer_exp) (ODBC 2.0) Returns numeric_exp rounded to integer_exp places right of
the decimal point. If integer_exp is negative, numeric_exp is
rounded to |integer_exp| places to the left of the decimal
point.
SIN( float_exp ) (ODBC 1.0) Returns the sine of float_exp, where float_exp is an angle
expressed in radians.
TAN( float_exp ) (ODBC 1.0) Returns the tangent of float_exp, where float_exp is an angle
expressed in radians.
TRUNCATE( numeric_exp, integer_exp) (ODBC 2.0) Returns numeric_exp truncated to integer_exp places right of
the decimal point. If integer_exp is negative, numeric_exp is
truncated to |integer_exp| places to the left of the decimal
point.
Numeric Literal Syntax
12/20/2017 • 1 min to read • Edit Online
Numeric literals are used when numeric data values are stored in character strings. For conversion of numeric SQL
data to an SQL_C_CHAR string, or conversion of numeric C data to an SQL_CHAR or SQL_VARCHAR string,
numeric literal syntax is used to specify what is stored in the target. For conversion of a numeric stored as a
SQL_C_CHAR string to numeric SQL data, or a numeric stored as a SQL_CHAR string to numeric C data, this syntax
is used to validate what is stored in the source.
Numeric literals should conform to the syntax defined in the section Numeric Literal Syntax in Appendix C: SQL
Grammar.
This section contains the following topics.
Rules for Conversions
Overriding Default Precision and Scale for Numeric Data Types
ODBC Escape Sequences
12/20/2017 • 1 min to read • Edit Online
The following escape sequences are used in ODBC. The grammar in this section uses some elements defined in
Elements Used in SQL Statements.
This section contains the following topics.
Date, Time, and Timestamp Escape Sequences
GUID Escape Sequences
Interval Escape Sequences
LIKE Escape Sequence
Outer Join Escape Sequence
Procedure Call Escape Sequence
Scalar Function Escape Sequence
ODBC Functions and the Cursor Library
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
When the ODBC cursor library is enabled for a connection, the Driver Manager calls functions in the cursor library
instead of in the driver. The cursor library either executes the function or calls it in the specified driver.
This section contains the following topics.
ODBC Functions Executed by the Cursor Library
ODBC Functions Not Executed by the Cursor Library
SQLBindCol (Cursor Library)
SQLBindParameter (Cursor Library)
SQLBulkOperations (Cursor Library)
SQLCloseCursor (Cursor Library)
SQLEndTran (Cursor Library)
SQLExtendedFetch (Cursor Library)
SQLFetch (Cursor Library)
SQLFetchScroll (Cursor Library)
SQLFreeStmt (Cursor Library)
SQLGetData (Cursor Library)
SQLGetDescField and SQLGetDescRec (Cursor Library)
SQLGetFunctions (Cursor Library)
SQLGetInfo (Cursor Library)
SQLGetStmtAttr (Cursor Library)
SQLGetStmtOption (Cursor Library)
SQLNativeSql (Cursor Library)
SQLRowCount (Cursor Library)
SQLSetConnectAttr (Cursor Library)
SQLSetDescField and SQLSetDescRec (Cursor Library)
SQLSetEnvAttr (Cursor Library)
SQLSetPos (Cursor Library)
SQLSetScrollOptions (Cursor Library)
SQLSetStmtAttr (Cursor Library)
ODBC Functions Executed by the Cursor Library
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
The cursor library executes the following functions. When an application calls a function in this list, the Driver
Manager invokes the cursor library, not the driver. Note that the cursor library may call the driver when executing
the function.
SQLBindCol SQLGetStmtOption
SQLBindParam SQLNativeSql
SQLBindParameter SQLNumParams
SQLCloseCursor SQLParamOptions
SQLEndTran SQLRowCount
SQLExtendedFetch SQLSetConnectAttr
SQLFetchScroll SQLSetConnectOption
SQLFreeHandle SQLSetDescField
SQLFreeStmt SQLSetDescRec
SQLGetData SQLSetPos
SQLGetDescField SQLSetScrollOptions
SQLGetDescRec SQLSetStmtAttr
SQLGetFunctions SQLSetStmtOption
SQLGetInfo SQLTransact
SQLGetStmtAttr
ODBC Functions Not Executed by the Cursor Library
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
The cursor library does not execute the following functions. When an application calls one of these functions, the
Driver Manager invokes the driver, not the cursor library.
SQLFetch SQLGetEnvAttr
SQLGetConnectAttr SQLSetDescRec
SQLGetDiagField SQLSetEnvAttr
SQLGetDiagRec
SQLBindCol (Cursor Library)
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLBindCol function in the cursor library. For general information about
SQLBindCol, see SQLBindCol Function.
An application allocates one or more buffers for the cursor library to return the current rowset in. It calls
SQLBindCol one or more times to bind these buffers to the result set.
An application can call SQLBindCol to rebind result set columns after it has called SQLExtendedFetch, SQLFetch,
or SQLFetchScroll,as long as the C data type, column size, and decimal digits of the bound column remain the
same. The application need not close the cursor to rebind columns to different addresses.
The cursor library supports setting the SQL_ATTR_ROW_BIND_OFFSET_PTR statement attribute to use bind offsets.
(SQLBindCol does not have to be called for this rebinding to occur.) If the cursor library is used with an ODBC 3.x
driver, the bind offset is not used when SQLFetch is called. The bind offset is used if SQLFetch is called when the
cursor library is used with an ODBC 2.x driver because SQLFetch is then mapped to SQLExtendedFetch.
The cursor library supports calling SQLBindCol to bind the bookmark column.
When working with an ODBC 2.x driver, the cursor library returns SQLSTATE HY090 (Invalid string or buffer length)
when SQLBindCol is called to set the buffer length for a bookmark column to a value not equal to 4. When
working with an ODBC 3.x driver, the cursor library allows the buffer to be any size.
SQLBindParameter (Cursor Library)
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLBindParameter function in the cursor library. For general information
about SQLBindParameter, see SQLBindParameter Function.
An application can call SQLBindParameter to rebind parameters, as long as the C data type, column size, and
decimal digits of the bound column remain the same.
The cursor library supports setting the SQL_ATTR_ROW_BIND_OFFSET_PTR statement attribute to use bind offsets.
(SQLBindParameter does not have to be called for this rebinding to occur.)
The cursor library supports binding data-at-execution parameters.
SQLBulkOperations and the Cursor Library
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
The cursor library does not support calling SQLBulkOperations. For general information about
SQLBulkOperations, see SQLBulkOperations Function.
SQLCloseCursor_ODBC
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLCloseCursor function in the cursor library. For general information about
SQLCloseCursor, see SQLCloseCursor Function.
The cursor library does not support calling SQLCloseCursor without an open cursor. Attempting this will return
SQLSTATE 24000 (Invalid cursor state). Calling SQLFreeStmt with an Option of SQL_CLOSE when no cursor is
open is supported by the cursor library.
SQLEndTran (Cursor Library)
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLEndTran function in the cursor library. For general information about
SQLEndTran, see SQLEndTran Function.
The cursor library does not support transactions and passes calls to SQLEndTran directly to the driver. However,
the cursor library does support the cursor commit and rollback behaviors as returned by the data source with the
SQL_CURSOR_ROLLBACK_BEHAVIOR and SQL_CURSOR_COMMIT_BEHAVIOR information types:
For data sources that preserve cursors across transactions, changes that are rolled back in the data source
are not rolled back in the cursor library's cache. To make the cache match the data in the data source, the
application must close and reopen the cursor.
For data sources that close cursors at transaction boundaries, the cursor library closes the cursors and
deletes the caches for all statements on the connection.
For data sources that delete prepared statements at transaction boundaries, the application must reprepare
all prepared statements on the connection before reexecuting them.
SQLExtendedFetch (Cursor Library)
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLExtendedFetch function in the cursor library. For general information
about SQLExtendedFetch, see SQLExtendedFetch Function.
The cursor library implements SQLExtendedFetch by repeatedly calling SQLFetch in the driver.
The cursor library supports calling SQLExtendedFetch with a FetchOrientation of SQL_FETCH_BOOKMARK.
When the cursor library is used, calls to SQLExtendedFetch cannot be mixed with calls to either SQLFetchScroll
or SQLFetch.
SQLFetch (Cursor Library)
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLFetch function in the cursor library. For general information about
SQLFetch, see SQLFetch Function.
When the cursor library is used, calls to SQLFetch cannot be mixed with calls to either SQLFetchScroll or
SQLExtendedFetch.
If SQLFetch is called with SQL_ATTR_ROW_ARRAY_SIZE set to a value greater than 1, the cursor library will pass
the call to the driver. If the driver is an ODBC 2.x driver, the rowset size will be ignored and the call to SQLFetch will
return a single row of data.
If the cursor library is used with an ODBC 2.x driver, a bind offset (as defined by the
SQL_ATTR_ROW_BIND_OFFSET_PTR statement attribute) is not used when SQLFetch is called.
When the cursor library is loaded, an application cannot call SQLFetch to fetch bookmark columns. The cursor
library passes the call to SQLFetch through to the driver, but the function calls to enable bookmarks and bind the
bookmark column are intercepted by the cursor library.
SQLFetchScroll (Cursor Library)
12/20/2017 • 5 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLFetchScroll function in the cursor library. For general information about
SQLFetchScroll, see SQLFetchScroll Function.
The cursor library implements SQLFetchScroll by repeatedly calling SQLFetch in the driver. It transfers the data it
retrieves from the driver to the rowset buffers provided by the application. It also caches the data in memory and
disk files. When an application requests a new rowset, the cursor library retrieves it as necessary from the driver (if
it has not been previously fetched) or the cache (if it has been previously fetched). Finally, the cursor library
maintains the status of the cached data and returns this information to the application in the row status array.
When the cursor library is used, calls to SQLFetchScroll cannot be mixed with calls to either SQLFetch or
SQLExtendedFetch.
When the cursor library is used, calls to SQLFetchScroll are supported both for ODBC 2.x and for ODBC 3.x
drivers.
Rowset Buffers
The cursor library optimizes the transfer of data from the driver to the rowset buffer provided by the application if:
The application uses row-wise binding.
There are no unused bytes between fields in the structure the application declares to hold a row of data.
The fields in which SQLFetch or SQLFetchScroll returns the length/indicator for a column follows the
buffer for that column and precedes the buffer for the next column. These fields are optional.
When the application requests a new rowset, the cursor library retrieves data from its cache and from the
driver as necessary. If the new and old rowsets overlap, the cursor library can optimize its performance by
reusing the data from the overlapping sections of the rowset buffers. Therefore, unsaved changes to the
rowset buffers are lost unless the new and old rowsets overlap and the changes are in the overlapping
sections of the rowset buffers. To save the changes, an application submits a positioned update statement.
Note that the cursor library always refreshes the rowset buffers with data from the cache when an
application calls SQLFetchScroll with the FetchOrientation argument set to SQL_FETCH_RELATIVE and the
FetchOffset argument set to 0.
The cursor library supports calling SQLSetStmtAttr with an Attribute of SQL_ATTR_ROW_ARRAY_SIZE to
change the rowset size while a cursor is open. The new rowset size will take effect the next time
SQLFetchScroll is called.
Scrolling
The cursor library supports the following fetch types in SQLFetchScroll.
Forward-only SQL_FETCH_NEXT
Static SQL_FETCH_NEXT
SQL_FETCH_PRIOR
SQL_FETCH_FIRST
SQL_FETCH_LAST
SQL_FETCH_RELATIVE
SQL_FETCH_ABSOLUTE
SQL_FETCH_BOOKMARK
Errors
When SQLFetchScroll is called and one of the calls to SQLFetch returns SQL_ERROR, the cursor library proceeds
as follows. After it completes these steps, the cursor library continues processing.
1. Calls SQLGetDiagRec to obtain error information from the driver and posts this as a diagnostic record in
the Driver Manager.
2. Sets the SQL_DIAG_ROW_NUMBER field in the diagnostic record to the appropriate value.
3. Sets the SQL_DIAG_COLUMN_NUMBER field in the diagnostic record to the appropriate value, if applicable;
otherwise, it sets it to 0.
4. Sets the value for the row in error in the row status array to SQL_ROW_ERROR.
After the cursor library has called SQLFetch multiple times in its implementation of SQLFetchScroll, any
error or warning returned by one of the calls to SQLFetch will be in a diagnostic record and can be retrieved
by a call to SQLGetDiagRec. If the data was truncated when it was fetched, the truncated data will now
reside in the cursor library's cache. Subsequent calls to SQLFetchScroll to scroll to a row with truncated
data will return the truncated data, and no warning will be raised because the data is fetched from the cursor
library's cache. To keep track of the length of data returned so that it can determine whether the data
returned in a buffer has been truncated, an application should bind the length/indicator buffer.
Bookmark Operations
The cursor library supports calling SQLFetchScroll with a FetchOrientation of SQL_FETCH_BOOKMARK. It also
supports specifying an offset in the FetchOffset argument that can be used in the bookmark operation. This is the
only bookmark operation the cursor library supports. The cursor library does not support calling
SQLBulkOperations.
If the application has set the SQL_ATTR_USE_BOOKMARKS statement attribute and has bound to the bookmark
column, the cursor library generates a fixed-length bookmark and returns it to the application. The cursor library
creates and maintains the bookmarks that it uses; it does not use bookmarks maintained at the data source. When
SQLFetchScroll is called to retrieve a block of data that has already been fetched from the data source, it retrieves
the data from the cursor library cache. As a result, the bookmark used in a call to SQLFetchScroll with a
FetchOrientation of SQL_FETCH_BOOKMARK must be created and maintained by the cursor library.
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLFreeStmt function in the cursor library. For general information about
SQLFreeStmt, see SQLFreeStmt Function.
If an application calls SQLFreeStmt with the SQL_UNBIND option after it calls SQLExtendedFetch, SQLFetch, or
SQLFetchScroll, the cursor library returns an error. Before it can unbind result set columns, an application must
call SQLCloseCursor or SQLFreeStmt with the SQL_CLOSE option.
SQLGetData (Cursor Library)
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLGetData function in the cursor library. For general information about
SQLGetData, see SQLGetData Function.
The cursor library implements SQLGetData by first constructing a SELECT statement with a WHERE clause that
enumerates the values stored in its cache for each bound column in the current row. It then executes the SELECT
statement to reselect the row and calls SQLGetData in the driver to retrieve the data from the data source (as
opposed to the cache).
Cau t i on
The WHERE clause constructed by the cursor library to identify the current row can fail to identify any rows,
identify a different row, or identify more than one row. For more information, see Constructing Searched
Statements.
If the SQL_ATTR_USE_BOOKMARKS statement attribute is set to SQL_UB_VARIABLE, SQLGetData can be called on
column 0 to return bookmark data.
Calls to SQLGetData are subject to the following restrictions:
SQLGetData cannot be called for forward-only cursors.
SQLGetData can be called only when the following conditions are met: a SELECT statement generated the
result set; the SELECT statement did not contain a join, a UNION clause, or a GROUP BY clause; and any
columns that used an alias or expression in the select list were not bound with SQLBindCol.
If the driver supports only one active statement, the cursor library fetches the rest of the result set before
executing the SELECT statement and calling SQLGetData.
SQLGetDescField and SQLGetDescRec (Cursor
Library)
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLGetDescField and SQLGetDescRec functions in the cursor library. For
general information about these functions, see SQLGetDescField Function and SQLGetDescRec Function.
The cursor library executes SQLGetDescRec to return metadata for bookmark columns. The cursor library executes
SQLGetDescField to return the same fields returned by SQLGetDescRec, which are SQL_DESC_NAME,
SQL_DESC_TYPE, SQL_DESC_DATETIME_INTERVAL_CODE, SQL_DESC_OCTET_LENGTH, SQL_DESC_PRECISION,
SQL_DESC_SCALE, and SQL_DESC_NULLABLE. For consistency, SQLGetDescField also returns
SQL_DESC_UNNAMED.
The cursor library executes SQLGetDescField when it is called to return the value of the following fields that are
set for binding bookmark columns: SQL_DESC_DATA_PTR, SQL_DESC_INDICATOR_PTR,
SQL_DESC_OCTET_LENGTH_PTR, and SQL_DESC_LENGTH.
The cursor library executes SQLGetDescField when it is called to return the value of the
SQL_DESC_BIND_OFFSET_PTR, SQL_DESC_BIND_TYPE, SQL_DESC_ROW_ARRAY_SIZE, or
SQL_DESC_ROW_STATUS_PTR field. These fields can be returned for any row, not just the bookmark row.
If an application calls SQLGetDescField to return the value of any field other than those mentioned previously, the
cursor library passes the call to the driver.
SQLGetFunctions (Cursor Library)
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLGetFunctions function in the cursor library. For general information about
SQLGetFunctions, see SQLGetFunctions Function.
When you call SQLGetFunctions, the cursor library returns that it supports SQLExtendedFetch, SQLFetchScroll,
SQLSetPos, and SQLSetScrollOptions, in addition to the functions supported by the driver.
SQLGetInfo (Cursor Library)
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLGetInfo function in the cursor library. For general information about
SQLGetInfo, see SQLGetInfo Function.
The cursor library returns values for the following values of InfoType (| represents a bitwise OR); for all other values
of InfoType, it calls SQLGetInfo in the driver.
SQL_BOOKMARK_PERSISTENCE SQL_BP_SCROLL
SQL_DYNAMIC_CURSOR_ATTRIBUTES1 0
SQL_DYNAMIC_CURSOR_ATTRIBUTES2 0
SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 SQL_CA2_READ_ONLY_CONCUR |
SQL_CA2_OPT_VALUES_CONCURRENCY |
SQL_CA2_SENSITIVITY_UPDATES
SQL_KEYSET_DRIVEN_CURSOR_ATTRIBUTES1 0
SQL_KEYSET_DRIVEN_CURSOR_ATTRIBUTES2 0
SQL_LOCK_TYPES[1] SQL_LCK_NO_CHANGE
INFOTYPE RETURNED VALUE
SQL_POS_OPERATIONS[1] SQL_POS_POSITION
SQL_ROW_UPDATES "Y"
SQL_STATIC_SENSITIVITY[1] SQL_SS_UPDATES
[1] Used only when the cursor library is used with an ODBC 2.x driver.
IMPORTANT
The cursor library implements the same cursor behavior when transactions are committed or rolled back as the data source.
That is, committing or rolling back a transaction, either by calling SQLEndTran or by using the SQL_ATTR_AUTOCOMMIT
connection attribute, can cause the data source to delete the access plans and close the cursors for all statements on a
connection. For more information, see the SQL_CURSOR_COMMIT_BEHAVIOR and SQL_CURSOR_ROLLBACK_BEHAVIOR
information types in SQLGetInfo.
SQLGetInfo Support
12/20/2017 • 3 min to read • Edit Online
When an ODBC 2.x application calls SQLGetInfo to an ODBC 3.x driver, the InfoType arguments in the following
table must be supported.
INFOTYPE RETURNS
SQL_ALTER_TABLE (ODBC 2.0) Note: This information type is An SQLINTEGER bitmask enumerating the clauses in the
not deprecated; the bitmasks in the column to the right are ALTER TABLE statement supported by the data source.
deprecated.
The following bitmasks are used to determine which clauses
are supported:
SQL_LCK_NO_CHANGE SQL_LCK_EXCLUSIVE
SQL_LCK_UNLOCK
SQL_OAC_NONE = None
SQL_PS_POSITIONED_DELETE SQL_PS_POSITIONED_UPDATE
SQL_PS_SELECT_FOR_UPDATE
An ODBC 3.x application working with an ODBC 3.x driver should not call SQLGetInfo with the InfoType
arguments described in the preceding table but should use the ODBC 3.x InfoType arguments listed in the
following paragraph. There is not a one-to-one correspondence between InfoType arguments used in ODBC 2.x
and those used in ODBC 3.x. An ODBC 3.x application working with an ODBC 2.x driver, on the other hand, should
use the InfoType arguments described previously.
Some of the information types in the previous table are deprecated in favor of the cursor attributes information
types. These deprecated information types are SQL_FETCH_DIRECTION, SQL_LOCK_TYPES,
SQL_POS_OPERATIONS, SQL_POSITIONED_STATEMENTS, SQL_SCROLL_CONCURRENCY, and
SQL_STATIC_SENSITIVITY. The new cursor attributes types are SQL_XXX_CURSOR_ATTRIBUTES1and
SQL_XXX_CURSOR_ATTRIBUTES2, where XXX equals DYNAMIC, FORWARD_ONLY, KEYSET_DRIVEN, or STATIC.
Each of the new types indicates the driver capabilities for a single cursor type. For more information about these
options, see the SQLGetInfo function description.
SQLGetStmtAttr (Cursor Library)
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLGetStmtAttr function in the cursor library. For general information about
SQLGetStmtAttr, see SQLGetStmtAttr Function.
The cursor library supports the following statement attributes with SQLGetStmtAttr:
SQL_ATTR_CONCURRENCY SQL_ATTR_ROW_BIND_OFFSET_PTR
SQL_ATTR_CURSOR_TYPE SQL_ATTR_ROW_BIND_TYPE
SQL_ATTR_FETCH_BOOKMARK_PTR SQL_ATTR_ROW_NUMBER
SQL_ATTR_PARAM_BIND_OFFSET_PTR SQL_ATTR_ROW_ARRAY_SIZE
SQL_ATTR_PARAM_BIND_TYPE SQL_ATTR_SIMULATE_CURSOR
SQLGetStmtOption (Cursor Library)
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLGetStmtOption function in the cursor library. For general information
about SQLGetStmtOption, see SQLGetStmtOption Function.
The cursor library supports the following statement options with SQLGetStmtOption:
SQL_BIND_TYPE SQL_ROW_NUMBER
SQL_CONCURRENCY SQL_ROWSET_SIZE
SQL_CURSOR_TYPE SQL_SIMULATE_CURSOR
SQL_GET_BOOKMARK
SQLNativeSql (Cursor Library)
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLNativeSql function in the cursor library. For general information about
SQLNativeSql, see SQLNativeSql Function.
If the driver supports this function, the cursor library calls SQLNativeSql in the driver and passes it the SQL
statement. For positioned update, positioned delete, and SELECT FOR UPDATE statements, the cursor library
modifies the statement before passing it to the driver.
NOTE
The cursor library incorrectly returns SQLSTATE 34000 (Invalid cursor name) if the cursor name is invalid in a positioned
update or delete statement that is passed in the InStatementText argument of SQLNativeSql. SQLNativeSql is not
intended to return syntax errors, which are returned only upon statement preparation or execution.
SQLRowCount (Cursor Library)
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLRowCount function in the cursor library. For general information about
SQLRowCount, see SQLRowCount Function.
When an application calls SQLRowCount with the statement associated with the cursor, the cursor library returns
the number of rows of data it has retrieved from the driver.
When an application calls SQLRowCount with the statement associated with a positioned update or delete
statement, the cursor library returns the number of rows affected by the statement.
When an application calls SQLRowCount after a SELECT statement, the cursor library returns –1.
SQLSetConnectAttr (Cursor Library)
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLSetConnectAttr function in the cursor library. For general information
about SQLSetConnectAttr, see SQLSetConnectAttr Function.
An application calls SQLSetConnectAttr with the SQL_ATTR_ODBC_CURSORS attribute to specify whether the
cursor library is always used, used if the driver does not support scrollable cursors, or never used. The cursor
library assumes that a driver supports scrollable cursors if it returns SQL_CA1_RELATIVE for the
SQL_STATIC_CURSOR_ATTRIBUTES1 information type in SQLGetInfo.
The application must call SQLSetConnectAttr to specify the cursor library usage after it calls SQLAllocHandle
with a HandleType of SQL_HANDLE_DBC to allocate the connection and before it connects to the data source. If an
application calls SQLSetConnectAttr with the SQL_ATTR_ODBC_CURSORS attribute while the connection is still
active, the cursor library returns an error.
To set a statement attribute supported by the cursor library for all statements associated with a connection, an
application must call SQLSetConnectAttr for that statement attribute after it connects to the data source and
before it opens the cursor. If an application calls SQLSetConnectAttr with a statement attribute and a cursor is
open on a statement associated with the connection, the statement attribute will not be applied to that statement
until the cursor is closed and reopened.
SQLSetDescField and SQLSetDescRec (Cursor
Library)
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLSetDescField and SQLSetDescRec functions in the cursor library. For
general information about these functions, see SQLSetDescField Function and SQLSetDescRec Function.
The cursor library executes SQLSetDescField when it is called to return the value of the fields set for bookmark
columns:
SQL_DESC_DATA_PTR
SQL_DESC_INDICATOR_PTR
SQL_DESC_OCTET_LENGTH_PTR
SQL_DESC_LENGTH
SQL_DESC_OCTET_LENGTH
SQL_DESC_DATETIME_INTERVAL_CODE
SQL_DESC_SCALE
SQL_DESC_PRECISION
SQL_DESC_TYPE
SQL_DESC_NAME
SQL_DESC_UNNAMED
SQL_DESC_NULLABLE
The cursor library executes calls to SQLSetDescRec for a bookmark column.
When working with an ODBC 2.x driver, the cursor library returns SQLSTATE HY090 (Invalid string or buffer length)
when SQLSetDescField or SQLSetDescRec is called to set the SQL_DESC_OCTET_LENGTH field for the bookmark
record of an ARD to a value not equal to 4. When working with an ODBC 3.x driver, the cursor library allows the
buffer to be any size.
The cursor library executes SQLSetDescField when it is called to return the value of the
SQL_DESC_BIND_OFFSET_PTR, SQL_DESC_BIND_TYPE, SQL_DESC_ROW_ARRAY_SIZE, or
SQL_DESC_ROW_STATUS_PTR field. These fields can be returned for any row, not just the bookmark row.
The cursor library does not execute SQLSetDescField to change any descriptor field other than the fields
mentioned previously. If an application calls SQLSetDescField to set any other field while the cursor library is
loaded, the call is passed through to the driver.
The cursor library supports changing the SQL_DESC_DATA_PTR, SQL_DESC_INDICATOR_PTR, and
SQL_DESC_OCTET_LENGTH_PTR fields of any row of an application row descriptor dynamically (after a call to
SQLExtendedFetch, SQLFetch, or SQLFetchScroll). The SQL_DESC_OCTET_LENGTH_PTR field can be changed to
a null pointer only to unbind the length buffer for a column.
The cursor library does not support changing the SQL_DESC_BIND_TYPE field in an APD or ARD when a cursor is
open. The SQL_DESC_BIND_TYPE field can be changed only after the cursor is closed and before a new cursor is
opened. The only descriptor fields that the cursor library supports changing when a cursor is open are
SQL_DESC_ARRAY_STATUS_PTR, SQL_DESC_BIND_OFFSET_PTR, SQL_DESC_DATA_PTR,
SQL_DESC_INDICATOR_PTR, SQL_DESC_OCTET_LENGTH_PTR, and SQL_DESC_ROWS_PROCESSED_PTR.
The cursor library does not support modifying the SQL_DESC_COUNT field of the ARD after SQLExtendedFetch
or SQLFetchScroll has been called and before the cursor has been closed.
SQLSetEnvAttr and the Cursor Library
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLSetEnvAttr function with the cursor library. For general information about
SQLSetEnvAttr, see SQLSetEnvAttr Function.
The cursor library is unaffected by the setting of the SQL_ATTR_ODBC_VERSION environment attribute, regardless
of the application version or driver version.
SQLSetPos (Cursor Library)
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLSetPos function in the cursor library. For general information about
SQLSetPos, see SQLSetPos Function.
The cursor library supports the SQL_POSITION operation only for the Operation argument in SQLSetPos. It
supports the SQL_LOCK_NO_CHANGE value only for the LockType argument.
If the driver does not support bulk operations, the cursor library returns SQLSTATE HYC00 (Driver not capable)
when SQLSetPos is called with RowNumber equal to 0. This driver behavior is not recommended.
The cursor library does not support the SQL_UPDATE and SQL_DELETE operations in a call to SQLSetPos. The
cursor library implements a positioned update or delete SQL statement by creating a searched update or delete
statement with a WHERE clause that enumerates the values stored in its cache for each bound column. For more
information, see Processing Positioned Update and Delete Statements.
If the driver does not support static cursors, an application working with the cursor library should call SQLSetPos
only on a rowset fetched by SQLExtendedFetch or SQLFetchScroll, not by SQLFetch. The cursor library
implements SQLExtendedFetch and SQLFetchScroll by making repeated calls of SQLFetch (with a rowset size of
1) in the driver. The cursor library passes calls to SQLFetch, on the other hand, through to the driver. If SQLSetPos
is called on a multirow rowset fetched by SQLFetch when the driver does not support static cursors, the call will
fail because SQLSetPos does not work with forward-only cursors. This will occur even if an application has
successfully called SQLSetStmtAttr to set SQL_ATTR_CURSOR_TYPE to SQL_CURSOR_STATIC, which the cursor
library supports even if the driver does not support static cursors.
SQLSetScrollOptions (Cursor Library)
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLSetScrollOptions function in the cursor library. For general information
about SQLSetScrollOptions, see SQLSetScrollOptions Function.
The cursor library supports SQLSetScrollOptions only for backward compatibility; applications should use the
SQL_ATTR_CONCURRENCY, SQL_ATTR_CURSOR_TYPE, and SQL_ATTR_ROW_ARRAY_SIZE statement attributes
instead.
SQLSetStmtAttr (Cursor Library)
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
This topic discusses the use of the SQLSetStmtAttr function in the cursor library. For general information about
SQLSetStmtAttr, see SQLSetStmtAttr Function.
The cursor library supports the following statement attributes with SQLSetStmtAttr:
SQL_ATTR_CONCURRENCY SQL_ATTR_ROW_BIND_OFFSET_PTR
SQL_ATTR_CURSOR_TYPE SQL_ATTR_ROW_BIND_TYPE
SQL_ATTR_FETCH_BOOKMARK_PTR SQL_ATTR_ROWSET_ARRAY_SIZE
SQL_ATTR_PARAM_BIND_OFFSET_PTR SQL_ATTR_SIMULATE_CURSOR
SQL_ATTR_PARAM_BIND_TYPE SQL_ATTR_USE_BOOKMARKS
The cursor library supports only the SQL_CURSOR_FORWARD_ONLY and SQL_CURSOR_STATIC values of the
SQL_ATTR_CURSOR_TYPE statement attribute.
For forward-only cursors, the cursor library supports the SQL_CONCUR_READ_ONLY value of the
SQL_ATTR_CONCURRENCY statement attribute. For static cursors, the cursor library supports the
SQL_CONCUR_READ_ONLY and SQL_CONCUR_VALUES values of the SQL_ATTR_CONCURRENCY statement
attribute.
The cursor library supports only the SQL_SC_NON_UNIQUE value of the SQL_ATTR_SIMULATE_CURSOR
statement attribute.
Although the ODBC specification supports calls to SQLSetStmtAttr with the SQL_ATTR_PARAM_BIND_TYPE or
SQL_ATTR_ROW_BIND_TYPE attributes after SQLFetch or SQLFetchScroll has been called, the cursor library does
not. Before it can change the binding type in the cursor library, the application must close the cursor. The cursor
library supports changing the SQL_ATTR_ROW_BIND_OFFSET_PTR, SQL_ATTR_PARAM_BIND_OFFSET_PTR,
SQL_ATTR_ROWS_FETCHED_PTR, and SQL_ATTR_PARAMS_PROCESSED_PTR statement attributes when a cursor is
open.
An application can call SQLSetStmtAttr with an Attribute of SQL_ATTR_ROW_ARRAY_SIZE to change the rowset
size while a cursor is open. The new rowset size will take effect the next time SQLFetchScroll or SQLFetch is
called.
The cursor library supports setting the SQL_ATTR_PARAM_BIND_OFFSET_PTR or
SQL_ATTR_ROW_BIND_OFFSET_PTR statement attribute to enable binding offsets. The binding offset will not be
used for calls to SQLFetch when the cursor library is used with an ODBC 2.x driver.
The cursor library supports setting the SQL_ATTR_USE_BOOKMARKS statement attribute to SQL_UB_VARIABLE.
ODBC Cursor Library Error Codes
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Microsoft Data Access Component. Avoid using this feature in new
development work and plan to modify applications that currently use this feature. Instead, use driver and server cursors.
The ODBC cursor library returns the following SQLSTATEs in addition to those listed in ODBC API Reference.
NOTE
The cursor library does not order status records; the Driver Manager and ODBC 3.x drivers are responsible for ordering
status records.
SQLFetchScroll
SQLConnect
SQLDriverConnect
SQLDriverConnect
SQLDriverConnect
SQLGetData
SQLSTATE DESCRIPTION CAN BE RETURNED FROM
SQLGetData
SQLGetData
SQLPrepare
SQLGetData
SQLGetData
SQLSTATE DESCRIPTION CAN BE RETURNED FROM
SQLFreeStmt
SQLSetStmtAttr
SQLPrepare
SQLFetchScroll
Outer Join Escape Sequence
12/20/2017 • 1 min to read • Edit Online
ODBC uses escape sequences for outer joins. The syntax of this escape sequence is as follows:
{oj outer-join}
Remarks
In BNF notation, the syntax is as follows:
ODBC-outer-join-escape ::=
ODBC-esc-initiator oj outer-join ODBC-esc-terminator
outer-join ::= table-name [correlation-name] {LEFT | RIGHT | FULL}
OUTER JOIN{table-name [correlation-name] | outer-join} ON
search-
condition
correlation-name ::= user-defined-name
ODBC-esc-initiator ::= {
ODBC-esc-terminator ::= }
To determine which parts of this statement are supported, an application calls SQLGetInfo with the
SQL_OJ_CAPABILITIES information type. For outer joins, search-condition must contain only the join condition
between the specified table-names.
Overriding Default Leading and Seconds Precision
for Interval Data Types
12/20/2017 • 1 min to read • Edit Online
When the SQL_DESC_TYPE field of an ARD is set to a datetime or interval C type, by calling either SQLBindCol or
SQLSetDescField, the SQL_DESC_PRECISION field (which contains the interval seconds precision) is set to the
following defaults:
6 for timestamp and all interval data types with a second component.
0 for all other data types.
For all interval data types, the SQL_DESC_DATETIME_INTERVAL_PRECISION descriptor field, which contains
the interval leading field precision, is set to a default value of 2.
When the SQL_DESC_TYPE field in an APD is set to a datetime or interval C type, by calling either
SQLBindParameter or SQLSetDescField, the SQL_DESC_PRECISION and
SQL_DESC_DATETIME_INTERVAL_PRECISION fields in the APD are set to the default given previously. This is
true for input parameters but not for input/output or output parameters.
A call to SQLSetDescRec sets the interval leading precision to the default but sets the interval seconds
precision (in the SQL_DESC_PRECISION field) to the value of its Precision argument.
If either of the defaults given previously is not acceptable to an application, the application should set the
SQL_DESC_PRECISION or SQL_DESC_DATETIME_INTERVAL_PRECISION field by calling SQLSetDescField.
If the application calls SQLGetData to return data into a datetime or interval C type, the default interval
leading precision and interval seconds precision are used. If either default is not acceptable, the application
must call SQLSetDescField to set either descriptor field, or SQLSetDescRec to set SQL_DESC_PRECISION.
The call to SQLGetData should have a TargetType of SQL_ARD_TYPE to use the values in the descriptor
fields.
When SQLPutData is called, the interval leading precision and interval seconds precision are read from the
fields of the descriptor record that correspond to the data-at-execution parameter or column, which are APD
fields for calls to SQLExecute or SQLExecDirect, or ARD fields for calls to SQLBulkOperations or
SQLSetPos.
Overriding Default Precision and Scale for Numeric
Data Types
12/20/2017 • 1 min to read • Edit Online
When the SQL_DESC_TYPE field in an ARD is set to SQL_C_NUMERIC, by calling either SQLBindCol or
SQLSetDescField, the SQL_DESC_SCALE field in the ARD is set to 0 and the SQL_DESC_PRECISION field is set to a
driver-defined default precision. This is also true when the SQL_DESC_TYPE field in an APD is set to
SQL_C_NUMERIC, by calling either SQLBindParameter or SQLSetDescField. This is true for input, input/output,
or output parameters.
If either of the defaults described previously are not acceptable for an application, the application should set the
SQL_DESC_SCALE or SQL_DESC_PRECISION field by calling SQLSetDescField or SQLSetDescRec.
If the application calls SQLGetData to return data into an SQL_C_NUMERIC structure, the default
SQL_DESC_SCALE and SQL_DESC_PRECISION fields are used. If the defaults are not acceptable, the application
must call SQLSetDescRec or SQLSetDescField to set the fields and then call SQLGetData with a TargetType of
SQL_ARD_TYPE to use the values in the descriptor fields.
When SQLPutData is called, the call uses the SQL_DESC_SCALE and SQL_DESC_PRECISION fields of the
descriptor record that corresponds to the data-at-execution parameter or column, which are APD fields for calls to
SQLExecute or SQLExecDirect, or ARD fields for calls to SQLBulkOperations or SQLSetPos.
Parameter Data Types
12/20/2017 • 1 min to read • Edit Online
Even though each parameter specified with SQLBindParameter is defined using an SQL data type, the parameters
in an SQL statement have no intrinsic data type. Therefore, parameter markers can be included in an SQL statement
only if their data types can be inferred from another operand in the statement. For example, in an arithmetic
expression such as ? + COLUMN1, the data type of the parameter can be inferred from the data type of the named
column represented by COLUMN1. An application cannot use a parameter marker if the data type cannot be
determined.
The following table describes how a data type is determined for several types of parameters, in accordance with
SQL-92. For a more comprehensive specification on inferring the parameter type when other SQL clauses are used,
see the SQL-92 specification.
One operand of a binary arithmetic or comparison operator Same as the other operand
The second or third operand in a BETWEEN clause Same as the first operand
An expression used with IN Same as the first value or the result column of the subquery
A value used with IN Same as the expression or the first value if there is a
parameter marker in the expression
In accordance with the SQL-92 specification, an application cannot place parameter markers in the following
locations. For a more comprehensive list, see the SQL-92 specification.
In a SELECT list
As both expressions in a comparison-predicate
As both operands of a binary operator
As both the first and second operands of a BETWEEN operation
As both the first and third operands of a BETWEEN operation
As both the expression and the first value of an IN operation
As the operand of a unary + or – operation
As the argument of a set-function-reference
For more information about parameter markers, see the SQL-92 specification. For more information about
parameters, see Statement Parameters.
Procedure Call Escape Sequence
12/20/2017 • 1 min to read • Edit Online
ODBC uses escape sequences for procedure calls. The syntax of this escape sequence is as follows:
{[?=]call procedure-name[([parameter][,[parameter]]...)]}
In BNF notation, the syntax is as follows:
ODBC-procedure-escape ::=
| ODBC-esc-initiator [?=] call procedure ODBC-esc-terminator
procedure ::= procedure-name | procedure-name (procedure-parameter-list)
procedure-identifier ::= user-defined-name
procedure-name ::= procedure-identifier
| owner-name.procedure-identifier
| catalog-name catalog-separator procedure-identifier
| catalog-name catalog-separator [owner-name].procedure-identifier
(The third syntax is valid only if the data source does not support owners.)
owner-name ::= user-defined-name
catalog-name ::= user-defined-name
catalog-separator ::= {implementation-defined}
(The catalog separator is returned through SQLGetInfo with the SQL_CATALOG_NAME_SEPARATOR information
option.)
procedure-parameter-list ::= procedure-parameter
| procedure-parameter, procedure-parameter-list
procedure-parameter ::= dynamic-parameter | literal | empty-string
empty-string ::=
ODBC-esc-initiator ::= {
ODBC-esc-terminator ::= }
(If a procedure parameter is an empty string, the procedure uses the default value for that parameter.)
To determine whether the data source supports procedures and the driver supports the ODBC procedure
invocation syntax, an application can call SQLGetInfo with the SQL_PROCEDURES information type.
Processing Batches of SQL Statements
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
The cursor library does not support batches of SQL statements, including SQL statements for which the
SQL_ATTR_PARAMSET_SIZE statement attribute is greater than 1. If an application submits a batch of SQL
statements to the cursor library, the results are undefined.
Processing Positioned Update and Delete Statements
12/20/2017 • 2 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
The cursor library supports positioned update and delete statements by replacing the WHERE CURRENT OF
clause in such statements with a WHERE clause that enumerates the values stored in its cache for each bound
column. The cursor library passes the newly constructed UPDATE and DELETE statements to the driver for
execution. For positioned update statements, the cursor library then updates its cache from the values in the rowset
buffers and sets the corresponding value in the row status array to SQL_ROW_UPDATED. For positioned delete
statements, it sets the corresponding value in the row status array to SQL_ROW_DELETED.
Cau t i on
The WHERE clause constructed by the cursor library to identify the current row can fail to identify any rows,
identify a different row, or identify more than one row. For more information, see Constructing Searched
Statements, later in this appendix.
Positioned update and delete statements are subject to the following restrictions:
Positioned update and delete statements can be used only in the following cases: when a SELECT statement
generated the result set; when the SELECT statement did not contain a join, a UNION clause, or a GROUP
BY clause; and when any columns that used an alias or expression in the select list were not bound with
SQLBindCol.
If an application prepares a positioned update or delete statement, it must do so after it has called SQLFetch
or SQLFetchScroll. Although the cursor library submits the statement to the driver for preparation, it closes
the statement and executes it directly when the application calls SQLExecute.
If the driver supports only one active statement, the cursor library fetches the rest of the result set and then
refetches the current rowset from its cache before it executes a positioned update or delete statement. If the
application then calls a function that returns metadata in a result set (for example, SQLNumResultCols or
SQLDescribeCol), the cursor library returns an error.
If a positioned update or delete statement is performed on a column of a table that includes a timestamp
column that is automatically updated every time an update is performed, all subsequent positioned update
or delete statements will fail if the timestamp column is bound. This occurs because the searched update or
delete statement that the cursor library creates will not accurately identify the row to update. The value in
the searched statement for the timestamp column will not match the automatically updated value of the
timestamp column.
Processing SELECT FOR UPDATE Statements
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
For maximum interoperability, applications should generate result sets that will be updated with a positioned
update statement by executing a SELECT FOR UPDATE statement. Although the cursor library does not require
this, it is required by most data sources that support positioned update statements.
The cursor library ignores the columns in the FOR UPDATE clause of a SELECT FOR UPDATE statement; it
removes this clause before passing the statement to the driver. In the cursor library, the
SQL_ATTR_CONCURRENCY statement attribute, along with the restrictions mentioned in the previous section,
controls whether the columns in a result set can be updated.
Processing SQL Statements
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
The ODBC cursor library passes all SQL statements directly to the driver except the following:
Positioned update and delete statements
SELECT FOR UPDATE statements
Batched SQL statements
To execute positioned update and delete statements and to position the cursor on a row to call SQLGetData
for that row, the cursor library constructs a searched statement that identifies the row.
This section contains the following topics.
Processing Positioned Update and Delete Statements
Processing SELECT FOR UPDATE Statements
Processing Batches of SQL Statements
Constructing Searched Statements
Pseudo-Type Identifiers
12/20/2017 • 1 min to read • Edit Online
For application programming convenience, ODBC defines a number of pseudo-type identifiers. These identifiers do
not actually correspond to actual data types, but instead, depending on the situation, resolve to existing data types.
This section contains the following topics.
Default C Data Types
Bookmark C Data Type
SQL_ARD_TYPE
SQL_C_TCHAR
Reserved Keywords
12/20/2017 • 1 min to read • Edit Online
The following words are reserved for use in ODBC function calls. These words do not constrain the minimum SQL
grammar; however, to ensure compatibility with drivers that support the core SQL grammar, applications should
avoid using any of these keywords. The #define value SQL_ODBC_KEYWORDS contains a comma-separated list of
these keywords.
ABSOLUTE IS
ACTION ISOLATION
ADA JOIN
ADD KEY
ALL LANGUAGE
ALLOCATE LAST
ALTER LEADING
AND LEFT
ANY LEVEL
ARE LIKE
AS LOCAL
ASC LOWER
ASSERTION MATCH
AT MAX
AUTHORIZATION MIN
AVG MINUTE
BEGIN MODULE
BETWEEN MONTH
BIT NAMES
BIT_LENGTH NATIONAL
BOTH NATURAL
BY NCHAR
CASCADE NEXT
CASCADED NO
CASE NONE
CAST NOT
CATALOG NULL
CHAR NULLIF
CHAR_LENGTH NUMERIC
CHARACTER OCTET_LENGTH
CHARACTER_LENGTH OF
CHECK ON
CLOSE ONLY
COALESCE OPEN
COLLATE OPTION
COLLATION OR
COLUMN ORDER
COMMIT OUTER
CONNECT OUTPUT
CONNECTION OVERLAPS
CONSTRAINT PAD
CONSTRAINTS PARTIAL
CONTINUE PASCAL
CONVERT POSITION
CORRESPONDING PRECISION
COUNT PREPARE
CREATE PRESERVE
CROSS PRIMARY
CURRENT PRIOR
CURRENT_DATE PRIVILEGES
CURRENT_TIME PROCEDURE
CURRENT_TIMESTAMP PUBLIC
CURRENT_USER READ
CURSOR REAL
DATE REFERENCES
DAY RELATIVE
DEALLOCATE RESTRICT
DEC REVOKE
DECIMAL RIGHT
DECLARE ROLLBACK
DEFAULT ROWS
DEFERRABLE SCHEMA
DEFERRED SCROLL
DELETE SECOND
DESC SECTION
DESCRIBE SELECT
DESCRIPTOR SESSION
DIAGNOSTICS SESSION_USER
DISCONNECT SET
DISTINCT SIZE
DOMAIN SMALLINT
DOUBLE SOME
DROP SPACE
ELSE SQL
END SQLCA
END-EXEC SQLCODE
ESCAPE SQLERROR
EXCEPT SQLSTATE
EXCEPTION SQLWARNING
EXEC SUBSTRING
EXECUTE SUM
EXISTS SYSTEM_USER
EXTERNAL TABLE
EXTRACT TEMPORARY
FALSE THEN
FETCH TIME
FIRST TIMESTAMP
FLOAT TIMEZONE_HOUR
FOR TIMEZONE_MINUTE
FOREIGN TO
FORTRAN TRAILING
FOUND TRANSACTION
FROM TRANSLATE
FULL TRANSLATION
GET TRIM
GLOBAL TRUE
GO UNION
GOTO UNIQUE
GRANT UNKNOWN
GROUP UPDATE
HAVING UPPER
HOUR USAGE
IDENTITY USER
IMMEDIATE USING
IN VALUE
INCLUDE VALUES
INDEX VARCHAR
INDICATOR VARYING
INITIALLY VIEW
INNER WHEN
INPUT WHENEVER
INSENSITIVE WHERE
INSERT WITH
INT WORK
INTEGER WRITE
INTERSECT YEAR
INTERVAL ZONE
INTO
Returning SQL_NO_DATA
12/20/2017 • 1 min to read • Edit Online
When an ODBC 2.x application workingwith an ODBC 3.x driver calls SQLExecDirect, SQLExecute, or
SQLParamData, and a searched update or delete statement was executed but did not affect any rows at the data
source, the ODBC 3.x driver should return SQL_SUCCESS. When an ODBC 3.x application working with an ODBC
3.x driver calls SQLExecDirect, SQLExecute, or SQLParamData with the same result, the ODBC 3.x driver should
return SQL_NO_DATA.
If a searched update or delete statement in a batch of statements does not affect any rows at the data source,
SQLMoreResults returns SQL_SUCCESS. It cannot return SQL_NO_DATA, because that would mean that there are
no more results, not that there is a result from a searched update/delete that affected no rows.
Row Status
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
The cursor library creates a buffer in the cache for the row status. The cursor library retrieves values for the row
status array (specified with the SQL_ATTR_ROW_STATUS_PTR statement attribute) from this buffer. For each row,
the cursor library sets this buffer to:
SQL_ROW_DELETED when it executes a positioned delete statement on the row.
SQL_ROW_ERROR when it encounters an error retrieving the row from the data source with SQLFetch.
SQL_ROW_SUCCESS when it successfully fetches the row from the data source with SQLFetch.
SQL_ROW_UPDATED when it executes a positioned update statement on the row.
Rules for Conversions
12/20/2017 • 3 min to read • Edit Online
The rules in this section apply for conversions involving numeric literals. For the purposes of these rules, the
following terms are defined:
Store assignment: When sending data into a table column in a database. This occurs during calls to
SQLExecute, SQLExecDirect, and SQLSetPos. During store assignment, "target" refers to a database
column and "source" refers to data in application buffers.
Retrieval assignment: When retrieving data from the database into application buffers. This occurs during
calls to SQLFetch, SQLGetData, SQLFetchScroll, and SQLSetPos. During retrieval assignment, "target"
refers to the application buffers and "source" refers to the database column.
CS: The value in the character source.
NT: The value in the numeric target.
NS: The value in the numeric source.
CT: The value in the character target.
Precision of an exact numeric literal: the number of digits it contains.
The scale of an exact numeric literal: the number of digits to the right of the expressed or implied period.
The precision of an approximate numeric literal: the precision of its mantissa.
ODBC uses escape sequences for scalar functions. The syntax of this escape sequence is as follows:
{fn scalar-function}
Remarks
In BNF notation, the syntax is as follows:
ODBC-scalar-function-escape ::=
ODBC-esc-initiator fn scalar-function ODBC-esc-terminator
scalar-function ::= function-name (argument-list)
(The definitions for the nonterminals function-name and function-name (argument-list) are derived from the list of
scalar functions in Appendix E: Scalar Functions.)
ODBC-esc-initiator ::= {
ODBC-esc-terminator ::= }
To determine whether the data source supports procedures and the driver supports the ODBC procedure
invocation syntax, an application can call SQLGetInfo. For more information, see Appendix E: Scalar Functions.
SQL Data Types
12/20/2017 • 6 min to read • Edit Online
Each DBMS defines its own SQL types. Each ODBC driver exposes only those SQL data types that the associated
DBMS defines. Information about how a driver maps DBMS SQL types to the ODBC-defined SQL type identifiers
and how a driver maps DBMS SQL types to its own driver-specific SQL type identifiers is returned through a call to
SQLGetTypeInfo. A driver also returns the SQL data types when describing the data types of columns and
parameters through calls to SQLColAttribute, SQLColumns, SQLDescribeCol, SQLDescribeParam,
SQLProcedureColumns, and SQLSpecialColumns.
NOTE
The SQL data types are contained in the SQL_DESC_ CONCISE_TYPE, SQL_DESC_TYPE, and
SQL_DESC_DATETIME_INTERVAL_CODE fields of the implementation descriptors. Characteristics of the SQL data types are
contained in the SQL_DESC_PRECISION, SQL_DESC_SCALE, SQL_DESC_LENGTH, and SQL_DESC_OCTET_LENGTH fields of
the implementation descriptors. For more information, see Data Type Identifiers and Descriptors later in this appendix.
A given driver and data source do not necessarily support all the SQL data types that are defined in this appendix.
A driver's support for SQL data types depends on the level of SQL-92 that the driver complies with. To determine
the level of SQL-92 grammar supported by the driver, an application calls SQLGetInfo with the
SQL_SQL_CONFORMANCE information type. Additionally, a given driver and data source may support additional,
driver-specific SQL data types. To determine which data types a driver supports, an application calls
SQLGetTypeInfo. For information about driver-specific SQL data types, see the driver's documentation. For
information about the data types in a specific data source, see the documentation for that data source.
IMPORTANT
The tables throughout this appendix are only guidelines and show typically used names, ranges, and limits of SQL data
types. A given data source might support only some of the listed data types, and the characteristics of the supported data
types can differ from those listed.
The following table lists valid SQL type identifiers for all SQL data types. The table also lists the name and
description of the corresponding data type from SQL-92 (if one exists).
[1] This is the value returned in the DATA_TYPE column by a call to SQLGetTypeInfo.
[2] This is the value returned in the NAME and CREATE PARAMS column by a call to SQLGetTypeInfo. The NAME
column returns the designation—for example, CHAR—whereas the CREATE PARAMS column returns a comma-
separated list of creation parameters such as precision, scale, and length.
[3] An application uses SQLGetTypeInfo or SQLColAttribute to determine whether a particular data type or a
particular column in a result set is unsigned.
[4] SQL_DECIMAL and SQL_NUMERIC data types differ only in their precision. The precision of a DECIMAL(p,s) is
an implementation-defined decimal precision that is no less than p, whereas the precision of a NUMERIC(p,s) is
exactly equal to p.
[5] Depending on the implementation, the precision of SQL_FLOAT can be either 24 or 53: if it is 24, the
SQL_FLOAT data type is the same as SQL_REAL; if it is 53, the SQL_FLOAT data type is the same as SQL_DOUBLE.
[6] In ODBC 3.x, the SQL date, time, and timestamp data types are SQL_TYPE_DATE, SQL_TYPE_TIME, and
SQL_TYPE_TIMESTAMP, respectively; in ODBC 2.x, the data types are SQL_DATE, SQL_TIME, and SQL_TIMESTAMP.
[7] For more information about the interval SQL data types, see the Interval Data Types section, later in this
appendix.
[8] The SQL_BIT data type has different characteristics than the BIT type in SQL-92.
[9] This data type has no corresponding data type in SQL-92.
This section provides the following example.
Example SQLGetTypeInfo Result Set
SQL Minimum Grammar
12/20/2017 • 1 min to read • Edit Online
This section describes the minimum SQL syntax that an ODBC driver must support. The syntax described in this
section is a subset of the Entry level syntax of SQL-92.
An application can use any of the syntax in this section and be assured that any ODBC-compliant driver will
support that syntax. To determine whether additional features of SQL-92 not in this section are supported, the
application should call SQLGetInfo with the SQL_SQL_CONFORMANCE information type. Even if the driver does
not conform to any SQL-92 conformance level, an application can still use the syntax described in this section. If a
driver conforms to an SQL-92 level, on the other hand, it supports all syntax included in that level. This includes the
syntax in this section because the minimum grammar described here is a pure subset of the lowest SQL-92
conformance level. Once the application knows the SQL-92 level supported, it can determine whether a higher-
level feature is supported (if any) by calling SQLGetInfo with the individual information type corresponding to that
feature.
Drivers that work only with read-only data sources might not support those parts of the grammar included in this
section that deal with changing data. An application can determine if a data source is read-only by calling
SQLGetInfo with the SQL_DATA_SOURCE_READ_ONLY information type.
Statement
create-table-statement ::=
CREATE TABLE base-table-name
(column-identifier data-type [,column-identifier data-type]...)
IMPORTANT
As a data-type in a create-table-statement, applications must use a data type from the TYPE_NAME column of the result set
returned by SQLGetTypeInfo.
delete-statement-searched ::=
DELETE FROM table-name [WHERE search-condition]
drop-table-statement ::=
DROP TABLE base-table-name
insert-statement ::=
INSERT INTO table-name [( column-identifier [, column-identifier]...)] VALUES (insert-value[, insert-value]... )
select-statement ::=
SELECT [ALL | DISTINCT] select-list
FROM table-reference-list
[WHERE search-condition]
[order-by-clause]
statement ::= create-table-statement
| delete-statement-searched
| drop-table-statement
| insert-statement
| select-statement
| update-statement-searched
update-statement-searched
UPDATE table-name
SET column-identifier = {expression | NULL }
[, column-identifier = {expression | NULL}]...
[WHERE search-condition]
This section contains the following topics.
Elements Used in SQL Statements
Data Type Support
Parameter Data Types
Parameter Markers
Converting Data from SQL to C Data Types
12/20/2017 • 3 min to read • Edit Online
When an application calls SQLFetch, SQLFetchScroll, or SQLGetData, the driver retrieves the data from the data
source. If necessary, it converts the data from the data type in which the driver retrieved it to the data type
specified by the TargetType argument in SQLBindCol or SQLGetData. Finally, it stores the data in the location
pointed to by the TargetValuePtr argument in SQLBindCol or SQLGetData (and the SQL_DESC_DATA_PTR field
of the ARD).
The following table shows the supported conversions from ODBC SQL data types to ODBC C data types. A filled
circle indicates the default conversion for an SQL data type (the C data type to which the data will be converted
when the value of TargetType is SQL_C_DEFAULT). A hollow circle indicates a supported conversion.
For an ODBC 3.x application working with an ODBC 2.x driver, conversion from driver-specific data types might
not be supported.
The format of the converted data is not affected by the Windows® country setting.
The tables in the following sections describe how the driver or data source converts data retrieved from the data
source; drivers are required to support conversions to all ODBC C data types from the ODBC SQL data types that
they support. For a given ODBC SQL data type, the first column of the table lists the legal input values of the
TargetType argument in SQLBindCol and SQLGetData. The second column lists the outcomes of a test, often
using the BufferLength argument specified in SQLBindCol or SQLGetData, which the driver performs to
determine whether it can convert the data. For each outcome, the third and fourth columns list the values placed
in the buffers specified by the TargetValuePtr and StrLen_or_IndPtr arguments specified in SQLBindCol or
SQLGetData after the driver has attempted to convert the data. (The StrLen_or_IndPtr argument corresponds to
the SQL_DESC_OCTET_LENGTH_PTR field of the ARD.) The last column lists the SQLSTATE returned for each
outcome by SQLFetch, SQLFetchScroll, or SQLGetData.
If the TargetType argument in SQLBindCol or SQLGetData contains an identifier for an ODBC C data type not
shown in the table for a given ODBC SQL data type, SQLFetch, SQLFetchScroll, or SQLGetData returns
SQLSTATE 07006 (Restricted data type attribute violation). If the TargetType argument contains an identifier that
specifies a conversion from a driver-specific SQL data type to an ODBC C data type and this conversion is not
supported by the driver, SQLFetch, SQLFetchScroll, or SQLGetData returns SQLSTATE HYC00 (Optional feature
not implemented).
Although it is not shown in the tables, the driver returns SQL_NULL_DATA in the buffer specified by the
StrLen_or_IndPtr argument when the SQL data value is NULL. For an explanation of the use of StrLen_or_IndPtr
when multiple calls are made to retrieve data, see the SQLGetDatafunction description. When SQL data is
converted to character C data, the character count returned in *StrLen_or_IndPtr does not include the null-
termination byte. If TargetValuePtr is a null pointer, SQLGetData returns SQLSTATE HY009 (Invalid use of null
pointer); in SQLBindCol, this unbinds the column.
The following terms and conventions are used in the tables:
Byte length of data is the number of bytes of C data available to return in *TargetValuePtr, whether or
not the data will be truncated before it is returned to the application. For string data, this does not include
the space for the null-termination character.
Character byte length is the total number of bytes needed to display the data in character format. This is
as defined for each C data type in the section Display Size, except that character byte length is in bytes
while the display size is in characters.
Words in italics represent function arguments or elements of the SQL grammar. For the syntax of
grammar elements, see Appendix C: SQL Grammar.
This section contains the following topics.
SQL to C: Character
SQL to C: Numeric
SQL to C: Bit
SQL to C: Binary
SQL to C: Date
SQL to C: GUID
SQL to C: Time
SQL to C: Timestamp
SQL to C: Year-Month Intervals
SQL to C: Day-Time Intervals
SQL to C Data Conversion Examples
SQL to C Data Conversion Examples
12/20/2017 • 1 min to read • Edit Online
The examples shown in the following table illustrate how the driver converts SQL data to C data :
[a] "\0" represents a null-termination byte. The driver always null-terminates SQL_C_CHAR data.
[b] The numbers in this list are the numbers stored in the fields of the TIMESTAMP_STRUCT structure.
SQL to C: Binary
12/20/2017 • 1 min to read • Edit Online
The identifiers for the binary ODBC SQL data types are:
SQL_BINARY
SQL_VARBINARY
SQL_LONGVARBINARY
The following table shows the ODBC C data types to which binary SQL data may be converted. For an explanation
of the columns and terms in the table, see Converting Data from SQL to C Data Types.
When binary SQL data is converted to character C data, each byte (8 bits) of source data is represented as two
ASCII characters. These characters are the ASCII character representation of the number in its hexadecimal form.
For example, a binary 00000001 is converted to "01" and a binary 11111111 is converted to "FF".
The driver always converts individual bytes to pairs of hexadecimal digits and terminates the character string with a
null byte. Because of this, if BufferLength is even and is less than the length of the converted data, the last byte of
the *TargetValuePtr buffer is not used. (The converted data requires an even number of bytes, the next-to-last byte
is a null byte, and the last byte cannot be used.)
NOTE
Application developers are discouraged from binding binary SQL data to a character C data type. This conversion is usually
inefficient and slow.
SQL to C: Bit
12/20/2017 • 1 min to read • Edit Online
The identifier for the bit ODBC SQL data type is:
SQL_BIT
The following table shows the ODBC C data types to which bit SQL data may be converted. For an explanation of
the columns and terms in the table, see Converting Data from SQL to C Data Types.
SQL_C_TINYINT
SQL_C_SBIGINT
SQL_C_UBIGINT
SQL_C_SSHORT
SQL_C_USHORT
SQL_C_SHORT
SQL_C_SLONG
SQL_C_ULONG
SQL_C_LONG
SQL_C_FLOAT
SQL_C_DOUBLE
SQL_C_NUMERIC
[a] The value of BufferLength is ignored for this conversion. The driver assumes that the size of *TargetValuePtr is
the size of the C data type.
[b] This is the size of the corresponding C data type.
When bit SQL data is converted to character C data, the possible values are "0" and "1".
SQL to C: Character
12/20/2017 • 3 min to read • Edit Online
The identifiers for the character ODBC SQL data types are:
SQL_CHAR
SQL_VARCHAR
SQL_LONGVARCHAR
SQL_WCHAR
SQL_WVARCHAR
SQL_WLONGVARCHAR
The following table shows the ODBC C data types to which character SQL data may be converted. For an
explanation of the columns and terms in the table, see Converting Data from SQL to C Data Types.
Data is not a
numeric-literal[b]
Data is not a
numeric-literal
All C interval types Data value is a valid Data Length of data in n/a
interval value; no bytes
truncation Truncated data 01S07
Length of data in
Data value is a valid Undefined bytes 22015
interval value;
truncation of one or Undefined Undefined 22018
more trailing fields
Undefined
Data is valid interval;
leading field
significant precision is
lost
[a] The value of BufferLength is ignored for this conversion. The driver assumes that the size of *TargetValuePtr is
the size of the C data type.
[b] This is the size of the corresponding C data type.
[c] The time portion of the timestamp-value is truncated.
[d] The date portion of the timestamp-value is ignored.
[e] The fractional seconds portion of the timestamp is truncated.
[f] The time fields of the timestamp structure are set to zero.
[g] The date fields of the timestamp structure are set to the current date.
When character SQL data is converted to numeric, date, time, timestamp, or interval C data, leading and trailing
spaces are ignored.
SQL to C: Date
12/20/2017 • 1 min to read • Edit Online
The identifier for the date ODBC SQL data type is:
SQL_TYPE_DATE
The following table shows the ODBC C data types to which date SQL data may be converted. For an explanation of
the columns and terms in the table, see Converting Data from SQL to C Data Types.
BufferLength < 11
[a] The value of BufferLength is ignored for this conversion. The driver assumes that the size of *TargetValuePtr is
the size of the C data type.
[b] The time fields of the timestamp structure are set to zero.
[c] This is the size of the corresponding C data type.
When date SQL data is converted to character C data, the resulting string is in the "yyyy-mm-dd" format. This
format is not affected by the Windows® country setting.
SQL to C: Day-Time Intervals
12/20/2017 • 2 min to read • Edit Online
The identifiers for the day-time interval ODBC SQL data types are:
SQL_INTERVAL_DAY
SQL_INTERVAL_DAY_TO_MINUTE
SQL_INTERVAL_HOUR
SQL_INTERVAL_DAY_TO_SECOND
SQL_INTERVAL_MINUTE
SQL_INTERVAL_HOUR_TO_MINUTE
SQL_INTERVAL_SECOND
SQL_INTERVAL_HOUR_TO_SECOND
SQL_INTERVAL_DAY_TO_HOUR
SQL_INTERVAL_MINUTE_TO_SECOND
The following table shows the ODBC C data types to which day-time interval SQL data may be converted. For an
explanation of the columns and terms in the table, see Converting Data from SQL to C Data Types.
All day-time C interval Trailing fields portion Data Length of data n/a
types not truncated
Truncated data Length of data 01S07
Trailing fields portion
truncated Undefined Undefined 22015
Leading precision of
target is not big
enough to hold data
from source
[a] A day-time interval SQL type can be converted to any day-time interval C type.
[b] If the interval precision is a single field (one of DAY, HOUR, MINUTE, or SECOND), the interval SQL type can be
converted to any exact numeric (SQL_C_STINYINT, SQL_C_UTINYINT, SQL_C_USHORT, SQL_C_SHORT,
SQL_C_SLONG, SQL_C_ULONG, or SQL_C_NUMERIC).
The default conversion of an interval SQL type is to the corresponding C interval data type. The application then
binds the column or parameter (or sets the SQL_DESC_DATA_PTR field in the appropriate record of the ARD) to
point to the initialized SQL_INTERVAL_STRUCT structure (or passes a pointer to the SQL_ INTERVAL_STRUCT
structure as the TargetValuePtr argument in a call to SQLGetData).
The following example demonstrates how to transfer data from a column of type SQL_INTERVAL_DAY_TO_MINUTE
into the SQL_INTERVAL_STRUCT structure such that it comes back as a DAY_TO_HOUR interval.
SQL_INTERVAL_STRUCT is;
SQLINTEGER cbValue;
SQLUINTEGER days, hours;
// Bind
SQLBindCol(hstmt, 1, SQL_C_INTERVAL_DAY_TO_MINUTE, &is, sizeof(SQL_INTERVAL_STRUCT), &cbValue);
// Fetch
SQLFetch(hstmt);
// Process data
days = is.intval.day_second.day;
hours = is.intval.day_second.hour;
SQL to C: GUID
12/20/2017 • 1 min to read • Edit Online
The identifier for the GUID ODBC SQL data type is:
SQL_GUID
The following table shows the ODBC C data types to which GUID SQL data may be converted. For an explanation of
the columns and terms in the table, see Converting Data from SQL to C Data Types.
[a] The value of BufferLength is ignored for this conversion. The driver assumes that the size of *TargetValuePtr is
the size of the C data type.
[b] This is the size of the corresponding C data type.
SQL to C: Numeric
12/20/2017 • 3 min to read • Edit Online
The identifiers for the numeric ODBC SQL data types are:
SQL_DECIMAL
SQL_BIGINT
SQL_NUMERIC
SQL_REAL
SQL_TINYINT
SQL_FLOAT
SQL_SMALLINT
SQL_DOUBLE SQL_INTEGER
The following table shows the ODBC C data types to which numeric SQL data may be converted. For an explanation
of the columns and terms in the table, see Converting Data from SQL to C Data Types.
SQL_C_USHORT
SQL_C_SHORT
SQL_C_SLONG
SQL_C_ULONG
SQL_C_LONG
SQL_C_NUMERIC
[a] The value of BufferLength is ignored for this conversion. The driver assumes that the size of *TargetValuePtr is
the size of the C data type.
[b] This is the size of the corresponding C data type.
[c] This conversion is supported only for the exact numeric data types (SQL_DECIMAL, SQL_NUMERIC,
SQL_TINYINT, SQL_SMALLINT, SQL_INTEGER, and SQL_BIGINT). It is not supported for the approximate numeric
data types (SQL_REAL, SQL_FLOAT, or SQL_DOUBLE).
The identifier for the timestamp ODBC SQL data type is:
SQL_TYPE_TIMESTAMP
The following table shows the ODBC C data types to which timestamp SQL data can be converted. For an
explanation of the columns and terms in the table, see Converting Data from SQL to C Data Types.
Fractional seconds
portion of timestamp
is nonzero[a]
C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE
Fractional seconds
portion of timestamp
is truncated[a]
[a] The value of BufferLength is ignored for this conversion. The driver assumes that the size of *TargetValuePtr is
the size of the C data type.
[b] The fractional seconds of the timestamp are truncated.
[c] The time portion of the timestamp is truncated.
[d] The date portion of the timestamp is ignored.
[e] The fractional seconds portion of the timestamp is truncated.
[f] This is the size of the corresponding C data type.
When timestamp SQL data is converted to character C data, the resulting string is in the "yyyy-mm-dd
hh:mm:ss[.f...]" format, where up to nine digits can be used for fractional seconds. This format is not affected by the
Windows® country setting. (Except for the decimal point and fractional seconds, the entire format must be used,
regardless of the precision of the timestamp SQL data type.)
SQL to C: Time
12/20/2017 • 1 min to read • Edit Online
The identifier for the time ODBC SQL data type is:
SQL_TYPE_TIME
The following table shows the ODBC C data types to which time SQL data may be converted. For an explanation of
the columns and terms in the table, see Converting Data from SQL to C Data Types.
The identifiers for the year-month interval ODBC SQL data types are:
SQL_INTERVAL_YEAR
SQL_INTERVAL_MONTH
SQL_INTERVAL_YEAR_TO_MONTH
The following table shows the ODBC C data types to which year-month interval SQL data may be converted. For an
explanation of the columns and terms in the table, see Converting Data from SQL to C Data Types.
SQL_C_NUMERIC[b]
SQL_C_BIGINT[b]
[a] A year-month interval SQL type can be converted to any year-month interval C type.
[b] If the interval precision is a single field (one of YEAR or MONTH), the interval SQL type can be converted to any
exact numeric (SQL_C_STINYINT, SQL_C_UTINYINT, SQL_C_USHORT, SQL_C_SHORT, SQL_C_SLONG,
SQL_C_ULONG, or SQL_C_NUMERIC).
The default conversion of an interval SQL type is to the corresponding C interval data type. The application then
binds the column or parameter (or sets the SQL_DESC_DATA_PTR field in the appropriate record of the ARD) to
point to the initialized SQL_INTERVAL_STRUCT structure (or passes a pointer to the SQL_ INTERVAL_STRUCT
structure as the TargetValuePtr argument in a call to SQLGetData).
SQL-92 CAST Function
12/20/2017 • 1 min to read • Edit Online
The CAST function defined in SQL-92 is equivalent to the CONVERT function defined in ODBC. The syntax of the
equivalent functions is as follows:
The SQL-92 CAST function mandates which data types can be converted to which other data types. (For more
information, see the SQL-92 specification.) The CAST function is supported at the FIPS Transitional level.
An application can determine support for the CAST function as follows:
1. Call SQLGetInfo with the SQL_SQL_CONFORMANCE information type. If the return value for the
information type is SQL_SC_FIPS127_2_TRANSITIONAL, SQL_SC_SQL92_INTERMEDIATE, or
SQL_SC_SQL92_FULL, the CAST function is supported.
2. If the return value of the SQL_SQL_CONFORMANCE information type is SQL_SC_ENTRY_LEVEL or 0, call
SQLGetInfo with the SQL_SQL92_VALUE_EXPRESSIONS information type. If the SQL_SVE_CAST bit is set,
the CAST function is supported.
SQL_ARD_TYPE
12/20/2017 • 1 min to read • Edit Online
The SQL_ARD_TYPE type identifier is used to indicate that the data in a buffer will be of the type specified in the
SQL_DESC_CONCISE_TYPE field of the ARD. SQL_ARD_TYPE is entered in the TargetType argument of a call to
SQLGetData instead of a specific data type and enables an application to change the data type of the buffer by
changing the descriptor field. This value ties the data type of the *TargetValuePtr buffer to the descriptor field.
(SQL_ARD_TYPE is not entered in a call to SQLBindCol or SQLBindParameter because the type of the bound
buffer is already tied to the SQL_DESC_TYPE and SQL_DESC_CONCISE_TYPE fields and can be changed at any time
by changing either of those fields.)
The SQL_ARD_TYPE type identifier can be used to specify nondefault values for leading precision and seconds
precision of interval data types, and precision and scale values for the SQL_C_NUMERIC data type. For more
information, see Overriding Default Leading and Seconds Precision for Interval Data Types and Overriding Default
Precision and Scale for Numeric Data Types, later in this appendix.
SQL_C_TCHAR
12/20/2017 • 1 min to read • Edit Online
The SQL_C_TCHAR type identifier does not actually identify a data type; it is a macro that exists within the header
file for Unicode conversion. It is replaced by SQL_C_CHAR or SQL_C_WCHAR depending on the setting of the
UNICODE #define. It is useful for an application transferring character data that is compiled as both an ANSI and a
Unicode application.
Statement Transitions
12/20/2017 • 17 min to read • Edit Online
STATE DESCRIPTION
S1 Allocated statement.
States S2 and S3 are known as the prepared states, states S5 through S7 as the cursor states, states S8 through
S10 as the need data states, and states S11 and S12 as the asynchronous states. In each of these groups, the
transitions are shown separately only when they are different for each state in the group; in most cases, the
transitions for each state in each a group are the same.
The following tables show how each ODBC function affects the statement state.
SQLAllocHandle
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
SQLBindCol
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
IH -- -- -- -- HY010 HY010
SQLBindParameter
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
IH -- -- -- -- HY010 HY010
SQLCancel
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
[1] The statement was temporarily in state S11 while a function was executing. SQLCancel was called from a
different thread.
[2] The statement was in state S11 because a function called asynchronously returned SQL_STILL_EXECUTING.
SQLCloseCursor
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
SQLColAttribute
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
IH HY010 See next table 24000 -- [s] S11 [x] HY010 NS [c] HY010
o
NO RESULTS RESULTS
(IH) S5 [s] S11 [x] S1 [e] S5 [s] S1 [e] and [1] See next table HY010 NS [c] HY010
S11 [x] S5 [s] and [1] o
S11 [x] and [1]
24000[2]
[1] The current result is the last or only result, or there are no current results. For more information about multiple
results, see Multiple Results.
[2] The current result is not the last result.
[1] This error is returned by the Driver Manager if SQLFetch or SQLFetchScroll has not returned SQL_NO_DATA
and is returned by the driver if SQLFetch or SQLFetchScroll has returned SQL_NO_DATA.
SQLCopyDesc
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
IH[2] HY010 See next table 24000 -- [s] S11 x HY010 NS [c] and [3]
HY010 [o] or
[4]
[1] This row shows transitions when the SourceDescHandle argument was an ARD, APD, or IPD.
[2] This row shows transitions when the SourceDescHandle argument was an IRD.
[3] The SourceDescHandle and TargetDescHandle arguments were the same as in the SQLCopyDesc function that
is running asynchronously.
[4] Either the SourceDescHandle argument or the TargetDescHandle argument (or both) were different than in the
SQLCopyDesc function that is running asynchronously.
NO RESULTS RESULTS
[1]This row shows transitions when the SourceDescHandle argument was an IRD.
-- -- -- -- -- -- --
SQLDescribeCol
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
IH HY010 See next table 24000 -- [s] S11 [x] HY010 NS [c] HY010
o
NO RESULTS RESULTS
SQLDescribeParam
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
SQLDisconnect
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
[1] Calling SQLDisconnect frees all statements associated with the connection. Furthermore, this returns the
connection state to C2; the connection state must be C4 before the statement state is S0.
SQLEndTran
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
[1] The CompletionType argument is SQL_COMMIT and SQLGetInfo returns SQL_CB_DELETE for the
SQL_CURSOR_COMMIT_BEHAVIOR information type, or the CompletionType argument is SQL_ROLLBACK and
SQLGetInfo returns SQL_CB_DELETE for the SQL_CURSOR_ROLLBACK_BEHAVIOR information type.
[2] The CompletionType argument is SQL_COMMIT and SQLGetInfo returns SQL_CB_CLOSE for the
SQL_CURSOR_COMMIT_BEHAVIOR information type, or the CompletionType argument is SQL_ROLLBACK and
SQLGetInfo returns SQL_CB_CLOSE for the SQL_CURSOR_ROLLBACK_BEHAVIOR information type.
[3] The CompletionType argument is SQL_COMMIT and SQLGetInfo returns SQL_CB_PRESERVE for the
SQL_CURSOR_COMMIT_BEHAVIOR information type, or the CompletionType argument is SQL_ROLLBACK and
SQLGetInfo returns SQL_CB_PRESERVE for the SQL_CURSOR_ROLLBACK_BEHAVIOR information type.
SQLExecDirect
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
(IH) S4 [s] and [nr] -- [e] and [1] -- [e], [1], and See next table HY010 NS [c] HY010
S5 [s] and [r] S1 [e] and [2] [3] S1 [e], [2], [o]
S8 [d] S11 [x] S4 [s] and [nr] and [3] S4 [s],
S5 [s] and [r] [nr], and [3]
S8 [d] S11 [x] S5 [s], [r], and
[3] S8 [d] and
[3] S11 [x] and
[3] 24000 [4]
[1] This error is returned by the Driver Manager if SQLFetch or SQLFetchScroll has not returned SQL_NO_DATA,
and is returned by the driver if SQLFetch or SQLFetchScroll has returned SQL_NO_DATA.
SQLExecute
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
(IH) (HY010) See next table S2 [e], p, and See cursor HY010 NS [c] HY010
[1] S4 [s], [p], states table [o]
[nr], and [1]
S5 [s], [p], [r],
and [1] S8 [d],
[p], and [1]
S11 [x], [p],
and [1] 24000
[p] and [2]
HY010 [np]
[1] The current result is the last or only result, or there are no current results. For more information about multiple
results, see Multiple Results.
[2] The current result is not the last result.
SQLExecute (Prepared States)
S2 S3
NO RESULTS RESULTS
24000 [p] HY010 [np] 24000 [p], [1] HY010 [np] 24000 [p] HY010 [np]
[1] This error is returned by the Driver Manager if SQLFetch or SQLFetchScroll has not returned SQL_NO_DATA,
and is returned by the driver if SQLFetch or SQLFetchScroll has returned SQL_NO_DATA.
SQLExtendedFetch
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
SQLFreeHandle
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
-- [3] -- -- -- -- -- --
[1] This row shows transitions when HandleType was SQL_HANDLE_ENV or SQL_HANDLE_DBC.
[2] This row shows transitions when HandleType was SQL_HANDLE_STMT.
[3] This row shows transitions when HandleType was SQL_HANDLE_DESC and the descriptor was explicitly
allocated.
SQLFreeStmt
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
SQLGetConnectAttr
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
-- -- -- -- -- -- --
SQLGetCursorName
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
IH -- -- -- -- HY010 HY010
SQLGetData
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
24000 -- [s] or [nf] S11 [x] 24000 [b] HY109 [i] -- [s] or [nf] S11 [x] 24000 [b] HY109 [i]
IH -- [1] or [2] See next table -- [1] or [2] -- [1], [2], or HY010 NS [c] or [4]
HY010 [3] 24000 [3] [3] S11 [3] HY010 [o] and
and [x] [5]
NO RESULTS RESULTS
--[1], [2], or [3] S11[2] and [x] --[1], [2], or [3] S11 [x]
--[1] -- -- -- -- -- --
[1] This row shows transitions when HandleType was SQL_HANDLE_ENV, SQL_HANDLE_DBC, or
SQL_HANDLE_DESC.
[2] This row shows transitions when HandleType was SQL_HANDLE_STMT.
[3] SQLGetDiagField always returns an error in this state when DiagIdentifier is SQL_DIAG_ROW_COUNT.
SQLGetEnvAttr
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
-- -- -- -- -- -- --
SQLGetFunctions
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
-- -- -- -- -- -- --
SQLGetInfo
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
-- -- -- -- -- -- --
SQLGetStmtAttr
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
IH --[1] 24000[2] --[1] 24000[2] --[1] 24000[2] See next table HY010 HY010
--[1] 24000[2] --[1] or ([v] and [2]) 24000 [b] and [2] -- [i] or ([v] and [2]) 24000 [b] and [2]
HY109 [i] and [2] HY109[1] and [2]
SQLMoreResults
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
(IH) --[1] --[1] -- [s] and [2] S1 [nf], [np], HY010 NS [c] HY010
S1 [nf], [np], and [4] S3 [nf], [o]
and [4] S2 [nf], [p] and [4] S4
[p], and [4] S5 [s] and [2] S5
[s] and [3] S11 [s] and [3] S11
[x] [x]
SQLNativeSql
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
-- -- -- -- -- -- --
SQLNumParams
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
IH HY010 -- [s] S11 [x] -- [s] S11 [x] -- [s] S11 [x] HY010 NS [c] HY010
[o]
SQLNumResultCols
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
IH HY010 -- [s] S11 [x] -- [s] S11 [x] -- [s] S11 [x] HY010 NS [c] HY010
[o]
SQLParamData
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
S1 [e] and [1] S2 [e], [nr], and [2] S3 [e], HY010 S1 [e] and [1] S2 [e], [nr], and [2] S3 [e],
[r], and [2] S5 [e] and [4] S6 [e] and [5] [r], and [2] S4 [s], [nr], and ([1] or [2]) S5
S7 [e] and [3] S9 [d] S11 [x] [s], [r], and ([1] or [2]) S5 ([s] or [e]) and
[4] S6 ([s] or [e]) and [5] S7 ([s] or [e])
and [3] S9 [d] S11 [x]
SQLPrepare
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
(IH) S2 [s] and [nr] -- [s] or ([e] S1 [e] and [3] See next table HY010 NS [c] HY010
S3 [s] and [r] and [1]) S1 [e] S2 [s], [nr], [o]
S11 [x] and [2] S11 [x] and [3] S3 [s],
[r], and [3]
S11 [x] and [3]
24000[4]
[1] The preparation fails for a reason other than validating the statement (the SQLSTATE was HY009 [Invalid
argument value] or HY090 [Invalid string or buffer length]).
[2] The preparation fails while validating the statement (the SQLSTATE was not HY009 [Invalid argument value] or
HY090 [Invalid string or buffer length]).
[3] The current result is the last or only result, or there are no current results. For more information about multiple
results, see Multiple Results.
[4] The current result is not the last result.
SQLPutData
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
HY010 S1 [e] and [1] S2 [e], [nr], and [2] S3 [e], -- [s] S1 [e] and [1] S2 [e], [nr], and [2]
[r], and [2] S5 [e] and [4] S6 [e] and [5] S3 [e], [r], and [2] S5 [e] and [4] S6 [e]
S7 [e] and [3] S10 [s] S11 [x] and [5] S7 [e] and [3] S11 [x] HY011[6]
SQLRowCount
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
SQLSetConnectAttr
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
[1] This row shows transitions when Attribute was a connection attribute. For transitions when Attribute was a
statement attribute, see the statement transition table for SQLSetStmtAttr.
[2] The Attribute argument was not SQL_ATTR_CURRENT_CATALOG.
[3] The Attribute argument was SQL_ATTR_CURRENT_CATALOG.
SQLSetCursorName
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
[1] This row shows transitions where the DescriptorHandle argument is an ARD, APD, IPD, or (for
SQLSetDescField) an IRD when the FieldIdentifier argument is SQL_DESC_ARRAY_STATUS_PTR or
SQL_DESC_ROWS_PROCESSED_PTR. It is an error to call SQLSetDescField for an IRD when FieldIdentifier is any
other value.
SQLSetEnvAttr
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
SQLSetPos
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
24000 -- [s] S8 [d] S11 [x] 24000 [b] HY109 [i] -- [s] S8 [d] S11 [x] 24000 [b] HY109 [i]
SQLSetStmtAttr
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12
The following table lists string manipulation functions. An application can determine which string functions are
supported by a driver by calling SQLGetInfo with an information type of SQL_STRING_FUNCTIONS.
Remarks
Arguments denoted as string_exp can be the name of a column,a character-string-literal, or the result of another
scalar function, where the underlying data type can be represented as SQL_CHAR, SQL_VARCHAR, or
SQL_LONGVARCHAR.
Arguments denoted as character_exp are a variable-length character string.
Arguments denoted as start, length, or count can be a numeric-literal or the result of another scalar function, where
the underlying data type can be represented as SQL_TINYINT, SQL_SMALLINT, or SQL_INTEGER.
The string functions listed here are 1-based; that is, the first character in the string is character 1.
The BIT_LENGTH, CHAR_LENGTH, CHARACTER_LENGTH, OCTET_LENGTH, and POSITION string scalar functions
have been added in ODBC 3.0 to align with SQL-92.
FUNCTION DESCRIPTION
ASCII( string_exp ) (ODBC 1.0) Returns the ASCII code value of the leftmost character of
string_exp as an integer.
BIT_LENGTH( string_exp ) (ODBC 3.0) Returns the length in bits of the string expression.
Does not work only for string data types, therefore will not
implicitly convert string_exp to string but instead will return
the (internal) size of whatever datatype it is given.
CHAR( code ) (ODBC 1.0) Returns the character that has the ASCII code value specified
by code. The value of code should be between 0 and 255;
otherwise, the return value is data source–dependent.
CHAR_LENGTH( string_exp ) (ODBC 3.0) Returns the length in characters of the string expression, if the
string expression is of a character data type; otherwise, returns
the length in bytes of the string expression (the smallest
integer not less than the number of bits divided by 8). (This
function is the same as the CHARACTER_LENGTH function.)
CHARACTER_LENGTH( string_exp ) (ODBC 3.0) Returns the length in characters of the string expression, if the
string expression is of a character data type; otherwise, returns
the length in bytes of the string expression (the smallest
integer not less than the number of bits divided by 8). (This
function is the same as the CHAR_LENGTH function.)
CONCAT( string_exp1,string_exp2) (ODBC 1.0) Returns a character string that is the result of concatenating
string_exp2 to string_exp1. The resulting string is DBMS-
dependent. For example, if the column represented by
string_exp1 contained a NULL value, DB2 would return NULL
but SQL Server would return the non-NULL string.
FUNCTION DESCRIPTION
DIFFERENCE( string_exp1,string_exp2) (ODBC 2.0) Returns an integer value that indicates the difference between
the values returned by the SOUNDEX function for string_exp1
and string_exp2.
INSERT( string_exp1, start, length, string_exp2) (ODBC 1.0) Returns a character string where length characters have been
deleted from string_exp1, beginning at start, and where
string_exp2 has been inserted into string_exp, beginning at
start.
LCASE( string_exp ) (ODBC 1.0) Returns a string equal to that in string_exp, with all uppercase
characters converted to lowercase.
LEFT( string_exp, count) (ODBC 1.0) Returns the leftmost count characters of string_exp.
LENGTH( string_exp ) (ODBC 1.0) Returns the number of characters in string_exp, excluding
trailing blanks.
LOCATE( string_exp1, string_exp2[, start]) (ODBC 1.0) Returns the starting position of the first occurrence of
string_exp1 within string_exp2. The search for the first
occurrence of string_exp1 begins with the first character
position in string_exp2 unless the optional argument, start, is
specified. If start is specified, the search begins with the
character position indicated by the value of start. The first
character position in string_exp2 is indicated by the value 1. If
string_exp1 is not found within string_exp2, the value 0 is
returned.
LTRIM( string_exp ) (ODBC 1.0) Returns the characters of string_exp, with leading blanks
removed.
OCTET_LENGTH( string_exp ) (ODBC 3.0) Returns the length in bytes of the string expression. The result
is the smallest integer not less than the number of bits divided
by 8.
Does not work only for string data types, therefore will not
implicitly convert string_exp to string but instead will return
the (internal) size of whatever datatype it is given.
POSITION( character_exp IN character_exp) (ODBC 3.0) Returns the position of the first character expression in the
second character expression. The result is an exact numeric
with an implementation-defined precision and a scale of 0.
FUNCTION DESCRIPTION
REPEAT( string_exp, count) (ODBC 1.0) Returns a character string composed of string_exp repeated
count times.
REPLACE( string_exp1, string_exp2, string_exp3) (ODBC 1.0) Search string_exp1 foroccurrences of string_exp2, and replace
with string_exp3.
RIGHT( string_exp, count) (ODBC 1.0) Returns the rightmost count characters of string_exp.
RTRIM( string_exp ) (ODBC 1.0) Returns the characters of string_exp with trailing blanks
removed.
SPACE( count ) (ODBC 2.0) Returns a character string consisting of count spaces.
SUBSTRING( string_exp, start, length) (ODBC 1.0) Returns a character string that is derived from string_exp,
beginning at the character position specified by start for
length characters.
UCASE( string_exp ) (ODBC 1.0) Returns a string equal to that in string_exp, with all lowercase
characters converted to uppercase.
System Functions
12/20/2017 • 1 min to read • Edit Online
The following table lists system functions that are included in the ODBC scalar function set. By calling SQLGetInfo
with an information type of SQL_SYSTEM_FUNCTIONS, an application can determine which system functions are
supported by a driver.
Arguments denoted as exp can be the name of a column, the result of another scalar function, or a literal, where the
underlying data type could be represented as SQL_NUMERIC, SQL_DECIMAL, SQL_TINYINT, SQL_SMALLINT,
SQL_INTEGER, SQL_BIGINT, SQL_FLOAT, SQL_REAL, SQL_DOUBLE, SQL_TYPE_DATE, SQL_TYPE_TIME, or
SQL_TYPE_TIMESTAMP.
Arguments denoted as value can be a literal constant, where the underlying data type can be represented as
SQL_NUMERIC, SQL_DECIMAL, SQL_TINYINT, SQL_SMALLINT, SQL_INTEGER, SQL_BIGINT, SQL_FLOAT, SQL_REAL,
SQL_DOUBLE, SQL_TYPE_DATE, SQL_TYPE_TIME, or SQL_TYPE_TIMESTAMP.
Values returned are represented as ODBC data types.
FUNCTION DESCRIPTION
DATABASE( ) (ODBC 1.0) Returns the name of the database corresponding to the
connection handle. (The name of the database is also available
by calling SQLGetConnectOption with the
SQL_CURRENT_QUALIFIER connection option.)
IFNULL( exp,value) (ODBC 1.0) If exp is null, value is returned. If exp is not null, exp is
returned. The possible data type or types of value must be
compatible with the data type of exp.
USER( ) (ODBC 1.0) Returns the user name in the DBMS. (The user name is also
available by way of SQLGetInfo by specifying the information
type: SQL_USER_NAME.) This can be different than the login
name.
Time, Date, and Interval Functions
12/20/2017 • 4 min to read • Edit Online
The following table lists time and date functions that are included in the ODBC scalar function set. An application
can determine which time and date functions are supported by a driver by calling SQLGetInfo with an information
type of SQL_TIMEDATE_FUNCTIONS.
Arguments denoted as timestamp_exp can be the name of a column, the result of another scalar function, or an
ODBC-time-escape, ODBC-date- escape, or ODBC-timestamp-escape, where the underlying data type could be
represented as SQL_CHAR, SQL_VARCHAR, SQL_TYPE_TIME, SQL_TYPE_DATE, or SQL_TYPE_TIMESTAMP.
Arguments denoted as date_exp can be the name of a column, the result of another scalar function, or an ODBC-
date- escape or ODBC-timestamp-escape, where the underlying data type could be represented as SQL_CHAR,
SQL_VARCHAR, SQL_TYPE_DATE, or SQL_TYPE_TIMESTAMP.
Arguments denoted as time_exp can be the name of a column, the result of another scalar function, or an ODBC-
time-escape or ODBC-timestamp-escape, where the underlying data type could be represented as SQL_CHAR,
SQL_VARCHAR, SQL_TYPE_TIME, or SQL_TYPE_TIMESTAMP.
The CURRENT_DATE, CURRENT_TIME, and CURRENT_TIMESTAMP timedate scalar functions have been added in
ODBC 3.0 to align with SQL-92.
FUNCTION DESCRIPTION
CURRENT_TIME[( time-precision )] (ODBC 3.0) Returns the current local time. The time-precision argument
determines the seconds precision of the returned value.
CURRENT_TIMESTAMP Returns the current local date and local time as a timestamp
[( timestamp-precision )] (ODBC 3.0) value. The timestamp-precision argument determines the
seconds precision of the returned timestamp.
DAYNAME( date_exp ) (ODBC 2.0) Returns a character string containing the data source–specific
name of the day (for example, Sunday through Saturday or
Sun. through Sat. for a data source that uses English, or
Sonntag through Samstag for a data source that uses
German) for the day portion of date_exp.
DAYOFMONTH( date_exp ) (ODBC 1.0) Returns the day of the month based on the month field in
date_exp as an integer value in the range of 1–31.
DAYOFWEEK( date_exp ) (ODBC 1.0) Returns the day of the week based on the week field in
date_exp as an integer value in the range of 1–7, where 1
represents Sunday.
DAYOFYEAR( date_exp ) (ODBC 1.0) Returns the day of the year based on the year field in
date_exp as an integer value in the range of 1–366.
FUNCTION DESCRIPTION
EXTRACT( extract-field FROM extract-source ) (ODBC 3.0) Returns the extract-field portion of the extract-source. The
extract-source argument is a datetime or interval expression.
The extract-field argument can be one of the following
keywords:
HOUR( time_exp ) (ODBC 1.0) Returns the hour based on the hour field in time_exp as an
integer value in the range of 0–23.
MINUTE( time_exp ) (ODBC 1.0) Returns the minute based on the minute field in time_exp as
an integer value in the range of 0–59.
MONTH( date_exp ) (ODBC 1.0) Returns the month based on the month field in date_exp as
an integer value in the range of 1–12.
MONTHNAME( date_exp ) (ODBC 2.0) Returns a character string containing the data source–specific
name of the month (for example, January through December
or Jan. through Dec. for a data source that uses English, or
Januar through Dezember for a data source that uses
German) for the month portion of date_exp.
NOW( ) (ODBC 1.0) Returns current date and time as a timestamp value.
QUARTER( date_exp ) (ODBC 1.0) Returns the quarter in date_exp as an integer value in the
range of 1–4, where 1 represents January 1 through March
31.
SECOND( time_exp ) (ODBC 1.0) Returns the second based on the second field in time_exp as
an integer value in the range of 0–59.
FUNCTION DESCRIPTION
TIMESTAMPADD( interval, integer_exp, timestamp_exp ) Returns the timestamp calculated by adding integer_exp
(ODBC 2.0) intervals of type interval to timestamp_exp. Valid values of
interval are the following keywords:
SQL_TSI_FRAC_SECOND
SQL_TSI_SECOND
SQL_TSI_MINUTE
SQL_TSI_HOUR
SQL_TSI_DAY
SQL_TSI_WEEK
SQL_TSI_MONTH
SQL_TSI_QUARTER
SQL_TSI_YEAR
TIMESTAMPDIFF( interval, timestamp_exp1, Returns the integer number of intervals of type interval by
timestamp_exp2 ) (ODBC 2.0) which timestamp_exp2 is greater than timestamp_exp1. Valid
values of interval are the following keywords:
SQL_TSI_FRAC_SECOND
SQL_TSI_SECOND
SQL_TSI_MINUTE
SQL_TSI_HOUR
SQL_TSI_DAY
SQL_TSI_WEEK
SQL_TSI_MONTH
SQL_TSI_QUARTER
SQL_TSI_YEAR
WEEK( date_exp ) (ODBC 1.0) Returns the week of the year based on the week field in
date_exp as an integer value in the range of 1–53.
YEAR( date_exp ) (ODBC 1.0) Returns the year based on the year field in date_exp as an
integer value. The range is data source–dependent.
Transfer Octet Length
12/20/2017 • 1 min to read • Edit Online
The transfer octet length of a column is the maximum number of bytes returned to the application when data is
transferred to its default C data type. For character data, the transfer octet length does not include space for the
null-termination character. The transfer octet length of a column may be different than the number of bytes
required to store the data on the data source.
The transfer octet length defined for each ODBC SQL data type is shown in the following table.
All character types[a] The defined or the maximum (for variable type) length of the
column in bytes. This is the same value as the descriptor field
SQL_DESC_OCTET_LENGTH.
SQL_TINYINT 1
SQL_SMALLINT 2
SQL_INTEGER 4
SQL_REAL 4
SQL_FLOAT 8
SQL_DOUBLE 8
SQL_BIT 1
All binary types[a] The number of bytes required to hold the defined (for fixed
types) or maximum (for variable types) number of characters.
[a] If the driver cannot determine the column or parameter length for variable types, it returns SQL_NO_TOTAL.
Transferring Data in Its Binary Form
12/20/2017 • 1 min to read • Edit Online
An application can safely transfer data (in the internal form used by a specified DBMS) between two data sources
that use the same DBMS and hardware platform. For a given piece of data, the SQL data types must be the same in
the source and target data sources. The C data type is SQL_C_BINARY.
When the application calls SQLFetch, SQLFetchScroll, or SQLGetData to retrieve the data from the source data
source, the driver retrieves the data from the data source and transfers it, without conversion, to a storage location
of type SQL_C_BINARY. When the application calls SQLBulkOperations, SQLExecute, SQLExecDirect,
SQLPutData, or SQLSetPos to send the data to the target data source, the driver retrieves the data from the
storage location and transfers it, without conversion, to the target data source.
NOTE
Applications that transfer any data (except binary data) in this manner are not interoperable among DBMSs.
SQLCopyDesc can be used to copy row bindings from the source DBMS to parameter bindings in the target
DBMS.
Using Data Type Identifiers
12/20/2017 • 1 min to read • Edit Online
Applications use data type identifiers in two ways: to describe their buffers to the driver, and to retrieve metadata
about the result set from the driver so that they can determine what type of C buffers to use to store the data.
Applications call the following functions to perform these tasks:
SQLBindParameter, SQLBindCol, and SQLGetData — to describe the C data type of application buffers.
SQLBindParameter — to describe the SQL data type of dynamic parameters.
SQLColAttribute and SQLDescribeCol — to retrieve the SQL data types of result set columns.
SQLDescribeParameter — to retrieve the SQL data types of parameters.
SQLColumns, SQLProcedureColumns, and SQLSpecialColumns — to retrieve the SQL data types of
various schema information
SQLGetTypeInfo — to retrieve a list of supported data types
Data type identifiers are stored in the SQL_DESC_CONCISE_TYPE field of a descriptor. The descriptor
functions SQLSetDescField and SQLSetDescRec can be used with the appropriate types to perform the
tasks listed in the previous list. For more information, see SQLSetDescField.
Using the ODBC Cursor Library
12/20/2017 • 1 min to read • Edit Online
IMPORTANT
This feature will be removed in a future version of Windows. Avoid using this feature in new development work and plan to
modify applications that currently use this feature. Microsoft recommends using the driver's cursor functionality.
The following table summarizes what functions and statement attributes an ODBC 3.x driver should implement for
block and scrollable cursors.
FUNCTION OR
SQL_ATTR_ROW_STATUS_PTR Sets the address of the row status array filled by SQLFetch
and SQLFetchScroll. This array is also filled by SQLSetPos if
SQLSetPos is called in statement state S6. If SQLSetPos is
called in state S7, this array is not filled but the array pointed
to by the RowStatusArray argument of SQLExtendedFetch is
filled. For more information, see Statement Transitions in
Appendix B: ODBC State Transition Tables.
SQLBulkOperations If an ODBC 3.x driver should work with ODBC 2.x applications
that use SQLSetPos with an Operation of SQL_ADD, the
driver must support SQLSetPos with an Operation of
SQL_ADD in addition to SQLBulkOperations with an
Operation of SQL_ADD.
FUNCTION OR
SQLExtendedFetch Returns the specified rowset. ODBC 3.x drivers implement this
if they want to work with ODBC 2.x applications that call
SQLExtendedFetch or SQLSetPos. The following are
implementation details:
- The driver retrieves the rowset size from the value of the
SQL_ROWSET_SIZE statement attribute.
- The driver retrieves the address of the row status array from
the RowStatusArray argument, not the
SQL_ATTR_ROW_STATUS_PTR statement attribute. The
RowStatusArray argument in a call to SQLExtendedFetch
must not be a null pointer. (Note that in ODBC 3.x, the
SQL_ATTR_ROW_STATUS_PTR statement attribute can be a
null pointer.)
- The driver retrieves the address of the rows fetched buffer
from the RowCountPtr argument, not the
SQL_ATTR_ROWS_FETCHED_PTR statement attribute.
- The driver returns SQLSTATE 01S01 (Error in row) to indicate
that an error has occurred while rows were fetched by a call to
SQLExtendedFetch. An ODBC 3.x driver should return
SQLSTATE 01S01 (Error in row) only when
SQLExtendedFetch is called, not when SQLFetch or
SQLFetchScroll is called. To preserve backward compatibility,
when SQLSTATE 01S01 (Error in row) is returned by
SQLExtendedFetch, the Driver Manager does not order
status records in the error queue according to the rules stated
in the "Sequence of Status Records" section of
SQLGetDiagField.
- The driver retrieves the rowset size from the value of the
SQL_ATTR_ROW_ARRAY_SIZE statement attribute.
- The driver retrieves the address of the row status array from
the SQL_ATTR_ROW_STATUS_PTR statement attribute.
- The driver retrieves the address of the rows fetched buffer
from the SQL_ATTR_ROWS_FETCHED_PTR statement attribute.
- The application can mix calls between SQLFetchScroll and
SQLFetch.
- SQLFetch returns bookmarks if column 0 is bound.
- SQLFetch can be called to return more than one row.
- The driver does not return SQLSTATE 01S01 (Error in row) to
indicate that an error has occurred while rows were fetched by
a call to SQLFetch.
FUNCTION OR
The following table summarizes how the ODBC 3.x Driver Manager maps calls to ODBC 2.x and ODBC 3.x drivers.
FUNCTION OR
SQL_ATTR_ROW_ARRAY_SIZE Sets the rowset size. The following are implementation details:
SQLExtendedFetch Returns the specified rowset. Except for the restriction just
noted, the ODBC 3.x Driver Manager passes calls to
SQLExtendedFetch to the driver, regardless of the driver
version.
FUNCTION OR
The C type for the SQL_C_SBIGINT and SQL_C_UBIGINT data type identifiers on Microsoft C compilers is _int64.
When a compiler other than a Microsoft® C compiler is used, the C type might be different. If the compiler
supports 64-bit integers natively, the driver or application should define ODBCINT64 to be the native 64-bit integer
type. If the compiler does not support 64-bit integers natively, an application or driver can define the following
structures to ensure that it has access to this data:
typedef struct{
SQLUINTEGER dwLowWord;
SQLUINTEGER dwHighWord;
} SQLUBIGINT
typedef struct{
SQLUINTEGER dwLowWord;
SQLINTEGER sdwHighWord;
} SQLBIGINT
These structures should be aligned to an 8-byte boundary because a 64-bit integer is aligned to the 8-byte
boundary.