特殊字符在 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;
/
我的 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;
/