Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Ignoruj ​​przecinki między cytatami podczas odczytywania procedury składowanej CSV Oracle UTL_FILE

Jeśli możesz uzyskać plik wejściowy dostarczony ze wszystkimi polami ujętymi w podwójne cudzysłowy (lub możesz go przetłumaczyć po przeczytaniu; moje wyrażenie regularne nie jest wystarczająco dobre), możesz użyć dbms_utility.comma_to_table ; pola muszą być ujęte, ponieważ (jak wspomniano tutaj ) tokeny muszą być poprawnymi nazwami obiektów, więc 1 powoduje błąd. Na przykład:

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;
/

daje:

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

Jeśli nie są cytowane, możesz użyć wyrażenia regularnego (wzór z tutaj ):

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;
/

co daje:

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

Nie jestem pewien, czy naprawdę masz spacje między polami, jak pokazano w pytaniu. Jeśli tak, pierwsza metoda nadal działa i możesz dodać trim() wokół tab(i) . Druga metoda się psuje, więc wymagałoby to trochę dostosowania...



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ORA-02270:brak pasującego klucza unikalnego lub podstawowego dla tej listy kolumn

  2. przepełnienie liczbowe z kolumną NULL (0,3)

  3. Tworzenie i używanie tabeli tymczasowej w zapytaniach zagnieżdżonych

  4. Czyszczenie kolumny Data Oracle

  5. Oracle:jak uzyskać procent całości za pomocą zapytania?