0% found this document useful (0 votes)
99 views

ODBC SQL Microsoft

The document discusses ODBC error codes and SQLSTATE values that can be returned by ODBC functions. It provides tables listing the SQLSTATE values, their meaning, and the functions that can return each error code.

Uploaded by

hrasko
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
99 views

ODBC SQL Microsoft

The document discusses ODBC error codes and SQLSTATE values that can be returned by ODBC functions. It provides tables listing the SQLSTATE values, their meaning, and the functions that can return each error code.

Uploaded by

hrasko
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 297

Table of Contents

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.

SQLSTATE ERROR CAN BE RETURNED FROM

01000 General warning All ODBC functions except:

SQLError

SQLGetDiagField

SQLGetDiagRec

01001 Cursor operation conflict SQLExecDirect

SQLExecute

SQLParamData

SQLSetPos

01002 Disconnect error SQLDisconnect

01003 NULL value eliminated in set function SQLExecDirect

SQLExecute

SQLParamData
SQLSTATE ERROR CAN BE RETURNED FROM

01004 String data, right-truncated SQLBrowseConnect

SQLBulkOperations

SQLColAttribute

SQLDataSources

SQLDescribeCol

SQLDriverConnect

SQLDrivers

SQLExecDirect

SQLExecute

SQLExtendedFetch

SQLFetch

SQLFetchScroll

SQLGetConnectAttr

SQLGetCursorName

SQLGetData

SQLGetDescField

SQLGetDescRec

SQLGetEnvAttr

SQLGetInfo

SQLGetStmtAttr

SQLNative

Sql SQLParamData

SQLPutData

SQLSetCursorName

01006 Privilege not revoked SQLExecDirect

SQLExecute

SQLParamData

01007 Privilege not granted SQLExecDirect

SQLExecute

SQLParamData
SQLSTATE ERROR CAN BE RETURNED FROM

01S00 Invalid connection string attribute SQLBrowseConnect

SQLDriverConnec

01S01 Error in row SQLBulkOperations

SQLExtendedFetch

SQLSetPos

01S02 Option value changed SQLBrowseConnect

SQLConnect

SQLDriverConnect

SQLExecDirect

SQLExecute

SQLParamData

SQLPrepare

SQLSetConnectAttr

SQLSetDescField

SQLSetEnvAttr

SQLSetStmtAttr

01S06 Attempt to fetch before the result set SQLExtendedFetch


returned the first rowset
SQLFetchScroll

01S07 Fractional truncation SQLBulkOperations

SQLExecDirect

SQLExecute

SQLExtendedFetch

SQLFetch

SQLFetchScroll

SQLGetData

SQLParamData

SQLSetPos

01S08 Error saving File DSN SQLDriverConnect

01S09 Invalid keyword SQLDriverConnect


SQLSTATE ERROR CAN BE RETURNED FROM

07001 Wrong number of parameters SQLExecDirect

SQLExecute

07002 COUNT field incorrect SQLExecDirect

SQLExecute

SQLParamData

07005 Prepared statement not a cursor- SQLColAttribute


specification
SQLDescribeCol

07006 Restricted data type attribute violation SQLBindCol

SQLBindParameter

SQLBulkOperations

SQLExecDirect

SQLExecute

SQLExtendedFetch

SQLFetch

SQLFetchScroll

SQLGetData

SQLParamData

SQLPutData

SQLSetPos
SQLSTATE ERROR CAN BE RETURNED FROM

07009 Invalid descriptor index SQLBindCol

SQLBindParameter

SQLBulkOperations

SQLColAttribute

SQLDescribeCol

SQLDescribeParam

SQLFetch

SQLFetchScroll

SQLGetData

SQLGetDescField

SQLGetDescRec

SQLParamData

SQLSetDescField

SQLSetDescRecSQLSetPos

07S01 Invalid use of default parameter SQLExecDirect

SQLExecute

SQLParamData

SQLPutData

08001 Client unable to establish connection SQLBrowseConnect

SQLConnect

SQLDriverConnect

08002 Connection name in use SQLBrowseConnect

SQLConnect

SQLDriverConnect

SQLSetConnectAttr
SQLSTATE ERROR CAN BE RETURNED FROM

08003 Connection not open SQLAllocHandle

SQLDisconnect

SQLEndTran

SQLGetConnectAttr

SQLGetInfo

SQLNativeSql

SQLSetConnectAttr

08004 Server rejected the connection SQLBrowseConnect

SQLConnect

SQLDriverConnect

08007 Connection failure during transaction SQLEndTran

08S01 Communication link failure SQLBrowseConnect

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

21S01 Insert value list does not match column SQLExecDirect


list
SQLPrepare

21S02 Degree of derived table does not match SQLBulkOperations


column list
SQLExecDirect

SQLExecute

SQLParamData

SQLPrepare

SQLSetPos
SQLSTATE ERROR CAN BE RETURNED FROM

22001 String data, right-truncated SQLBulkOperations

SQLExecDirect

SQLExecute

SQLFetch

SQLFetchScroll

SQLParamData

SQLPutData

SQLSetDescField

SQLSetPos

22002 Indicator variable required but not SQLExecDirect


supplied
SQLExecute

SQLExtendedFetch

SQLFetch

SQLFetchScroll

SQLGetData

SQLParamData

22003 Numeric value out of range SQLBulkOperations

SQLExecDirect

SQLExecute

SQLExtendedFetch

SQLFetch

SQLFetchScroll

SQLGetData

SQLGetInfo

SQLParamData

SQLPutData

SQLSetPos
SQLSTATE ERROR CAN BE RETURNED FROM

22007 Invalid datetime format SQLBulkOperations

SQLExecDirect

SQLExecute

SQLExtendedFetch

SQLFetch

SQLFetchScroll

SQLGetData

SQLParamData

SQLPutData

SQLSetPos

22008 Datetime field overflow SQLBulkOperations

SQLExecDirect

QLParamData

SQLPutData

22012 Division by zero SQLExecDirect

SQLExecute

SQLExtendedFetch

SQLFetch

SQLFetchScroll

SQLGetData

SQLPutData
SQLSTATE ERROR CAN BE RETURNED FROM

22015 Interval field overflow SQLBulkOperations

SQLExecDirect

SQLExecute

SQLExtendedFetch

SQLFetch

SQLFetchScroll

SQLGetData

SQLParamData

SQLPutData

SQLSetPos

22018 Invalid character value for cast SQLBulkOperations


specification
SQLExecDirect

SQLExecute

SQLExtendedFetch

SQLFetch

SQLFetchScroll

SQLGetData

SQLParamData

SQLPutData

SQLSetPos

22019 Invalid escape character SQLExecDirect

SQLExecute

SQLPrepare

22025 Invalid escape sequence SQLExecDirect

SQLExecute

SQLPrepare

22026 String data, length mismatch SQLParamData


SQLSTATE ERROR CAN BE RETURNED FROM

23000 Integrity constraint violation SQLBulkOperations

SQLExecDirect

SQLExecute

SQLParamData

SQLSetPos

24000 Invalid cursor state SQLBulkOperations

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

25000 Invalid transaction state SQLDisconnect

25S01 Transaction state SQLEndTran

25S02 Transaction is still active SQLEndTran

25S03 Transaction is rolled back SQLEndTran

28000 Invalid authorization specification SQLBrowseConnect

SQLConnect

SQLDriverConnect

34000 Invalid cursor name SQLExecDirect

SQLPrepare

SQLSetCursorName

3C000 Duplicate cursor name SQLSetCursorName

3D000 Invalid catalog name SQLExecDirect

SQLPrepare

SQLSetConnectAttr

3F000 Invalid schema name SQLExecDirect

SQLPrepare
SQLSTATE ERROR CAN BE RETURNED FROM

40001 Serialization failure SQLBulkOperations

SQLColumnPrivileges

SQLColumns

SQLEndTran

SQLExecDirect

SQLExecute

SQLFetch

SQLFetchScroll

SQLForeignKeys

SQLGetTypeInfo

SQLMoreResults

SQLParamData

SQLPrimaryKeys

SQLProcedureColumns

SQLProcedures

SQLSetPos

SQLSpecialColumns

SQLStatistics

SQLTablePrivileges

SQLTables

40002 Integrity constraint violation SQLEndTran


SQLSTATE ERROR CAN BE RETURNED FROM

40003 Statement completion unknown SQLBulkOperations

SQLColumnPrivileges

SQLColumns

SQLExecDirect

SQLExecute

SQLFetch

SQLFetchScroll

SQLForeignKeys

SQLGetTypeInfo

SQLMoreResults

SQLPrimaryKeys

SQLProcedureColumns

SQLProcedures

SQLParamData

SQLSetPos

SQLSpecialColumns

SQLStatistics

SQLTablePrivileges

SQLTables

42000 Syntax error or access violation SQLBulkOperations

SQLExecDirect

SQLExecute

SQLParamData

SQLPrepare

SQLSetPos

42S01 Base table or view already exists SQLExecDirect

SQLPrepare

42S02 Base table or view not found SQLExecDirect

SQLPrepare
SQLSTATE ERROR CAN BE RETURNED FROM

42S11 Index already exists SQLExecDirect

SQLPrepare

42S12 Index not found SQLExecDirect

SQLPrepare

42S21 Column already exists SQLExecDirect

SQLPrepare

42S22 Column not found SQLExecDirect

SQLPrepare

44000 WITH CHECK OPTION violation SQLBulkOperations

SQLExecDirect

SQLExecute

SQLParamData

SQLSetPos

HY000 General error All ODBC functions except:

SQLError

SQLGetDiagField

SQLGetDiagRec

HY001 Memory allocation error All ODBC functions except:

SQLError

SQLGetDiagField

SQLGetDiagRec

HY003 Invalid application buffer type SQLBindCol

SQLBindParameter

SQLGetData

HY004 Invalid SQL data type SQLBindParameter

SQLGetTypeInfo

HY007 Associated statement is not prepared SQLCopyDesc

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

HY009 Invalid use of null pointer SQLAllocHandle

SQLBindParameter

SQLBulkOperations

SQLColumnPrivileges

SQLColumns

SQLExecDirect

SQLForeignKeys

SQLGetCursorName

SQLGetData

SQLGetFunctions

SQLNativeSql

SQLPrepare

SQLPrimaryKeys

SQLProcedureColumns

SQLProcedures

SQLPutData

SQLSetConnectAttr

SQLSetCursorName

SQLSetEnvAttr

SQLSetStmtAttr

SQLSpecialColumns

SQLStatistics

SQLTablePrivileges

SQLTables

HY010 Function sequence error SQLAllocHandle

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

HY011 Attribute cannot be set now SQLBulkOperations

SQLParamData

QLSetPos

SQLSetStmtAttr

HY012 Invalid transaction operation code SQLEndTran

HY013 Memory management error All ODBC functions except:

SQLGetDiagField

SQLGetDiagRec

HY014 Limit on the number of handles SQLAllocHandle


exceeded

HY015 No cursor name available SQLGetCursorName

HY016 Cannot modify an implementation row SQLCopyDesc


descriptor
SQLSetDescField

SQLSetDescRec

HY017 Invalid use of an automatically allocated SQLFreeHandle


descriptor handle
SQLSetStmtAttr

HY018 Server declined cancel request SQLCancel

HY019 Non-character and non-binary data SQLPutData


sent in pieces
SQLSTATE ERROR CAN BE RETURNED FROM

HY020 Attempt to concatenate a null value SQLPutData

HY021 Inconsistent descriptor information SQLBindParameter

SQLCopyDesc

SQLGetDescField

SQLSetDescField

SQLSetDescRec

HY024 Invalid attribute value SQLSetConnectAttr

SQLSetEnvAttr

SQLSetStmtAttr

HY090 Invalid string or buffer length SQLBindCol

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

HY091 Invalid descriptor field identifier SQLColAttribute

SQLGetDescField

SQLSetDescField
SQLSTATE ERROR CAN BE RETURNED FROM

HY092 Invalid attribute/option identifier SQLAllocHandle

QLBulkOperations

SQLCopyDesc

SQLDriverConnect

SQLEndTran

SQLFreeStmt

SQLGetConnectAttr

SQLGetEnvAttr

QLParamData

SQLSetConnectAttr

SQLSetDescField

SQLSetEnvAttr

SQLSetPos

SQLSetStmtAttr

HY095 Function type out of range SQLGetFunctions

HY096 Invalid information type SQLGetInfo

HY097 Column type out of range SQLSpecialColumns

HY098 Scope type out of range SQLSpecialColumns

HY099 Nullable type out of range SQLSpecialColumns

HY100 Uniqueness option type out of range SQLStatistics

HY101 Accuracy option type out of range SQLStatistics

HY103 Invalid retrieval code SQLDataSources

SQLDrivers

HY104 Invalid precision or scale value SQLBindParameter

HY105 Invalid parameter type SQLBindParameter

SQLExecDirect

SQLExecute

SQLParamData

SQLSetDescField
SQLSTATE ERROR CAN BE RETURNED FROM

HY106 Fetch type out of range SQLExtendedFetch

SQLFetchScroll

HY107 Row value out of range SQLExtendedFetch

SQLFetch

SQLFetchScroll

SQLSetPos

HY109 Invalid cursor position SQLExecDirect

SQLExecute

SQLGetData

SQLGetStmtAttr

SQLNativeSql

SQLParamData

SQLSetPos

HY110 Invalid driver completion SQLDriverConnect

HY111 Invalid bookmark value SQLExtendedFetch

SQLFetchScroll

HYC00 Optional feature not implemented SQLBindCol

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

HYT00 Timeout expired SQLBrowseConnect

SQLBulkOperations

SQLColumnPrivileges

SQLColumns

SQLConnect

SQLDriverConnect

SQLExecDirect

SQLExecute

SQLExtendedFetch

SQLForeignKeys

SQLGetTypeInfo

SQLParamData

SQLPrepare

SQLPrimaryKeys

SQLProcedureColumns

SQLProcedures

SQLSetPos

SQLSpecialColumns

SQLStatistics

SQLTablePrivileges

SQLTables

HYT01 Connection timeout expired All ODBC functions except:

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

IM002 Data source name not found and no SQLBrowseConnect


default driver specified
SQLConnect

SQLDriverConnect

IM003 Specified driver could not be loaded SQLBrowseConnect

SQLConnect

SQLDriverConnect

IM004 Driver's SQLAllocHandle on SQLBrowseConnect


SQL_HANDLE_ENV failed
SQLConnect

SQLDriverConnect

IM005 Driver's SQLAllocHandle on SQLBrowseConnect


SQL_HANDLE_DBC failed
SQLConnect

SQLDriverConnect

IM006 Driver's SQLSetConnectAttr failed SQLBrowseConnect

SQLConnect

SQLDriverConnect

IM007 No data source or driver specified; SQLDriverConnect


dialog prohibited

IM008 Dialog failed SQLDriverConnect

IM009 Unable to load translation DLL SQLBrowseConnect

SQLConnect

SQLDriverConnect

SQLSetConnectAttr
SQLSTATE ERROR CAN BE RETURNED FROM

IM010 Data source name too long SQLBrowseConnect

SQLConnect

SQLDriverConnect

IM011 Driver name too long SQLBrowseConnect

SQLDriverConnect

IM012 DRIVER keyword syntax error SQLBrowseConnect

SQLDriverConnect

IM013 Trace file error All ODBC functions.

IM014 Invalid name of File DSN SQLDriverConnect

IM015 Corrupt file data source SQLDriverConnect


Appendix B: ODBC State Transition Tables
12/20/2017 • 5 min to read • Edit Online

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:

The connection and statement states overlap as follows:

The statement and descriptor states overlap as follows:

The connection and descriptor states overlap as follows:

Each entry in a transition table can be one of the following values:


-- —The state is unchanged after executing the function.
E
n , C*n, **Sn, or *D*n* — The environment, connection, statement, or descriptor state moves to the specified
state.
(IH) — An invalid handle was passed to the function. If the handle was a null handle or was a valid handle of
the wrong type — for example, a connection handle was passed when a statement handle was required —
the function returns SQL_INVALID_HANDLE; otherwise the behavior is undefined and probably fatal. This
error is shown only when it is the only possible outcome of calling the function in the specified state. This
error does not change the state and is always detected by the Driver Manager, as indicated by the
parentheses.
NS — Next State. The statement transition is the same as if the statement had not gone through the
asynchronous states. For example, suppose a statement that creates a result set enters state S11 from state
S1 because SQLExecDirect returned SQL_STILL_EXECUTING. The NS notation in state S11 means that the
transitions for the statement are the same as those for a statement in state S1 that creates a result set. If
SQLExecDirect returns an error, the statement remains in state S1; if it succeeds, the statement moves to
state S5; if it needs data, the statement moves to state S8; and if it is still executing, it remains in state S11.
XXXXX or (XXXXX) — An SQLSTATE that is related to the transition table; SQLSTATEs detected by the Driver
Manager are enclosed in parentheses. The function returned SQL_ERROR and the specified SQLSTATE, but
the state does not change. For example, if SQLExecute is called before SQLPrepare, it returns SQLSTATE
HY010 (Function sequence error).

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

b Before or after. The cursor was positioned before the start of


the result set or after the end of the result set.

c Current function. The current function was executing


asynchronously.

d Need data. The function returned SQL_NEED_DATA.

e Error. The function returned SQL_ERROR.

i Invalid row. The cursor was positioned on a row in the result


set and either the row had been deleted or an error had
occurred in an operation on the row. If the row status array
existed, the value in the row status array for the row was
SQL_ROW_DELETED or SQL_ROW_ERROR. (The row status
array is pointed to by the SQL_ATTR_ROW_STATUS_PTR
statement attribute.)

nf Not found. The function returned SQL_NO_DATA. This does


not apply when SQLExecDirect, SQLExecute, or
SQLParamData returns SQL_NO_DATA after executing a
searched update or delete statement.

np Not prepared. The statement was not prepared.


FOOTNOTE MEANING

nr No results. The statement will not or did not create a result


set.

o Other function. Another function was executing


asynchronously.

p Prepared. The statement was prepared.

r Results. The statement will or did create a (possibly empty)


result set.

s Success. The function returned SQL_SUCCESS_WITH_INFO or


SQL_SUCCESS.

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.)

x Executing. The function returned SQL_STILL_EXECUTING.

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

UNALLOCATED ALLOCATED CONNECTION

(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

This appendix contains the following topics.


SQL Minimum Grammar
ODBC Escape Sequences
Literals in ODBC
Reserved Keywords
Appendix D: Data Types
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.

ODBC and SQL-92 Scalar Functions


The tables in this appendix include functions that have been added in ODBC 3.0 to align with SQL-92. Those
functions added for a particular type of scalar function, as defined in ODBC, are indicated in each section.
ODBC and SQL-92 classify their scalar functions differently. ODBC classifies scalar functions by argument type;
SQL-92 classifies them by return value. For example, the EXTRACT function is classified as a timedate function by
ODBC, because the extract-field argument is a datetime keyword and the extract-source argument is a datetime or
interval expression. SQL-92, on the other hand, classifies EXTRACT as a numeric scalar function, because the return
value is a numeric.
An application can determine which scalar functions a driver supports by calling SQLGetInfo. Information types
are included both for ODBC and for SQL-92 classifications of scalar functions. Because these classifications are
different, the support for some scalar functions may be indicated in information types that do not correspond to
ODBC and SQL-92. For example, support for EXTRACT in ODBC is indicated by the SQL_TIMEDATE_FUNCTIONS
information type; support for EXTRACT in SQL-92, on the other hand, is indicated by the
SQL_SQL92_NUMERIC_VALUE_FUNCTIONS information type.
Appendix F: ODBC Cursor Library
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 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.

C TYPE IDENTIFIER ODBC C TYPEDEF C TYPE

SQL_C_BOOKMARK BOOKMARK unsigned long int


(Deprecated)

SQL_C_VARBOOKMARK SQLCHAR * unsigned char *


C Data Types
12/20/2017 • 4 min to read • Edit Online

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.

C TYPE IDENTIFIER ODBC C TYPEDEF C TYPE

SQL_C_CHAR SQLCHAR * unsigned char *

SQL_C_WCHAR SQLWCHAR * wchar_t *

SQL_C_SSHORT[j] SQLSMALLINT short int

SQL_C_USHORT[j] SQLUSMALLINT unsigned short int

SQL_C_SLONG[j] SQLINTEGER long int

SQL_C_ULONG[j] SQLUINTEGER unsigned long int

SQL_C_FLOAT SQLREAL float

SQL_C_DOUBLE SQLDOUBLE, SQLFLOAT double

SQL_C_BIT SQLCHAR unsigned char

SQL_C_STINYINT[j] SQLSCHAR signed char

SQL_C_UTINYINT[j] SQLCHAR unsigned char

SQL_C_SBIGINT SQLBIGINT _int64[h]

SQL_C_UBIGINT SQLUBIGINT unsigned _int64[h]

SQL_C_BINARY SQLCHAR * unsigned char *

SQL_C_BOOKMARK[i] BOOKMARK unsigned long int[d]


C TYPE IDENTIFIER ODBC C TYPEDEF C TYPE

SQL_C_VARBOOKMARK SQLCHAR * unsigned char *

All C interval data types SQL_INTERVAL_STRUCT See the C Interval Structure section,
later in this appendix.

C type identifier SQL_C_TYPE_DATE[c]


ODBC C typedef SQL_DATE_STRUCT
C type

struct tagDATE_STRUCT {
SQLSMALLINT year;
SQLUSMALLINT month;
SQLUSMALLINT day;
} DATE_STRUCT;[a]

C type identifier SQL_C_TYPE_TIME[c]


ODBC C typedef SQL_TIME_STRUCT
C type

struct tagTIME_STRUCT {
SQLUSMALLINT hour;
SQLUSMALLINT minute;
SQLUSMALLINT second;
} TIME_STRUCT;[a]

C type identifier SQL_C_TYPE_TIMESTAMP[c]


ODBC C typedef SQL_TIMESTAMP_STRUCT
C type

struct tagTIMESTAMP_STRUCT {
SQLSMALLINT year;
SQLUSMALLINT month;
SQLUSMALLINT day;
SQLUSMALLINT hour;
SQLUSMALLINT minute;
SQLUSMALLINT second;
SQLUINTEGER fraction;[b]
} TIMESTAMP_STRUCT;[a]

C type identifier SQL_C_NUMERIC


ODBC C typedef SQL_NUMERIC_STRUCT
C type
struct tagSQL_NUMERIC_STRUCT {
SQLCHAR precision;
SQLSCHAR scale;
SQLCHAR sign[g];
SQLCHAR val[SQL_MAX_NUMERIC_LEN];[e], [f]
} SQL_NUMERIC_STRUCT;

C type identifier SQL_C_GUID


ODBC C typedef SQLGUID
C type

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.

SQL_NUMERIC_STRUCT code sample


This code sample shows you how to:
Set the precision.
Set the scale.
Retrieve the correct values.

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

SQLHENV henv = SQL_NULL_HENV;


SQLHDBC hdbc1 = SQL_NULL_HDBC;
SQLHSTMT hstmt1 = SQL_NULL_HSTMT;
SQLHDESC hdesc = NULL;

SQL_NUMERIC_STRUCT NumStr;

int main()
{
RETCODE retcode;

//Change the values below as appropriate to make a successful connection.


//szDSN: DataSourceName, szUID=userid, szAuthStr: password

UCHAR szDSN[MAXDSN+1] = "sql33",szUID[MAXUID+1]="sa", szAuthStr[MAXAUTHSTR+1] = "";


SQLINTEGER strlen1;
SQLINTEGER a;
int i,sign =1;
long myvalue, divisor;
float final_val;

// Allocate the Environment handle. Set the Env attribute, allocate the
//connection handle, connect to the database and allocate the statement //handle.

retcode = SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv);


retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,(SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1);
retcode = SQLConnect(hdbc1, szDSN,SQL_NTS,szUID,SQL_NTS,szAuthStr,SQL_NTS);
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc1, &hstmt1);

// Execute the select statement. Here it is assumed that numeric_test


//table is created using the following statements:

// Create table numeric_test (col1 numeric(5,3))


//insert into numeric_test values (25.212)

retcode = SQLExecDirect(hstmt1,(UCHAR *)"select * from numeric_test",SQL_NTS);

// 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.

retcode = SQLGetStmtAttr(hstmt1, SQL_ATTR_APP_ROW_DESC,&hdesc, 0, NULL);

// You can either use SQLSetDescRec or SQLSetDescField when using


// SQLBindCol. However, if you prefer to call SQLGetData, you have to
// call SQLSetDescField instead of SQLSetDescRec. For more information on
// descriptors, please refer to the ODBC 3.0 Programmers reference or
// your Online documentation.

//Used when using SQLSetDescRec


//a=b=sizeof(NumStr);
// Set the datatype, precision and scale fields of the descriptor for the
//numeric column. Otherwise the default precision (driver defined) and
//scale (0) are returned.

// 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);

retcode = SQLSetDescField (hdesc,1,SQL_DESC_TYPE,(VOID*)SQL_C_NUMERIC,0);


retcode = SQLSetDescField (hdesc,1,SQL_DESC_PRECISION,(VOID*) 5,0);
retcode = SQLSetDescField (hdesc,1,SQL_DESC_SCALE,(VOID*) 3,0);

// Initialize the val array in the numeric structure.

memset(NumStr.val,0,16);

// Call SQLFetch to fetch the first record.

while((retcode =SQLFetch(hstmt1)) != SQL_NO_DATA)


{
// Notice that the TargetType (3rd Parameter) is SQL_ARD_TYPE, which
//forces the driver to use the Application Row Descriptor with the
//specified scale and precision.

retcode = SQLGetData(hstmt1, 1, SQL_ARD_TYPE, &NumStr, 19, &a);

// Check for null indicator.

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.

if(!NumStr.sign) sign = -1;


else sign =1;

final_val *= sign;
printf("The final value: %f\n",final_val);
}

while ( ( retcode = SQLMoreResults(hstmt1) ) != SQL_NO_DATA_FOUND);


/* clean up */
SQLFreeHandle(SQL_HANDLE_STMT, hstmt1);
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return(0);
}

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() {

SQLHENV henv = NULL;


SQLHDBC hdbc = NULL;
SQLHSTMT hstmt = NULL;

SQL_NUMERIC_STRUCT NumStr;
SQLINTEGER cbNumStr = sizeof (NumStr);

SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);

/* Set the ODBC behavior version. */


SQLSetEnvAttr(henv,
SQL_ATTR_ODBC_VERSION,
(SQLPOINTER) SQL_OV_ODBC3,
SQL_IS_INTEGER);

SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);

/* Substitute your own connection information */


SQLConnect(hdbc,
(SQLCHAR *) "MyDSN", 5,
(SQLCHAR *) "UserID", 6,
(SQLCHAR *) "Password", 8);

SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);

/*
Set up the SQL_NUMERIC_STRUCT, NumStr, to hold "123.45".

First, we need to scale 123.45 to an integer: 12345


One way to switch the bytes is to convert 12345 to Hex: 0x3039
Since the least significant byte will be stored starting from the
leftmost byte, "0x3039" will be stored as "0x3930".

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.
*/

NumStr.sign = 1; /* 1 if positive, 2 if negative */

memset (NumStr.val, 0, 16);


NumStr.val [0] = 0x39;
NumStr.val [1] = 0x30;

/* SQLBindParameter needs to be called before SQLSetDescField */


SQLBindParameter(hstmt,
1,
SQL_PARAM_INPUT,
SQL_C_NUMERIC,
SQL_NUMERIC,
5,
2,
&NumStr,
0,
(SQLINTEGER *) &cbNumStr);

/* Modify the fields in the implicit application parameter descriptor */


SQLHDESC hdesc = NULL;

SQLGetStmtAttr(hstmt, SQL_ATTR_APP_PARAM_DESC, &hdesc, 0, NULL);


SQLSetDescField(hdesc, 1, SQL_DESC_TYPE, (SQLPOINTER) SQL_C_NUMERIC, 0);
SQLSetDescField(hdesc, 1, SQL_DESC_PRECISION, (SQLPOINTER) 5, 0);
SQLSetDescField(hdesc, 1, SQL_DESC_SCALE, (SQLPOINTER) 2, 0);
SQLSetDescField(hdesc, 1, SQL_DESC_DATA_PTR, (SQLPOINTER) &NumStr, 0);

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:

typedef struct tagSQL_INTERVAL_STRUCT


{
SQLINTERVAL interval_type;
SQLSMALLINT interval_sign;
union {
SQL_YEAR_MONTH_STRUCT year_month;
SQL_DAY_SECOND_STRUCT day_second;
} intval;
} SQL_INTERVAL_STRUCT;
typedef enum
{
SQL_IS_YEAR = 1,
SQL_IS_MONTH = 2,
SQL_IS_DAY = 3,
SQL_IS_HOUR = 4,
SQL_IS_MINUTE = 5,
SQL_IS_SECOND = 6,
SQL_IS_YEAR_TO_MONTH = 7,
SQL_IS_DAY_TO_HOUR = 8,
SQL_IS_DAY_TO_MINUTE = 9,
SQL_IS_DAY_TO_SECOND = 10,
SQL_IS_HOUR_TO_MINUTE = 11,
SQL_IS_HOUR_TO_SECOND = 12,
SQL_IS_MINUTE_TO_SECOND = 13
} SQLINTERVAL;

typedef struct tagSQL_YEAR_MONTH


{
SQLUINTEGER year;
SQLUINTEGER month;
} SQL_YEAR_MONTH_STRUCT;

typedef struct tagSQL_DAY_SECOND


{
SQLUINTEGER day;
SQLUINTEGER hour;
SQLUINTEGER minute;
SQLUINTEGER second;
SQLUINTEGER fraction;
} SQL_DAY_SECOND_STRUCT;

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 :

SQL TYPE COLUMN SQL DATA

C TYPE IDENTIFIER C DATA VALUE IDENTIFIER LENGTH VALUE SQLSTATE

SQL_C_CHAR abcdef\0[a] SQL_CHAR 6 abcdef n/a

SQL_C_CHAR abcdef\0[a] SQL_CHAR 5 abcde 22001

SQL_C_CHAR 1234.56\0[a] SQL_DECIMAL 8[b] 1234.56 n/a

SQL_C_CHAR 1234.56\0[a] SQL_DECIMAL 7[b] 1234.5 22001

SQL_C_CHAR 1234.56\0[a] SQL_DECIMAL 4 ---- 22003

SQL_C_FLOAT 1234.56 SQL_FLOAT n/a 1234.56 n/a

SQL_C_FLOAT 1234.56 SQL_INTEGER n/a 1234 22001

SQL_C_FLOAT 1234.56 SQL_TINYINT n/a ---- 22003

SQL_C_TYPE_DAT 1992,12,31[c] SQL_CHAR 10 1992-12-31 n/a


E

SQL_C_TYPE_DAT 1992,12,31[c] SQL_CHAR 9 ---- 22003


E

SQL_C_TYPE_DAT 1992,12,31[c] SQL_TIMESTAMP n/a 1992-12-31 n/a


E 00:00:00.0

SQL_C_TYPE_TIM 1992,12,31, SQL_CHAR 22 1992-12-31 n/a


ESTAMP 23,45,55, 23:45:55.12
120000000[d]

SQL_C_TYPE_TIM 1992,12,31, SQL_CHAR 21 1992-12-31 22001


ESTAMP 23,45,55, 23:45:55.1
120000000[d]

SQL_C_TYPE_TIM 1992,12,31, SQL_CHAR 18 ---- 22003


ESTAMP 23,45,55,
120000000[d]

[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

The identifier for the binary ODBC C data type is:


SQL_C_BINARY
The following table shows the ODBC SQL data types to which binary 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 TYPE IDENTIFIER TEST SQLSTATE

SQL_CHAR Byte length of data <= Column byte n/a


length
SQL_VARCHAR 22001
Byte length of data > Column byte
SQL_LONGVARCHAR length

SQL_WCHAR Character length of data <= Column n/a


character length
SQL_WVARCHAR 22001
Character length of data > Column
SQL_WLONGVARCHAR character length

SQL_DECIMAL Byte length of data = SQL data length n/a

SQL_NUMERIC Byte length of data <> SQL data length 22003

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_BINARY Length of data <= column length n/a

SQL_VARBINARY Length of data > column length 22001

SQL_LONGVARBINARY
C to SQL: Bit
12/20/2017 • 1 min to read • Edit Online

The identifier for the bit ODBC C data type is:


SQL_C_BIT
The following table shows the ODBC SQL data types to which bit 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 TYPE IDENTIFIER TEST SQLSTATE

SQL_CHAR SQL_VARCHAR None n/a

SQL_LONGVARCHAR

SQL_WCHAR SQL_WVARCHAR

SQL_WLONGVARCHAR

SQL_DECIMAL SQL_NUMERIC None n/a

SQL_TINYINT SQL_SMALLINT

SQL_INTEGER SQL_BIGINT

SQL_REAL SQL_FLOAT

SQL_DOUBLE

SQL_BIT None n/a

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

The identifiers for the character ODBC C data type are:


SQL_C_CHAR
SQL_C_WCHAR
The following table shows the ODBC SQL data types to which C character data may be converted. For an
explanation of the columns and terms in the table, see Converting Data from C to SQL Data Types.

NOTE
When character C data is converted to Unicode SQL data, the length of the Unicode data must be an even number.

SQL TYPE IDENTIFIER TEST SQLSTATE

SQL_CHAR Byte length of data <= Column length. n/a

SQL_VARCHAR Byte length of data > Column length. 22001

SQL_LONGVARCHAR

SQL_WCHAR Character length of data <= Column n/a


length.
SQL_WVARCHAR 22001
Character length of data > Column
SQL_WLONGVARCHAR length.

SQL_DECIMAL Data converted without truncation n/a

SQL_NUMERIC Data converted with truncation of 22001


fractional digits[e]
SQL_TINYINT 22001
Conversion of data would result in loss
SQL_SMALLINT of whole (as opposed to fractional) 22018
digits[e]
SQL_INTEGER SQL_BIGINT
Data value is not a numeric-literal

SQL_REAL Data is within the range of the data n/a


type to which the number is being
SQL_FLOAT converted 22003

SQL_DOUBLE Data is outside the range of the data 22018


type to which the number is being
converted

Data value is not a numeric-literal


SQL TYPE IDENTIFIER TEST SQLSTATE

SQL_BIT Data is 0 or 1 n/a

Data is greater than 0, less than 2, and 22001


not equal to 1
22003
Data is less than 0 or greater than or
equal to 2 22018

Data is not a numeric-literal

SQL_BINARY (Byte length of data) / 2 <= column n/a


byte length
SQL_VARBINARY 22001
(Byte length of data) / 2 > column byte
SQL_LONGVARBINARY length 22018

Data value is not a hexadecimal value

SQL_TYPE_DATE Data value is a valid ODBC-date-literal n/a

Data value is a valid ODBC-timestamp- n/a


literal; time portion is zero
22008
Data value is a valid ODBC-timestamp-
literal; time portion is nonzero[a] 22018

Data value is not a valid ODBC-date-


literal or ODBC-timestamp-literal

SQL_TYPE_TIME Data value is a valid ODBC-time-literal n/a

Data value is a valid ODBC-timestamp- n/a


literal; fractional seconds portion is
zero[b] 22008

Data value is a valid ODBC-timestamp- 22018


literal; fractional seconds portion is
nonzero[b]

Data value is not a valid ODBC-time-


literal or ODBC-timestamp-literal

SQL_TYPE_TIMESTAMP Data value is a valid ODBC-timestamp- n/a


literal; fractional seconds portion not
truncated 22008

Data value is a valid ODBC-timestamp- n/a


literal; fractional seconds portion
truncated n/a

Data value is a valid ODBC-date- 22018


literal[c]

Data value is a valid ODBC-time-


literal[d]

Data value is not a valid ODBC-date-


literal, ODBC-time-literal, or ODBC-
timestamp-literal
SQL TYPE IDENTIFIER TEST SQLSTATE

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

The data value is not a valid interval


literal

[a] The time portion of the timestamp is truncated.


[b] The date portion of the timestamp is ignored.
[c] The time portion of the timestamp is set to zero.
[d] The date portion of the timestamp is set to the current date.
[e] The driver/data source effectively waits until the entire string has been received (even if the character data is
sent in pieces by calls to SQLPutData) before attempting to perform the conversion.
When character C data is converted to numeric, date, time, or timestamp SQL data, leading and trailing blanks are
ignored.
When character C data is converted to binary SQL data, each two bytes of character data are converted to a single
byte (8 bits) of binary data. Each two bytes of character data represent a number in hexadecimal form. For example,
"01" is converted to a binary 00000001 and "FF" is converted to a binary 11111111.
The driver always converts pairs of hexadecimal digits to individual bytes and ignores the null-termination byte.
Because of this, if the length of the character string is odd, the last byte of the string (excluding the null-termination
byte, if any) is not converted.

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 identifier for the date ODBC C data type is:


SQL_C_TYPE_DATE
The following table shows the ODBC SQL data types to which date 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 TYPE IDENTIFIER TEST SQLSTATE

SQL_CHAR Column byte length >= 10 n/a

SQL_VARCHAR Column byte length < 10 22001

SQL_LONGVARCHAR Data value is not a valid date 22008

SQL_WCHAR Column character length >= 10 n/a

SQL_WVARCHAR Column character length < 10 22001

SQL_WLONGVARCHAR Data value is not a valid date 22008

SQL_TYPE_DATE Data value is a valid date n/a

Data value is not a valid date 22007

SQL_TYPE_TIMESTAMP Data value is a valid date[a] n/a

Data value is not a valid date 22007

[a] The time portion of the timestamp is set to zero.


For information about what values are valid in a SQL_C_TYPE_DATE structure, see C Data Types, earlier in this
appendix.
When date C data is converted to character SQL data, the resulting character data is in the "yyyy-mm-dd" format.
The driver ignores the length/indicator value when converting data from the date C data type and assumes that the
size of the data buffer is the size of the date 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: Day-Time Intervals
12/20/2017 • 2 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 TYPE IDENTIFIER TEST SQLSTATE

SQL_CHAR[a] Column byte length >= Character byte n/a


length
SQL_VARCHAR[a] 22001
Column byte length < Character byte
SQL_LONGVARCHAR[a] length[a] 22015

Data value is not a valid interval literal

SQL_WCHAR[a] Column character length >= Character n/a


length of data
SQL_WVARCHAR[a] 22001
Column character length < Character
SQL_WLONGVARCHAR[a] length of data[a] 22015

Data value is not a valid interval literal

SQL_TINYINT[b] Conversion of a single-field interval did n/a


not result in truncation of whole digits
SQL_SMALLINT[b] SQL_INTEGER[b] 22003
Conversion resulted in truncation of
SQL_BIGINT[b] SQL_NUMERIC[b] whole digits

SQL_DECIMAL[b]
SQL TYPE IDENTIFIER TEST SQLSTATE

SQL_INTERVAL_DAY Data value was converted without n/a


truncation of any fields
SQL_INTERVAL_HOUR 22015
One or more fields of data value were
SQL_INTERVAL_MINUTE truncated during conversion

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;

// Initialize the interval struct to contain the DAY_TO_SECOND


// interval "154 days, 22 hours, 44 minutes, and 10 seconds"
is.intval.day_second.day = 154;
is.intval.day_second.hour = 22;
is.intval.day_second.minute = 44;
is.intval.day_second.second = 10;
is.interval_sign = SQL_FALSE;

// Bind the dynamic parameter


SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_INTERVAL_DAY_TO_SECOND,
SQL_INTERVAL_DAY_TO_MINUTE, 0, 0, &is,
sizeof(SQL_INTERVAL_STRUCT), &cbValue);

// Execute an insert statement; "interval_column" is a column


// whose data type is SQL_INTERVAL_DAY_TO_MINUTE.
SQLExecDirect(hstmt,"INSERT INTO table(interval_column) VALUES (?)",SQL_NTS);
C to SQL: GUID
12/20/2017 • 1 min to read • Edit Online

The identifier for the GUID ODBC C data type is:


SQL_C_GUID
The following table shows the ODBC SQL data types to which GUID 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 TYPE IDENTIFIER TEST SQLSTATE

SQL_CHAR Column byte length >= 36 n/a

SQL_VARCHAR Column byte length < 36 22001

SQL_LONGVARCHAR Data value is not a valid GUID 22018

SQL_WCHAR Column character length >= 36 n/a

SQL_WVARCHAR Column character length < 36 22001

SQL_WLONGVARCHAR Data value is not a valid GUID 22018

SQL_GUID None[a] n/a

[a] All hexidecimal values are valid as a GUID.


The driver ignores the length/indicator value when converting data from the GUID C data type and assumes that
the size of the data buffer is the size of the GUID 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: Numeric
12/20/2017 • 1 min to read • Edit Online

The identifiers for the numeric ODBC C data types are:


SQL_C_STINYINT
SQL_C_SLONG
SQL_C_UTINYINT
SQL_C_ULONG
SQL_C_TINYINT
SQL_C_LONG
SQL_C_SSHORT
SQL_C_FLOAT
SQL_C_USHORT
SQL_C_DOUBLE
SQL_C_SHORT
SQL_C_NUMERIC
SQL_C_SBIGINT
SQL_C_UBIGINT
The following table shows the ODBC SQL data types to which numeric 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 TYPE IDENTIFIER TEST SQLSTATE

SQL_CHAR Number of digits <= Column byte n/a


length
SQL_VARCHAR 22001
Number of digits > Column byte length
SQL_LONGVARCHAR

SQL_WCHAR Number of characters <= Column n/a


character length
SQL_WVARCHAR 22001
Number of characters > Column
SQL_WLONGVARCHAR character length
SQL TYPE IDENTIFIER TEST SQLSTATE

SQL_DECIMAL[b] Data converted without truncation or n/a


with truncated of fractional digits
SQL_NUMERIC[b] 22003
Data converted with truncation of
SQL_TINYINT[b] whole digits

SQL_SMALLINT[b]

SQL_INTEGER[b]

SQL_BIGINT[b]

SQL_REAL Data is within the range of the data n/a


type to which the number is being
SQL_FLOAT converted 22003

SQL_DOUBLE Data is outside the range of the data


type to which the number is being
converted

SQL_BIT Data is 0 or 1 n/a

Data is greater than 0, less than 2, and 22001


not equal to 1
22003
Data is less than 0 or greater than or
equal to 2

SQL_INTERVAL_YEAR[a] Data not truncated. n/a

SQL_INTERVAL_MONTH[a] Data truncated. 22015

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

The identifier for the timestamp ODBC C data type is:


SQL_C_TYPE_TIMESTAMP
The following table shows the ODBC SQL data types to which timestamp 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 TYPE IDENTIFIER TEST SQLSTATE

SQL_CHAR Column byte length >= Character byte n/a


length
SQL_VARCHAR 22001
19 <= Column byte length < Character
SQL_LONGVARCHAR byte length 22001

Column byte length < 19 22008

Data value is not a valid timestamp

SQL_WCHAR Column character length >= Character n/a


length of data
SQL_WVARCHAR 22001
19 <= Column character length <
SQL_WLONGVARCHAR Character length of data 22001

Column character length < 19 22008

Data value is not a valid timestamp

SQL_TYPE_DATE Time fields are zero n/a

Time fields are nonzero 22008

Data value does not contain a valid 22007


date

SQL_TYPE_TIME Fractional seconds fields are zero[a] n/a

Fractional seconds fields are nonzero[a] 22008

Data value does not contain a valid 22007


time

SQL_TYPE_TIMESTAMP Fractional seconds fields are not n/a


truncated
22008
Fractional seconds fields are truncated
22007
Data value is not a valid timestamp

[a] The date fields of the timestamp structure are ignored.


For information about what values are valid in a SQL_C_TIMESTAMP structure, see C Data Types, earlier in this
appendix.
When timestamp C data is converted to character SQL data, the resulting character data is in the "yyyy-mm-dd
hh:mm:ss[.f...]" format.
The driver ignores the length/indicator value when converting data from the timestamp C data type and assumes
that the size of the data buffer is the size of the timestamp 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: Time
12/20/2017 • 1 min to read • Edit Online

The identifier for the time ODBC C data type is:


SQL_C_TYPE_TIME
The following table shows the ODBC SQL data types to which time 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 TYPE IDENTIFIER TEST SQLSTATE

SQL_CHAR Column byte length >= 8 n/a

SQL_VARCHAR Column byte length < 8 22001

SQL_LONGVARCHAR Data value is not a valid time 22008

SQL_WCHAR Column character length >= 8 n/a

SQL_WVARCHAR Column character length < 8 22001

SQL_WLONGVARCHAR Data value is not a valid time 22008

SQL_TYPE_TIME Data value is a valid time n/a

Data value is not a valid time 22007

SQL_TYPE_TIMESTAMP Data value is a valid time[a] n/a

Data value is not a valid time 22007

[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 TYPE IDENTIFIER TEST SQLSTATE

SQL_CHAR[a] Column byte length >= Character byte n/a


length
SQL_VARCHAR[a] 22001
Column byte length < Character byte
SQL_LONGVARCHAR[a] length[a] 22015

Data value is not a valid interval literal

SQL_WCHAR[a] Column character length >= Character n/a


length of data
SQL_WVARCHAR[a] 22001
Column character length < Character
SQL_WLONGVARCHAR[a] length of data[a] 22015

Data value is not a valid interval literal

SQL_TINYINT[b] Conversion of a single-field interval did n/a


not result in truncation of whole digits
SQL_SMALLINT[b] 22003
Conversion resulted in truncation of
SQL_INTEGER[b] whole digits

SQL_BIGINT[b]

SQL_NUMERIC[b]

SQL_DECIMAL[b]

SQL_INTERVAL_MONTH Data value was converted without n/a


truncation of any fields
SQL_INTERVAL_YEAR 22015
One or more fields of data value were
SQL_INTERVAL_YEAR_TO_MONTH truncated during conversion

[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.

SQL TYPE IDENTIFIER COLUMN SIZE

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_BIGINT[c] 19 (if signed) or 20 (if unsigned)

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.

SQL_TYPE_DATE[c] 10 (the number of characters in the yyyy-mm-dd format).

SQL_TYPE_TIME[c] 8 (the number of characters in the hh-mm-ss format), or 9 +


s (the number of characters in the hh:mm:ss[.fff...] format,
where s is the seconds precision).
SQL TYPE IDENTIFIER COLUMN SIZE

SQL_TYPE_TIMESTAMP 16 (the number of characters in the yyyy-mm-dd hh:mm


format)

19 (the number of characters in the yyyy-mm-dd hh:mm:ss


format)

or

20 + s (the number of characters in the yyyy-mm-dd


hh:mm:ss[.fff...] format, where s is the seconds precision).

SQL_INTERVAL_SECOND Where p is the interval leading precision and s is the seconds


precision, p (if s=0) or p+s+1 (if s>0).[d]

SQL_INTERVAL_DAY_TO_SECOND Where p is the interval leading precision and s is the seconds


precision, 9+p (if s=0) or 10+p+s (if s>0).[d]

SQL_INTERVAL_HOUR_TO_SECOND Where p is the interval leading precision and s is the seconds


precision, 6+p (if s=0) or 7+p+s (if s>0).[d]

SQL_INTERVAL_MINUTE_TO_SECOND Where p is the interval leading precision and s is the seconds


precision, 3+p (if s=0) or 4+p+s (if s>0).[d]

SQL_INTERVAL_YEAR SQL_INTERVAL_MONTH p, where p is the interval leading precision.[d]


SQL_INTERVAL_DAY SQL_INTERVAL_HOUR
SQL_INTERVAL_MINUTE

SQL_INTERVAL_YEAR_TO_MONTH 3+p, where p is the interval leading precision.[d]


SQL_INTERVAL_DAY_TO_HOUR

SQL_INTERVAL_DAY_TO_MINUTE 6+p, where p is the interval leading precision.[d]

SQL_INTERVAL_HOUR_TO_MINUTE 3+p, where p is the interval leading precision.[d]

SQL_GUID 36 (the number of characters in the aaaaaaaa-bbbb-cccc-


dddd-eeeeeeeeeeee format)

[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 TYPE COLUMN OR PARAMETER SIZE

All character and binary types LENGTH

All numeric types PRECISION

All datetime and interval types LENGTH

SQL_BIT LENGTH
Connection Transitions
12/20/2017 • 8 min to read • Edit Online

ODBC connections have the following states.

STATE DESCRIPTION

C0 Unallocated environment, unallocated connection

C1 Allocated environment, unallocated connection

C2 Allocated environment, allocated connection

C3 Connection function needs data

C4 Connected connection

C5 Connected connection, allocated statement

C6 Connected connection, transaction in progress. It is possible


for a connection to be in state C6 with no statements
allocated on the connection. For example, suppose the
connection is in manual commit mode and is in state C4. If a
statement is allocated, executed (starting a transaction), and
then freed, the transaction remains active but there are no
statements on the 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

C1[1] --[5] --[5] --[5] --[5] --[5] --[5]

(IH)[2] C2 --[5] --[5] --[5] --[5] --[5]

(IH)[3] (IH) (08003) (08003) C5 --[5] --[5]

(IH)[4] (IH) (08003) (08003) --[5] --[5] --[5]

[1] This row shows transitions when HandleType was SQL_HANDLE_ENV.


[2] This row shows transitions when HandleType was SQL_HANDLE_DBC.
[3] This row shows transitions when HandleType was SQL_HANDLE_STMT.
[4] This row shows transitions when HandleType was SQL_HANDLE_DESC.
[5] Calling SQLAllocHandle with OutputHandlePtr pointing to a valid handle overwrites that handle without
regard for the previous contents ofthat handle, and might cause problems for ODBC drivers. It is incorrect ODBC
application programming to call SQLAllocHandle twice with the same application variable defined for
*OutputHandlePtr without calling SQLFreeHandle to free the handle before reallocating it. Overwriting ODBC
handles in such a manner can lead to inconsistent behavior or errors on the part of ODBC drivers.

SQLBrowseConnect
C0 C1 C2 C3 C4 C5 C6

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

(IH) (IH) C3 [d] C4 [s] -- [d] C2 [e] (08002) (08002) (08002)


C4 [s]

SQLCloseCursor
C0 C1 C2 C3 C4 C5 C6

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

(IH) (IH) (IH) (IH) (IH) -- --[1] C5[2]

[1] The connection was in manual-commit mode.


[2] The connection was in auto-commit mode.

SQLColumnPrivileges, SQLColumns, SQLForeignKeys,


SQLGetTypeInfo, SQLPrimaryKeys, SQLProcedureColumns,
SQLProcedures, SQLSpecialColumns, SQLStatistics,
SQLTablePrivileges, and SQLTables
C0 C1 C2 C3 C4 C5 C6

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

(IH) (IH) (IH) (IH) (IH) --[1] C6[2] --

[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

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

(IH) (IH) C4 (08002) (08002) (08002) (08002)

SQLCopyDesc, SQLGetDescField, SQLGetDescRec, SQLSetDescField,


and SQLSetDescRec
C0 C1 C2 C3 C4 C5 C6

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

(IH) (IH) (IH) (IH) --[1] -- --

[1] In this state, the only descriptors available to the application are explicitly allocated descriptors.

SQLDataSources and SQLDrivers


C0 C1 C2 C3 C4 C5 C6

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

(IH) -- -- -- -- -- --

SQLDisconnect
C0 C1 C2 C3 C4 C5 C6

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

(IH) (IH) (08003) C2 C2 C2 25000

SQLDriverConnect
C0 C1 C2 C3 C4 C5 C6

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

(IH) (IH) C4 s -- n[f] (08002) (08002) (08002) (08002)

SQLEndTran
C0 C1 C2 C3 C4 C5 C6

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

(IH)[1] --[3] --[3] --[3] -- -- --[4] or ([5],


[6], and [8])
C4[5] and [7]
C5[5], [6], and
[9]

(IH)[2] (IH) (08003) (08003) -- -- C5

[1] This row shows transitions when HandleType was SQL_HANDLE_ENV.


[2] This row shows transitions when HandleType was SQL_HANDLE_DBC.
[3] Because the connection is not in a connected state, it is unaffected by the transaction.
[4] The commit or rollback failed on the connection. The function returns SQL_ERROR in this case.
[5] The commit or rollback succeeded on the connection. The function returns SQL_ERROR if the commit or
rollback failed on another connection, or the function returns SQL_SUCCESS if the commit or rollback succeeded
on all connections.
[6] There was at least one statement allocated on the connection.
[7] There were no statements allocated on the connection.
[8] The connection had at least one statement for which there was an open cursor, and the data source preserves
cursors when transactions are committed or rolled back, whichever applies (depending on whether
CompletionType was SQL_COMMIT or SQL_ROLLBACK). For more information, see the
SQL_CURSOR_COMMIT_BEHAVIOR and SQL_CURSOR_ROLLBACK_BEHAVIOR attributes in SQLGetInfo.
[9] If the connection had any statements for which there were open cursors, the cursors were not preserved when
the transaction was committed or rolled back.

SQLExecDirect and SQLExecute


C0 C1 C2 C3 C4 C5 C6

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

(IH) (IH) (IH) (IH) (IH) --[1] C6[2] --


C6[3]

[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

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

(IH)[1] C0 (HY010) (HY010) (HY010) (HY010) (HY010)

(IH)[2] (IH) (C1) (HY010) (HY010) (HY010) (HY010)

(IH)[3] (IH) (IH) (IH) (IH) C4[5] --[6] --[7] C4[5]


and [8] C5[6]
and [8]

(IH)[4] (IH) (IH) (IH) -- -- --

[1] This row shows transitions when HandleType was SQL_HANDLE_ENV.


[2] This row shows transitions when HandleType was SQL_HANDLE_DBC.
[3] This row shows transitions when HandleType was SQL_HANDLE_STMT.
[4] This row shows transitions when HandleType was SQL_HANDLE_DESC.
[5] There was only one statement allocated on the connection.
[6] There were multiple statements allocated on the connection.
[7] The connection was in manual-commit mode.
[8] The connection was in auto-commit mode.

SQLFreeStmt
C0 C1 C2 C3 C4 C5 C6

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

(IH)[1] (IH) (IH) (IH) (IH) -- C5[3] --[4]

(IH)[2] (IH) (IH) (IH) (IH) -- --

[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

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

IH IH --[1] 08003[2] HY010 -- -- --

[1] The Attribute argument was SQL_ATTR_ACCESS_MODE, SQL_ATTR_AUTOCOMMIT,


SQL_ATTR_LOGIN_TIMEOUT, SQL_ATTR_ODBC_CURSORS, SQL_ATTR_TRACE, or SQL_ATTR_TRACEFILE, or a value
had been set for the connection attribute.
[2] The Attribute argument was not SQL_ATTR_ACCESS_MODE, SQL_ATTR_AUTOCOMMIT,
SQL_ATTR_LOGIN_TIMEOUT, SQL_ATTR_ODBC_CURSORS, SQL_ATTR_TRACE, or SQL_ATTR_TRACEFILE, and a
value had not been set for the connection attribute.

SQLGetDiagField and SQLGetDiagRec


C0 C1 C2 C3 C4 C5 C6

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

(IH)[1] -- -- -- -- -- --

(IH)[2] (IH) -- -- -- -- --

(IH)[3] (IH) (IH) (IH) (IH) -- --

(IH)[4] (IH) (IH) (IH) -- -- --

[1] This row shows transitions when HandleType was SQL_HANDLE_ENV.


[2] This row shows transitions when HandleType was SQL_HANDLE_DBC.
[3] This row shows transitions when HandleType was SQL_HANDLE_STMT.
[4] This row shows transitions when HandleType was SQL_HANDLE_DESC.

SQLGetEnvAttr
C0 C1 C2 C3 C4 C5 C6

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

IH -- -- -- -- -- --

SQLGetFunctions
C0 C1 C2 C3 C4 C5 C6

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

IH IH HY010 HY010 -- -- --

SQLGetInfo
C0 C1 C2 C3 C4 C5 C6

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

IH IH --[1] 08003[2] 08003 -- -- --

[1] The InfoType argument was SQL_ODBC_VER.


[2] The InfoType argument was not SQL_ODBC_VER.

SQLMoreResults
C0 C1 C2 C3 C4 C5 C6

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

(IH) (IH) (IH) (IH) (IH) --[1] C6[2] --[3] C5[1]

[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

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

(IH) (IH) (08003) (08003) -- -- --


SQLPrepare
C0 C1 C2 C3 C4 C5 C6

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

(IH) (IH) (IH) (IH) (IH) --[1] C6[2] --

[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

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

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]

[1] The Attribute argument was not SQL_ATTR_TRANSLATE_LIB or SQL_ATTR_TRANSLATE_OPTION.


[2] The Attribute argument was SQL_ATTR_TRANSLATE_LIB or SQL_ATTR_TRANSLATE_OPTION.
[3] The Attribute argument was not SQL_ATTR_ODBC_CURSORS or SQL_ATTR_PACKET_SIZE.
[4] The Attribute argument was SQL_ATTR_ODBC_CURSORS.
[5] The Attribute argument was SQL_ATTR_PACKET_SIZE.
[6] The Attribute argument was not SQL_ATTR_AUTOCOMMIT, or the Attribute argument was
SQL_ATTR_AUTOCOMMIT and setting this attribute did not commit the transaction.
[7] The Attribute argument was SQL_ATTR_TXN_ISOLATION.
[8] The Attribute argument was SQL_ATTR_AUTOCOMMIT, and setting this attribute committed the transaction.

SQLSetEnvAttr
C0 C1 C2 C3 C4 C5 C6

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

(IH) -- -- (HY010) -- -- --

All Other ODBC Functions


C0 C1 C2 C3 C4 C5 C6

NO ENV. UNALLOCATED ALLOCATED NEED DATA CONNECTED STATEMENT TRANSACTION

(IH) (IH) (IH) (IH) (IH) -- --


Constraints of the Gregorian Calendar
12/20/2017 • 1 min to read • Edit Online

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];

SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);


SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, SQL_OV_ODBC3,0);
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);

// Specify that the ODBC Cursor Library is always used, then connect.

SQLSetConnectAttr(hdbc, SQL_ATTR_ODBC_CURSORS, SQL_CUR_USE_ODBC);


SQLConnect(hdbc, "SalesOrder", SQL_NTS,
"JohnS", SQL_NTS,
"Sesame", SQL_NTS);

if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {

/* Allocate a statement handle for the result set and a statement */


/* handle for positioned update statements. */

SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt1);


SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt2);

/* Specify an updatable static cursor with 20 rows of data. Set */


/* the cursor name, execute the SELECT statement, and bind the */
/* rowset buffers to result set columns in column-wise fashion. */
SQLSetStmtAttr(hstmt1, SQL_ATTR_CONCURRENCY, SQL_CONCUR_VALUES, 0);
SQLSetStmtAttr(hstmt1, SQL_ATTR_CURSOR_TYPE, SQL_CURSOR_STATIC, 0);
SQLSetStmtAttr(hstmt1, SQL_ATTR_ROW_ARRAY_SIZE, ROWS, 0);
SQLSetStmtAttr(hstmt1, SQL_ATTR_ROW_STATUS_PTR, RowStatusArray, 0);
SQLSetStmtAttr(hstmt1, SQL_ATTR_ROWS_FETCHED_PTR, &crow, 0);
SQLSetCursorName(hstmt1, "ORDERCURSOR", SQL_NTS);
SQLExecDirect(hstmt1,
"SELECT ORDERID, OPENDATE, STATUS FROM ORDERS ",
SQL_NTS);
SQLBindCol(hstmt1, 1, SQL_C_SSHORT, sOrderID, 0, cbName);
SQLBindCol(hstmt1, 2, SQL_C_CHAR, szOpenDate, OPENDATE_LEN, cbOpenDate);
SQLBindCol(hstmt1, 3, SQL_C_CHAR, szStatus, STATUS_LEN, cbStatus);

/* 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 {

SQLFetchScroll(hstmt1, FetchOrientation, FetchOffset);


DisplayRows(sOrderID, szOpenDate, szStatus, RowStatusArray);

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);
}

while (PromptScroll(&FetchOrientation, &FetchOffset) != DONE)


}
Data Type Identifiers and Descriptors
12/20/2017 • 1 min to read • Edit Online

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).

CONCISE SQL TYPE CONCISE C TYPE VERBOSE TYPE DATETIME_INTERVAL_CODE

SQL_TYPE_DATE SQL_C_TYPE_DATE SQL_DATETIME SQL_CODE_DATE

SQL_TYPE_TIME SQL_C_TYPE_TIME SQL_DATETIME SQL_CODE_TIME

SQL_TYPE_TIMESTAMP SQL_C_TYPE_TIMESTAMP SQL_DATETIME SQL_CODE_TIMESTAMP

SQL_INTERVAL_MONTH SQL_C_INTERVAL_MONTH SQL_INTERVAL SQL_CODE_MONTH

SQL_INTERVAL_YEAR SQL_C_INTERVAL_YEAR SQL_INTERVAL SQL_CODE_YEAR

SQL_INTERVAL_YEAR_TO_M SQL_C_INTERVAL_YEAR_TO_ SQL_INTERVAL SQL_CODE_YEAR_TO_MONT


ONTH MONTH H

QL_INTERVAL_DAY SQL_C_INTERVAL_DAY SQL_INTERVAL SQL_CODE_DAY

SQL_INTERVAL_HOUR SQL_C_INTERVAL_HOUR SQL_INTERVAL SQL_CODE_HOUR

SQL_INTERVAL_MINUTE SQL_C_INTERVAL_MINUTE SQL_INTERVAL SQL_CODE_MINUTE

SQL_INTERVAL_SECOND SQL_C_INTERVAL_SECOND SQL_INTERVAL SQL_CODE_SECOND

SQL_INTERVAL_DAY_TO_HO SQL_C_INTERVAL_DAY_TO_ SQL_INTERVAL SQL_CODE_DAY_TO_HOUR


UR HOUR
CONCISE SQL TYPE CONCISE C TYPE VERBOSE TYPE DATETIME_INTERVAL_CODE

SQL_INTERVAL_DAY_TO_MI SQL_C_INTERVAL_DAY_TO_ SQL_INTERVAL SQL_CODE_DAY_TO_MINUT


NUTE MINUTE E

QL_INTERVAL_DAY_TO_SEC SQL_C_INTERVAL_DAY_TO_S SQL_INTERVAL SQL_CODE_DAY_TO_SECON


OND ECOND D

SQL_INTERVAL_HOUR_TO_ SQL_C_INTERVAL_HOUR_TO SQL_INTERVAL SQL_CODE_HOUR_TO_MIN


MINUTE _MINUTE UTE

SQL_INTERVAL_HOUR_TO_S SQL_C_INTERVAL_HOUR_TO SQL_INTERVAL SQL_CODE_HOUR_TO_SECO


ECOND _SECOND ND

SQL_INTERVAL_MINUTE_TO SQL_C_INTERVAL_MINUTE_T SQL_INTERVAL SQL_CODE_MINUTE_TO_SE


_SECOND O_SECOND COND
Data Type Support
12/20/2017 • 1 min to read • Edit Online

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'}

In BNF notation, the syntax is as follows:

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 TYPE DECIMAL DIGITS

All character and binary types[a] n/a

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 exact numeric types other than SQL_DECIMAL and 0


SQL_NUMERIC[a]

All approximate data types[a] n/a

SQL_TYPE_DATE, and all interval types with no seconds n/a


component[a]

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.

DESCRIPTOR FIELD CORRESPONDING TO

SQL TYPE DECIMAL DIGITS

All character and binary types n/a

All exact numeric types SCALE


DESCRIPTOR FIELD CORRESPONDING TO

SQL TYPE DECIMAL DIGITS

SQL_BIT n/a

All approximate numeric types n/a

All datetime types PRECISION

All interval types with a seconds component PRECISION

All interval types with no seconds component n/a


Default C Data Types
12/20/2017 • 1 min to read • Edit Online

If an application specifies SQL_C_DEFAULT in SQLBindCol, SQLGetData, or SQLBindParameter, the driver


assumes that the C data type of the output or input buffer corresponds to the SQL data type of the column or
parameter to which the buffer is bound.

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

ODBC descriptors have the following three states.

STATE DESCRIPTION

D0 Unallocated descriptor

D1i Implicitly allocated descriptor

D1e Explicitly allocated descriptor

The following tables show how each ODBC function affects the descriptor state.

SQLAllocHandle
D0 D1I D1E

UNALLOCATED IMPLICIT EXPLICIT

D1i[1] -- --

D1e[2] -- --

[1] This row shows transitions when HandleType was SQL_HANDLE_STMT.


[2] This row shows transitions when HandleType was SQL_HANDLE_DESC.

SQLCopyDesc
D0 D1I D1E

UNALLOCATED IMPLICIT EXPLICIT

(IH) -- --

SQLFreeHandle
D0 D1I D1E

UNALLOCATED IMPLICIT EXPLICIT

--[1] D0 --

(IH)[2] (HY017) D0

[1] This row shows transitions when HandleType was SQL_HANDLE_STMT.


[2] This row shows transitions when HandleType was SQL_HANDLE_DESC.
SQLGetDescField and SQLGetDescRec
D0 D1I D1E

UNALLOCATED IMPLICIT EXPLICIT

(IH) -- --

SQLSetDescField and SQLSetDescRec


D0 D1I D1E

UNALLOCATED IMPLICIT EXPLICIT

(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.

All Other ODBC Functions


D0 D1I D1E

UNALLOCATED IMPLICIT EXPLICIT

-- -- --
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.

SQL TYPE IDENTIFIER DISPLAY SIZE

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_TINYINT 4 if signed (a sign and 3 digits) or 3 if unsigned (3 digits).

SQL_SMALLINT 6 if signed (a sign and 5 digits) or 5 if unsigned (5 digits).

SQL_INTEGER 11 if signed (a sign and 10 digits) or 10 if unsigned (10 digits).

SQL_BIGINT 20 (a sign and 19 digits if signed or 20 digits if unsigned).

SQL_REAL 14 (a sign, 7 digits, a decimal point, the letter E, a sign, and 2


digits).

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.)

SQL_TYPE_DATE 10 (a date in the format yyyy-mm-dd).

SQL_TYPE_TIME 8 (a time in the format hh:mm:ss)

- or -

9 + s (a time in the format hh:mm:ss[.fff...], where s is the


fractional seconds precision).

SQL_TYPE_TIMESTAMP 19 (for a timestamp in the yyyy-mm-dd hh:mm:ss format)

- or -

20 + s (for a timestamp in the yyyy-mm-dd hh:mm:ss[.fff...]


format, where s is the fractional seconds precision).
SQL TYPE IDENTIFIER DISPLAY SIZE

All interval data types See Interval Data Type Length.

SQL_GUID 36 (the number of characters in the aaaaaaaa-bbbb-cccc-


dddd-eeeeeeeeeeee format

[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

ODBC environments have the following three states.

STATE DESCRIPTION

E0 Unallocated environment

E1 Allocated environment, unallocated connection

E2 Allocated environment, allocated connection

The following tables show how each ODBC function affects the environment state.

SQLAllocHandle
E0 E1 E2

UNALLOCATED ALLOCATED CONNECTION

E1[1] --[4] --[4]

(IH)[2] E2[5] --[4]


(HY010)[6]

(IH)[3] (IH) --[4]

[1] This row shows transitions when HandleType was SQL_HANDLE_ENV.


[2] This row shows transitions when HandleType was SQL_HANDLE_DBC.
[3] This row shows transitions when HandleType was SQL_HANDLE_STMT or SQL_HANDLE_DESC.
[4] Calling SQLAllocHandle with OutputHandlePtr pointing to a valid handle overwrites that handle. This might
be an application programming error.
[5] The SQL_ATTR_ODBC_VERSION environment attribute had been set on the environment.
[6] The SQL_ATTR_ODBC_VERSION environment attribute had not been set on the environment.

SQLDataSources and SQLDrivers


E0 E1 E2

UNALLOCATED ALLOCATED CONNECTION

(IH) --[1] --[1]


(HY010)[2] (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.
SQLEndTran
E0 E1 E2

UNALLOCATED ALLOCATED CONNECTION

(IH)[1] --[3] --[3]


(HY010)[4] (HY010)[4]

(IH)[2] (IH) --

[1] This row shows transitions when HandleType was SQL_HANDLE_ENV.


[2] This row shows transitions when HandleType was SQL_HANDLE_DBC.
[3] The SQL_ATTR_ODBC_VERSION environment attribute had been set on the environment.
[4] The SQL_ATTR_ODBC_VERSION environment attribute had not been set on the environment.

SQLFreeHandle
E0 E1 E2

UNALLOCATED ALLOCATED CONNECTION

(IH)[1] E0 (HY010)

(IH)[2] (IH) --[4]


E1[5]

(IH)[3] (IH) --

[1] This row shows transitions when HandleType was SQL_HANDLE_ENV.


[2] This row shows transitions when HandleType was SQL_HANDLE_DBC.
[3] This row shows transitions when HandleType was SQL_HANDLE_STMT or SQL_HANDLE_DESC.
[4] There were other allocated connection handles.
[5] The connection handle specified in Handle was the only allocated connection handle.

SQLGetDiagField and SQLGetDiagRec


E0 E1 E2

UNALLOCATED ALLOCATED CONNECTION

(IH)[1] -- --

(IH)[2] (IH) --

[1] This row shows transitions when HandleType was SQL_HANDLE_ENV.


[2] This row shows transitions when HandleType was SQL_HANDLE_DBC, SQL_HANDLE_STMT, or
SQL_HANDLE_DESC.

SQLGetEnvAttr
E0 E1 E2

UNALLOCATED ALLOCATED CONNECTION

(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

UNALLOCATED ALLOCATED CONNECTION

(IH) --[1] (HY011)


(HY010)[2]

[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.

All Other ODBC Functions


E0 E1 E2

UNALLOCATED ALLOCATED CONNECTION

(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

"char" SQL_CHAR 255 "'" "'" "length" SQL_TRUE

"text" SQL_LONGVA 2147483647 "'" "'" <Null> SQL_TRUE


RCHAR

"decimal" SQL_DECIMA 28 <Null> <Null> "precision, SQL_TRUE


L scale"

"real" SQL_REAL 7 <Null> <Null> <Null> SQL_TRUE

"datetime" SQL_TYPE_TI 23 "'" "'" <Null> SQL_TRUE


MESTAMP

"INTERVAL SQL_INTERVA 9 "'" "'" "precision" SQL_TRUE


YEAR() TO L_YEAR
YEAR"

"INTERVAL SQL_INTERVA 24 "'" "'" "precision" SQL_TRUE


DAY() TO L_DAY_TO_SE
FRACTION(5)" COND

CASE_SENSITIV UNSIGNED_ATT FIXED_PREC_SC AUTO_UNIQUE_ LOCAL_TYPE_NA


DATA_TYPE E SEARCHABLE RIBUTE ALE VALUE ME

SQL_CHAR SQL_FALSE SQL_SEARCH <Null> SQL_FALSE <Null> "char"


ABLE

SQL_LONGV SQL_FALSE SQL_PRED_CH <Null> SQL_FALSE <Null> "text"


ARCHAR AR

SQL_DECIMA SQL_FALSE SQL_PRED_BA SQL_FALSE SQL_FALSE SQL_FALSE "decimal"


L SIC

SQL_REAL SQL_FALSE SQL_PRED_BA SQL_FALSE SQL_FALSE SQL_FALSE "real"


SIC

SQL_TYPE_TI SQL_FALSE SQL_SEARCH <Null> SQL_FALSE <Null> "datetime"


MESTAMP ABLE
CASE_SENSITIV UNSIGNED_ATT FIXED_PREC_SC AUTO_UNIQUE_ LOCAL_TYPE_NA
DATA_TYPE E SEARCHABLE RIBUTE ALE VALUE ME

SQL_INTERV SQL_FALSE SQL_SEARCH <Null> SQL_FALSE <Null> "INTERVAL


AL_YEAR ABLE YEAR() TO
YEAR"

TERVAL_DAY_ SQL_FALSE SQL_PRED_BA <Null> SQL_FALSE <Null> "INTERVAL


TO_SECOND* SIC DAY() TO
* FRACTION(5)"

MINIMUM_SCA MAXIMUM_SCA SQL_DATA_TYP SQL_DATETIME NUM_PREC_RA INTERVAL_PREC


DATA_TYPE LE LE E _SUB DIX ISION

SQL_CHAR <Null> <Null> SQL_CHAR <Null> <Null> <Null>

SQL_LONGV <Null> <Null> SQL_LONGVA <Null> <Null> <Null>


ARCHAR RCHAR

SQL_DECIMA 0 28 SQL_DECIMA <Null> 10 <Null>


L L

SQL_REAL <Null> <Null> SQL_REAL <Null> 10 <Null>

SQL_TYPE_TI 3 3 SQL_DATETIM SQL_CODE_TI <Null> 12


MESTAMP E MESTAMP

SQL_INTERV 0 0 SQL_INTERVA SQL_CODE_IN <Null> 9


AL_YEAR L TERVALYEAR

ERVAL_DAY_T 5 5 SQL_INTERVA SQL_CODE_IN <Null> 9


O_SECOND** L TERVALDAY_T
O_SECOND
Executing 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.

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

Positioned update SQL_ROW_UPDATED New values[1] New values[1]

Positioned delete SQL_ROW_DELETED Old values Old values

[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:

{ fn CONVERT( { fn CURDATE() }, SQL_CHAR ) }

converts the output of the CURDATE scalar function to a character string.


Because 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.
The following two examples illustrate the use of the CONVERT function. These examples assume the existence of a
table called EMPLOYEES, with an EMPNO column of type SQL_SMALLINT and an EMPNAME column of type
SQL_CHAR.
If an application specifies the following SQL statement:

SELECT EMPNO FROM EMPLOYEES WHERE {fn CONVERT(EMPNO,SQL_CHAR)} LIKE '1%'

A driver for ORACLE translates the SQL statement to:

SELECT EMPNO FROM EMPLOYEES WHERE to_char(EMPNO) LIKE '1%'

A driver for SQL Server translates the SQL statement to:

SELECT EMPNO FROM EMPLOYEES WHERE convert(char,EMPNO) LIKE '1%'

If an application specifies the following SQL statement:

SELECT {fn ABS(EMPNO)}, {fn CONVERT(EMPNAME,SQL_SMALLINT)}


FROM EMPLOYEES WHERE EMPNO <> 0

A driver for ORACLE translates the SQL statement to:

SELECT abs(EMPNO), to_number(EMPNAME) FROM EMPLOYEES WHERE EMPNO <> 0

A driver for SQL Server translates the SQL statement to:


SELECT abs(EMPNO), convert(smallint, EMPNAME) FROM EMPLOYEES
WHERE EMPNO <> 0

A driver for Ingres translates the SQL statement to:

SELECT abs(EMPNO), int2(EMPNAME) FROM EMPLOYEES WHERE EMPNO <> 0


Fixed-Length Bookmarks
12/20/2017 • 1 min to read • Edit Online

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

The following sections address interval and numeric data types.


Interval Data Types
Numeric Literals
Overriding Default Precision and Scale for Numeric Data Types
Implementation Notes
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.

TYPE IDENTIFIER CLASS DESCRIPTION

MONTH Year-Month Number of months between two dates.

YEAR Year-Month Number of years between two dates.

YEAR_TO_MONTH Year-Month Number of years and months between


two dates.

DAY Day-Time Number of days between two dates.

HOUR Day-Time Number of hours between two


date/times.

MINUTE Day-Time Number of minutes between two


date/times.

SECOND Day-Time Number of seconds between two


date/times.

DAY_TO_HOUR Day-Time Number of days/hours between two


date/times.

DAY_TO_MINUTE Day-Time Number of days/hours/minutes


between two date/times.
TYPE IDENTIFIER CLASS DESCRIPTION

DAY_TO_SECOND Day-Time Number of


days/hours/minutes/seconds between
two date/times.

HOUR_TO_MINUTE Day-Time Number of hours/minutes between two


date/times.

HOUR_TO_SECOND Day-Time Number of hours/minutes/seconds


between two date/times.

MINUTE_TO_SECOND Day-Time Number of minutes/seconds between


two date/times.

This section contains the following topics.


C Interval Structure
Interval Data Type Precision
Interval Data Type Length
Interval Literals
Overriding Default Leading and Seconds Precision for Interval Data Types
Interval Escape Sequences
12/20/2017 • 1 min to read • Edit Online

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

The following syntax is used for interval literals in ODBC.


interval-literal ::= INTERVAL [+|-] interval-string interval-qualifier
interval-string ::= quote { year-month-literal | day-time-literal } quote
year-month-literal ::= years-value | [years-value -] months-value
day-time-literal ::= day-time-interval | time-interval
day-time-interval ::= days-value [hours-value [:minutes-value[:seconds-value]]]
time-interval ::= hours-value [:minutes-value [:seconds-value ] ]
| minutes-value [:seconds-value ]
| seconds-value
years-value ::= datetime-value
months-value ::= datetime-value
days-value ::= datetime-value
hours-value ::= datetime-value
minutes-value ::= datetime-value
seconds-value ::= seconds-integer-value [.[seconds-fraction] ]
seconds-integer-value ::= unsigned-integer
seconds-fraction ::= unsigned-integer
datetime-value ::= unsigned-integer
interval-qualifier ::= start-field TO end-field | single-datetime-field
start-field ::= non-second-datetime-field [(interval-leading-field-precision )]
end-field ::= non-second-datetime-field | SECOND[(interval-fractional-seconds-precision)]
single-datetime-field ::= non-second-datetime-field [(interval-leading-field-precision)] | SECOND[(interval-
leading-field-precision [, (interval-fractional-seconds-precision)]
datetime-field ::= non-second-datetime-field | SECOND
non-second-datetime-field ::= YEAR | MONTH | DAY | HOUR | MINUTE
interval-fractional-seconds-precision ::= unsigned-integer
interval-leading-field-precision ::= unsigned-integer
quote ::= '
unsigned-integer ::= digit...
Interval Literals
12/20/2017 • 5 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:

INTERVAL[<sign>] 'value' <interval qualifier>

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}

LITERAL ESCAPE CLAUSE INTERVAL SPECIFIED

{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.

The following table lists examples of invalid interval literals:

LITERAL ESCAPE CLAUSE REASON WHY INVALID

{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 '223.16' SECOND} Because the leading precision is unspecified, it defaults to 2,


which is too small to hold the specified literal.
{INTERVAL '223' YEAR}

{INTERVAL '22.1234567' SECOND} The seconds precision is unspecified, so it defaults to 6. The


literal has seven digits after the decimal point.

{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}

{INTERVAL '163 62:39' DAY(3) TO MINUTE}

{INTERVAL '163 12:125:59.163' DAY(3) TO SECOND(3)}

{INTERVAL '163:144' HOUR(3) TO MINUTE}

{INTERVAL '163:567:234.163' HOUR(3) TO SECOND(4)}

{INTERVAL '163:591.163' MINUTE(3) TO SECOND(5)}


Length of 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 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.

ODBC 2.X FUNCTION ODBC 3.X FUNCTION

SQLAllocConnect SQLAllocHandle

SQLAllocEnv SQLAllocHandle

SQLAllocStmt SQLAllocHandle

SQLBindParam[1] SQLBindParameter

SQLColAttributes SQLColAttribute

SQLError SQLGetDiagRec

SQLFreeConnect SQLFreeHandle

SQLFreeEnv SQLFreeHandle

SQLFreeStmt with an Option of SQL_DROP 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

SQLAllocHandle(SQL_HANDLE_DBC, InputHandle, OutputHandlePtr)

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

SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, OutputHandlePtr)

in the driver with OutputHandlePtr set to phenv.


SQLAllocStmt Mapping
12/20/2017 • 1 min to read • Edit Online

When an application calls SQLAllocStmt through an ODBC 3.x driver, the call to:

SQLAllocStmt(hdbc, phstmt)

is mapped to SQLAllocHandle by the Driver Manager in the driver as follows:

SQLAllocHandle(SQL_HANDLE_STMT, InputHandle, OutputHandlePtr)

with InputHandle set to hdbc and OutputHandlePtr set to phstmt.


SQLBindParam Mapping
12/20/2017 • 1 min to read • Edit Online

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:

SQLBindParam( StatementHandle, ParameterNumber, ValueType, ParameterType, ColumnSize,


DecimalDigits, ParameterValuePtr, StrLen_or_IndPtr)

the Driver Manager calls SQLBindParameter in the driver as follows:

SQLBindParameter( StatementHandle, ParameterNumber, SQL_PARAM_INPUT, ValueType, ParameterType,


ColumnSize, DecimalDigits, ParameterValuePtr, BufferLength, StrLen_or_IndPtr)

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

SQLError(henv, hdbc, hstmt, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg)

is mapped to

SQLGetDiagRec(HandleType, Handle, RecNumber, szSqlstate, pfNativeErrorPtr, szErrorMsg, cbErrorMsgMax,


pcbErrorMsg)

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)

with the Handle argument set to the value in hdbc.


SQLFreeEnv Mapping
12/20/2017 • 1 min to read • Edit Online

When an application calls SQLFreeEnv through an ODBC 3.x driver, the call to

SQLFreeEnv(henv)

is mapped to

SQLFreeHandle(SQL_HANDLE_ENV,Handle)

with the Handle argument set to the value in henv.


SQLFreeStmt Mapping
12/20/2017 • 1 min to read • Edit Online

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)

with the Handle argument set to the value in hstmt.


SQLGetConnectOption Mapping
12/20/2017 • 1 min to read • Edit Online

When an application calls SQLGetConnectOption through an ODBC 3.x driver, the call to

SQLGetConnectOption(hdbc, fOption, pvParam)

is mapped as follows:
If fOption indicates an ODBC-defined connection option that returns a string, the Driver Manager calls

SQLGetConnectAttr(ConnectionHandle, Attribute, ValuePtr, BufferLength, NULL)

If fOption indicates an ODBC-defined connection option that returns a 32-bit integer value, the Driver
Manager calls

SQLGetConnectAttr(ConnectionHandle, Attribute, ValuePtr, 0, NULL)

If fOption indicates a driver-defined statement option, the Driver Manager calls

SQLGetConnectAttr(ConnectionHandle, Attribute, ValuePtr, BufferLength, NULL)

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

SQLGetStmtOption(hstmt, fOption, pvParam)

will result as follows:


If fOption indicates an ODBC-defined statement option that returns a string, the Driver Manager calls

SQLGetStmtAttr(StatementHandle, Attribute, ValuePtr, BufferLength, NULL)

If fOption indicates an ODBC-defined statement option that returns a 32-bit integer value, the Driver
Manager calls

SQLGetStmtAttr(StatementHandle, Attribute, ValuePtr, 0, NULL)

If fOption indicates a driver-defined statement option, the Driver Manager calls

SQLGetStmtAttr(StatementHandle, Attribute, ValuePtr, BufferLength, NULL)

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

SQLParamOptions(hstmt, crow, piRow);

will be mapped to two calls of SQLSetStmtAttr as follows:

SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMSET_SIZE, crow, 0);


SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMS_PROCESSED_PTR, piRow, 0);
SQLSetConnectOption Mapping
12/20/2017 • 2 min to read • Edit Online

When an ODBC 2.x application calls SQLSetConnectOption through an ODBC 3.x driver, the call to

SQLSetConnectOption(hdbc, fOption, vParam)

will result as follows:


If fOption indicates an ODBC-defined connection attribute that requires a string, the Driver Manager calls

SQLSetConnectAttr(ConnectionHandle, Attribute, ValuePtr, SQL_NTS)

If fOption indicates an ODBC-defined connection attribute that returns a 32-bit integer value, the Driver
Manager calls

SQLSetConnectAttr(ConnectionHandle, Attribute, ValuePtr, 0)

If fOption indicates a driver-defined connection attribute, the Driver Manager calls

SQLSetConnectAttr(ConnectionHandle, Attribute, ValuePtr, BufferLength)

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.

Setting Statement Options on the Connection Level


In ODBC 2.x, an application could call SQLSetConnectOption to set a statement option. When that is done, the
driver establishes the statement option as a default for any statements later allocated for that connection. It is
driver-defined whether the driver sets the statement option for any existing statements associated with the
specified connection.
This ability has been deprecated in ODBC 3.x. ODBC 3.x drivers need only support setting ODBC 2.x statement
attributes at the connection level if they want to work with ODBC 2.x applications that do this. ODBC 3.x
applications should never set statement attributes at the connection level. ODBC 3.x statement attributes cannot be
set at the connection level, with the exception of the SQL_ATTR_METADATA_ID and SQL_ATTR_ASYNC_ENABLE
attributes, which are both connection attributes and statement attributes, and can be set at either the connection
level or the statement level.
SQLSetParam Mapping
12/20/2017 • 1 min to read • Edit Online

SQLSetParam continues to be mapped on top of SQLBindParameter as in ODBC 2.x. Even though it is


conceptually similar to SQLBindParam, the Driver Manager does not map SQLSetParam to SQLBindParam. This
is because certain existing ODBC 2.x drivers use the special value of BufferLength (SQL_SETPARAM_VALUE_MAX)
that the Driver Manager generates when it maps SQLSetParam on top of SQLBindParameter to determine when
it is called by a 1.x ODBC application.
A call to

SQLSetParam(hstmt, ipar, fCType, fSqlType, cbColDef, ibScale, rgbValue, pcbValue)

will result in the following:

SQLBindParameter(StatementHandle, ParameterNumber, SQL_PARAM_INPUT_OUTPUT, ValueType, ParameterType,


ColumnSize, DecimalDigits, ParameterValuePtr, SQL_SETPARAM_VALUE_MAX, StrLen_or_IndPtr)
SQLSetScrollOptions Mapping
12/20/2017 • 2 min to read • Edit Online

When an application calls SQLSetScrollOptions through an ODBC 3.x driver and the driver does not support
SQLSetScrollOptions, the call to

SQLSetScrollOptions(StatementHandle, Concurrency, KeysetSize, RowsetSize)

will result as follows:


A call to

SQLGetInfo(ConnectionHandle, InfoType, InfoValuePtr, BufferLength, StringLengthPtr)

with the InfoType argument set to one of the values in the following table, depending on the value of the
KeysetSize argument in SQLSetScrollOptions.

KEYSETSIZE ARGUMENT INFOTYPE ARGUMENT

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

A value greater than the RowsetSize argument SQL_KEYSET_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.

CONCURRENCY ARGUMENT INFOTYPE SETTING

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

SQLSetStmtAttr(StatementHandle, SQL_ATTR_CURSOR_TYPE, ValuePtr, 0)

with *ValuePtr set to one of the values in the following table, according to the value of the KeysetSize
argument in SQLSetScrollOptions.

KEYSETSIZE ARGUMENT *VALUEPTR

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 value greater than the RowsetSize argument SQL_CURSOR_KEYSET_DRIVEN

A call to

SQLSetStmtAttr(StatementHandle, SQL_ATTR_CONCURRENCY, ValuePtr, 0)

with *ValuePtr set to the Concurrency argument in SQLSetScrollOptions.


If the KeysetSize argument in the call to SQLSetScrollOptions is positive, a call to

SQLSetStmtAttr(StatementHandle, SQL_ATTR_KEYSET_SIZE, ValuePtr, 0)

with *ValuePtr set to the KeysetSize argument in SQLSetScrollOptions.


A call to

SQLSetStmtAttr(StatementHandle, SQL_ROWSET_SIZE, ValuePtr, 0)

with *ValuePtr set to the RowsetSize argument in SQLSetScrollOptions.

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

SQLSetStmtOption(StatementHandle, fOption, vParam)

will result as follows:


If fOption indicates an ODBC-defined statement attribute that is a string, the Driver Manager calls

SQLSetStmtAttr(StatementHandle, fOption, ValuePtr, SQL_NTS)

If fOption indicates an ODBC-defined statement attribute that returns a 32-bit integer value, the Driver
Manager calls

SQLSetStmtAttr(StatementHandle, fOption, ValuePtr, 0)

If fOption indicates a driver-defined statement attribute, the Driver Manager calls

SQLSetStmtAttr(StatementHandle, fOption, ValuePtr, BufferLength)

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:

SQLTransact(henv, hdbc, fType)

is mapped to

SQLEndTran(SQL_HANDLE_DBC, ConnectionHandle, CompletionType);

if ConnectionHandle is not equal to SQL_NULL_HDBC. The ConnectionHandle argument is set to the value of hdbc.
SQL_Transact is mapped to

SQLEndTran (SQL_HANDLE_ENV, EnvironmentHandle, CompletionType);

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

ABS( numeric_exp ) (ODBC 1.0) Returns the absolute value of numeric_exp.

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

EXP( float_exp ) (ODBC 1.0) Returns the exponential value of float_exp.

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.

LOG( float_exp ) (ODBC 1.0) Returns the natural logarithm of float_exp.

LOG10( float_exp ) (ODBC 2.0) Returns the base 10 logarithm of float_exp.

MOD( integer_exp1, integer_exp2) (ODBC 1.0) Returns the remainder (modulus) of integer_exp1 divided by
integer_exp2.

PI( ) (ODBC 1.0) Returns the constant value of pi as a floating-point value.

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.

RAND([integer_exp]) (ODBC 1.0) Returns a random floating-point value using integer_exp as


the optional seed value.

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.

SIGN( numeric_exp ) (ODBC 1.0) Returns an indicator of the sign of numeric_exp. If


numeric_exp is less than zero, –1 is returned. If numeric_exp
equals zero, 0 is returned. If numeric_exp is greater than zero,
1 is returned.

SIN( float_exp ) (ODBC 1.0) Returns the sine of float_exp, where float_exp is an angle
expressed in radians.

SQRT( float_exp ) (ODBC 1.0) Returns the square root of float_exp.

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

The following syntax is used for numeric literals in ODBC:


numeric-literal ::= signed-numeric-literal | unsigned-numeric-literal
signed-numeric-literal ::= [sign] unsigned-numeric-literal
unsigned-numeric-literal ::= exact-numeric-literal | approximate-numeric-literal
exact-numeric-literal ::= unsigned-integer [period[unsigned-integer]] |period unsigned-integer
sign ::= plus-sign | minus-sign
approximate-numeric-literal ::= mantissa E exponent
mantissa ::= exact-numeric-literal
exponent ::= signed-integer
signed-integer ::= [sign] unsigned-integer
unsigned-integer ::= digit...
plus-sign ::= +
minus-sign ::= -
digit ::= 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0
period ::= .
Numeric Literals
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.

Result Set Membership


The cursor library retrieves data from the driver only as the application requests it. Depending on the data source
and the setting of the SQL_CONCURRENCY statement attribute, this has the following consequences:
The data retrieved by the cursor library might differ from the data that was available at the time the
statement was executed. For example, after the cursor was opened, rows inserted at a point beyond the
current cursor position can be retrieved by some drivers.
The data in the result set might be locked by the data source for the cursor library and therefore be
unavailable to other users.
After the cursor library has cached a row of data, it cannot detect changes to that row in the underlying data
source (except for positioned updates and deletes operating on the same cursor's cache). This occurs
because, for calls to SQLFetchScroll, the cursor library never refetches data from the data source. Instead, it
refetches data from its cache.

Scrolling
The cursor library supports the following fetch types in SQLFetchScroll.

CURSOR TYPE FETCH TYPES

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.

Interaction with Other Functions


An application must call SQLFetch or SQLFetchScroll before it prepares or executes any positioned update or
delete statements.
SQLFreeStmt (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 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.

INFOTYPE RETURNED VALUE

SQL_BOOKMARK_PERSISTENCE SQL_BP_SCROLL

SQL_DYNAMIC_CURSOR_ATTRIBUTES1 0

SQL_DYNAMIC_CURSOR_ATTRIBUTES2 0

SQL_FETCH_DIRECTION[1] SQL_FD_FETCH_ABSOLUTE | SQL_FD_FETCH_FIRST |


SQL_FD_FETCH_LAST | SQL_FD_FETCH_NEXT |
SQL_FD_FETCH_PRIOR | SQL_FD_FETCH_RELATIVE |
SQL_FD_FETCH_BOOKMARK

SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1 SQL_CA1_NEXT | SQL_CA1_ABSOLUTE | SQL_CA1_RELATIVE |


SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION |
SQL_CA1_POSITIONED_DELETE |
SQL_CA1_POSITIONED_UPDATE |
SQL_CA1_SELECT_FOR_UPDATE

SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2 SQL_CA2_READ_ONLY_CONCUR |
SQL_CA2_OPT_VALUES_CONCURRENCY |
SQL_CA2_SENSITIVITY_UPDATES

SQL_GETDATA_EXTENSIONS SQL_GD_BLOCK | any values returned by the driver Note:


When data is retrieved with SQLFetchScroll, SQLGetData
supports the functionality specified with the
SQL_GD_ANY_COLUMN and SQL_GD_BOUND bitmasks.

SQL_KEYSET_DRIVEN_CURSOR_ATTRIBUTES1 0

SQL_KEYSET_DRIVEN_CURSOR_ATTRIBUTES2 0

SQL_LOCK_TYPES[1] SQL_LCK_NO_CHANGE
INFOTYPE RETURNED VALUE

SQL_STATIC_CURSOR_ATTRIBUTES1 SQL_CA1_NEXT | SQL_CA1_ABSOLUTE | SQL_CA1_RELATIVE |


SQL_CA1_BOOKMARK | SQL_CA1_LOCK_NO_CHANGE |
SQL_CA1_POS_POSITION | SQL_CA1_POSITIONED_DELETE |
SQL_CA1_POSITIONED_UPDATE |
SQL_CA1_SELECT_FOR_UPDATE

SQL_STATIC_CURSOR_ATTRIBUTES2 SQL_CA2_READ_ONLY_CONCUR | SQL_CA2_OPT_VALUES_


CONCURRENCY | SQL_CA2_SENSITIVITY_UPDATES

SQL_POS_OPERATIONS[1] SQL_POS_POSITION

SQL_POSITIONED_STATEMENTS[1] SQL_PS_POSITIONED_DELETE | SQL_PS_POSITIONED_UPDATE


| SQL_PS_SELECT_FOR_UPDATE

SQL_ROW_UPDATES "Y"

SQL_SCROLL_CONCURRENCY[1] SQL_SCCO_READ_ONLY | SQL_SCCO_OPT_VALUES

SQL_SCROLL_OPTIONS SQL_SO_FORWARD_ONLY | SQL_SO_STATIC

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_AT_DROP_COLUMN = The ability to drop columns is


supported. Whether this results in cascade or restrict behavior
is driver-defined. (ODBC 2.0)

SQL_AT_ADD_COLUMN = The ability to add multiple columns


in a single ALTER TABLE statement is supported. This bit does
not combine with other SQL_AT_ADD_COLUMN_XXX bits or
SQL_AT_CONSTRAINT_XXX bits. (ODBC 2.0)

SQL_FETCH_DIRECTION (ODBC 1.0) An SQLINTEGER bitmask enumerating the supported fetch


direction options.
The information type was introduced in ODBC 1.0; each
bitmask is labeled with the version in which it was introduced. The following bitmasks are used in conjunction with the flag to
determine which options are supported:

SQL_FD_FETCH_NEXT (ODBC 1.0) SQL_FD_FETCH_FIRST


(ODBC 1.0) SQL_FD_FETCH_LAST (ODBC 1.0)
SQL_FD_FETCH_PRIOR (ODBC 1.0) SQL_FD_FETCH_ABSOLUTE
(ODBC 1.0) SQL_FD_FETCH_RELATIVE (ODBC 1.0)
SQL_FD_FETCH_BOOKMARK (ODBC 2.0)

SQL_LOCK_TYPES (ODBC 2.0) An SQLINTEGER bitmask enumerating the supported lock


types for the fLock argument in SQLSetPos.

The following bitmasks are used in conjunction with the flag to


determine which lock types are supported:

SQL_LCK_NO_CHANGE SQL_LCK_EXCLUSIVE
SQL_LCK_UNLOCK

SQL_ODBC_API_CONFORMANCE (ODBC 1.0) An SQLSMALLINT value indicating the level of ODBC


conformance.

SQL_OAC_NONE = None

SQL_OAC_LEVEL1 = Level 1 supported

SQL_OAC_LEVEL2 = Level 2 supported


INFOTYPE RETURNS

SQL_ODBC_SQL_CONFORMANCE (ODBC 1.0) An SQLSMALLINT value indicating SQL grammar supported


by the driver. See Appendix C: SQL Grammar for a definition
of SQL conformance levels.

SQL_OSC_MINIMUM = Minimum grammar supported

SQL_OSC_CORE = Core grammar supported

SQL_OSC_EXTENDED = Extended grammar supported

SQL_POS_OPERATIONS (ODBC 2.0) An SQLINTEGER bitmask enumerating the supported


operations in SQLSetPos.

The following bitmasks are used to in conjunction with the flag


to determine which options are supported:

SQL_POS_POSITION (ODBC 2.0) SQL_POS_REFRESH (ODBC


2.0) SQL_POS_UPDATE (ODBC 2.0) SQL_POS_DELETE (ODBC
2.0) SQL_POS_ADD (ODBC 2.0)

SQL_POSITIONED_STATEMENTS (ODBC 2.0) An SQLINTEGER bitmask enumerating the supported


positioned SQL statements.

The following bitmasks are used to determine which


statements are supported:

SQL_PS_POSITIONED_DELETE SQL_PS_POSITIONED_UPDATE
SQL_PS_SELECT_FOR_UPDATE

SQL_SCROLL_CONCURRENCY (ODBC 1.0) An SQLINTEGER bitmask enumerating the concurrency control


options supported for the cursor.

The following bitmasks are used to determine which options


are supported:

SQL_SCCO_READ_ONLY = Cursor is read-only. No updates


are allowed.

SQL_SCCO_LOCK = Cursor uses the lowest level of locking


sufficient to ensure that the row can be updated.

SQL_SCCO_OPT_ROWVER = Cursor uses optimistic


concurrency control, comparing row versions, such as
SQLBase ROWID or Sybase TIMESTAMP.

SQL_SCCO_OPT_VALUES = Cursor uses optimistic


concurrency control, comparing values.
INFOTYPE RETURNS

SQL_STATIC_SENSITIVITY (ODBC 2.0) An SQLINTEGER bitmask enumerating whether changes made


by an application to a static or keyset-driven cursor through
SQLSetPos or positioned update or delete statements can be
detected by that application.

SQL_SS_ADDITIONS = Added rows are visible to the cursor;


the cursor can scroll to these rows. Where these rows are
added to the cursor is driver-dependent.

SQL_SS_DELETIONS = Deleted rows are no longer available to


the cursor and do not leave a "hole" in the result set; after the
cursor scrolls from a deleted row, it cannot return to that row.

SQL_SS_UPDATES = Updates to rows are visible to the cursor;


if the cursor scrolls from and returns to an updated row, the
data returned by the cursor is the updated data, not the
original data. This option applies only to static cursors or
updates on keyset-driven cursors that do not update the key.
This option does not apply for a dynamic cursor or in the case
in which a key is changed in a mixed cursor.

Whether an application can detect changes made to the result


set by other users, including other cursors in the same
application, depends on the cursor type.

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.

SQLSTATE DESCRIPTION CAN BE RETURNED FROM

01000 Cursor is not updatable. SQLFetch

SQLFetchScroll

01000 Cursor library not used. Load failed. SQLBrowseConnect

SQLConnect

SQLDriverConnect

01000 Cursor library not used. Insufficient SQLBrowseConnect


driver support.
SQLConnect

SQLDriverConnect

01000 Cursor library not used. Version SQLBrowseConnect


mismatch with Driver Manager.
SQLConnect

SQLDriverConnect

01000 Driver returned SQLFetch


SQL_SUCCESS_WITH_INFO. The
warning message has been lost. SQLFetchScroll

S1000 General error: Unable to create file SQLFetch


buffer.
SQLFetchScroll

SQLGetData
SQLSTATE DESCRIPTION CAN BE RETURNED FROM

S1000 General error: Unable to read from file SQLFetch


buffer.
SQLFetchScroll

SQLGetData

S1000 General error: Unable to write to file SQLFetch


buffer.
SQLFetchScroll

SQLGetData

S1000 General error: Unable to close or SQLFreeHandle


remove file buffer.
SQLFreeStmt

SL001 Positioned request cannot be SQLExecDirect


performed because no searchable
columns were bound. SQLGetData

SQLPrepare

SL002 Positioned request could not be SQLExecute


performed because result set was
created by a join condition. SQLExecDirect

SQLGetData

SL003 Bound buffer exceeds maximum SQLFetch


segment size.
SQLFetchScroll

SL004 Result set was not generated by a SQLGetData


SELECT statement.

SL005 SELECT statement contains a GROUP SQLGetData


BY clause.

SL006 Parameter arrays are not supported SQLPrepare


with positioned requests.
SQLExecDirect

SL008 SQLGetData is not allowed on a SQLGetData


forward-only (nonbuffered) cursor.

SL009 No columns were bound prior to calling SQLFetch


SQLFetch or SQLFetchScroll.
SQLFetchScroll

SL010 SQLBindCol returned SQL_ERROR SQLFetch


during an attempt to bind to an
internal buffer. SQLFetchScroll

SQLGetData
SQLSTATE DESCRIPTION CAN BE RETURNED FROM

SL011 Statement option is valid only after SQLGetStmtAttr


calling SQLFetch or SQLFetchScroll.

SL012 Statement bindings may not be SQLBindCol


changed while a cursor is open.
SQLFreeHandle

SQLFreeStmt

SQLSetStmtAttr

SL014 A positioned request was issued and SQLExecDirect


not all column count fields were
buffered. SQLExecute

SQLPrepare

SL015 SQLFetch and SQLFetchScroll cannot SQLExtendedFetch


be mixed.
SQLFetch

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.

LOCATION OF PARAMETER ASSUMED DATA TYPE

One operand of a binary arithmetic or comparison operator Same as the other operand

The first operand in a BETWEEN clause Same as the second 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

A pattern value used with LIKE VARCHAR

An update value used with UPDATE Same as the update column


Parameter Markers
12/20/2017 • 1 min to read • Edit Online

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.

Character Source to Numeric Target


Following are the rules for converting from a character source (CS) to a numeric target (NT):
1. Replace CS with the value obtained by removing any leading or trailing spaces in CS. If CS is not a valid
numeric-literal, SQLSTATE 22018 (Invalid character value for cast specification) is returned.
2. Replace CS with the value obtained by removing leading zeroes before the decimal point, trailing zeroes
after the decimal point, or both.
3. Convert CS to NT. If the conversion results in a loss of significant digits, SQLSTATE 22003 (Numeric value
out of range) is returned. If the conversion results in the loss of nonsignificant digits, SQLSTATE 01S07
(Fractional truncation) is returned.

Numeric Source to Character Target


Following are the rules for converting from a numeric source (NS) to a character target (CT):
1. Let LT be the length in characters of CT. For retrieval assignment, LT is equal to the length of the buffer in
characters minus the number of bytes in the null-termination character for this character set.
2. Cases:
If NS is an exact numeric type, then let YP equal the shortest character string that conforms to the
definition of exact-numeric-literal such that the scale of YP is the same as the scale of NS, and the
interpreted value of YP is the absolute value of NS.
If NS is an approximate numeric type, then let YP be a character string as follows:
Case:
If NS is equal to 0, then YP is 0.
Let YSN be the shortest character string that conforms to the definition of exact-numeric-literal and
whose interpreted value is the absolute value of NS. If the length of YSN is less than the (precision +
1) of the data type of NS, then let YP equal YSN.
Otherwise, YP is the shortest character string that conforms to the definition of approximate-
numeric-literal whose interpreted value is the absolute value of NS and whose mantissa consists of a
single digit that is not '0', followed by a period and an unsigned-integer.
3. Case:
If NS is less than 0, then let Y be the result of:
'-' || YP
where '||' is the string concatenation operator.
Otherwise, let Y equal YP.
4. Let LY be the length in characters of Y.
5. Case:
If LY equals LT, then CT is set to Y.
If LY is less than LT, then CT is set to Y extended on the right by appropriate number of spaces.
Otherwise (LY > LT), copy the first LT characters of Y into CT.
Case:
If this is a store assignment, return the error SQLSTATE 22001 (String data, right-truncated).
If this is retrieval assignment, return the warning SQLSTATE 01004 (String data, right-truncated).
When the copy results in the loss of fractional digits (other than trailing zeros), it is driver-defined
whether one of the following occurs:
(1) The driver truncates the string in Y to an appropriate scale (which can be zero also) and writes the
result into CT.
(2) The driver rounds the string in Y to an appropriate scale (which can be zero also) and writes the
result into CT.
(3) The driver neither truncates nor rounds, but just copies the first LT characters of Y into CT.
Scalar Function Escape Sequence
12/20/2017 • 1 min to read • Edit Online

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).

TYPICAL SQL DATA

SQL TYPE IDENTIFIER[1] TYPE[2] TYPICAL TYPE DESCRIPTION

SQL_CHAR CHAR(n) Character string of fixed string length n.

SQL_VARCHAR VARCHAR(n) Variable-length character string with a


maximum string length n.

SQL_LONGVARCHAR LONG VARCHAR Variable length character data.


Maximum length is data source–
dependent.[9]

SQL_WCHAR WCHAR(n) Unicode character string of fixed string


length n
TYPICAL SQL DATA

SQL TYPE IDENTIFIER[1] TYPE[2] TYPICAL TYPE DESCRIPTION

SQL_WVARCHAR VARWCHAR(n) Unicode variable-length character


string with a maximum string length n

SQL_WLONGVARCHAR LONGWVARCHAR Unicode variable-length character data.


Maximum length is data source–
dependent

SQL_DECIMAL DECIMAL(p,s) Signed, exact, numeric value with a


precision of at least p and scale s. (The
maximum precision is driver-defined.) (1
<= p <= 15; s <= p).[4]

SQL_NUMERIC NUMERIC(p,s) Signed, exact, numeric value with a


precision p and scale s (1 <= p <= 15;
s <= p).[4]

SQL_SMALLINT SMALLINT Exact numeric value with precision 5


and scale 0 (signed: –32,768 <= n <=
32,767, unsigned: 0 <= n <= 65,535)
[3].

_INTEGER INTEGER Exact numeric value with precision 10


and scale 0 (signed: –2[31] <= n <=
2[31] – 1, unsigned: 0 <= n <= 2[32] –
1)[3].

SQL_REAL REAL Signed, approximate, numeric value


with a binary precision 24 (zero or
absolute value 10[–38] to 10[38]).

SQL_FLOAT FLOAT(p) Signed, approximate, numeric value


with a binary precision of at least p.
(The maximum precision is driver-
defined.)[5]

SQL_DOUBLE DOUBLE PRECISION Signed, approximate, numeric value


with a binary precision 53 (zero or
absolute value 10[–308] to 10[308]).

SQL_BIT BIT Single bit binary data.[8]

SQL_TINYINT TINYINT Exact numeric value with precision 3


and scale 0 (signed: –128 <= n <=
127, unsigned: 0 <= n <= 255)[3].

_BIGINT BIGINT Exact numeric value with precision 19 (if


signed) or 20 (if unsigned) and scale 0
(signed: –2[63] <= n <= 2[63] – 1,
unsigned: 0 <= n <= 2[64] – 1)[3],[9].

SQL_BINARY BINARY(n) Binary data of fixed length n.[9]


TYPICAL SQL DATA

SQL TYPE IDENTIFIER[1] TYPE[2] TYPICAL TYPE DESCRIPTION

SQL_VARBINARY VARBINARY(n) Variable length binary data of


maximum length n. The maximum is set
by the user.[9]

SQL_LONGVARBINARY LONG VARBINARY Variable length binary data. Maximum


length is data source–dependent.[9]

SQL_TYPE_DATE[6] DATE Year, month, and day fields, conforming


to the rules of the Gregorian calendar.
(See Constraints of the Gregorian
Calendar, later in this appendix.)

SQL_TYPE_TIME[6] TIME(p) Hour, minute, and second fields, with


valid values for hours of 00 to 23, valid
values for minutes of 00 to 59, and
valid values for seconds of 00 to 61.
Precision p indicates the seconds
precision.

SQL_TYPE_TIMESTAMP[6] TIMESTAMP(p) Year, month, day, hour, minute, and


second fields, with valid values as
defined for the DATE and TIME data
types.

_TYPE_UTCDATETIME UTCDATETIME Year, month, day, hour, minute, second,


utchour, and utcminute fields. The
utchour and utcminute fields have 1/10
microsecond precision.

SQL_TYPE_UTCTIME UTCTIME Hour, minute, second, utchour, and


utcminute fields. The utchour and
utcminute fields have 1/10 microsecond
precision..

SQL_INTERVAL_MONTH[7] INTERVAL MONTH(p) Number of months between two dates;


p is the interval leading precision.

SQL_INTERVAL_YEAR[7] INTERVAL YEAR(p) Number of years between two dates; p


is the interval leading precision.

SQL_INTERVAL_YEAR_TO_MONTH[7] INTERVAL YEAR(p) TO MONTH Number of years and months between


two dates; p is the interval leading
precision.

SQL_INTERVAL_DAY[7] INTERVAL DAY(p) Number of days between two dates; p


is the interval leading precision.

SQL_INTERVAL_HOUR[7] INTERVAL HOUR(p) Number of hours between two


date/times; p is the interval leading
precision.

SQL_INTERVAL_MINUTE[7] INTERVAL MINUTE(p) Number of minutes between two


date/times; p is the interval leading
precision.
TYPICAL SQL DATA

SQL TYPE IDENTIFIER[1] TYPE[2] TYPICAL TYPE DESCRIPTION

SQL_INTERVAL_SECOND[7] INTERVAL SECOND(p,q) Number of seconds between two


date/times; p is the interval leading
precision and q is the interval seconds
precision.

_INTERVAL_DAY_TO_HOUR[7] INTERVAL DAY(p) TO HOUR Number of days/hours between two


date/times; p is the interval leading
precision.

SQL_INTERVAL_DAY_TO_MINUTE[7] INTERVAL DAY(p) TO MINUTE Number of days/hours/minutes


between two date/times; p is the
interval leading precision.

SQL_INTERVAL_DAY_TO_SECOND[7] INTERVAL DAY(p) TO SECOND(q) Number of


days/hours/minutes/seconds between
two date/times; p is the interval leading
precision and q is the interval seconds
precision.

SQL_INTERVAL_HOUR_TO_MINUTE[7] INTERVAL HOUR(p) TO MINUTE Number of hours/minutes between two


date/times; p is the interval leading
precision.

SQL_INTERVAL_HOUR_TO_SECOND[7] INTERVAL HOUR(p) TO SECOND(q) Number of hours/minutes/seconds


between two date/times; p is the
interval leading precision and q is the
interval seconds precision.

_INTERVAL_MINUTE_TO_SECOND[7] INTERVAL MINUTE(p) TO SECOND(q) Number of minutes/seconds between


two date/times; p is the interval leading
precision and q is the interval seconds
precision.

SQL_GUID GUID Fixed length GUID.

[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 :

SQL TYPE SQL DATA C TYPE BUFFER


*TARGETVALUEPT
IDENTIFIER VALUE IDENTIFIER LENGTH R SQLSTATE

SQL_CHAR abcdef SQL_C_CHAR 7 abcdef\0[a] n/a

SQL_CHAR abcdef SQL_C_CHAR 6 abcde\0[a] 01004

SQL_DECIMAL 1234.56 SQL_C_CHAR 8 1234.56\0[a] n/a

SQL_DECIMAL 1234.56 SQL_C_CHAR 5 1234\0[a] 01004

SQL_DECIMAL 1234.56 SQL_C_CHAR 4 ---- 22003

SQL_DECIMAL 1234.56 SQL_C_FLOAT ignored 1234.56 n/a

SQL_DECIMAL 1234.56 SQL_C_SSHORT ignored 1234 01S07

SQL_DECIMAL 1234.56 SQL_C_STINYINT ignored ---- 22003

SQL_DOUBLE 1.2345678 SQL_C_DOUBLE ignored 1.2345678 n/a

SQL_DOUBLE 1.2345678 SQL_C_FLOAT ignored 1.234567 n/a

SQL_DOUBLE 1.2345678 SQL_C_STINYINT ignored 1 n/a

SQL_TYPE_DATE 1992-12-31 SQL_C_CHAR 11 1992-12-31\0[a] n/a

SQL_TYPE_DATE 1992-12-31 SQL_C_CHAR 10 ----- 22003

SQL_TYPE_DATE 1992-12-31 SQL_C_TIMESTA ignored 1992,12,31, n/a


MP 0,0,0,0[b]

SQL_TYPE_TIMES 1992-12-31 SQL_C_CHAR 23 1992-12-31 n/a


TAMP 23:45:55.12 23:45:55.12\0[a]

SQL_TYPE_TIMES 1992-12-31 SQL_C_CHAR 22 1992-12-31 01004


TAMP 23:45:55.12 23:45:55.1\0[a]

SQL_TYPE_TIMES 1992-12-31 SQL_C_CHAR 18 ---- 22003


TAMP 23:45:55.12

[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.

C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE

SQL_C_CHAR (Byte length of data) * Data Length of data in n/a


2 < BufferLength bytes
Truncated data 01004
(Byte length of data) * Length of data in
2 >= BufferLength bytes

SQL_C_WCHAR (Character length of Data Length of data in n/a


data) * 2 < characters
BufferLength Truncated data 01004
Length of data in
(Character length of characters
data) * 2 >=
BufferLength

SQL_C_BINARY Byte length of data Data Length of data in n/a


<= BufferLength bytes
Truncated data 01004
Byte length of data > Length of data in
BufferLength bytes

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.

C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE

SQL_C_CHAR BufferLength > 1 Data 1 n/a

SQL_C_WCHAR BufferLength <= 1 Undefined Undefined 22003

SQL_C_STINYINT None[a] Data Size of the C data n/a


type
SQL_C_UTINYINT

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

SQL_C_BIT None[a] Data 1[b] n/a

SQL_C_BINARY BufferLength >= 1 Data 1 n/a

BufferLength < 1 Undefined Undefined 22003

[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.

C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE

SQL_C_CHAR Byte length of data < Data Length of data in n/a


BufferLength bytes
Truncated data 01004
Byte length of data Length of data in
>= BufferLength bytes

SQL_C_WCHAR Character length of Data Length of data in n/a


data < BufferLength characters
Truncated data 01004
Character length of Length of data in
data >= BufferLength characters

SQL_C_STINYINT Data converted Data Number of bytes of n/a


SQL_C_UTINYINT without truncation[b] the C data type
SQL_C_TINYINT Truncated data 01S07
SQL_C_SBIGINT Data converted with Number of bytes of
SQL_C_UBIGINT truncation of Undefined the C data type 22003
SQL_C_SSHORT fractional digits[a]
SQL_C_USHORT Undefined Undefined 22018
SQL_C_SHORT Conversion of data
SQL_C_SLONG would result in loss of Undefined
SQL_C_ULONG whole (as opposed to
SQL_C_LONG fractional) digits[a]
SQL_C_NUMERIC
Data is not a
numeric-literal[b]
C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE

SQL_C_FLOAT Data is within the Data Size of the C data n/a


SQL_C_DOUBLE range of the data type
type to which the Undefined 22003
number is being Undefined
converted[a] Undefined 22018
Undefined
Data is outside the
range of the data
type to which the
number is being
converted[a]

Data is not a
numeric-literal[b]

_C_BIT Data is 0 or 1 Data 1[b] n/a

Data is greater than Truncated data 1[b] 01S07


0, less than 2, and not
equal to 1 Undefined Undefined 22003

Data is less than 0 or Undefined Undefined 22018


greater than or equal
to 2

Data is not a
numeric-literal

SQL_C_BINARY Byte length of data Data Length of data in n/a


<= BufferLength bytes
Truncated data 01004
Byte length of data > Length of data
BufferLength

SQL_C_TYPE_DATE Data value is a valid Data 6[b] n/a


date-value[a]
Data 6[b] n/a
Data value is a valid
timestamp-value; Truncated data 6[b] 01S07
time portion is zero[a]
Undefined Undefined 22018
Data value is a valid
timestamp-value;
time portion is
nonzero[a],[c]

Data value is not a


valid date-value or
timestamp-value[a]
C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE

SQL_C_TYPE_TIME Data value is a valid Data 6[b] n/a


time-value and the
fractional seconds Data 6[b] n/a
value is 0[a]
Truncated data 6[b] 01S07
Data value is a valid
timestamp-value or a Undefined Undefined 22018
valid time-value;
fractional seconds
portion is zero[a],[d]

Data value is a valid


timestamp-value;
fractional seconds
portion is nonzero[a],
[d],[e]

Data value is not a


valid time-value or
timestamp-value[a]

_C_TYPE_TIMESTAMP Data value is a valid Data 16[b] n/a


timestamp-value or a
valid time-value; Truncated data 16[b] 01S07
fractional seconds
portion not Data[f] 16[b] n/a
truncated[a]
Data[g] 16[b] n/a
Data value is a valid
timestamp-value or a Undefined Undefined 22018
valid time-value;
fractional seconds
portion truncated[a]

Data value is a valid


date-value[a]

Data value is a valid


time-value[a]

Data value is not a


valid date-value,
time-value, or
timestamp-value[a]
C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE

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

The data value is not


a valid interval value

[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.

C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE

SQL_C_CHAR BufferLength > Data 10 n/a


Character byte length
Truncated data Length of data in 01004
11 <= BufferLength bytes
<= Character byte Undefined 22003
length Undefined

BufferLength < 11

SQL_C_WCHAR BufferLength > Data 10 n/a


Character length
Truncated data Length of data in 01004
11 <= BufferLength characters
<= Character length Undefined 22003
Undefined
BufferLength < 11

SQL_C_BINARY Byte length of data Data Length of data in n/a


<= BufferLength bytes
Undefined 22003
Byte length of data > Undefined
BufferLength

SQL_C_TYPE_DATE None[a] Data 6[c] n/a

SQL_C_TYPE_TIMESTA None[a] Data[b] 16[c] n/a


MP

[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.

C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE

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

SQL_C_STINYINT[b] Interval precision was Data Size of the C data n/a


SQL_C_UTINYINT[b] a single field and the type
SQL_C_USHORT[b] data was converted Truncated data 01S07
SQL_C_SHORT[b] without truncation Length of data
SQL_C_SLONG[b] Truncated data 22003
SQL_C_ULONG[b] Interval precision was Length of data
SQL_C_NUMERIC[b] a single field and Undefined 07006
SQL_C_BIGINT[b] truncated fractional Size of the C data
type
Interval precision was
a single field and
truncated whole

Interval precision was


not a single field
C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE

SQL_C_BINARY Byte length of data Data Length of data n/a


<= BufferLength
Undefined Undefined 22003
Byte length of data >
BufferLength

SQL_C_CHAR Character byte length Data Size of the C data n/a


< BufferLength type
Truncated data 01004
Number of whole (as Size of the C data
opposed to fractional) Undefined type 22003
digits < BufferLength
Undefined
Number of whole (as
opposed to fractional)
digits >=
BufferLength

_C_WCHAR Character length < Data Size of the C data n/a


BufferLength type
Truncated data 01004
Number of whole (as Size of the C data
opposed to fractional) Undefined type 22003
digits < BufferLength
Undefined
Number of whole (as
opposed to fractional)
digits >=
BufferLength

[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;

// Execute a select statement; "interval_column" is a column


// whose data type is SQL_INTERVAL_DAY_TO_MINUTE.
SQLExecDirect(hstmt, "SELECT interval_column FROM table", SQL_NTS);

// 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.

C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE

SQL_C_CHAR BufferLength > Data 36 n/a


Character byte length

BufferLength < 37 Undefined Undefined 22003

SQL_C_WCHAR BufferLength > Data 36 n/a


Character length

BufferLength < 37 Undefined Undefined 22003

SQL_C_BINARY Byte length of data Data Length of data in n/a


<= BufferLength bytes

Byte length of data > Undefined Undefined 22003


BufferLength

SQL_C_GUID None[a] Data 16[b] n/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] 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.

C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE

SQL_C_CHAR Character byte length Data Length of data in n/a


< BufferLength bytes
Truncated data 01004
Number of whole (as Length of data in
opposed to fractional) Undefined bytes 22003
digits < BufferLength
Undefined
Number of whole (as
opposed to fractional)
digits >=
BufferLength

SQL_C_WCHAR Character length < Data Length of data in n/a


BufferLength characters
Truncated data 01004
Number of whole (as Length of data in
opposed to fractional) Undefined characters 22003
digits < BufferLength
Undefined
Number of whole (as
opposed to fractional)
digits >=
BufferLength
C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE

SQL_C_STINYINT Data converted Data Size of the C data n/a


without truncation[a] type
SQL_C_UTINYINT Truncated data 01S07
Data converted with Size of the C data
SQL_C_TINYINT truncation of Undefined type 22003
fractional digits[a]
SQL_C_SBIGINT Undefined
Conversion of data
SQL_C_UBIGINT would result in loss of
whole (as opposed to
SQL_C_SSHORT fractional) digits[a]

SQL_C_USHORT

SQL_C_SHORT

SQL_C_SLONG

SQL_C_ULONG

SQL_C_LONG

SQL_C_NUMERIC

_C_FLOAT Data is within the Data Size of the C data n/a


range of the data type
SQL_C_DOUBLE type to which the Undefined 22003
number is being Undefined
converted[a]

Data is outside the


range of the data
type to which the
number is being
converted[a]

SQL_C_BIT Data is 0 or 1[a] Data 1[b] n/a

Data is greater than Truncated data 1[b] 01S07


0, less than 2, and not
equal to 1[a] Undefined Undefined 22003

Data is less than 0 or


greater than or equal
to 2[a]

SQL_C_BINARY Byte length of data Data Length of data n/a


<= BufferLength
Undefined Undefined 22003
Byte length of data >
BufferLength
C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE

SQL_C_INTERVAL_M Data not truncated Data Length of data in n/a


ONTH[c] bytes
SQL_C_INTERVAL_YE Fractional seconds Truncated data 01S07
AR[c] portion truncated Length of data in
SQL_C_INTERVAL_DA Undefined bytes 22015
Y[c] Whole part of number
SQL_C_INTERVAL_HO truncated Undefined
UR[c]
SQL_C_INTERVAL_MI
NUTE[c]
SQL_C_INTERVAL_SEC
OND[c]

_C_INTERVAL_YEAR_T Whole part of number Undefined Undefined 22015


O_MONTH truncated
SQL_C_INTERVAL_DA
Y_TO_HOUR
SQL_C_INTERVAL_DA
Y_TO_MINUTE
SQL_C_INTERVAL_DA
Y_TO_SECOND
SQL_C_INTERVAL_HO
UR_TO_MINUTE
SQL_C_INTERVAL_HO
UR_TO_SECOND

[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).

SQL_C_NUMERIC and SQLSetDescField


The SQLSetDescField Function is required to perform manual binding with SQL_C_NUMERIC values. (Note that
SQLSetDescField was added in ODBC 3.0.) To perform manual binding, you must first get the descriptor handle.
if (fCType == SQL_C_NUMERIC) {
// special processing required for NUMERIC to get right scale & precision
// Modify the fields in the implicit application parameter descriptor
SQLHDESC hdesc=NULL;

// Use SQL_ATTR_APP_ROW_DESC for calls to SQLBindCol()


// Use SQL_ATTR_APP_PARAM_DESC for calls to SQLBindParameter()
//
// retcode = SQLGetStmtAttr(hstmt, SQL_ATTR_APP_ROW_DESC, &hdesc, 0, NULL);
retcode = SQLGetStmtAttr(hstmt, SQL_ATTR_APP_PARAM_DESC, &hdesc, 0, NULL);
if (!ODBC_CALL_SUCCESS(retcode)) {
printf ("\nSQLGetStmtAttr failed");
i = 1;
sqlstate[7] = '\0';
while (SQLGetDiagRec(SQL_HANDLE_STMT, hstmt, i, sqlstate, &NativeError, wrkbuf, sizeof(wrkbuf), &len) !=
SQL_NO_DATA) {
printf("\niTestCase = %d Failed...Precision = %d, Scale = %d\nNativeError=%d, State=%s, \n
Message=%s",
iTestCase, Precision, Scale, NativeError, sqlstate, wrkbuf);
i++;
}
continue;
}
retcode = SQLSetDescField(hdesc, iCol, SQL_DESC_TYPE, (SQLPOINTER) SQL_C_NUMERIC, 0);
if (!ODBC_CALL_SUCCESS(retcode))
goto error;
retcode = SQLSetDescField(hdesc, iCol, SQL_DESC_PRECISION, (SQLPOINTER)num.precision, 0);
if (!ODBC_CALL_SUCCESS(retcode))
goto error;
retcode = SQLSetDescField(hdesc, iCol, SQL_DESC_SCALE, (SQLPOINTER)num.scale, 0);
if (!ODBC_CALL_SUCCESS(retcode))
goto error;
retcode = SQLSetDescField(hdesc, iCol, SQL_DESC_DATA_PTR, (SQLPOINTER) &(num), sizeof(num));
SQL to C: Timestamp
12/20/2017 • 1 min to read • Edit Online

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.

C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE

SQL_C_CHAR BufferLength > Data Length of data in n/a


Character byte length bytes
Truncated data[b] 01004
20 <= BufferLength Length of data in
<= Character byte Undefined bytes 22003
length
Undefined
BufferLength < 20

SQL_C_WCHAR BufferLength > Data Length of data in n/a


Character length characters
Truncated data[b] 01004
20 <= BufferLength Length of data in
<= Character length Undefined characters 22003

BufferLength < 20 Undefined

SQL_C_BINARY Byte length of data Data Length of data in n/a


<= BufferLength bytes
Undefined 22003
Byte length of data > Undefined
BufferLength

SQL_C_TYPE_DATE Time portion of Data 6[f] n/a


timestamp is zero[a]
Truncated data[c] 6[f] 01S07
Time portion of
timestamp is
nonzero[a]

SQL_C_TYPE_TIME Fractional seconds Data[d] 6[f] n/a


portion of timestamp
is zero[a] Truncated data[d], [e] 6[f] 01S07

Fractional seconds
portion of timestamp
is nonzero[a]
C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE

_C_TYPE_TIMESTAMP Fractional seconds Data[e] 16[f] n/a


portion of timestamp
is not truncated[a] Truncated data[e] 16[f] 01S07

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.

C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE

SQL_C_CHAR BufferLength > Data Length of data in n/a


Character byte length bytes
Truncated data[a] 01004
9 <= BufferLength Length of data in
<= Character byte Undefined bytes 22003
length
Undefined
BufferLength < 9

SQL_C_WCHAR BufferLength > Data Length of data in n/a


Character length characters
Truncated data[a] 01004
9 <= BufferLength Length of data in
<= Character length Undefined characters 22003

BufferLength < 9 Undefined

SQL_C_BINARY Byte length of data Data Length of data in n/a


<= BufferLength bytes
Undefined 22003
Byte length of data > Undefined
BufferLength

SQL_C_TYPE_TIME None[b] Data 6[d] n/a

SQL_C_TYPE_TIMESTA None[b] Data[c] 16[d] n/a


MP

[a] The fractional seconds of the time are truncated.


[b] 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.
[c] The date fields of the timestamp structure are set to the current date, and the fractional seconds field of the
timestamp structure is set to zero.
[d] This is the size of the corresponding C data type.
When time SQL data is converted to character C data, the resulting string is in the "hh:mm:ss" format. This format is
not affected by the Windows® country setting.
SQL to C: Year-Month Intervals
12/20/2017 • 1 min to read • Edit Online

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.

C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE

SQL_C_INTERVAL_M Trailing fields portion Data Length of data in n/a


ONTH[a] not truncated bytes
Truncated data 01S07
SQL_C_INTERVAL_YE Trailing fields portion Length of data in
AR[a] truncated Undefined bytes 22015

SQL_C_INTERVAL_YE Leading precision of Undefined


AR_TO_MONTH[a] target is not big
enough to hold data
from source

SQL_C_STINYINT[b] Interval precision was Data Size of the C data n/a


a single field and the type
SQL_C_UTINYINT[b] data was converted Truncated data 22003
without truncation Length of data in
SQL_C_USHORT[b] Undefined bytes 22015
Interval precision was
SQL_C_SHORT[b] a single field and Size of the C data
truncated whole type
SQL_C_SLONG[b]
Interval precision was
SQL_C_ULONG[b] not a single field

SQL_C_NUMERIC[b]

SQL_C_BIGINT[b]

_C_BINARY Byte length of data Data Length of data in n/a


<= BufferLength bytes
Undefined 22003
Byte length of data > Undefined
BufferLength
C TYPE IDENTIFIER TEST *TARGETVALUEPTR *STRLEN_OR_INDPTR SQLSTATE

SQL_C_CHAR Character byte length Data Size of the C data n/a


< BufferLength type
Truncated data 01004
Number of whole (as Size of the C data
opposed to fractional) Undefined type 22003
digits < BufferLength
Undefined
Number of whole (as
opposed to fractional)
digits >=
BufferLength

SQL_C_WCHAR Character length < Data Size of the C data n/a


BufferLength type
Truncated data 01004
Number of whole (as Size of the C data
opposed to fractional) Undefined type 22003
digits < BufferLength
Undefined
Number of whole (as
opposed to fractional)
digits >=
BufferLength

[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:

{ fn CONVERT (value-exp, data-type) } /* ODBC


CAST (value-exp AS data-type) /* SQL92

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

ODBC statements have the following states.

STATE DESCRIPTION

S0 Unallocated statement. (The connection state must be C4, C5,


or C6. For more information, see Connection Transitions.)

S1 Allocated statement.

S2 Prepared statement. No result set will be created.

S3 Prepared statement. A (possibly empty) result set will be


created.

S4 Statement executed and no result set was created.

S5 Statement executed and a (possibly empty) result set was


created. The cursor is open and positioned before the first row
of the result set.

S6 Cursor positioned with SQLFetch or SQLFetchScroll.

S7 Cursor positioned with SQLExtendedFetch.

S8 Function needs data. SQLParamData has not been called.

S9 Function needs data. SQLPutData has not been called.

S10 Function needs data. SQLPutData has been called.

S11 Still executing. A statement is left in this state after a function


that is executed asynchronously returns
SQL_STILL_EXECUTING. A statement is temporarily in this
state while any function that accepts a statement handle is
executing. Temporary residence in state S11 is not shown in
any state tables except the state table for SQLCancel. While a
statement is temporarily in state S11, the function can be
canceled by calling SQLCancel from another thread.

S12 Asynchronous execution canceled. In S12, an application must


call the canceled function until it returns a value other than
SQL_STILL_EXECUTING. The function was canceled
successfully only if the function returns SQL_ERROR and
SQLSTATE HY008 (Operation canceled). If it returns any other
value, such as SQL_SUCCESS, the cancel operation failed and
the function executed normally.

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

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

--[1], [5], [6] --[5] --[5] --[5] --[5] --[5] --[5]

--[2], [5] --[5] --[5] --[5] --[5] --[5] --[5]

S1[3] --[5] --[5] --[5] --[5] --[5] --[5]

--[4], [5] --[5] --[5] --[5] --[5] --[5] --[5]

[1] This row shows transitions when HandleType was SQL_HANDLE_ENV.


[2] This row shows transitions when HandleType was SQL_HANDLE_DBC.
[3] This row shows transitions when HandleType was SQL_HANDLE_STMT.
[4] This row shows transitions when HandleType was SQL_HANDLE_DESC.
[5] Calling SQLAllocHandle with OutputHandlePtr pointing to a valid handle overwrites that handle without
regard for the previous contents to that handle and might cause problems for ODBC drivers. It is incorrect ODBC
application programming to call SQLAllocHandle twice with the same application variable defined for
*OutputHandlePtr without calling SQLFreeHandle to free the handle before reallocating it. Overwriting ODBC
handles in such a manner might lead to inconsistent behavior or errors on the part of ODBC drivers.

SQLBindCol
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH -- -- -- -- HY010 HY010

SQLBindParameter
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH -- -- -- -- HY010 HY010

SQLBrowseConnect, SQLConnect, and SQLDriverConnect


S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

08002 08002 08002 08002 08002 08002 08002


SQLBulkOperations
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH HY010 HY010 24000 See next table HY010 NS [c] HY010


o

SQLBulkOperations (Cursor States)


S5 S6 S7

OPENED SQLFETCH OR SQLFETCHSCROLL SQLEXTENDEDFETCH

-- [s] S8 [d] S11 [x] -- [s] S8 [d] S11 [x] HY010

SQLCancel
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH -- -- -- -- S1[1] S2 [nr] See next table


and [2] S3
[r]and [2]
S5[3] and [5]
S6([3] or [4])
and [6] S7[4]
and [7]

[1] SQLExecDirect returned SQL_NEED_DATA.


[2] SQLExecute returned SQL_NEED_DATA.
[3] SQLBulkOperations returned SQL_NEED_DATA.
[4] SQLSetPos returned SQL_NEED_DATA.
[5] SQLFetch, SQLFetchScroll, or SQLExtendedFetch had not been called.
[6] SQLFetch or SQLFetchScroll had been called.
[7] SQLExtendedFetch had been called.

SQLCancel (Asynchronous States)


S11 S12

STILL EXECUTING ASYNCH CANCELED

NS[1] S12[2] 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

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH 24000 24000 24000 S1 [np] S3 [p] HY010 HY010

SQLColAttribute
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH HY010 See next table 24000 -- [s] S11 [x] HY010 NS [c] HY010
o

SQLColAttribute (Prepared States)


S2 S3

NO RESULTS RESULTS

--[1] 07005[2] -- [s] S11 x

[1] FieldIdentifier was SQL_DESC_COUNT.


[2] FieldIdentifier was not SQL_DESC_COUNT.

SQLColumnPrivileges, SQLColumns, SQLForeignKeys,


SQLGetTypeInfo, SQLPrimaryKeys, SQLProcedureColumns,
SQLProcedures, SQLSpecialColumns, SQLStatistics,
SQLTablePrivileges, and SQLTables
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

(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.

SQLColumnPrivileges, SQLColumns, SQLForeignKeys,


SQLGetTypeInfo, SQLPrimaryKeys, SQLProcedureColumns,
SQLProcedures, SQLSpecialColumns, SQLStatistics,
SQLTablePrivileges, and SQLTables (Cursor States)
S5 S6 S7

OPENED SQLFETCH OR SQLFETCHSCROLL SQLEXTENDEDFETCH

24000 24000[1] 24000

[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

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH[1] -- -- -- -- HY010 NS [c] and [3]


HY010 [o] or
[4]

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.

SQLCopyDesc (Prepared States)


S2 S3

NO RESULTS RESULTS

24000[1] -- [s] S11 [x]

[1]This row shows transitions when the SourceDescHandle argument was an IRD.

SQLDataSources and SQLDrivers


S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

-- -- -- -- -- -- --

SQLDescribeCol
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH HY010 See next table 24000 -- [s] S11 [x] HY010 NS [c] HY010
o

SQLDescribeCol (Prepared States)


S2 S3

NO RESULTS RESULTS

07005 -- [s] S11 [x]

SQLDescribeParam
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH HY010 -- [s] S11 [x] HY010 HY010 HY010 NS [c] HY010


[o]

SQLDisconnect
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

--[1] S0[1] S0[1] S0[1] S0[1] (HY010) (HY010)

[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

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

-- -- --[2] or [3] --[3] S1 [np] --[3] S1 [np] (HY010) (HY010)


S1[1] and ([1] or [2]) and ([1] or [2])
S1 [p] and [1] S1 [p] and [1]
S2 [p] and [2] S3 [p] and [2]

[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

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

(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] The error was returned by the Driver Manager.


[2] The error was not returned by the Driver Manager.
[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.

SQLExecDirect (Cursor States)


S5 S6 S7

OPENED SQLFETCH OR SQLFETCHSCROLL SQLEXTENDEDFETCH

24000 24000 [1] 24000

[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

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

(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

S4 [s] S8 [d] S11 [x] S5 [s] S8 [d] S11 [x]

SQLExecute (Cursor States)


S5 S6 S7

OPENED SQLFETCH OR SQLFETCHSCROLL SQLEXTENDEDFETCH

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

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH S1010 S1010 24000 See next table S1010 NS [c] S1010


[o]

SQLExtendedFetch (Cursor States)


S5 S6 S7

OPENED SQLFETCH OR SQLFETCHSCROLL SQLEXTENDEDFETCH

S7 [s] or [nf] S11 [x] S1010 -- [s] or [nf] S11 [x]

SQLFetch and SQLFetchScroll


S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH HY010 HY010 24000 See next table HY010 NS [c] HY010


[o]

SQLFetch and SQLFetchScroll (Cursor states)


S5 S6 S7

OPENED SQLFETCH OR SQLFETCHSCROLL SQLEXTENDEDFETCH

S6 [s] or [nf] S11 [x] -- [s] or [nf] S11 [x] HY010

SQLFreeHandle
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

-- [1] HY010 HY010 HY010 HY010 HY010 HY010

IH [2] S0 S0 S0 S0 HY010 HY010

-- [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

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH [1] -- -- S1 [np] S2 [p] S1 [np] S3 [p] HY010 HY010

IH [2] -- -- -- -- HY010 HY010

[1] This row shows transitions when Option was SQL_CLOSE.


[2] This row shows transitions when Option was SQL_UNBIND or SQL_RESET_PARAMS. If the Option argument
was SQL_DROP and the underlying driver is an ODBC 3.x driver, the Driver Manager maps this to a call to
SQLFreeHandle with HandleType set to SQL_HANDLE_STMT. For more information, see the transition table for
SQLFreeHandle.

SQLGetConnectAttr
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

-- -- -- -- -- -- --

SQLGetCursorName
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH -- -- -- -- HY010 HY010

SQLGetData
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH HY010 HY010 24000 See next table HY010 NS [c] HY010


[o]

SQLGetData (Cursor States)


S5 S6 S7

OPENED SQLFETCH OR SQLFETCHSCROLL SQLEXTENDEDFETCH

24000 -- [s] or [nf] S11 [x] 24000 [b] HY109 [i] -- [s] or [nf] S11 [x] 24000 [b] HY109 [i]

SQLGetDescField and SQLGetDescRec


S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

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]

[1] The DescriptorHandle argument was an APD or ARD.


[2] The DescriptorHandle argument was an IPD.
[3] The DescriptorHandle argument was an IRD.
[4] The DescriptorHandle argument was the same as the DescriptorHandle argument in the SQLGetDescField or
SQLGetDescRec function that is running asynchronously.
[5] The DescriptorHandle argument was different than the DescriptorHandle argument in the SQLGetDescField or
SQLGetDescRec function that is running asynchronously.

SQLGetDescField and SQLGetDescRec (Prepared States)


S2 S3

NO RESULTS RESULTS

--[1], [2], or [3] S11[2] and [x] --[1], [2], or [3] S11 [x]

[1] The DescriptorHandle argument was an APD or ARD.


[2] The DescriptorHandle argument was an IPD.
[3] The DescriptorHandle argument was an IRD. Note that these functions always return SQL_NO_DATA in state S2
when DescriptorHandle was an IRD.

SQLGetDiagField and SQLGetDiagRec


S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

--[1] -- -- -- -- -- --

IH[2] --[3] --[3] -- -- --[3] --[3]

[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

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

-- -- -- -- -- -- --

SQLGetFunctions
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

-- -- -- -- -- -- --

SQLGetInfo
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

-- -- -- -- -- -- --

SQLGetStmtAttr
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH --[1] 24000[2] --[1] 24000[2] --[1] 24000[2] See next table HY010 HY010

[1] The statement attribute was not SQL_ATTR_ROW_NUMBER.


[2] The statement attribute was SQL_ATTR_ROW_NUMBER.

SQLGetStmtAttr (Cursor States)


S5 S6 S7

OPENED SQLFETCH OR SQLFETCHSCROLL SQLEXTENDEDFETCH

--[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]

[1] The Attribute argument was not SQL_ATTR_ROW_NUMBER.


[2] The Attribute argument was SQL_ATTR_ROW_NUMBER.

SQLMoreResults
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

(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]

[1] The function always returns SQL_NO_DATA in this state.


[2] The next result is a row count.
[3] The next result is a result set.
[4] The current result is the last result.

SQLNativeSql
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

-- -- -- -- -- -- --

SQLNumParams
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

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

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

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

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH HY010 HY010 HY010 HY010 See next table NS [c] HY010


[o]

SQLParamData (Need Data States)


S8 S9 S10

NEED DATA MUST PUT CAN PUT

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]

[1] SQLExecDirect returned SQL_NEED_DATA.


[2] SQLExecute returned SQL_NEED_DATA.
[3] SQLSetPos had been called from state S7 and returned SQL_NEED_DATA.
[4] SQLBulkOperations had been called from state S5 and returned SQL_NEED_DATA.
[5] SQLSetPos or SQLBulkOperations had been called from state S6 and returned SQL_NEED_DATA.

SQLPrepare
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

(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.

SQLPrepare (Cursor States)


S5 S6 S7

OPENED SQLFETCH OR SQLFETCHSCROLL SQLEXTENDEDFETCH

24000 24000 24000

SQLPutData
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH HY010 HY010 HY010 HY010 See next table NS [c] HY010


[o]

SQLPutData (Need Data States)


S8 S9 S10

NEED DATA MUST PUT CAN PUT

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]

[1] SQLExecDirect returned SQL_NEED_DATA.


[2] SQLExecute returned SQL_NEED_DATA.
[3] SQLSetPos had been called from state S7 and returned SQL_NEED_DATA.
[4] SQLBulkOperations had been called from state S5 and returned SQL_NEED_DATA.
[5] SQLSetPos or SQLBulkOperations had been called from state S6 and returned SQL_NEED_DATA.
[6] One or more calls to SQLPutData for a single parameter returned SQL_SUCCESS, and then a call to
SQLPutData was made for the same parameter with StrLen_or_Ind set to SQL_NULL_DATA.

SQLRowCount
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

(IH) (HY010) (HY010) -- -- (HY010) (HY010)

SQLSetConnectAttr
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

--[1] -- -- -- --[2] 24000[3] HY010 HY010

[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

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH -- -- 24000 24000 HY010 HY010

SQLSetDescField and SQLSetDescRec


S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH[1] -- -- -- -- HY010 HY010

[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

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

HY011 HY011 HY011 HY011 Y011 HY01 HY011

SQLSetPos
S0 S1 S2–S3 S4 S5–S7 S8–S10 S11–S12

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH HY010 HY010 24000 See next table HY010 NS [c] HY010


[o]

SQLSetPos (Cursor States)


S5 S6 S7

OPENED SQLFETCH OR SQLFETCHSCROLL SQLEXTENDEDFETCH

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

UNALLOCATED ALLOCATED PREPARED EXECUTED CURSOR NEED DATA ASYNC

IH -- --[1] --[1] 24000[2] --[1] 24000[2] HY010 [np] or HY010 [np] or


HY011[2] [1] HY011 [p] [1] HY011 [p]
and [2] and [2]

[1] The Attribute argument was not SQL_ATTR_CONCURRENCY, SQL_ATTR_CURSOR_TYPE,


SQL_ATTR_SIMULATE_CURSOR, SQL_ATTR_USE_BOOKMARKS, SQL_ATTR_CURSOR_SCROLLABLE, or
SQL_ATTR_CURSOR_SENSITIVITY.
[2] The Attribute argument was SQL_ATTR_CONCURRENCY, SQL_ATTR_CURSOR_TYPE,
SQL_ATTR_SIMULATE_CURSOR, SQL_ATTR_USE_BOOKMARKS, SQL_ATTR_CURSOR_SCROLLABLE, or
SQL_ATTR_CURSOR_SENSITIVITY.
String Functions
12/20/2017 • 4 min to read • Edit Online

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.

LENGTH only accepts strings. Therefore will implicitly convert


string_exp to a string, and return the length of this string (not
the internal size of the datatype).

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.

If an application can call the LOCATE scalar function with the


string_exp1, string_exp2, and start arguments, the driver
returns SQL_FN_STR_LOCATE when SQLGetInfo is called with
an Option of SQL_STRING_FUNCTIONS. If the application can
call the LOCATE scalar function with only the string_exp1 and
string_exp2 arguments, the driver returns
SQL_FN_STR_LOCATE_2 when SQLGetInfo is called with an
Option of SQL_STRING_FUNCTIONS. Drivers that support
calling the LOCATE function with either two or three
arguments return both SQL_FN_STR_LOCATE and
SQL_FN_STR_LOCATE_2.

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.

SOUNDEX( string_exp ) (ODBC 2.0) Returns a data source–dependent character string


representing the sound of the words in string_exp. For
example, SQL Server returns a 4-digit SOUNDEX code; Oracle
returns a phonetic representation of each word.

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_DATE( ) (ODBC 3.0) Returns the current date.

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.

CURDATE( ) (ODBC 1.0) Returns the current date.

CURTIME( ) (ODBC 1.0) Returns the current local time.

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:

YEAR MONTH DAY HOUR MINUTE SECOND

The precision of the returned value is implementation-defined.


The scale is 0 unless SECOND is specified, in which case the
scale is not less than the fractional seconds precision of the
extract-source field.

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

where fractional seconds are expressed in billionths of a


second. For example, the following SQL statement returns the
name of each employee and his or her one-year anniversary
date:

SELECT NAME, {fn TIMESTAMPADD(SQL_TSI_YEAR, 1,


HIRE_DATE)} FROM EMPLOYEES

If timestamp_exp is a time value and interval specifies days,


weeks, months, quarters, or years, the date portion of
timestamp_exp is set to the current date before calculating
the resulting timestamp.

If timestamp_exp is a date value and interval specifies


fractional seconds, seconds, minutes, or hours, the time
portion of timestamp_exp is set to 0 before calculating the
resulting timestamp.

An application determines which intervals a data source


supports by calling SQLGetInfo with the
SQL_TIMEDATE_ADD_INTERVALS option.
FUNCTION DESCRIPTION

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

where fractional seconds are expressed in billionths of a


second. For example, the following SQL statement returns the
name of each employee and the number of years he or she
has been employed:

SELECT NAME, {fn TIMESTAMPDIFF(SQL_TSI_YEAR, {fn


CURDATE()}, HIRE_DATE)} FROM EMPLOYEES

If either timestamp expression is a time value and interval


specifies days, weeks, months, quarters, or years, the date
portion of that timestamp is set to the current date before
calculating the difference between the timestamps.

If either timestamp expression is a date value and interval


specifies fractional seconds, seconds, minutes, or hours, the
time portion of that timestamp is set to 0 before calculating
the difference between the timestamps.

An application determines which intervals a data source


supports by calling SQLGetInfo with the
SQL_TIMEDATE_DIFF_INTERVALS option.

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.

SQL TYPE IDENTIFIER LENGTH

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_DECIMAL The number of bytes required to hold the character


SQL_NUMERIC representation of this data if the character set is ANSI, and
twice this number if the character set is UNICODE. This is the
maximum number of digits plus two, because the data is
returned as a character string and characters are needed for
the digits, a sign, and a decimal point. For example, the
transfer length of a column defined as NUMERIC(10,3) is 12.

SQL_TINYINT 1

SQL_SMALLINT 2

SQL_INTEGER 4

SQL_BIGINT The number of bytes required to hold the character


representation of this data if the character set is ANSI, and
twice this number if the character set is UNICODE, because
this data type is returned as a character string by default. The
character representation consists of 20 characters: 19 for
digits and a sign, if signed, or 20 digits, if unsigned. Therefore,
the length is 20.

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.

SQL_TYPE_DATE 6 (the size of the SQL_DATE_STRUCT or SQL_TIME_STRUCT


SQL_TYPE_TIME structure).
SQL TYPE IDENTIFIER LENGTH

SQL_TYPE_TIMESTAMP 16 (the size of the SQL_TIMESTAMP_STRUCT structure).

All interval data types 34 (the size of the interval structure).

SQL_GUID 16 (the size of the GUID structure).

[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.

To use the ODBC cursor library, an application:


1. Calls SQLSetConnectAttr with an Attribute of SQL_ATTR_ODBC_CURSORS to specify how the cursor
library should be used with a particular connection. The cursor library can be always used
(SQL_CUR_USE_ODBC), used only if driver does not support scrollable cursors (SQL_CUR_USE_IF_NEEDED),
or never used (SQL_CUR_USE_DRIVER).
2. Calls SQLConnect, SQLDriverConnect, or SQLBrowseConnect to connect to the data source.
3. Calls SQLSetStmtAttr to specify the cursor type (SQL_ATTR_CURSOR_TYPE), concurrency
(SQL_ATTR_CONCURRENCY), and rowset size (SQL_ATTR_ROW_ARRAY_SIZE). The cursor library supports
forward-only and static cursors. Forward-only cursors must be read-only, while static cursors can be read-
only or can use optimistic concurrency control comparing values.
4. Allocates one or more rowset buffers and calls SQLBindCol one or more times to bind these buffers to
result set columns.
5. Generates a result set by executing a SELECT statement or a procedure, or by calling a catalog function. If
the application will execute positioned update statements, it should execute a SELECT FOR UPDATE
statement to generate the result set.
6. Calls SQLFetch or SQLFetchScroll one or more times to scroll through the result set.
The application can change data values in the rowset buffers. To refresh the rowset buffers with data from
the cursor library's cache, an application calls SQLFetchScroll with the FetchOrientation argument set to
SQL_FETCH_RELATIVE and the FetchOffset argument set to 0.
To retrieve data from an unbound column, the application calls SQLSetPos to position the cursor on the
desired row. It then calls SQLGetData to retrieve the data.
To determine the number of rows that have been retrieved from the data source, the application calls
SQLRowCount.
What the Driver Does
12/20/2017 • 4 min to read • Edit Online

The following table summarizes what functions and statement attributes an ODBC 3.x driver should implement for
block and scrollable cursors.

FUNCTION OR

STATEMENT ATTRIBUTE COMMENTS

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.

SQL_ATTR_ROWS_FETCHED_PTR Sets the address of the buffer in which SQLFetch and


SQLFetchScroll return the number of rows fetched. If
SQLExtendedFetch is called, this buffer is not filled but the
RowCountPtr argument points to the number of rows fetched.

SQL_ATTR_ROW_ARRAY_SIZE Sets the rowset size used by SQLFetch and SQLFetchScroll.

SQL_ROWSET_SIZE Sets the rowset size used by SQLExtendedFetch. ODBC 3.x


drivers implement this if they want to work with ODBC 2.x
applications that call SQLExtendedFetch or SQLSetPos.

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

STATEMENT ATTRIBUTE COMMENTS

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.

SQLFetch Returns the next rowset. The following are implementation


details:

- 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

STATEMENT ATTRIBUTE COMMENTS

SQLFetchScroll Returns the specified rowset. The following are


implementation details:

- The driver retrieves the rowset size from 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.
- 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 SQLFetchScroll.

SQLSetPos Performs various positioned operations. The following are


implementation details:

- This can be called in statement states S6 or S7. For more


details, see Statement Transitions in Appendix B: ODBC State
Transition Tables.
- If this is called in statement state S5 or S6, the driver
retrieves the rowset size from the
SQL_ATTR_ROWS_FETCHED_PTR statement attribute and the
address of the row status array from the
SQL_ATTR_ROW_STATUS_PTR statement attribute.
- If this is called in statement state S7, the driver retrieves the
rowset size from the SQL_ROWSET_SIZE statement attribute
and the address of the row status array from the
RowStatusArray argument of SQLExtendedFetch.
- The driver returns SQLSTATE 01S01 (Error in row) only to
indicate that an error has occurred while rows were fetched by
a call to SQLSetPos to perform a bulk operation when the
function is called in state S7. To preserve backward
compatibility, if SQLSTATE 01S01 (Error in row) is returned by
SQLSetPos, 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.
- If the driver should work with ODBC 2.x applications that call
SQLSetPos with an Operation argument of SQL_ADD, the
driver must support SQLSetPos with an Operation argument
of SQL_ADD.
What the Driver Manager Does
12/20/2017 • 5 min to read • Edit Online

The following table summarizes how the ODBC 3.x Driver Manager maps calls to ODBC 2.x and ODBC 3.x drivers.

FUNCTION OR

STATEMENT ATTRIBUTE COMMENTS

SQL_ATTR_FETCH_BOOKMARK_PTR Points to the bookmark to use with SQLFetchScroll. The


following are implementation details:

- When an application sets this in an ODBC 2.x driver, the


ODBC 3.x Driver Manager caches it. It dereferences the
pointer and passes the value to the ODBC 2.x driver in the
FetchOffset argument of SQLExtendedFetch when
SQLFetchScroll is later called by the application.
- When an application sets this in an ODBC 3.x driver, the
ODBC 3.x Driver Manager passes the call to the driver.

SQL_ATTR_ROW_STATUS_PTR Points to the row status array filled by SQLFetch,


SQLFetchScroll, SQLBulkOperations, and SQLSetPos. The
following are implementation details:

- When an application sets this in an ODBC 2.x driver, the


ODBC 3.x Driver Manager caches its value. It passes this value
to the ODBC 2.x driver in the RowStatusArray argument of
SQLExtendedFetch when SQLFetchScroll or SQLFetch is
called.
- When an application sets this in an ODBC 3.x driver, the
ODBC 3.x Driver Manager passes the call to the driver.
- In state S6, if an application sets
SQL_ATTR_ROW_STATUS_PTR and then calls
SQLBulkOperations (with an Operation of SQL_ADD) or
SQLSetPos without first calling SQLFetch or SQLFetchScroll,
SQLSTATE HY011 (Attribute cannot be set now) is returned.

SQL_ATTR_ROWS_FETCHED_PTR Points to the buffer in which SQLFetch and SQLFetchScroll


return the number of rows fetched. The following are
implementation details:

- When an application sets this in an ODBC 2.x driver, the


ODBC 3.x Driver Manager caches its value. It passes this value
to the ODBC 2.x driver in the RowCountPtr argument of
SQLExtendedFetch when SQLFetch or SQLFetchScroll is
called by the application.
- When an application sets this in an ODBC 3.x driver, the
ODBC 3.x Driver Manager passes the call to the driver.
FUNCTION OR

STATEMENT ATTRIBUTE COMMENTS

SQL_ATTR_ROW_ARRAY_SIZE Sets the rowset size. The following are implementation details:

- When an application sets this in an ODBC 2.x driver, the


ODBC 3.x Driver Manager maps it to the SQL_ROWSET_SIZE
statement attribute.
- When an application sets this in an ODBC 3.x driver, the
ODBC 3.x Driver Manager passes the call to the driver.
- When an application working with an ODBC 3.x driver calls
SQLSetScrollOptions, SQL_ROWSET_SIZE is set to the value
in the RowsetSize argument if the underlying driver does not
support SQLSetScrollOptions.

SQL_ROWSET_SIZE Sets the rowset size used by SQLExtendedFetch when


SQLExtendedFetch is called by an ODBC 2.x application. The
following are implementation details:

- When an application sets this, the ODBC 3.x Driver Manager


passes the call to the driver, regardless of driver version.
- When an application working with an ODBC 2.x driver calls
SQLSetScrollOptions, SQL_ROWSET_SIZE is set to the value
in the RowsetSize argument.

SQLBulkOperations Performs an insert operation, or update, delete, or fetch by


bookmark operations. The following are implementation
details:

- When an application calls SQLBulkOperations with an


Operation of SQL_ADD in an ODBC 2.x driver, the ODBC 3.x
Driver Manager maps it to SQLSetPos with an Operation of
SQL_ADD.
- When working with an ODBC 2.x driver that does not
support SQLSetPos with an Operation of SQL_ADD, the
ODBC 3.x Driver Manager does not map SQLSetPos with an
Operation of SQL_ADD to SQLBulkOperations with an
Operation of SQL_ADD. This is because SQLBulkOperations
cannot be called in state S7, which in ODBC 2.x was the only
state in which SQLSetPos could be called.
- If the application calls SQLBulkOperations with an
Operation of SQL_ADD in an ODBC 2.x driver before calling
SQLFetchScroll, the ODBC 3.x Driver Manager returns an
error.

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

STATEMENT ATTRIBUTE COMMENTS

SQLFetch Returns the next rowset. The following are implementation


details:

- When an application calls SQLFetch in an ODBC 2.x driver,


the ODBC 3.x Driver Manager maps it to SQLExtendedFetch.
The FetchOrientation argument of SQLExtendedFetch is set
to SQL_FETCH_NEXT. The Driver Manager uses the cached
value of the SQL_ATTR_ROW_STATUS_PTR statement attribute
for the RowStatusArray argument and the cached value of the
SQL_ATTR_ROWS_FETCHED_PTR statement attribute for the
RowCountPtr argument.
- An ODBC 3.x application can mix calls to SQLFetch and
SQLFetchScroll in an ODBC 2.x driver because the ODBC 3.x
Driver Manager maps SQLFetch to SQLExtendedFetch when
an application calls it in an ODBC 2.x driver.
- If an ODBC 2.x driver does not support SQLExtendedFetch,
the ODBC 3.x Driver Manager does not map SQLFetch or
SQLFetchScroll to SQLExtendedFetch when an application
calls it in that driver. If the application attempts to set
SQL_ATTR_ROW_ARRAY_SIZE to a value greater than 1,
SQLSTATE HYC00 (Optional feature not implemented) is
returned.
- Except for the restrictions just noted, the ODBC 3.x Driver
Manager passes calls to SQLFetch to the driver, regardless of
the driver version.

SQLFetchScroll Returns the specified rowset. The following are


implementation details:

- When an application calls SQLFetchScroll in an ODBC 2.x


driver, the ODBC 3.x Driver Manager maps it to
SQLExtendedFetch. It uses the cached value of the
SQL_ATTR_ROW_STATUS_PTR statement attribute for the
RowStatusArray argument and the cached value of the
SQL_ATTR_ROWS_FETCHED_PTR statement attribute for the
RowCountPtr argument. If the FetchOrientation argument in
SQLFetchScroll is SQL_FETCH_BOOKMARK, it uses the
cached value of the SQL_ATTR_FETCH_BOOKMARK_PTR
statement attribute for the FetchOffset argument and returns
an error if the FetchOffset argument of SQLFetchScroll is not
0.
- When an application calls this in an ODBC 3.x driver, the
ODBC 3.x Driver Manager passes the call to the driver.

SQLSetPos Performs various positioned operations. The ODBC 3.x Driver


Manager passes calls to SQLSetPos to the driver, regardless
of the driver version.

SQLSetScrollOptions 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.
64-Bit Integer Structures
12/20/2017 • 1 min to read • Edit Online

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.

You might also like