本文介绍了使用 Microsoft ODBC Driver for SQL Server(在 Linux 或 macOS 上)的应用程序的编程注意事项。 有些链接指向 SQL Server Native Client 的资料。 这些页面提供了有关 API 历史沿革的背景信息。
选择驱动版本
使用Microsoft ODBC Driver 18 for SQL Server,即当前的驱动系列,进行新开发。 Microsoft ODBC 驱动 17 for SQL Server 仍支持已部署该驱动的应用程序,具体说明在支持生命周期中。 随 SQL Server 2017 一起发布的 ODBC 驱动程序 13 有资格获得延长支持至 2027 年 10 月 12 日,但仅在签订扩展支持协议的情况下。
在你的连接字符串中指定已安装的驱动程序名称,并用大括号括起来:
Driver={ODBC Driver 18 for SQL Server}
Driver={ODBC Driver 17 for SQL Server}
在 odbc.ini 的数据源名称(DSN)中,使用不带大括号的名称,例如 Driver = ODBC Driver 18 for SQL Server。 关于DSN语法,请参见连接字符串关键字和数据源名称(DSN)。
关于版本特定的连接设置,请参见 主要版本差异。 有关支持日期和操作系统兼容性,请参见 支持生命周期 和 系统需求。
构建应用程序
有关头文件位置、顺序、编译器命令、库名以及 C++ 示例,请参见 使用 ODBC 驱动开发 C 和 C++ 应用程序 和 使用 C++ 和 ODBC 进行连接和查询。
ODBC 应用程序可以通过在 unixODBC 头文件(sqlext.h、sqlucode.h、sqltypes.h 和 msodbcsql.h)之后包含 sql.h,使用多活动结果集(MARS)及其他 SQL Server 特有功能。 使用与 Windows ODBC 应用中使用相同的符号名称来表示 SQL Server 特定项目。
查找驱动程序能力
从标准应用程序接口(API)的 ODBC程序员参考 开始。 然后使用当前的驱动程序文档了解驱动程序的具体行为。
Microsoft ODBC Driver for SQL Server概述链接到驱动程序文档。 以下 SQL Server Native Client 文章为在 Linux 和 macOS 上使用该驱动程序的应用程序提供了 API 上下文:
- 与 SQL Server 通信 (ODBC)
- 连接和查询超时支持
- 游标
- 日期/时间改进(ODBC)
- 执行查询(ODBC)
- 处理错误与消息
- Kerberos 身份验证
- 大型通用语言运行时(CLR)用户自定义类型(ODBC)
- 执行事务(ODBC)。 对于Linux和macOS上的分布式事务,使用 带有DTC的XA事务。
- 处理结果(ODBC)
- 运行存储过程
- 稀疏列支持(ODBC)
- 使用加密而不进行验证
- 表值参数
- 命令和数据API的UTF-8和UTF-16
- 使用编目函数
Limitations
以下功能尚未在 Linux 和 macOS 的 ODBC 驱动中被验证是否正确工作:
- 故障切换集群连接。
- 在 ODBC Driver 17 之前的透明网络 IP 解析
- Linux 和 macOS 的 ODBC 驱动 Built-In 诊断(BID)追踪:ODBC Driver 17.3 之前
不支持的功能
以下功能在 Linux 和 macOS 的 ODBC 驱动中不可用:
通过属性
SQL_ATTR_ENLIST_IN_DTC进行分布式事务。 该驱动程序通过 Microsoft 分布式事务处理协调器(DTC)支持 XA 事务。 更多信息请参见 使用 DTC 的 XA 事务。数据库镜像。
FILESTREAM。
ODBC 驱动程序性能分析,以及 SQLSetConnectAttr 中讨论的以下与性能相关的连接属性:
SQL_COPT_SS_PERF_DATASQL_COPT_SS_PERF_DATA_LOGSQL_COPT_SS_PERF_DATA_LOG_NOWSQL_COPT_SS_PERF_QUERYSQL_COPT_SS_PERF_QUERY_INTERVALSQL_COPT_SS_PERF_QUERY_LOG
SQLBrowseConnect在17.2版本之前。C 区间类型(如
SQL_C_INTERVAL_YEAR_TO_MONTH)见于 数据类型标识符和描述符。SQL_CUR_USE_ODBC的SQLSetConnectAttr属性的SQL_ATTR_ODBC_CURSORS值。
处理字符数据
在 Linux 和 macOS 上,使用带有 ODBC 宽字符 API 的 UTF-16 SQLWCHAR 缓冲区,而非原生 wchar_t 类型。 驱动接口使用16位代码单元。
字符编码
对于ODBC驱动13和13.1,必须对SQLCHAR数据使用 UTF-8。 这些版本不支持任何其他编码。
从 ODBC 驱动程序 17 开始,SQLCHAR 数据支持的字符集和编码包括:
注意
由于 glibc 和 musl 之间的 iconv 差异,许多这些区域设置在 Alpine Linux 上不受支持。 更多信息请参见 与glibc的功能差异。
| 名称 | 说明 |
|---|---|
| UTF-8 | Unicode |
| CP437 | MS-DOS 拉丁语(美国) |
| CP850 | MS-DOS 拉丁语 1 |
| CP874 | 拉丁语/泰语 |
| CP932 | 日语(Windows代码页932) |
| CP936 | 简体中文 (GBK) |
| CP949 | 韩语(Windows代码页949) |
| CP950 | 繁体中文 (Big5) |
| CP1250 | 中欧 |
| CP1251 | 西里尔语 |
| CP1252 | 西欧 |
| CP1253 | 希腊语 |
| CP1254 | 土耳其语 |
| CP1255 | 希伯来语 |
| CP1256 | 阿拉伯语 |
| CP1257 | 波罗的海 |
| CP1258 | 越南语 |
| ISO-8859-1 | 拉丁语 - 1 |
| ISO-8859-2 | 拉丁语 - 2 |
| ISO-8859-3 | 拉丁语 - 3 |
| ISO-8859-4 | 拉丁语 - 4 |
| ISO-8859-5 | 拉丁语/西里尔语 |
| ISO-8859-6 | 拉丁语/阿拉伯语 |
| ISO-8859-7 | 拉丁语/希腊语 |
| ISO-8859-8 | 希伯来语 |
| ISO-8859-9 | 土耳其语 |
| ISO-8859-13 | 拉丁语 - 7 |
| ISO-8859-15 | 拉丁语 - 9 |
连接时,驱动会检测加载进程当前的区域设置。 如果所在区域使用列表中的编码之一,驱动则使用该编码来处理 SQLCHAR (窄字符)数据。 否则,默认为 UTF-8。 进程默认在 C 区域设置中启动,导致驱动默认使用 UTF-8。 如果应用需要上述编码之一,请在连接前先调用setlocale。 明确指定区域设置,或者使用空字符串(例如,setlocale(LC_ALL, ""))来使用环境的区域设置。
在典型的Linux或macOS环境中,编码为UTF-8,使用ODBC驱动17的用户从13或13.1升级时不会察觉差异。 通过 setlocale 使用所列非 UTF-8 编码的应用程序需要对与驱动程序之间传输的数据使用该编码,而不是 UTF-8。
您必须对 SQLWCHAR 数据使用 UTF-16LE(小端序)。
当你用 SQLBindParameter 绑定输入参数时,如果你指定了像 SQL_VARCHAR 这样的窄字符 SQL 类型,驱动会将客户端编码中提供的数据转换为该参数的服务器端编码。 编码取决于排序规则;不一定是代码页1252。 对于输出参数,驱动程序将从与数据关联的排序规则信息中指定的编码转换为客户端编码。 源编码中无法在目标编码中表示的字符会转换为问号(?)。
为避免绑定输入参数时出现数据丢失,请指定 Unicode SQL 字符类型,如 SQL_WVARCHAR。 驱动程序将客户端编码转换为 UTF-16,可以表示所有 Unicode 字符。 目标列或参数还必须是 Unicode 类型(nchar、nvarchar 或 ntext),或具有可表示所有原始源数据的排序规则或编码的类型。 对于输出参数,指定一个Unicode SQL类型,并指定一个Unicode C类型(SQL_C_WCHAR),使驱动返回UTF-16数据,或者一个带有客户端编码的窄C类型,可以表示源数据。 UTF-8 总能表示这些数据。
有关排序规则和编码的更多信息,请参见 排序规则和 Unicode 支持。
Windows 与 Linux 或 macOS iconv 版本之间存在转换差异:
- 对于代码页1255,字节
0xCA在 Windows 上会转换为 UTF-16 代码点0x00CA,而在 macOS 和 Linux 上,使用早于 1.15 的0x05BA版本时,会转换为libiconv。 - 没有 2003 年修订版 Big5/CP950(
iconv)的 LinuxBIG5-2003库,无法正确转换该修订版中新增的字符。 - 对于代码页932(日文,Shift-JIS),未在编码标准中定义的字符解码不同。 例如,字节
0x80在 Windows 上转换为 U+0080,在 Linux 和 macOS 上则可能变为 U+30FB,具体取决于iconv版本。
在 ODBC 驱动 13 和 13.1 中,跨 SQLPutData 缓冲区拆分 UTF-8 多字节字符或 UTF-16 代理项会导致数据损坏。 使用不以部分字符编码结尾的流缓冲区。 这一限制在ODBC驱动17中被移除。
关于字符编码、转换、参数绑定和缓冲区大小的指导,请参见 已知问题。
OpenSSL
从 ODBC 驱动程序 17.4 开始,该驱动程序以动态方式加载 OpenSSL,因此它无需单独的驱动程序文件即可在装有 OpenSSL 版本 1.0 或 1.1 的系统上运行。 从版本 17.9 开始,驱动程序支持 OpenSSL 3.0 以及早期版本。 当存在多个版本的OpenSSL时,驱动程序会尝试从库搜索路径加载支持的版本。
| 驱动程序版本 | 支持的 OpenSSL 版本 |
|---|---|
| 17.4至17.8 | 1.0, 1.1 |
| 17.9及后续17.x版本,以及所有Driver 18版本 | 1.0、1.1、3.0 |
OpenSSL 4 不被支持。 在macOS上,指向OpenSSL 4的Homebrew openssl 链接可能会阻止驱动加载OpenSSL,即使已安装了OpenSSL 3,也会如此。 检查库路径以及已安装的版本。
注意
如果使用该驱动程序的应用程序或其某个组件链接到或动态加载了不同版本的 OpenSSL,则可能会发生潜在冲突。 如果系统上存在多个版本的 OpenSSL,且应用程序使用 OpenSSL,请确保应用程序加载的版本与驱动程序不冲突。 这些错误可能会导致内存损坏,而且可能不会以明显或一致的方式出现。
Alpine Linux
新线程 musl 的默认栈大小为 128 KB,除非可执行文件请求更大的默认栈大小。 线程在调用驱动程序时,可能会超过此限制。 将 Alpine Linux 上的 ODBC 应用与 -Wl,-z,stack-size=<size_in_bytes> 链接,以请求更大的默认线程栈。 创建具有显式栈大小的线程的应用程序也必须为这些线程选择足够的栈大小。
主线程的栈和新线程的默认栈设置不一样。 在 glibc 系统上,新线程的默认设置通常遵循进程的栈资源限制,当该限制为无限制时,则采用架构特定的回退。 不要假设所有 Linux 系统中的默认值都固定为 2 MB。
其他注释
要从ODBC应用创建专用管理员连接(DAC),请在你的连接字符串中设置Server=tcp:<server>,<dac_port>。 使用发现的DAC端口,而不是实例的常规连接端口。 例如,如果 DAC 端口是 33000,则将其设置为 Server=tcp:<server>,33000。 这些连接字符串片段仅指定端点,不指定认证。 分别配置认证和服务器证书验证。
该登录名必须是sysadmin服务器角色的成员。 远程访问需要启用服务器的远程管理员连接选项。 有关访问要求、服务器配置和命令行管理程序,请参见 数据库管理员的诊断连接。 关于端口发现,请参见 DAC端口。
UnixODBC 驱动管理器对通过SQLSetConnectAttr传递的语句属性的处理方式与 Windows 驱动管理器相同。 ODBC 2.x 的语句选项,如 SQL_ATTR_QUERY_TIMEOUT 和 SQL_ATTR_MAX_ROWS,适用于连接上的现有和新语句。 ODBC 3.x 仅语句属性,如 SQL_ATTR_ROW_ARRAY_SIZE 和 SQL_ATTR_PARAMSET_SIZE,返回 SQLSTATE HY092。 在连接和语句层定义的属性,如 SQL_ATTR_METADATA_ID,都可以在任一层设置。 在 ODBC 3.x 中,在连接层设置仅为语句属性的做法已被弃用,因此改为调用 SQLSetStmtAttr 。 更多信息请参见 SQLSetConnectAttr 函数。
在高度多线程的应用中,unixODBC的句柄验证可能会成为性能瓶颈。 使用 --enable-fastvalidate 编译 unixODBC 可能会提升性能。 然而,该选项可能导致将无效句柄传递给 ODBC API 的应用程序崩溃,而非返回 SQL_INVALID_HANDLE。
关于平台的安装和配置步骤,请参见: