将上传电子表格列与表格列匹配

时间:2014-06-18 15:33:55

标签: sql oracle upload spreadsheet oracle-apex

我的APEX应用程序中有一个电子表格上传选项,并且有代码可以解析数据并将其上传到表格。

我试图找到一种方法来匹配电子表格列与表格列,以防用户切换列
下面的代码是我用来解析数据的代码,但我一直无法弄清楚如何将电子表格column1与表column1相匹配。

DECLARE  
v_blob_data       BLOB;  
v_blob_len        NUMBER;  
v_position        NUMBER;  
v_raw_chunk       RAW(10000);  
v_char      CHAR(1);  
c_chunk_len   number       := 1;  
v_line        VARCHAR2 (32767)        := NULL;  
v_data_array      wwv_flow_global.vc_arr2;  
v_rows number;  
v_sr_no number := 1;
v_first_line_done boolean := false;  
BEGIN  
delete from TEMP_UPDATE;  
-- Read data from wwv_flow_files</span>  
select  
blob_content  
into v_blob_data  
from wwv_flow_files  
where name = :P2_FILE_UPLOAD;
/* last_updated = (select max(last_updated) from wwv_flow_files where UPDATED_BY = :APP_USER)  
and id = (select max(id) from wwv_flow_files where updated_by = :APP_USER); */  
v_blob_len := dbms_lob.getlength(v_blob_data);  
v_position := 1;  
-- Read and convert binary to char</span>
WHILE ( v_position <= v_blob_len )  
LOOP  
v_raw_chunk := dbms_lob.substr(v_blob_data,c_chunk_len,v_position);  
v_char :=  chr(hex_to_decimal(rawtohex(v_raw_chunk)));  
v_line := v_line || v_char;  
v_position := v_position + c_chunk_len;  
-- When a whole line is retrieved </span> 
IF v_char = CHR(10) THEN  
    -- Convert comma to : to use wwv_flow_utilities </span>  
    v_line := REPLACE (v_line, ',', ':');  
    -- Convert each column separated by : into array of data </span>  
    v_data_array := wwv_flow_utilities.string_to_table (v_line);
    -- Insert data into target table </span>   
    EXECUTE IMMEDIATE 'insert into TEMP_UPDATE (ONE,TWO,THREE,FOUR,FIVE,SIX,SEVEN) values (:1,:2,:3,:4,:5,:6,:7)'       
    USING v_data_array(1), v_data_array(2), v_data_array(3), v_data_array(4), v_data_array(5), v_data_array(6), v_data_array(7) ;  
    -- Clear out  
    v_line := NULL; v_sr_no := v_sr_no + 1;
END IF;  
END LOOP;
DELETE FROM WWV_FLOW_FILES where name = :P2_FILE_UPLOAD; 
--DELETE FROM TEMP_UPDATE WHERE PCFN LIKE 'P%'; 
--UPDATE TEMP_UPDATE SET USERNAME = REPLACE(USERNAME, ' ', '');
END;


任何人都可以帮忙解决这个问题吗?

感谢
史蒂芬

1 个答案:

答案 0 :(得分:1)

在我弄清楚如何首先查看列顺序后,我忘了发布最终代码:

procedure MM_IN_PARSE
is

begin

DECLARE    
v_blob_data       BLOB;    
v_blob_len        NUMBER;    
v_position        NUMBER;    
v_raw_chunk       RAW(10000);    
v_char      CHAR(1);    
c_chunk_len   number       := 1;    
v_line        VARCHAR2 (32767)        := NULL;    
v_data_array      wwv_flow_global.vc_arr2;    
v_rows number;    
v_sr_no number := 1;  
v_first_line_done boolean := false;  
v_error_cd number :=0;  
v_quote_pos1 NUMBER;  
v_quote_pos2 NUMBER;  
v_enclosed_str VARCHAR2(200);
v_errmsg VARCHAR2(4000);

BEGIN

delete from TEMP_MM_UPDATE where username = v('P1_USER_ID');

-- Read data from wwv_flow_files</span>    
select    
blob_content    
into v_blob_data    
from wwv_flow_files    
where name = v('P2_FILE_UPLOAD'); 

v_blob_len := dbms_lob.getlength(v_blob_data);    
v_position := 1; 

-- Read and convert binary to char</span>  
WHILE ( v_position <= v_blob_len )    
LOOP 
--BEGIN
v_raw_chunk := dbms_lob.substr(v_blob_data,c_chunk_len,v_position);    
v_char :=  chr(hex_to_decimal(rawtohex(v_raw_chunk)));    
v_line := v_line || v_char;    
v_position := v_position + c_chunk_len;

-- When a whole line is retrieved </span>   
IF v_char = CHR(10) THEN

v_line := REPLACE (v_line, '>', NULL);
v_line := REPLACE (v_line, '<', NULL);

LOOP  
--Make sure there's something to replace  
IF INSTR(v_line, '"', 1, 1) = 0 THEN  
EXIT; -- If nothing to replace, exit loop and don't try  
END IF;  
--Find the position of the first and second quotes in the line of text  
v_quote_pos1 := INSTR(v_line, '"', 1, 1);  
v_quote_pos2 := INSTR(v_line, '"', 1, 2);  
--Extract the inner string  
v_enclosed_str := SUBSTR(v_line, v_quote_pos1 + 1, v_quote_pos2 - v_quote_pos1 - 1);  
--perform the replacement  
v_line := SUBSTR(v_line, 0, v_quote_pos1 - 1) || REPLACE(v_enclosed_str, ',', '<') || SUBSTR(v_line, v_quote_pos2 + 1);  
END LOOP; 

-- Convert comma to : to use wwv_flow_utilities </span>
v_line := REPLACE (v_line, ':', NULL);
v_line := REPLACE (v_line, ',', ':');  
v_line := REPLACE (v_line, '<', ',');  
v_line := REPLACE (trim(v_line), '-', NULL);  
v_line := REPLACE (trim(v_line), '', NULL);  
--v_line := REPLACE (trim(v_line), '"', NULL);  
-- Convert each column separated by : into array of data </span>    
v_data_array := wwv_flow_utilities.string_to_table (v_line);  
--Check to see if the row of column headers has already been parsed through  
IF(v_first_line_done != true)THEN   
v_first_line_done := true;  
--Check column order in spreadsheet  
IF(v_data_array(1)      LIKE '%Username%' AND
        v_data_array(2)  LIKE '%NDN%' AND
        v_data_array(3)  LIKE '%PCFN%' AND
        v_data_array(4)  LIKE '%TCN%' AND
        v_data_array(5)  LIKE '%Primary Sea/Air%' AND

        v_data_array(7)  LIKE '%Customer%') THEN   
    v_error_cd := 0;  
    v_line := NULL;  
ELSE  
    v_error_cd := 1;  
END IF;  
--If first line is done and the column order is correct then  
ELSIF(v_first_line_done = true AND v_error_cd = 0 AND v_data_array(1) is not null) THEN   
-- Insert data into target table </span>    
EXECUTE IMMEDIATE 'insert into TEMP_MM_UPDATE   
(USERNAME,
  RPT_FLAG,
 PCFN,
 TCN,
CUSTOMER)
values (:1,:2,:3,:4,:7)'   
   USING   
v_data_array(1),   
v_data_array(2),   
v_data_array(3),   
v_data_array(4),   
v_data_array(7);    
   -- Clear out    
    v_line := NULL; v_sr_no := v_sr_no + 1; 

END IF;  
 END IF; 

/*EXCEPTION
WHEN OTHERS then
v_errmsg := SQLERRM;

v_errmsg := REPLACE(v_errmsg, 'ORA-12899: value too large for column "APEX01"."TEMP_MM_UPDATE".', '');
v_errmsg := REPLACE(v_errmsg, '"', NULL);
v_errmsg := REPLACE(v_errmsg, '(actual:', ' value too large. (current length:');
v_errmsg := REPLACE(v_errmsg, 'maximum:', 'maximum length:');

v_errmsg := REPLACE(v_errmsg, 'ORA-01438: value larger than specified precision allowed for this column', 'Numeric value to large for the column.');

v_errmsg := REPLACE(v_errmsg, 'ORA-01722: invalid number', 'Invalid value in a column expecting a number.');

v_errmsg := REPLACE(v_errmsg, 'ORA-01858: a non-numeric character was found where a numeric was expected', 'Check all date column values for a non-date value.');

v_errmsg := REPLACE(v_errmsg, 'ORA-01830: date format picture ends before converting entire input string', 'Check all date column values.');

v_errmsg := REPLACE(v_errmsg, 'ORA-01847: day of month must be between 1 and last day of month', 'Not a valid date day.');

v_errmsg := REPLACE(v_errmsg, 'ORA-01843: not a valid month', 'Not a valid date month.');

v_errmsg := REPLACE(v_errmsg, 'ORA-01861: literal does not match format string', 'Invalid value format.');

insert into temp_NDN_update (username,pcfn,tcn,error_desc)
values (v('P1_USER_ID'), v_data_array(3),v_data_array(4), v_errmsg); 
v_line := NULL; v_sr_no := v_sr_no + 1;

END;*/

 END LOOP;

DELETE FROM WWV_FLOW_FILES where name = v('P2_FILE_UPLOAD');
 IF(v_error_cd = 1) THEN  
INSERT INTO temp_mm_update (USERNAME, ERROR_DESC)  
VALUES (v('P1_USER_ID'), 'Error. Please check column order in spreadsheet.');  
END IF;

/*EXCEPTION
WHEN NO_DATA_FOUND THEN
insert into temp_mm_update (username,error_desc)
values (v('P1_USER_ID'), 'No Data Found.');*/


END;