UNION,CASE和相关构造
如果所有输入都是相同的类型,并且不是unknown类型,那么解析成这种类型。
如果输入不属于同一个类型范畴,失败。(unknown类型除外)
如果输入类型是同一个类型范畴,则选择该类型范畴的首选类型。(例外:union操作会选择第一个分支的类型作为所选类型。)
把所有输入转换为所选的类型(对于字符串保持原有长度)。如果从给定的输入到所选的类型没有隐式转换则失败。
- 如果所有输入都是相同的类型,并且不是unknown类型,那么解析成这种类型。
- 如果输入字符串(包括unknown,unknown当text来处理)和数字类型,那么解析成字符串类型,如果是其他不同的类型范畴,则报错。
- 如果输入类型是同一个类型范畴,则选择该类型的优先级较高的类型。
- 把所有输入转换为所选的类型。如果从给定的输入到所选的类型没有隐式转换则失败。
decode(expr, search1, result1, search2, result2, …, defresult),也即 case expr when search1 then result1 when search2 then result2 else defresult end; 在ORA兼容模式下的处理,将整个表达式最终的返回值类型定为result1的数据类型,或者与result1同类型范畴的更高精度的数据类型。(例如,numeric与int同属数值类型范畴,但numeric比int精度要高,具有更高优先级)
- 将result1的数据类型置为最终的返回值类型preferType,其所属类型范畴为preferCategory。
- 依次考虑result2、result3直至defresult的数据类型。如果其类型范畴也是preferCategory,即与result1具有相同的类型范畴,则判断其精度(优先级)是否高于preferType,如果高于,则将preferType更新为更高精度的数据类型;如果其类型范畴不是preferCategory,则判断其数据类型是否可以隐式转换为preferType,不可以则报错。
注1:
为了兼容一种特殊情况,即表示了超大数字的字符类型向数值类型转换的情况,例如select decode(1, 2, 2, “53465465676465454657567678676”),大数超过了bigint、double等的表示范围。所以,当result1的类型范畴为数值类型时,将返回值的类型直接置为numeric,以兼容此种特殊情况。
注2:
数值类型的优先级排序:numeric>float8>float4>int8>int4>int2>int1
字符类型的优先级排序:text>varchar=nvarchar2>bpchar>char
日期类型的优先级排序:timestamptz>timestamp>smalldatetime>date>abstime>timetz>time
注3:
ORA兼容模式,开启 set sql_beta_feature = ‘a_style_coerce’; 参数的情况下,所支持的隐式类型转换见下图,\代表不需要转换,yes表示支持,空白表示不支持:
示例1:Union中的待定类型解析。这里,unknown类型文本’b’将被解析成text类型。
示例2:简单Union中的类型解析。文本1.2的类型为numeric,而且integer类型的1可以隐含地转换为numeric,因此使用这个类型。
示例3:转置Union中的类型解析。这里,因为类型real不能被隐含转换成integer,但是integer可以隐含转换成real,那么联合的结果类型将是real。
示例4:TD模式下,coalesce参数输入int和varchar类型,那么解析成varchar类型。A模式下会报错。