Si puede obtener el archivo de entrada con todos los campos entre comillas dobles (o puede traducirlo después de leerlo; mi expresión regular no es lo suficientemente buena), puede usar dbms_utility.comma_to_table
; los campos deben encerrarse porque (como se indica aquí
) los tokens tienen que ser nombres de objetos válidos, por lo que 1
provoca un error. Por ejemplo:
declare
file utl_file.file_type;
list varchar2(120);
tablen binary_integer;
tab dbms_utility.lname_array;
begin
file := utl_file.fopen('MY_DIR', 'test1.csv', 'R');
loop
begin
utl_file.get_line(file => file, buffer => list);
exception
when no_data_found then
exit;
end;
dbms_output.put_line('Raw list: ' || list);
dbms_utility.comma_to_table(list => list,
tablen => tablen, tab => tab);
for i in 1..tablen
loop
dbms_output.put_line('Column ' || i || ': '
|| replace(tab(i), '"'));
end loop;
end loop;
utl_file.fclose(file);
end;
/
da:
Raw list: "1","test","xy, yz","dog","cat"
Column 1: 1
Column 2: test
Column 3: xy, yz
Column 4: dog
Column 5: cat
Raw list: "2","test2","xy","fish","bear"
Column 1: 2
Column 2: test2
Column 3: xy
Column 4: fish
Column 5: bear
Raw list: "3","test3","ab, cd","rabbit, rabbit","duck"
Column 1: 3
Column 2: test3
Column 3: ab, cd
Column 4: rabbit, rabbit
Column 5: duck
Si no están citados, puede usar una expresión regular (patrón de aquí ):
declare
file utl_file.file_type;
list varchar2(120);
pattern varchar2(15) := '("[^"]*"|[^,]+)';
c sys_refcursor;
i number;
f varchar2(20);
begin
file := utl_file.fopen('MY_DIR', 'test2.csv', 'R');
loop
begin
utl_file.get_line(file => file, buffer => list);
exception
when no_data_found then
exit;
end;
dbms_output.put_line('Raw list: ' || list);
open c for
select level as col,
regexp_substr(list, pattern, 1, rownum) split
from dual
connect by level <= length(regexp_replace(list, pattern)) + 1;
loop
fetch c into i, f;
exit when c%notfound;
dbms_output.put_line('Column ' || i || ': ' || replace(f, '"'));
end loop;
close c;
end loop;
utl_file.fclose(file);
end;
/
que da:
Raw list: 1,test,"xy, yz",dog,cat
Column 1: 1
Column 2: test
Column 3: xy, yz
Column 4: dog
Column 5: cat
Raw list: 2,test2,xy,fish,bear
Column 1: 2
Column 2: test2
Column 3: xy
Column 4: fish
Column 5: bear
Raw list: 3,test3,"ab, cd","rabbit, rabbit",duck
Column 1: 3
Column 2: test3
Column 3: ab, cd
Column 4: rabbit, rabbit
Column 5: duck
No estoy seguro si realmente tiene espacios entre los campos como se muestra en la pregunta. Si es así, el primer método aún funciona y puede agregar un trim()
alrededor de tab(i)
. El segundo método se descompone, por lo que necesitaría un poco de ajuste...