1

我的 Oracle DB 中有一个 Value Méroné 列。我们正在使用 utl_file 包将其写入 csv 文件。由于此值具有特殊字符,我们使用转换函数更改字符编码以在写入时删除垃圾字符。所以转换函数是这样的——转换(REC.DT25,'WE8DEC')。但现在的问题是,只有 Méron 的值来了,并且最后一个字符丢失了。我已经尝试了从将其更改为不同的字符编码的所有方法,但仍然没有运气。能否请你帮忙?代码如下 CREATE OR REPLACE PROCEDURE 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;
4

1 回答 1

0

在 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;
/

屏幕输出:

Lt. 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. 乔文斯·梅隆"

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

使用十六进制编辑器浏览文件可以确认这一点。

作为一种解决方法,您可以将所有数据组装到一个 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;
/
于 2017-11-29T13:10:17.873 回答