CSV输出显示在Excel中的单行中

时间:2018-10-25 09:02:59

标签: oracle csv plsql utl-file

我正在使用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;

1 个答案:

答案 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可以理解的格式。