在多字符集环境中工作时,可能出现字符集转换问题,而且难以确定出现转换问题的地方。遇到客户端 API 的字符集转换问题时,请检查数据库和连接控制字符集转换的选项及属性。
转换问题可以分为两类。第一类涉及向客户端 API 发送错误格式的数据。尽管 Unicode API 不会出现此类问题,但其它客户端 API 都可能出现此类问题,此类问题会生成垃圾数据。
第二类问题涉及在最终字符集或某个中间字符集中无等价内容的字符。这种情况下会使用替换字符。这被称为有损耗的转换,任何客户端 API 都可能发生此问题。可以配置数据库为数据库字符集使用 UTF-8 编码,以避免有损耗的转换。请参见有损耗的转换和替换字符。
通常可在完整的连接字符串中获取对连接有用的数据库和连接的选项和属性。也可以使用 PROPERTY、DB_PROPERTY 和 CONNECTION_PROPERTY 等系统功能来查询设置。例如:
查询 | 说明 |
---|---|
SELECT PROPERTY('CharSet'); | 返回数据库服务器的操作系统字符集。 |
SELECT DB_PROPERTY('CharSet'); | 返回数据库 CHAR 字符集。 |
SELECT DB_PROPERTY('NcharCharSet'); | 返回数据库 NCHAR 字符集。 |
SELECT DB_PROPERTY('MultibyteCharSet'); | 返回 CHAR 数据是否使用多字节字符集(On=是,Off=否)。 |
SELECT CONNECTION_PROPERTY('CharSet'); | 返回客户端 CHAR 字符集。 |
SELECT CONNECTION_PROPERTY('NcharCharSet'); | 返回客户端 NCHAR 字符集。 |
SELECT CONNECTION_PROPERTY('on_charset_conversion_failure'); | 返回 on_charset_conversion_warning 选项的值。 |
另请参见:
下图显示当客户端 API 与数据库服务器交互时字符集转换的可能位置。
图中的黑色星号表示可以进行字符集转换的位置。图中的数字与图后的附加说明相对应。
1 - DBLIB DBLIB CHAR 和 NCHAR 字符集缺省为客户端操作系统字符集。CHAR 字符集用于除 BINARY 和 NCHAR 之外的所有字符串数据。NCHAR 字符集用于 NCHAR 类型的主机变量和主机参数(这些在 DBTools 或 DBCAPI 接口上均不可用)。数据库服务器执行所有的字符集转换。
可使用 CharSet 连接参数和 db_change_nchar_charset 函数来分别设置 CHAR 字符集和 NCHAR 字符集。请参见CharSet (CS) 连接参数和db_change_nchar_charset 函数。
2 - Unicode API 使用 Unicode API 时,驱动程序为字符数据使用 Unicode UTF-16 编码,并在 Unicode 数据与数据库字符集之间互相转换。驱动程序将 Unicode 主机参数转换为 NCHAR 字符集 (UTF-8),然后将它们发送到数据库服务器。描述为 NCHAR 的结果集列以 NCHAR 字符集 (UTF-8) 进行读取,并在接收后被转换为 Unicode。不推荐设置 CharSet 连接参数,因为这会导致有损耗的转换。请参见有损耗的转换和替换字符。
3 - HTTP/HTTPS HTTP 服务(使用 SQL Anywhere 服务器):对于 HTTP 服务,有两类请求:URL 编码或多部分/形式数据请求。
URL 编码:请求采取 application/x-www-form-urlencoded 形式,以 "键/值" 对的形式传递变量。数据库服务器自动解码 % 编码数据(UTF-8 或数据库字符集),并将 "键/值" 对转换为数据库字符集。可使用 HTTP_VARIABLE 函数提取处理过的值,函数中的 @BINARY 或 @TRANSPORT 属性可分别用于返回经 % 解码但未转换为字符集的值,或原始的 HTTP(传输)值。
多部分/形式数据:请求被视为二进制数据 — 即使用 @BINARY 或 @TRANSPORT 属性会返回相同的值。
HTTP 服务响应的字符集转换由 CharsetConversion 和 AcceptCharset HTTP 选项来控制,可使用 sa_set_http_option 系统过程设置这些选项。请参见sa_set_http_option 系统过程。
其它会影响请求和响应的字符集转换的设置有 Accept-Charset 标头(用于指定偏好的字符集)和 Content-Type 标头(用于标识内容的字符集)。
HTTP 存储过程(使用 SQL Anywhere 客户端):对于 HTTP 存储过程,在数据库字符集中发送 CHAR 数据。如果有任意参数是 NCHAR 类型,则将以 UTF-8 发送所有数据(所有 CHAR 参数都转换为 UTF-8)。请求发送 Accept-Charset HTTP 标头,将数据库字符集标识为首选字符集。首选字符集列表中始终包含 UTF-8。如果响应在其 Content-Type 标头中指定了非数据库字符集的字符集,客户端将把响应转换为数据库字符集。
4a - 使用 Unicode 入口点的 ODBC 如果 ODBC 应用程序使用 Unicode 入口点,它将被视作 Unicode 客户端 API。WCHAR 数据的处理方式与其针对 Unicode API 时的处理方式相同。如果 ODBC 应用程序使用 Unicode 入口点和 CHAR (ANSI) 数据,将假定数据位于数据库字符集中。不推荐在同一应用程序中混用 CHAR 和 WCHAR 数据。
4a - 使用 ANSI 入口点的 ODBC 如果 ODBC 应用程序使用 ANSI 入口点,它将被视作 ANSI 客户端 API。CHAR 字符集缺省为客户端 OS 字符集。可使用 CharSet 连接参数更改 CHAR 字符集。请参见CharSet (CS) 连接参数。
任何 ANSI 数据转换均由数据库服务器完成。读取 WCHAR 主机变量会导致对数据库服务器 CHAR 数据进行有损耗的转换。不推荐在同一应用程序中混用 CHAR 和 WCHAR 数据。
4c - ODBC 驱动程序管理器 一些 ODBC 驱动程序管理器将所有 CHAR 数据转换为 WCHAR 数据,然后调用 Unicode 入口点。
5 - SQL Anywhere JDBC 驱动程序 SQL Anywhere JDBC 驱动程序不执行字符集转换,使用 ODBC 驱动程序的 WCHAR 类型和 Unicode 入口点。这与使用 Unicode 入口点的 ODBC 相同。
6 - Borland DBExpress Borland DBExpress 驱动程序使用 ODBC 作为 ANSI 客户端 API。CHAR 字符集缺省为客户端 OS 字符集。虽然可以使用 CharSet 连接参数进行更改,但这样会导致错误数据,因此不推荐使用。
7 - TDS 客户端 TDS 客户端(如 Sybase Open Client 和 jConnect)在连接时与数据库服务器协商,倾向于在客户端进行字符集转换。在协商过程中,将指示数据库服务器不进行字符集转换。
![]() |
使用DocCommentXchange 讨论此页。
|
版权 © 2010, iAnywhere Solutions, Inc. - SQL Anywhere 12.0.0 |