我必须将 .CSV 文件加载到我的 Oracle 表中。但问题是单个 CSV 文件将包含多个表的数据。诀窍是我们需要识别要插入特定表的第一列数据。即,如果第一列的值为“16”,则应将整行插入到 TABLE_16 中,它将有 16 列,如果值为 21,则 TABLE_21 将有 21 列,依此类推。还要注意的一件事是,我的 CSV 文件将有数百万条记录,所以我也需要考虑过程的性能,所以我认为BULK COLLECT
并且FORALL
将是快速插入数据的最佳方法。
当我尝试运行以下块时,我收到此错误:
01403. 00000 - "no data found"
*Cause: No data was found from the objects.
*Action: There was no data from the objects which may be due to end of fetch.
.CSV 数据示例
16,"Laura","Bissot","LBISSOT","650.124.5234",20-08-05,"ST_CLERK",3300,,121,50,"aaa",234,"asdf","ssedf","wsdrftd"
21,"Mozhe","Atkinson","MATKINSO","650.124.6234",30-10-05,"ST_CLERK",2800,,121,50,"aaa",234,"asdf","ssedf","wsdrftd","aaa",234,"asdf","ssedf","wsdrftd"
11,"James","Marlow","JAMRLOW","650.124.7234",16-02-05,"ST_CLERK",2500,,121,50
16,"TJ","Olson","TJOLSON","650.124.8234",10-04-07,"ST_CLERK",2100,,121,50,"aaa",234,"asdf","ssedf","wsdrftd"
19,"Jason","Mallin","JMALLIN","650.127.1934",14-06-04,"ST_CLERK",3300,,122,50,"aaa",234,"asdf","ssedf","wsdrftd","aaa",234,"asdf",
12,"Michael","Rogers","MROGERS","650.127.1834",26-08-06,"ST_CLERK",2900,,122,50,"aaa"
14,"Ki","Gee","KGEE","650.127.1734",12-12-07,"ST_CLERK",2400,,122,50,"aaa",234,"asdf"
30,"Ki","Gee","KGEE","650.127.1734",12-12-07,"ST_CLERK",2400,,122,50,"aaa",234,"asdf",11,"dd",23,43,789,9086,"1DRFtf","PST","RTF%$",123,"dsda",5656,"dsed",123,4333,112
create or replace type
T_CSV_DATA as object
(c001 varchar2(50),c002 varchar2(150),c003 varchar2(150),c004 varchar2(150),c005 varchar2(150),c006 varchar2(150),c007 varchar2(150),c008 varchar2(150),c009 varchar2(150), c010 varchar2(150),
c011 varchar2(150),c012 varchar2(150),c013 varchar2(150),c014 varchar2(150),c015 varchar2(150),c016 varchar2(150),c017 varchar2(150),c018 varchar2(150),c019 varchar2(150), c020 varchar2(150),
c021 varchar2(150),c022 varchar2(150),c023 varchar2(150),c024 varchar2(150),c025 varchar2(150),c026 varchar2(150),c027 varchar2(150),c028 varchar2(150),c029 varchar2(150), c030 varchar2(150));
create or replace type T_CSV_VAL as table of T_CSV_DATA;
DECLARE
--variables to do with the copying the blob into a clob
v_blob BLOB;
v_clob CLOB;
v_dest_offset INTEGER := 1;
v_src_offset INTEGER := 1;
v_lang_context INTEGER := dbms_lob.default_lang_ctx;
v_warning INTEGER;
--variables to do with iterating over each row of the clob
v_new_line_pos NUMBER;
v_start_pos NUMBER := 1;
v_current_line VARCHAR2(4000);
v_total_len NUMBER;
v_curr_row apex_application_global.vc_arr2;
V_DATA_ASSIGN T_CSV_VAL :=T_CSV_VAL();
V_BULK_DATA T_CSV_VAL :=T_CSV_VAL();
BEGIN --t_csv_line
SELECT FILE_BLOB INTO v_blob FROM FILE_UPLOAD WHERE ID=7;
dbms_lob.createtemporary(v_clob,true);
dbms_lob.converttoclob(dest_lob => v_clob,src_blob => v_blob,amount => dbms_lob.lobmaxsize,dest_offset => v_dest_offset,src_offset
=> v_src_offset,blob_csid => dbms_lob.default_csid,lang_context => v_lang_context,warning => v_warning);
v_total_len := dbms_lob.getlength(v_clob);
WHILE ( v_start_pos <= v_total_len ) LOOP
v_new_line_pos := instr(v_clob,chr(10),v_start_pos);
IF v_new_line_pos = 0 THEN
v_new_line_pos := v_total_len + 1;
END IF;
v_current_line := substr(v_clob,v_start_pos,v_new_line_pos - v_start_pos);
v_curr_row := apex_util.string_to_table(v_current_line,',');
V_DATA_ASSIGN.EXTEND;
V_DATA_ASSIGN(V_DATA_ASSIGN.count) := T_CSV_DATA(v_curr_row(1),v_curr_row(2),v_curr_row(3),v_curr_row(4),v_curr_row(5),
v_curr_row(6),v_curr_row(7),v_curr_row(8),v_curr_row(9),v_curr_row(10),
v_curr_row(11),v_curr_row(12),v_curr_row(13),v_curr_row(14),v_curr_row(15),
v_curr_row(16),v_curr_row(17),v_curr_row(18),v_curr_row(19),v_curr_row(20),
v_curr_row(21),v_curr_row(22),v_curr_row(23),v_curr_row(24),v_curr_row(25),
v_curr_row(26),v_curr_row(27),v_curr_row(28),v_curr_row(29),v_curr_row(30));
v_start_pos := v_new_line_pos + 1;
END LOOP;
FOR rec IN V_DATA_ASSIGN.first..V_DATA_ASSIGN.last LOOP
IF V_DATA_ASSIGN(rec).c001 = 16 THEN -- If first value is 16, then insert into TABLE_16(will have 16 columns).
INSERT INTO TABLE_16.....
ELSIF V_DATA_ASSIGN(rec).c001 = 21 THEN -- If first value is 21, then insert into TABLE_21(will have 21 columns).
INSERT INTO TABLE_21.....
ELSIF V_DATA_ASSIGN(rec).c001 = 11 THEN -- If first value is 11, then insert into TABLE_11(will have 11 columns).
INSERT INTO TABLE_11.....
...
...
ELSIF V_DATA_ASSIGN(rec).c001 = 30 THEN -- If first value is 30, then insert into TABLE_30(will have 30 columns). and so on...
INSERT INTO TABLE_30.....
END IF;
END LOOP;
END;