2012-10-08 86 views
0

我想在基於ID插入之前刪除現有數據。因此,如果傳入文件中有id,則應刪除現有的id,然後輸入數據。事情是這樣的:在插入之前刪除現有數據

數據庫表BEFORE:

-------------------------------- 
| ID | DATA     | 
-------------------------------- 
| 1 | This is data for ID 1 | 
| 2 | This is data for ID 2 | 
| 3 | This is data for ID 3 | 
-------------------------------- 

傳入文件:

----------------------------------------- 
| ID | DATA       | 
----------------------------------------- 
| 1 | This is new data for ID 1  | 
| 2 | This is new data for ID 2  | 
| 4 | This is new data for ID 4  | 
| 1 | This is also new data for ID 1 | 
----------------------------------------- 

數據庫表AFTER:

----------------------------------------- 
| ID | DATA       | 
----------------------------------------- 
| 1 | This is new data for ID 1  | 
| 2 | This is new data for ID 2  | 
| 4 | This is new data for ID 4  | 
| 1 | This is also new data for ID 1 | 
| 3 | This is data for ID 3   | 
----------------------------------------- 

這是我的程序。

CREATE OR REPLACE PROCEDURE absence_records_in AS 
    l_v_file  UTL_FILE.file_type; 
    l_filename VARCHAR2(128); 
    l_buffer  VARCHAR2(4096); 
    l_start  BINARY_INTEGER := 1; 
    l_pos   BINARY_INTEGER; 
    TYPE typ_cols IS TABLE OF VARCHAR2(4096) INDEX BY BINARY_INTEGER; 
    tbl_cols  typ_cols; 
    l_col_no  BINARY_INTEGER; 
    l_count  BINARY_INTEGER := 0; 
BEGIN 
    l_filename := 'records.csv'; 
    l_v_file := UTL_FILE.fopen('DIR_FENIX_IN', l_filename, 'R'); 
    UTL_FILE.get_line(l_v_file, l_buffer); 
    LOOP 
     BEGIN 
      UTL_FILE.get_line(l_v_file, l_buffer); 
      IF l_buffer IS NULL THEN 
       EXIT; 
      END IF; 
      l_col_no := 1; 
      l_start := 1; 
      WHILE INSTR(l_buffer, ';', 1, l_col_no) !=0 
      LOOP 
       l_pos := INSTR(l_buffer, ';', 1, l_col_no); 
       tbl_cols(l_col_no) := SUBSTR(l_buffer, l_start, l_pos - l_start); 
       l_start := l_pos + 1; 
       l_col_no := l_col_no + 1; 
      END LOOP; 
      l_start := l_pos + 1; 
      tbl_cols(l_col_no) := SUBSTR(l_buffer, l_start); 

      DELETE FROM absence_records WHERE id = tbl_cols(1) 
      LOG ERRORS INTO in_errors('File: '||l_filename||' => delete operation') REJECT LIMIT UNLIMITED; 

      l_count := l_count + 1; 
       EXCEPTION WHEN NO_DATA_FOUND THEN 
      EXIT; 
     END; 
     BEGIN 
      UTL_FILE.get_line(l_v_file, l_buffer); 
      IF l_buffer IS NULL THEN 
       EXIT; 
      END IF; 
      l_col_no := 1; 
      l_start := 1; 
      WHILE INSTR(l_buffer, ';', 1, l_col_no) !=0 
      LOOP 
       l_pos := INSTR(l_buffer, ';', 1, l_col_no); 
       tbl_cols(l_col_no) := SUBSTR(l_buffer, l_start, l_pos - l_start); 
       l_start := l_pos + 1; 
       l_col_no := l_col_no + 1; 
      END LOOP; 
      l_start := l_pos + 1; 
      tbl_cols(l_col_no) := SUBSTR(l_buffer, l_start); 

      INSERT INTO absence_records (id, data) 
      VALUES (tbl_cols(1), tbl_cols(2)) 
      LOG ERRORS INTO in_errors('File: '||l_filename|| ' => insert operation') REJECT LIMIT UNLIMITED; 

      l_count := l_count + 1; 
       EXCEPTION WHEN NO_DATA_FOUND THEN 
      EXIT; 
     END; 
    END LOOP; 
    UTL_FILE.fclose(l_v_file);   
END absence_records_in; 

因此,在短期,我要開始一個循環,將刪除這是在比較,將插入數據只是數據,然後另一個循環。 任何想法?在此先感謝:-)

回答

0

我將在followng的方式做到這一點:

  1. 從文件中讀取數據到新表TEMP
  2. 刪除所有記錄用的ID是TEMP,像DELETE FROM表,其中TABLE.ID IN(SELECT ID FROM TEMP)
  3. 從TEMP添加所有記錄表
+0

您的存儲過程主要關注解析CSV文件。你不能用別的東西把csv文件讀入表中嗎?看例如這裏http://stackoverflow.com/questions/6198863/oracle-import-csv-file-using-sqlplus – Zane

0

次嘗試e以下:

  1. 在第一個具有異常處理程序的BEGIN的END結束後立即關閉第一個循環。
  2. 關閉文件。
  3. 再次打開文件。
  4. 在具有異常處理程序的第二個BEGIN之前立即啓動另一個循環。

請注意,代替(2)和(3),您可以執行UTL_FILE.fseek(file,0)。

分享和享受。

相關問題