CSV-вывод отображается в одной строке в Excel - PullRequest
0 голосов
/ 25 октября 2018

Я создаю файл CSV с использованием пакета UTL_FILE.Когда я открываю файл в 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 голосов
/ 25 октября 2018

В конце каждого цикла, который вы делаете:

  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 равно нулю, вы вместо этого включаете '', но в Oracle '' равно нулю; из документации

База данных 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.

...