вы должны использовать SUBSTRB
, когда копируете данные из столбца 250 CHAR
в столбец 250 byte
. Эта функция будет выводить только целые символы (вы не получите неполные символы Юникода):
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
--------- -------- ------- ------ -----
中华人 中华 中华 中华 中
Edit:
@ mwardm сделал интересный комментарий относительно фактической длины полученной строки и того, может ли полученная строка содержать недопустимую последовательность байтов. Рассмотрим следующее на БД AL32UTF8:
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
Как видно, последний байт строки 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
В этом случае Oracle выбрал обрезать строку после второго байта, поскольку в наборе символов AL16UTF16 нет допустимого однобайтового символа. Результирующая строка составляет всего 2 байта вместо 3.
Это потребует дальнейшего тестирования и ни в коем случае не является строгой демонстрацией, но я по-прежнему придерживаюсь своей первой догадки, что substrb
вернет правильную последовательность байтов, которая кодирует действительную строку символов.