Я создаю файл 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;
В конце каждого цикла вы делаете:
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; из документации
Oracle Database treats a character value with a length of zero as null.
так что вы действительно делаете 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.
Измените declare
на create procedure <name>
с аргументами, если они имеют смысл - если вы хотите, чтобы вызывающая процедура имела возможность изменять данные, которые находит запрос цикла. См. Документацию.
Ya, nvl и '' одинаковы. Могу ли я узнать, как преобразовать этот анонимный блок в процедуру