[ 来源:http://www.it55.com | 作者: | 时间:2007-12-28 | 收藏 | 推荐 ] 【大 中 小】
本文将向您简要介绍 IBM® DB2 9® for Linux®, UNIX®, and Windows® 中最新引入的基于字符的字符串函数。首先解释一些关键概念,比如字符和字符串数据的字节语义。然后讨论需要使用这些函数的原因并举例说明一些常见的场景。还将讨论代码单元的概念和基于字符的函数。另外还会解释这些函数如何帮助解决之前讨论的问题,并对每个场景进行举例说明。最后,了解使用这些函数时的常见问题和性能考虑。
简介
在当今这个互联网和经济全球化时代,需要使用越来越多的应用程序处理不同国家语言表示的数据。对开发人员而言,这就意味着在应用程序开发的各个阶段 — 数据库设计、应用程序设计和应用程序编程 — 都要考虑到不同国家的语言需求。DB2 9 支持具有不同属性的各种语言,比如重音符号(法语)、双向(阿拉伯语)和大字符集(中文)。这些语言在存储、处理、访问和表示数据方面提出了各自不同的挑战。受国家语言影响的数据不仅限于字符串数据。还包括有数值型、日期型和货币型数据。
DB2 9 以前版本中的一些字符串函数从字节和双字节单元的混合角度处理字符和图形数据。正如之前解释的那样,越来越多的用户根据不同国家语言的字符来考虑数据。DB2 9 的新功能解决了字符组成及其长度计算方面的问题,本文将讨论这些新功能。
对于单字节字符编码模式,一个字节组成一个字符,单字节字符串的长度与字符串的字节长度相同。对于图形字符串,两个字节组成一个字符,使用双字节数来表示字符串的长度。但是对于多字节编码,字符的字节长度随使用编码模式的不同而不同,每个字符的长度可能是一个字节或多个字节。本文中将使用字节计算字符串长度的方法称作字节语义,而使用字符数计算字符串长度的方法称作字符语义。
考虑以下的中文字符串:
图 1. 中文字符串

如果使用字符语义计算字符串的长度,则该字符串的长度为 2。但是如果使用字节语义并使用 UTF-8 对字符进行编码,则该字符串的长度为 6 字节。
对基于字符的函数的需求
SQL 中基于字符的数据在很多上下文中都与数值有关,如下所述:
这些数值表示单字节数据的字节数和图形或双字节数据的双字节数。但是对于多字节字符编码(如 UTF-8),这些数值并不符合字符语义。下面的条件可以帮助我们理解为何需要基于字符的函数。
字符的组成
将字符看作一个单元而不是一个字节序列,这是进行多字节字符的字符串操作的必要条件。应用程序开发人员需要知道,分配缓冲区时应该给每个字符分配多大内存。因此,理解字符组成对编写应用程序处理多字节字符数据非常重要。 可以将字符定义为一个信息单元,对应于书面语言的一个原子单元。每个字符由一个使用字符编码的位序列表示。单个字符通常使用一个字节或多个字节进行编码,具体情况取决于使用的编码方式。 考虑字符 “A” 和 “上面带圈的大写拉丁字母 A”。字符 “A” 的十六进制表示是 x‘41’ 而 “上面带圈的大写拉丁字母 A” 的十六进制表示是 x‘C385’。通过 SQL 函数 hex() 可以获取此表示。
图 2. 字符的十六进制表示

从上面的表示可以看到,显示期间只存在一个字符。但是,“A” 的长度是一个字节而 “上面带圈的大写拉丁字母 A” 的长度则是两个字节。
根据代码单元计算的字符串长度
字符字符串的长度取决于用于编码字符的字符编码方式(ASCII、EBCDIC 和 Unicode)。可以使用一个或多个各自编码的代码单元来表示字符。因此,如果字符串中有相同的字符集,则其长度可能随使用编码方式的不同而有所不同。 考虑一个字符例子 “音符 G 音谱号”。考虑表 1 中对此字符的不同编码,您会发现不同代码单元中的不同编码的十六进制表示及其长度都有所不同。
表 1. 相同字符不同编码的十六进制表示
| 编码 | UTF-8 | UTF-16(Big-Endian) | UTF-32(Big-Endian) |
|---|---|---|---|
| 十六进制格式 | X'F09D849E' | X'D834DD1E' | X'0001D11E' |
| 各自代码单元的长度 | 4 | 2 | 1 |
从图 3 可以看出如何获取 “音符 G 音谱号” 字符按 UTF-8 编码时的字节长度。
图 3. “音符 G 音谱号” 的字节长度

搜索字符
在字符串中搜索特定的子字符串时,首先执行搜索,然后返回的结果(字符串中的位置)为字节位置数,而不是正确的字符或代码单元的位置。图 4 展示了对 “a” 的搜索,“a” 的实际字符位置是 2,而输出的位置是 3,原因在于字符串中有多字节字符。
(编辑:IT资讯之家 www.it55.com)