我正在使用UTL_FILE软件包生成CSV文件。当我在Excel中打开文件时,所有数据都显示在一行中。但是值在每一列中。我不确定如何在单独的行中获取数据。
这是我的PL / SQL块:
declare
v_file utl_file.file_type;
v_line_num number(7);
begin
for orec in ( select distinct --) loop
dbms_output.put_line('route '||orec.r_no);
v_file := utl_file.fopen('EXPORT_CSV','DAILY_REPORT_OF_'||OREC.r_no||'.csv','W',32767);
utl_file.put_line(v_file,'"SERVICEDAY","OP","PAC","RNO","DESC","DIRECTION","BLK","T_ID","T_NO","DUTY","S_STOP_SEQ","E_STOP_SEQ","LOC_FROM","SCH_TIME_FROM","OBS_TIME_FROM","LOC_TO","SCH_TIME_TO","OBS_TIME_TO","IS_SPLIT","CAUSE","M_AGE","OP_REASON","OP_COMMENT","L_COMMENT","L_AMENDED_CODE","STATUS"');
v_line_num:=0;
for irec in (select --) loop
utl_file.put(v_file, '"'||nvl(irec.SER,''));
utl_file.put(v_file,'","' || nvl(irec.OP,''));
utl_file.put(v_file,'","' || nvl(irec.PAC,''));
utl_file.put(v_file,'","' || nvl(irec.RNO,''));
utl_file.put(v_file,'","' || nvl(irec.DESC,''));
utl_file.put(v_file,'","' || nvl(irec.DIRECTION,''));
utl_file.put(v_file,'","' || nvl(irec.BLK,''));
utl_file.put(v_file,'","' || nvl(irec.T_ID,''));
utl_file.put(v_file,'","' || nvl(irec.T_NO,''));
utl_file.put(v_file,'","' || nvl(irec.DUTY,''));
utl_file.put(v_file,'","' || nvl(irec.S_STOP_SEQ,''));
utl_file.put(v_file,'","' || nvl(irec.E_STOP_SEQ,''));
utl_file.put(v_file,'","' || nvl(irec.LOC_FROM,''));
utl_file.put(v_file,'","' || nvl(irec.SCH_TIME_FROM,''));
utl_file.put(v_file,'","' || nvl(irec.OBS_TIME_FROM,''));
utl_file.put(v_file,'","' || nvl(irec.LOC_TO,''));
utl_file.put(v_file,'","' || nvl(irec.SCH_TIME_TO,''));
utl_file.put(v_file,'","' || nvl(irec.OBS_TIME_TO,''));
utl_file.put(v_file,'","' || nvl(irec.IS_SPLIT,''));
utl_file.put(v_file,'","' || nvl(irec.CAUSE,''));
utl_file.put(v_file,'","' || nvl(irec.M_AGE,''));
utl_file.put(v_file,'","' || nvl(irec.OP_REASON,''));
utl_file.put(v_file,'","' || nvl(irec.OP_COMMENT,''));
utl_file.put(v_file,'","' || nvl(irec.L_COMMENT,''));
utl_file.put(v_file,'","' || nvl(irec.L_AMENDED_CODE,''));
utl_file.put(v_file,'","' || nvl(irec.STATUS,''));
utl_file.put_line(v_file,chr(13) || chr(10));
v_line_num:=v_line_num+1;
end loop;
dbms_output.put_line('lines: '||v_line_num);
utl_file.fclose(v_file);
end loop;
--utl_file.fclose(v_file);
--utl_file.fclose_all;
/*
exception
when others then
utl_file.fclose_all;
dbms_output.put_line(sqlerrm);
*/
end;
答案 0 :(得分:0)
在每次循环结束时您都在做:
utl_file.put(v_file,'","' || nvl(irec.STATUS,''));
utl_file.put_line(v_file,chr(13) || chr(10));
该行上的最后一个值之后没有右双引号,因此chr(13)
和chr(10)
在双引号值内-因此被视为该值的一部分,而不是实际上读取文件时作为回车符和换行符。因此,一切都在同一行。
您需要执行以下操作:
utl_file.put(v_file,'","' || nvl(irec.STATUS,''));
utl_file.put_line(v_file, '"' || chr(13) || chr(10));
尽管put_line()
包含行终止符,但您实际上可能只需要:
utl_file.put(v_file,'","' || nvl(irec.STATUS,''));
utl_file.put_line(v_file, '"');
如果要在Unix-y服务器上生成文件,然后将其传输到Windows,则可能仍需要chr(13)
,尽管这样做可能会更好。我认为没有它,Excel将会很高兴。
顺便说一句,您所有的nvl()
通话都是毫无意义的。当您执行nvl(irec.SER,'')
时,如果irec.SER
为null,则改为包含''
,但是在Oracle中,''
与null是相同的; from the documentation
Oracle数据库将长度为零的字符值视为空。
所以您实际上是在做nvl(irec.SER,null)
,这没什么区别。
就所有值而言,我个人认为将开双引号和开双引号放在同一行会更清楚:
utl_file.put(v_file, '"' || irec.SER || '"');
utl_file.put(v_file, ',"' || irec.OP || '"');
...
utl_file.put(v_file, ',"' || irec.STATUS || '"');
utl_file.new_line(v_file);
最好为日期时间值(可能是数字)添加显式to_char()
调用,以便您指定Excel可以理解的格式。