根据定义,XML 元素和属性的值是区分大小写的。例如,如果搜索值为 “Paris” 的
下面的示例帮助您更清楚地理解不区分大小写的搜索。清单 1 定义一个包含一个 INTEGER 列和一个 XML 列的表,并在表中插入 7 行。每行包含一个小的客户文档,其中包含 XML 元素
此元素中的值在大小写方面并不一致。一些值是全大写的,一些是全小写的,其他是大小写混合的(首字母大写)。如果数据来自不同的应用程序,而这些应 用程序采用不同的大小写数据输入规则,就会出现这种情况。
清单 1. 示例表和数据
CREATE TABLE customer (id INTEGER, xmldoc XML); INSERT INTO customer (id, xmldoc) VALUES (1,'<Customer id="1"><city>PARIS</city></Customer>'), (2,'<Customer id="2"><city>Tokyo</city></Customer>'), (3,'<Customer id="3"><city>tokyo</city></Customer>'), (4,'<Customer id="4"><city>PARIS</city></Customer>'), (5,'<Customer id="5"><city>paris</city></Customer>'), (6,'<Customer id="6"><city>Delhi</city></Customer>'), (7,'<Customer id="7"><city>Paris</city></Customer>'); |
如果一个应用程序查询这些 XML 文档,寻找某一城市的客户,那么很可能需要不区分大小写的搜索。例如,可能希望找到 Paris 的所有客户,也就是希望获取第 1、4、5 和 7 行。但是,如果搜索值 “Paris”,那么只会返回第 7 行。要想获取所需的所有四行,可以使用 XQuery 函数 fn:upper-case() 把 city 元素值转换为大写并与 “PARIS” 做比较。清单 2 中的查询就采用这种方式,它会返回 Paris 的所有四个客户。
清单 2. 选择 Paris 的客户
SELECT id, XMLCAST( XMLQUERY('$XMLDOC/Customer/city') AS VARCHAR(15)) AS city FROM customer WHERE XMLEXISTS('$XMLDOC/Customer[fn:upper-case(city) = "PARIS"]'); |
如果查询通过一个参数标志提供搜索值,那么这个参数也应该转换为大写,见 清单 3。这个参数标志(“?”)的类型为 VARCHAR(15) 并作为变量 “c” 传递给 XQuery 谓词。
清单 3. 使用参数标志选择客户
SELECT id, XMLCAST( XMLQUERY('$XMLDOC/Customer/city') AS VARCHAR(15)) AS city FROM customer WHERE XMLEXISTS('$XMLDOC/Customer[fn:upper-case(city) = fn:upper-case($c)]' PASSING CAST(? AS VARCHAR(15)) AS "c"); |
图 1 显示以上示例查询的输出。
图 1. 示例查询的结果
如果只查询少量数据,或者查询还包含其他选择性谓词,使得大写谓词只应用于很小的中间结果集,那么这种方式效果还不错。问题是如果使用包含 fn:upper-case() 函数的谓词,就不会使用 DB2 中的 XML 索引。因此,这种方式不适用于大量数据。
要想避免使用 fn:upper-case() 函数并利用 XML 索引加快查询,就需要创建不区分大小写的数据库。
创建不区分大小写的 DB2 数据库
DB2 从 Version 9.5 Fixpack 1 开始支持感知地区的 Unicode 排序规则。这使我们能够忽略大小写和/或重音符号。要想创建对于所有字符串比较不区分大小写的数据库,需要使用排序规则 UCA500R1,见 清单 4。
清单 4. 创建不区分大小写的数据库
CREATE DATABASE testdb USING CODESET UTF-8 TERRITORY US COLLATE USING UCA500R1_LEN_S2; |
字符串 UCA500R1_LEN_S2 究竟意味着什么?UCA500R1 指定此数据库使用基于 Unicode 5.0.0 标准的默认 Unicode Collation Algorithm(UCA)。因为默认的 UCA 不能同时覆盖 Unicode 支持的每种语言的排序规则序列,所以可以使用可选属性定制字符的次序。属性以下划线(_)分隔。UCA500R1 关键字加上所有属性构成一个 UCA 排序规则名。