0

我正在使用写文件

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。有人知道怎么修这个东西吗?

4

2 回答 2

5

您还没有说您的数据库字符集是什么,因此在字符串中包含 'extended ascii' (可能是8859-1,在这种情况下)是否合法chr(235),或者这只是一个演示。无论哪种方式,我认为,您的问题是试图隐式转换非 unicode 字符串。

ë代码点 EB,也是 UTF-8 C3 AB。您将获得单独的字符Ã代码点 C3)和«代码点 AB)。所以它不能直接翻译 from chr(235),也就是0x00EB, to U+00EB。它似乎是通过 UTF-8C3 AB作为两个单独的字符。我不会试图去理解为什么...

您可以使用以下convert功能

l_file := utl_file.fopen('OUT', 'a.txt', 'w');
utl_file.put_line(l_file,
  convert('Rosëttenville', 'WE8ISO8859P1', 'UTF8'));

...或者,Oracle不鼓励使用该utl_raw.convert功能

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')));

两者都给了我你想要的值,而你的原件给了我你看到的相同的值(我的 DB 字符集AL32UTF8在 Linux 上的 11gR2 中)。如果您的 DB 字符集不是 Unicode,那么您的国家字符集肯定是(在问题中不清楚是否两次尝试都获得了相同的输出),因此该nchar版本应该可以工作:

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 值可能会更好,特别是如果您当前在表中混合了“扩展 ascii”和其他字符串类型;在这种情况下将转换应用于所有内容可能会产生一些奇怪的结果......

于 2013-06-11T10:57:33.883 回答
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
于 2014-05-30T13:16:33.807 回答