比较的转换规则

在比较两个字符串时,如有必要,其中一个字符串会先转换为另一个字符串的编码字符集。 只有在某些规则适用的情况下,转换才是必要的。

只有在以下所有条件都满足时,才需要进行转换:

  • 两个字符串的CCSID不同。
  • 两个CCSID都不是 X'FFFF' (两个字符串都没有被定义为二进制字符串)。
  • 转换所选的字符串既非空字符串,也非空字符串。
  • 以下转换表 (表2表3 )显示了何时需要进行转换。
转换所选的字符串取决于操作数的类型。 为了确定CCSID,语句中的字符串表达式分为6种类型,如下表所示。
表 1. 操作数类型
操作数类型 操作数类型的CCSID
来自包含表的CCSID
字符串常量 CCSID与应用程序编码方案相关联。 对于动态语句,这是当前应用程序编码方案专用寄存器。 对于静态语句,这是本机 SQL 过程的 CREATE PROCEDURE 或 ALTER PROCEDURE 语句的 ENCODING 绑定选项或 APPLICATION ENCODING SCHEME 选项
专用寄存器 CCSID与应用程序编码方案相关联。 对于动态语句,这是当前应用程序编码方案专用寄存器。 对于静态语句,这是本机 SQL 过程的 CREATE PROCEDURE 或 ALTER PROCEDURE 语句的 ENCODING 绑定选项或 APPLICATION ENCODING SCHEME 选项。
主变量 在DECLARE VARIABLE语句中指定的CCSID,与应用程序编码方案相关联,或在SQLDAID或SQLDA中指定
全局变量 UNICODE的CCSID
基于列的派生值 CCSID 源自派生值的来源。 基于列的派生值是一种表达式,其源直接或间接基于列。 这种表达的CCSID是源自其来源的CCSID。

例如:

  • SUBSTR(column_1, 5, length(column_2)) 的CCSID是 column_1 的CCSID。 请注意, column_2 的CCSID对SUBSTR的CCSID没有影响。
  • column_1 || 'ABC' 的CCSID是 column_1 的CCSID,根据表2 中的规则得出。
  • column_1 || GX'42C1' 的CCSID是 column_1 的DBCS CCSID,根据表2表3 中的规则得出。
  • COALESCE(EBCDIC_column_1, ASCII_column_1) 的CCSID是UNICODE CCSID,由表2中描述的规则得出。
  • CAST(string_column_1 AS GRAPHIC(10)) 的CCSID是 string_column_1 的DBCS CCSID。
  • CAST(EBCDIC_string_column_1 AS VARCHAR(10) CCSID UNICODE) 的CCSID是表2中描述的规则所导出的UNICODE CCSID。
  • CASE WHEN(1=1) THEN '1' ELSE ASCII_column_1 END 的CCSID是 ASCII_column_1 的CCSID,根据表2 中的规则得出。
  • CASE WHEN(1=1) THEN EBCDIC_column_1 ELSE ASCII_column_1 END 的CCSID是表2中描述的规则所导出的UNICODE CCSID。
  • 标量全选(SELECT column_1 FROM table_1 )的CCSID是 column_1 的CCSID。
非基于列的派生值 CCSID 源自派生值的来源。 非基于列的派生值是指其来源不直接或间接基于任何列的表达式。 这种表达的CCSID是源自其来源的CCSID。
  • 例如, SUBSTR('ABDC', 1, length('AB")) 的CCSID是字符串常量“ABCD”的CCSID。 请注意, column_1 的CCSID对SUBSTR的CCSID没有影响。
  • user_defined_function1(column1) 的CCSID是 user_defined_function1 定义的输出CCSID。
  • 不同类型、形状的投掷函数的CCSID是不同类型、形状的CCSID。
  • CURRENT SQLID || UX'0041' 的CCSID是UNICODE DBCS CCSID,由表2表3 中的规则得出。
  • CAST('abc' as CHAR(10) CCSID UNICODE) 的CCSID是UNICODE CCSID。

下表显示了当比较是涉及多个具有不同CCSID集的表的SQL语句的一部分时,哪个操作数提供了目标CCSID集。

表 2. 为字符转换提供CCSID的运算数
第一个操作数 第二个操作数
列值 字符串常量 专用寄存器 主变量 基于列的派生值 非基于列的派生值
列值 1 第一个操作数 第一个操作数 第一个操作数, 2 1 第一个操作数
字符串常量 第二个操作数 1 1 1 第二个操作数 1
专用寄存器 第二个操作数 1 1 1 第二个操作数 1
主变量 第二个操作数 1 1 1 第二个操作数, 2 1
全局变量 第二个操作数          
基于列的派生值 1 第一个操作数 第一个操作数 第一个操作数, 2 1 第一个操作数
非基于列的派生值 第二个操作数 1 1 1 第二个操作数 1
注:
  1. 如果CCSID集不同,则两个操作数都将在必要时转换为Unicode。 SBCS和Mixed转换为 UTF-8。 DBCS 转换为 UTF-16。 请参阅下表,确定哪个操作数用于为字符转换提供CCSID。
  2. 如果语句使用的编码方案是EBCDIC或ASCII,主机变量是Unicode图形,并且安装面板DSNTIPF上的混合数据字段的值为NO,则列或基于列的派生值将提供目标CCSID集。
下表显示了当两个操作数都基于列或不基于列时,如上表所示,选择哪个操作数进行转换。
表 3. 当两个操作数都基于或都不基于列时,用于字符转换的CCSID的运算数
第一个操作数 第二个操作数
SBCS 数据 混合数据 DBCS 数据
SBCS 数据   第二个操作数1 第二个操作数
混合数据 第一个操作数1   第二个操作数
DBCS 数据 第一个操作数 第一个操作数  
注:
  1. 对于ASCII和EBCDIC数据,转换取决于进行比较的 Db2 安装面板DSNTIPF上MIXED DATA字段的值。 如果混合数据 = 是,则 SBCS 操作数将转换为混合数据。 如果混合数据=否,则混合操作数将转换为SBCS
例如,假设比较的形式是:
   string-constant-SBCS =derived-value-not-based-on-column-DBCS
假设操作数具有不同的编码方案。 首先看表2。 相关表格条目位于第三行第二列。 此条目的值表明,如果CCSID集不同,则操作数将转换为Unicode。 第一个操作数(字符串常量-SBCS)如果还不是Unicode,则转换为 UTF-8 (混合)。 此外,第二个操作数(非基于DBCS列的派生值)在必要时转换为 UTF-16 (Unicode DBCS)。 在操作数转换为Unicode后,使用表3 确定哪个操作数提供转换所需的特定CCSID。 相关表格条目位于第二行和第三列。 这表明第二个操作数(非基于DBCS列的派生值)决定了CCSID,因为DBCS数据优先于混合数据。

如果字符串中的某个字符无法转换,则会发生错误;使用了 SYSSTRINGS 表,但其中不包含任何关于被比较操作数的 CCSID 对的信息;或者 Db2 无法通过 z/OS® 对 Unicode 的支持进行转换。 如果字符串中的某个字符被转换为替换字符,则会发出警告。

基于列的派生值是一种表达式,它包含影响表达式 CCSID 的列。 例如,在表达式 COL1||'abc' 中, COL1 决定了结果CCSID。 因此, COL1||'abc' 表达式被视为基于列的派生值,在任何进一步比较中,该列将继续优先。 表达式 CASE WHEN COL1 > 1 THEN 'abc' ELSE 'def' END 包含一列,该列不影响表达式的结果CCSID,因此不被视为基于列的派生值。

下表定义了哪些表达式被视为基于列的派生值。
表 4. 基于列的派生值
表达式 条件
expression1 || expression2 expression1expression2 是列或基于列的派生值
CASE 当条件然后结果表达式否则结果表达式结束 任何结果表达式都是字符串表达式 ,它是一个列或基于列的派生值
CAST(将表达式转换为数据类型 表达式 是一个字符串表达式 ,它是一个列或基于列和数据的派生值, 数据类型是字符串数据类型
标量全选:(SELECT expression FROM table 表达式 是一个字符串表达式 ,它是一个列或基于列和数据的派生值, 数据类型是字符串数据类型
当语句包含多个CCSID集时,如果其中一个字符串的长度在CCSID转换后发生变化,则该字符串将成为一个长度可变的字符串。 也就是说,数据类型变为VARCHAR、CLOB、VARGRAPHIC或DBCLOB。 下表显示了CCSID转换的最坏情况下的结果长度,其中X为字节数。
表5。 CCSID转换的最坏情况结果长度,其中X代表LENGTH(字符串的字节数)
源CCSID 至CCSID
EBCDIC ASCII Unicode
SBCS 混合 DBCS SBCS 混合 DBCS SBCS UTF-8 UTF-16
EBCDIC SBCS X X X*21 X X X*21 X1 X*3 X*2
混合 X X X*21 X X X*21 X1 X*3 X*2
DBCS X*0.51 X+2 X X*0.51 X X X*0.5 X*1.5 X
ASCII SBCS X X X*21 X X X*21 X1 X*3 X*2
混合 X X*1.8 X*21 X X X*21 X1 X*3 X*2
DBCS X*0.51 X+2 X X*0.51 X X X*0.5 X*1.5 X
Unicode SBCS X X X*2 X X X*2 X X X*2
UTF-8 X X*1.25 X X X X X X X*2
UTF-16 X*0.5 X+2 X X*0.5 X X X*0.5 X*1.5 X
注:
  1. 由于数据丢失的可能性很高, IBM® 不提供两个CCSID和数据子类型的组合的转换表。