我正在使用
编写文件l_file := utl_file.fopen('OUT', 'a.txt', 'w');
utl_file.put_line(l_file, 'Rosëttenville');
但我将其更改为
l_file := utl_file.fopen_nchar('OUT', 'a.txt', 'w', 32767);
utl_file.put_line_nchar(l_file, 'Rosëttenville');
当我发现扩展的ASCII(代码127以上的字符)未正确写出时。但是第二个unicode版本也没有正确写入扩展字符。而不是Rosëttenville我得到Rosëttenville。任何人都知道如何解决这个问题?
答案 0 :(得分:5)
你还没有说出你的数据库字符集是什么,因此在一个字符串中“扩展ascii”(可能是8859-1,在这种情况下是chr(235)
)是否合法,或者这只是一个演示。无论哪种方式,我认为,你的问题是试图隐式转换非unicode字符串。
ë
是code point EB,也是UTF-8 C3 AB
。您获得了单独的字符Ã
(code point C3)和«
(code point AB)。因此,它无法从chr(235)
0x00EB
直接转换为U+00EB
。它似乎是通过UTF-8 C3 AB
作为两个单独的字符。我不会试图理解为什么......
您可以使用convert
function:
l_file := utl_file.fopen('OUT', 'a.txt', 'w');
utl_file.put_line(l_file,
convert('Rosëttenville', 'WE8ISO8859P1', 'UTF8'));
......或者,由于Oracle的阻止使用utl_raw.convert
function:
l_file := utl_file.fopen('OUT', 'a.txt', 'w');
utl_file.put_line(l_file,
utl_raw.cast_to_varchar2(utl_raw.convert(utl_raw.cast_to_raw('Rosëttenville'),
'ENGLISH_UNITED KINGDOM.WE8ISO8859P1', 'ENGLISH_UNITED KINGDOM.UTF8')));
两者都给了我你想要的价值,而你的原版给了我你看到的相同价值(我的数据库字符集在Linux上的11gR2中为AL32UTF8
)。如果您的数据库字符集不是Unicode,那么您的国家字符集肯定会出现(如果您在两次尝试中获得相同的输出,则问题尚不清楚),因此nchar
版本应该起作用:< / p>
l_file := utl_file.fopen_nchar('OUT', 'a.txt', 'w', 32767);
utl_file.put_line_nchar(l_file,
utl_raw.cast_to_varchar2(utl_raw.convert(utl_raw.cast_to_raw('Rosëttenville'),
'ENGLISH_UNITED KINGDOM.WE8ISO8859P1', 'ENGLISH_UNITED KINGDOM.UTF8')));
首先使用Unicode值可能会更好,特别是如果您当前在表中混合使用'extended ascii'和其他字符串类型;在这种情况下将转换应用于所有内容可能会产生一些奇怪的结果......
答案 1 :(得分:0)
UTL_FILE.PUT_LINE不会在数据库默认字符集中转换数据和导出数据。
所以你需要在写上进行适当的转换:
UTL_FILE.PUT_LINE(file,CONVERT(text,'WE8ISO8859P1'),FALSE);
您必须设置:
LANG=GERMAN_AUSTRIA.WE8ISO8859P1;export LANG
LC_CTYPE=ISO-8859-1;export LC_CTYPE
NLS_LANG=GERMAN_AUSTRIA.WE8ISO8859P1;export NLS_LANG