这个问题基本弄清楚了,解释如下:
首先说字符集,GBK字符集有80个字符是后来增补的,因为需要与GB18030兼容,所以放在GB18030的PUA区(此时这80个字符也在Unicode中有自己的对应的一套编码了,这一套编码在GB18030和GBK中的映射是一致的),后来这80个字符被Unicode字符集收录,于是在Unicode中有了自己的第二套编码,但是这第二套编码是不被GBK所兼容,仅GB18030可识别,这些字符的新编码也叫非PUA编码。
简单说,这几个字符从GBK到Unicode,对应编码为A,从GB18030到Unicode,对应编码为A和A',Oracle在转换时选择的就是转为A',A'是转不回GBK编码的。这就是第一个'?出现'的原因。
做一个实验可验证:
select convert('?','ZHS16GBK','ZHS32GB18030') A,
convert(convert('?','UTF8','ZHS32GB18030'),'ZHS16GBK','UTF8') A1,
dump(convert('?','UTF8','ZHS32GB18030')) A2
from dual;
A A1 A2
-- -- ------------------------
? ? Typ=1 Len=3: 228,182,174
'?'字的Unicode的非PUA编码是4DAE,换算成UTF8的编码方式是11100100 10110110 10101110,刚好是228,182,174
而且从转换结果看,我们有理由相信Oracle在进行convert时是把源字符集的字符先转换到Unicode字符集,然后再转换到目标字符集。
再做另一个实验:
select
dump(convert('?','ZHS32GB18030','ZHS16GBK')) B,
dump(convert(convert('?','UTF8','ZHS16GBK'),'ZHS32GB18030','UTF8') )B1,
dump(convert('?','UTF8','ZHS16GBK')) B3
from dual;
B B1 B3
-------------------------- -------------------------- ------------------------
Typ=1 Len=4: 131,54,207,57 Typ=1 Len=4: 131,54,207,57 Typ=1 Len=3: 238,161,163
确实B和B1两种转换结果相同。另外对原贴中的'??'的解释,我们从B3的结果看,从GBK转换到UTF8时,转换后的UTF8编码对应的Unicode编码为E863,转换结果是正确的。而从E863转换到GB18030时结果是131,54,207,57,这个换算后对应的编码是8336 CF39,对应不到任何GB18030的字符,所以显示'??',但具体131,54,207,57是如何产生的,我还没有确切弄明白,可能是Oracle的BUG,也可能是对PUA区选择的问题。
以下是那80个字以及对应的GBK编码(GB18030编码也相同),PUA编码和非PUA编码(这两个是Unicode编码)
汉字 GBK编码 PUA编码 非PUA编码
? FE50 E815 2E81
? FE51 E816 20087
? FE52 E817 20089
? FE53 E818 200CC
? FE54 E819 2E84
? FE55 E81A 3473
? FE56 E81B 3447
? FE57 E81C 2E88
? FE58 E81D 2E8B
? FE59 E81E 9FB4
? FE5A E81F 359E
? FE5B E820 361A
? FE5C E821 360E
? FE5D E822 2E8C
? FE5E E823 2E97
? FE5F E824 396E
? FE60 E825 3918
? FE61 E826 9FB5
? FE62 E827 39CF
? FE63 E828 39DF
? FE64 E829 3A73
? FE65 E82A 39D0
? FE66 E82B 9FB6
? FE67 E82C 9FB7
? FE68 E82D 3B4E
? FE69 E82E 3C6E
? FE6A E82F 3CE0
? FE6B E830 2EA7
? FE6C E831 215D7
? FE6D E832 9FB8
? FE6E E833 2EAA
? FE6F E834 4056
? FE70 E835 415F
? FE71 E836 2EAE
? FE72 E837 4337
? FE73 E838 2EB3
? FE74 E839 2EB6
? FE75 E83A 2EB7
? FE76 E83B 2298F
? FE77 E83C 43B1
? FE78 E83D 43AC
? FE79 E83E 2EBB
? FE7A E83F 43DD
? FE7B E840 44D6
? FE7C E841 4661
? FE7D E842 464C
? FE7E E843 9FB9
? FE80 E844 4723
? FE81 E845 4729
? FE82 E846 477C
? FE83 E847 478D
? FE84 E848 2ECA
? FE85 E849 4947
? FE86 E84A 497A
? FE87 E84B 497D
? FE88 E84C 4982
? FE89 E84D 4983
? FE8A E84E 4985
? FE8B E84F 4986
? FE8C E850 499F
? FE8D E851 499B
? FE8E E852 49B7
? FE8F E853 49B6
? FE90 E854 9FBA
? FE91 E855 241FE
? FE92 E856 4CA3
? FE93 E857 4C9F
? FE94 E858 4CA0
? FE95 E859 4CA1
? FE96 E85A 4C77
? FE97 E85B 4CA2
? FE98 E85C 4D13
? FE99 E85D 4D14
? FE9A E85E 4D15
? FE9B E85F 4D16
? FE9C E860 4D17
? FE9D E861 4D18
? FE9E E862 4D19
? FE9F E863 4DAE
? FEA0 E864 9FBB