Als je het invoerbestand kunt laten bezorgen met alle velden tussen dubbele aanhalingstekens (of het kunt vertalen na het lezen; mijn regex is niet goed genoeg), dan kun je dbms_utility.comma_to_table
; de velden moeten worden ingesloten omdat (zoals hier
) de tokens moeten geldige objectnamen zijn, dus 1
veroorzaakt een fout. Bijvoorbeeld:
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;
/
geeft:
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
Als ze niet worden geciteerd, kun je een regex gebruiken (patroon van hier ):
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;
/
wat geeft:
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
Ik weet niet zeker of je echt spaties tussen de velden hebt, zoals weergegeven in de vraag. Als dat zo is, werkt de eerste methode nog steeds en kun je een trim()
. toevoegen rond tab(i)
. De tweede methode hapert, dus zou een beetje moeten worden aangepast...