特殊字符在 Oracle 中不重复两次

Special Character not repeated not twice in Oracle

我的 Oracle 数据库中有一个 Value Méroné 列。 我们正在使用 utl_file package.Since 将其写入 csv 文件这个值有一个特殊字符我们使用转换函数更改字符编码以在写入时删除垃圾字符。所以转换函数是这样的—— 转换(REC.DT25,'WE8DEC')。但现在的问题是,只有 Méron 出现了值,最后一个字符丢失了。我已经尝试了从将其更改为不同的字符编码的所有方法,但仍然没有运气。能否请你帮忙? 代码如下 创建或替换过程 SAMPLE_MERONE AS

CREATE OR REPLACE PROCEDURE SAMPLE_MERONE AS 

CURSOR C1 IS select * from gsal_mosaic_prf_output where CS46SIGFORMALNAME 
LIKE 'Lt. Jowens Méroné' AND ID_NUMBER='8-13678728';

MERONE_FILE UTL_FILE.FILE_TYPE;
V_MERONE_FILE VARCHAR2(300);

BEGIN
V_MERONE_FILE := 'MREONE_FILE.csv';
MERONE_FILE := UTL_FILE.FOPEN ( 'GSAL_PRF',V_MERONE_FILE,'w',32767) ;
IF UTL_FILE.IS_OPEN(MERONE_FILE) THEN
FOR REC IN C1
LOOP
UTL_FILE.PUT_LINE(MERONE_FILE,'"'||REC.ID_NUMBER||'","'||
REC.GROUP_ID||'","'||convert(REC.CS46LASTNAME,'WE8ISO8859P1', 
'UTF8')||'","'||
convert(REC.CS46SIGFORMALNAME,'WE8ISO8859P1', 
'UTF8')||'"',TRUE);
END LOOP;
UTL_FILE.FCLOSE ( MERONE_FILE ) ;
END IF;
END SAMPLE_MERONE;

运行 12.2 AL32UTF8 数据库上的以下脚本重现了该问题。

declare

   cursor c1 is
      select lastname
            ,convert(lastname, 'WE8ISO8859P1','UTF8') convertedname
            ,dump(convert(lastname, 'WE8ISO8859P1','UTF8')) dumpconvertedname
        from (select 'Lt. Jowens Méroné' as lastname
                from dual);

   merone_file   utl_file.file_type;
   v_merone_file varchar2(300);

begin
   merone_file := utl_file.fopen('NGM1_PAD_IN', 'test.csv', 'w', 32767);
   if utl_file.is_open(merone_file)
   then
      for rec in c1
      loop
         dbms_output.put_line(rec.lastname ||' - ' ||rec.convertedname);     
         dbms_output.put_line(rec.dumpconvertedname); 
         utl_file.put_line(merone_file
                          ,rec.lastname || '","' ||
                           rec.convertedname || '"'
                          ,true);
      end loop;
      utl_file.fclose(merone_file);
   end if;
end;
/

屏幕输出:

中尉。 Jowens Méroné - Lt. Jowens Méron

Typ=1 Len=17: 76,116,46,32,74,111,119,101,110,115,32,77,233,114,111,110,233

文件内容:

中尉。 Jowens Méroné","Lt. Jowens Méron"

转换将 195 169 更改为字符 233。您可以将其视为转换后的字符串中的最后一个字符。但不知何故并没有进入文件。

使用十六进制编辑器浏览文件证实了这一点。

作为解决方法,您可以assemble将所有数据放入 CLOB 中,然后按如下方式写入。这似乎可以正确转换您的数据。

declare

   l_clob   clob;
   l_string varchar2(32767);

   cursor c1 is
      select lastname
        from (select 'Lt. Jowens Méroné' as lastname
                from dual);

begin

   dbms_lob.createtemporary(lob_loc => l_clob, cache => true, dur => dbms_lob.call);
   dbms_lob.open(lob_loc => l_clob, open_mode => dbms_lob.lob_readwrite);

   for rec in c1
   loop
      l_string := rec.lastname || '","' || rec.lastname || '"' || chr(13) || chr(10);
      dbms_lob.writeappend(lob_loc => l_clob, amount => length(l_string), buffer => l_string);

   end loop;

   dbms_xslprocessor.clob2file(flocation => 'NGM1_PAD_IN'
                              ,fname     => 'test2.csv'
                              ,cl        => l_clob
                              ,csid      => nls_charset_id('WE8ISO8859P1'));

end;
/