Programming Guidelines

DownloadDownload ODBC Driver

The programming features of the Microsoft ODBC Driver for SQL Server on macOS and Linux are based on ODBC in SQL Server Native Client (SQL Server Native Client (ODBC)). SQL Server Native Client is based on ODBC in Windows Data Access Components (ODBC Programmer's Reference).

An ODBC application can use Multiple Active Result Sets (MARS) and other SQL Server specific features by including /usr/local/include/msodbcsql.h after including the unixODBC headers (sql.h, sqlext.h, sqltypes.h, and sqlucode.h). Then use the same symbolic names for SQL Server-specific items that you would use in your Windows ODBC applications.

Available Features

The following sections from the SQL Server Native Client documentation for ODBC (SQL Server Native Client (ODBC)) are valid when using the ODBC driver on macOS and Linux:

Unsupported Features

The following features have not been verified to work correctly in this release of the ODBC driver on macOS and Linux:

The following features are not available in this release of the ODBC driver on macOS and Linux:

  • Distributed Transactions (SQL_ATTR_ENLIST_IN_DTC attribute is not supported)
  • Database Mirroring
  • Profiling ODBC driver performance, discussed in SQLSetConnectAttr, and the following performance-related connection attributes:
  • SQLBrowseConnect
  • C interval types such as SQL_C_INTERVAL_YEAR_TO_MONTH (documented in Data Type Identifiers and Descriptors)
  • The SQL_CUR_USE_ODBC value of the SQL_ATTR_ODBC_CURSORS attribute of the SQLSetConnectAttr function.

Character Set Support

For ODBC Driver 13 and 13.1, SQLCHAR data must be UTF-8. No other encodings are supported.

For ODBC Driver 17, SQLCHAR data in one of the following character sets/encodings is supported:

Name Description
UTF-8 Unicode
CP437 MS-DOS Latin US
CP850 MS-DOS Latin 1
CP874 Latin/Thai
CP932 Japanese, Shift-JIS
CP936 Simplified Chinese, GBK
CP949 Korean, EUC-KR
CP950 Traditional Chinese, Big5
CP1251 Cyrillic
CP1253 Greek
CP1256 Arabic
CP1257 Baltic
CP1258 Vietnamese
ISO-8859-1 / CP1252 Latin-1
ISO-8859-2 / CP1250 Latin-2
ISO-8859-3 Latin-3
ISO-8859-4 Latin-4
ISO-8859-5 Latin/Cyrillic
ISO-8859-6 Latin/Arabic
ISO-8859-7 Latin/Greek
ISO-8859-8 / CP1255 Hebrew
ISO-8859-9 / CP1254 Turkish
ISO-8859-13 Latin-7
ISO-8859-15 Latin-9

Upon connection, the driver detects the current locale of the process it is loaded in. If it uses one of the encodings above, the driver uses that encoding for SQLCHAR (narrow-character) data; otherwise, it defaults to UTF-8. Since all processes start in the "C" locale by default (and thus cause the driver to default to UTF-8), if an application needs to use one of the encodings above, it should use the setlocale function to set the locale appropriately before connecting; either by specifying the desired locale explicitly, or using an empty string for example setlocale(LC_ALL, "") to use the locale settings of the environment.

Thus, in a typical Linux or Mac environment where the encoding is UTF-8, users of ODBC Driver 17 upgrading from 13 or 13.1 will not observe any differences. However, applications that use a non-UTF-8 encoding in the above list via setlocale() need to use that encoding for data to/from the driver instead of UTF-8.

SQLWCHAR data must be UTF-16LE (Little Endian).

When binding input parameters with SQLBindParameter, if a narrow character SQL type such as SQL_VARCHAR is specified, the driver converts the supplied data from the client encoding to the default (typically codepage 1252) SQL Server encoding. For output parameters, the driver converts from the encoding specified in the collation information associated with the data to the client encoding. However, data loss is possible --- characters in the source encoding not representable in the target encoding will convert to a question mark ('?').

To avoid this data loss when binding input parameters, specify a Unicode SQL character type such as SQL_NVARCHAR. In this case, the driver converts from the client encoding to UTF-16, which can represent all Unicode characters. Furthermore, the target column or parameter on the server must also be either a Unicode type (nchar, nvarchar, ntext) or one with a collation/encoding, which can represent all the characters of the original source data. For avoiding data loss with output parameters, specify a Unicode SQL type, and either a Unicode C type (SQL_C_WCHAR), causing the driver to return data as UTF-16; or a narrow C type, and ensure that the client encoding can represent all the characters of the source data (this is always possible with UTF-8.)

For more information about collations and encodings, see Collation and Unicode Support.

There are some encoding conversion differences between Windows and several versions of the iconv library on Linux and macOS. Text data in codepage 1255 (Hebrew) has one code point (0xCA) that behaves differently upon conversion to Unicode. On Windows, this character converts to the UTF-16 code point of 0x05BA. On macOS and Linux with libiconv versions earlier than 1.15, it converts to 0x00CA. On Linux with iconv libraries that do not support the 2003 revision of Big5/CP950 (named BIG5-2003), characters added with that revision will not convert correctly.

In ODBC Driver 13 and 13.1, when UTF-8 multibyte characters or UTF-16 surrogates are split across SQLPutData buffers, it results in data corruption. Use buffers for streaming SQLPutData that do not end in partial character encodings. This limitation has been removed with ODBC Driver 17.

Additional Notes

  1. You can make a dedicated administrator connection (DAC) using SQL Server authentication and host,port. A member of the Sysadmin role first needs to discover the DAC port. See Diagnostic Connection for Database Administrators to discover how. For example, if the DAC port were 33000, you could connect to it with sqlcmd as follows:

    sqlcmd –U <user> -P <pwd> -S <host>,33000


    DAC connections must use SQL Server Authentication.

  2. The UnixODBC driver manager returns "invalid attribute/option identifier" for all statement attributes when they are passed through SQLSetConnectAttr. On Windows, when SQLSetConnectAttr receives a statement attribute value, it causes the driver to set that value on all active statements which are children of the connection handle.

See Also

Frequently Asked Questions

Known Issues in this Version of the Driver

Release Notes