Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Bỏ qua dấu phẩy giữa các dấu ngoặc kép khi đọc CSV Oracle được lưu trữ thủ tục UTL_FILE

Nếu bạn có thể nhận được tệp đầu vào được phân phối với tất cả các trường được đặt trong dấu ngoặc kép (hoặc có thể dịch nó sau khi đọc; regex của tôi không đủ tốt), bạn có thể sử dụng dbms_utility.comma_to_table ; các trường cần được bao quanh bởi vì (như đã lưu ý đây ) các mã thông báo phải là tên đối tượng hợp lệ, vì vậy 1 gây ra lỗi. Ví dụ:

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

cho:

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

Nếu chúng không được trích dẫn thì bạn có thể sử dụng regex (mẫu từ tại đây ):

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

mang lại:

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

Tôi không chắc liệu bạn có thực sự có khoảng trắng giữa các trường như trong câu hỏi hay không. Nếu vậy, phương pháp đầu tiên vẫn hoạt động và bạn có thể thêm trim() xung quanh tab tab(i) . Phương thức thứ hai bị hỏng nên sẽ cần một chút điều chỉnh ...



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle - Kích hoạt để tạo một hàng lịch sử khi cập nhật

  2. Có ai biết kỹ thuật mã hóa JDeveloper / SQL Developer đang sử dụng để duy trì thông tin đăng nhập không?

  3. chèn vào ... chọn ... có truy vấn con hoặc không có thứ tự cột

  4. Oracle - cập nhật bản ghi và trả về ngày cập nhật trong cùng một truy vấn

  5. Oracle LISTAGG () cho nhiều thuộc tính?