我输入的数据来自一个平面文件,其中包含英文,日文,中文字符.我将这些值加载到其模式定义为VARCHAR2(250 CHAR)的临时表列中,主表列具有定义VARCHAR2(250)我无法更改.所以,我在这个专栏上做了一个SUBSTR.加载表后我做了一个
SELECT * FROM TABLE
Run Code Online (Sandbox Code Playgroud)
...我收到此错误:
ORA-29275:部分多字节字符
如果我选择其他列,那么没有问题.
SUBSTRB将数据从250 CHAR列复制到250 byte列时应使用.此函数只输出整个字符(不会得到不完整的unicode字符):
SQL> select substrb('???', 1, 9) ch9,
2 substrb('???', 1, 8) ch8,
3 substrb('???', 1, 7) ch7,
4 substrb('???', 1, 6) ch6,
5 substrb('???', 1, 5) ch5
6 FROM dual;
CH9 CH8 CH7 CH6 CH5
--------- -------- ------- ------ -----
??? ?? ?? ?? ?
Run Code Online (Sandbox Code Playgroud)
@mwardm对结果字符串的实际长度以及结果字符串是否包含无效的字节序列做了一个有趣的评论.在AL32UTF8 DB上考虑以下内容:
SQL> select lengthb('ÏÏÏ'),
2 lengthb(substrb('ÏÏÏÏÏÏ', 1, 5)),
3 dump('ÏÏÏ'),
4 dump(substrb('ÏÏÏÏÏÏ', 1, 5))
5 FROM dual;
LE LE DUMP('ÏÏÏ') DUMP(SUBSTRB('ÏÏÏÏÏÏ',1,5))
-- -- ------------------------------------- -------------------------------
6 5 Typ=96 Len=6: 195,143,195,143,195,143 Typ=1 Len=5: 195,143,195,143,32
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,substrb字符串的最后一个字节不是特殊字符的截断的第一个字节,而是编码一个合法的字符(此字符集中的前128个字符与ASCII7US字符集相同,因此这将对' '空格字符进行编码,使用另一个答案中建议的RTRIM将删除最后一个字符).
此外,我还使用字符集AL16UTF16得到了这个有趣的结果:
SQL> select lengthb(N'??') le,
2 dump(N'??') dump,
3 lengthb(substrb(N'?', 1, 3)) length_substr,
4 dump(substrb(N'??', 1, 3)) dump_substr
5 from dual;
LE DUMP LENGTH_SUBSTR DUMP_SUBSTR
---------- ----------------------- ------------- -----------------
4 Typ=96 Len=4: 1,8,1,8 2 Typ=1 Len=2: 1,8
Run Code Online (Sandbox Code Playgroud)
在这种情况下,Oracle选择在第二个字节之后剪切字符串,因为在AL16UTF16字符集中没有合法的单字节字符.结果字符串只有2个字节而不是3个字节.
这需要进一步测试,并不是一个严格的演示,但我仍然支持我的第一次预感,substrb它将返回一个有效的字节序列,编码一个有效的字符串.