前言
在信息整合的架构中,IBM 联邦数据库与若干异构数据源连接并提供整体一致的服务。从数据源到联邦数据库再到具体应用程序,数据的流动和转换依赖于各个环节代码页的正确配置。由于数据源环境本身的异构性,联邦数据库在包装器中采用了不同的策略和实现方式,客户需要根据实际环境进行配置以实现联邦数据库和数据源之间的代码页转换。另外,区别于传统欧美用户的使用习惯,东亚用户更多采用 Unicode 或者其他多字节字符集,也增大了代码页配置过程中的复杂性。
本文首先总体介绍一下联邦数据库在多国语言环境下配置代码页转换几种情况;其次对于不同数据源的包装器(如 DRDA、Oralce、ODBC 等),分别介绍如何根据用户的需要进行配置;最后,对使用联邦数据库的代码转换常见问题进行了解答。
联邦数据库中代码页简介
联邦数据库中涉及到的代码页包括操作系统级别区域设置选项默认的代码页,DB2 客户端应用程序的代码页,DB2 数据库代码页,远程数据源的客户端代码页和远程数据库的代码页。
操作系统 Locale:系统级别的代码页设置,决定应用程序或数据库的默认代码页。
DB2CODEPAGE:实例级别的代码页设置,影响到所有的 DB2 客户端应用程序的代码页。
数据库的代码页:数据库级别的代码页设置,在 DB2 V9.5 及之后的版本,数据库代码页默认是 1208(UTF-8),但在创建数据库时可以通过“USING CODESET”子句显性指定代码页名称。数据库一旦创建成功,此代码页将不能改变。例如,您可以使用下面的 SQL 创建一个支持 GBK 中文编码的数据库。
CREATE DATABASE <database_name>USING CODESET GBK TERRITORY CN
作为分布式异构数据库集合的核心,联邦数据库提供更灵活的代码页转换功能。图 1 显示了联邦数据库代码页转换的总体框架。
图 1. 联邦数据库代码页转换的总体框架
查看原图(大图)
从图 1 中,您可以容易的看到从远程数据库到用户应用程序中的数据流。每双箭头表示可能发生的代码页转换过程,这些过程可能是受不同的参数影响。通常情况数据的接收端负责代码页的转换。例如,如果 DB2 客户端应用程序从联邦服务器数据获取数据,那么 DB2 的客户端进行转换代码页,反之亦然。
代码页转换依赖于远端数据源客户端 / 服务器
对于那些功能强大的数据源,例如 DB2 和 Oracle,由于它们的客户端本身具有就拥有强大的代码页转换能力,因此我们只需要了解如何将它们的代码页转换配置设置到联邦数据库下。通常遵循以下准则:
对于远端数据源,联邦数据库扮演了该数据源的客户端应用程序的角色。包装器通过客户端 API 将联邦数据库和远程数据源连接起来。
根据相应的包装器,需要将远端数据源代码页转换的相关环境变量或系统参数设置到 db2dj.ini 文件中。
联邦数据库与远端数据源连接建立时,db2dj.ini 中的代码页环境变量将被设置在当前会话中。
下面我们以 Oracle 包装器为例,进行详细的说明:
图 2. Oracle 包装器代码页转换框架
查看原图(大图)
Oracle 包装器的代码页转换依赖于 Oracle 数据源。为了更好的理解联邦服务器 Oracle 包装器如何处理代码页转换,我们最好先了解下 Oracle 数据源处理代码页转换的机制。
Oracle 使用 NLS 参数来指定其服务器和客户端的行为约定。大约有 20 个 NLS 参数影响不同的 NLS 域,比如 NLS_LANG,NLS_DATE_FORMAT,NLS_TIMESTAMP_FORMAT,NLS_CURRENCY 等等。
共有四种设置 NLS 参数的方法,优先级依次增高
服务器端设置初始化参数
客户端设置服务器变量
使用 ALTER SESSION 语句指定
使用 SQL 函数指定
Oracle 客户端的环境变量 NLS_LANG 是联邦数据库中所使用的最重要的 NLS 参数。NLS_LANG 通过下面的语法指定语言、区域和代码字符集。
NLS_LANG = language_territory.charset
从 Oracle 的角度来看,联邦数据库更像 Oracle 的一个客户端应用程序,因此设置 Oracle 客户端环境变量 NLS_LANG 是利用 Oracle 进行联邦数据库和 Oracle 服务器之间的代码页转换前提条件。
联邦数据库 Oracle 包装器可以在配置文件 db2dj.ini 里配置环境变量 NLS_LANG。定义的格式和上面一样,但是所指定的参数要根据联邦数据库的字符集、语言和区域设置来指定对应 Oracle 的参数。如果 NLS_LANG 没有在 db2dj.ini 里显性指定,Oracle 包装器在发起和 Oracle 服务器连接时,会根据联邦数据库的代码页来自动设置该参数。
例如,当联邦数据库的代码页是 GBK(1386)、区域代码是 CN,并且 Oracle 服务器数据库代码页是 UTF8,NLS_LANG 应该设置如下参数:
NLS_LANG=Simplified Chinese_China.ZHS16GBK.
NLS_LANG 语言和区域参数指定了其他的 NLS 参数的默认值,如日期时间的格式、数字格式的显示等等。您也可以设置这些 NLS 环境变量来改变的 NLS_LANG 对应的默认值。
联邦数据库 Oracle 封装器只使用一种日期 / 时间戳格式。在与远程 Oracle 数据源建立连接的时候,以下 Oracle 变量将被设置在当前会话中,这样 Oracle 服务器和客户端之间的日期 / 时间戳格式将依照这样的格式。因此,其他日期 / 时间戳格式的数据将不能被正确处理,比如'20-MAY-2009'。
NLS_TIMESTAMP_FORMAT=YYYY-MM-DD HH24:MI:SS.FF
NLS_DATE_FORMAT=YYYY-MM-DD HH24:MI:SS
代码页转换依赖于联邦数据库包装器
联邦数据库可以帮助那些自身不能提供或者只能部分提供代码页转换的远端数据源完成相应转换。例如,对于有表结构特征的文本文件,显然数据源没有代码页转换的能力,此时联邦数据库中的 File 包装器可以通过设置昵称选项 CODEPAGE,提供不同代码页的转换。
复杂情况下的代码页转换
联邦数据库某些包装器如 ODBC 包装器,可以提供更为灵活的代码页转换配置。下面,我们以 ODBC 包装器为例进行说明。
ODBC 包装器可以联邦所有支持 ODBC 3.0 标准的数据源,因此,ODBC 包装器可以联邦那些本身功能强大的数据源如 PostgreSQL,也可以联邦一些非关系型数据源如文本文件。所以数据代码页转换还依赖于 ODBC 驱动管理器、远端数据源提供的 ODBC 驱动、远端数据源客户端以及服务器。例如,图 4 展示了三种不同数据源 Classic Federation Server、Microsoft SQL Server 和 PostgreSQL 数据源。
图 3. ODBC 包装器的代码页转换框架
查看原图(大图)
假设 DB2 的客户端应用程序通过昵称从远端数据源获取数据。我们需要考虑以下四个部分:
远端数据源服务器到其客户端:例如对于 PostgreSQL,您可以在其服务器端设置参数来控制其客户端和服务器的代码页转换规则。
客户端到数据源 ODBC 驱动:例如对于主机 Classic Federation Server,可以在客户端 ODBC 配置文件中设置客户机和服务器的代码页转换规则。
数据源 ODBC 驱动到 ODBC 驱动管理器:例如对于 IBM Branded 的 DataDirect ODBC 驱动管理器,当使用 Unicode 应用程序和 ASCII 的 ODBC 驱动或者,使用 ASCII 应用程序和 Unicode 的 ODBC 驱动时,它可以提供与驱动之间的代码页转换规则。如果使用 IBM Branded 的 DataDirect ODBC 驱动程序管理器,请到 DataDirect 网站上了解参数 IANAAppCodePage 更多细节。
ODBC 驱动管理器到 ODBC 包装器:ODBC 包装器来对于那些无法进行代码页转换的 ODBC 驱动程序管理器或驱动器进行补偿。
代码页转换依赖于 DB2 应用程序客户端
联邦数据库可以对异构数据源提供透明访问,客户端应用程序不用考虑在整个过程中进行了几次代码页的转换。通常 DB2 客户端应用程序的代码页依赖于客户端操作系统的 locale。但是,对于一些情况,在应用程序代码页和系统 locale 不兼容时,需要设置变量 DB2CODEPAGE。除此之外,对于 Java™ 应用程序,也需要一些特殊的配置。下面我们以 DB2 控制中心为例进行阐述。
在使用 DB2 的控制中心界面时,在数据源服务器、客户端和联邦数据库包装器的代码页都设置正确的前提下,仍然不能正确显示 Unicode 字符如中文和日文。这些字符可以显示在命令行窗口,但是却不能在控制中心界面上显示。为了深入了解此类问题,我们先介绍一些 Java 应用程序相关的编码设置技术。
Java 虚拟机默认编码格式
JVM 的每个实例都有一个默认的字符编码格式,这个默认的编码在虚拟机启动的时候确定,并且一般会依赖于操作系统使用的 locale 和 encoding,我们可以通过下面这个命令查看 JVM 默认的编码格式 encoding=System.getProperty(“file.encoding”)
Java 以系统默认编码读入源文件,然后按 Unicode 进行编码。Java 运行时,也采用 Unic