【问题标题】:DELETE existing data before insert插入前删除现有数据
【发布时间】:2012-10-08 19:15:48
【问题描述】:

我想在基于 id 插入之前删除现有数据。因此,如果传入文件中有 id,则应删除现有 id,然后应输入数据。像这样的:

之前的数据库表:

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

之后的数据库表:

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

简而言之,我需要启动一个循环,只删除比较中的数据,然后再启动另一个循环插入数据。 有任何想法吗?在此先感谢:-)

【问题讨论】:

    标签: oracle plsql oracle11g plsqldeveloper


    【解决方案1】:

    上面的一个稍微不同的转折是合并/更新数据。 看看这里如何在 Oracle 中合并数据:Oracle: how to UPSERT (update or insert into a table?)

    【讨论】:

      【解决方案2】:

      我会通过以下方式做到这一点:

      1. 将文件中的数据读入新表 TEMP
      2. 删除 ID 在 TEMP 中的所有记录,例如 DELETE FROM WHERE TABLE.ID IN (SELECT ID FROM TEMP)
      3. 将 TEMP 中的所有记录添加到 TABLE 中

      【讨论】:

      【解决方案3】:

      尝试以下方法:

      1. 在第一个具有异常处理程序的 BEGIN 的 END 之后立即关闭第一个循环。
      2. 关闭文件。
      3. 再次打开文件。
      4. 在具有异常处理程序的第二个 BEGIN 之前立即开始另一个循环。

      请注意,您可以只执行 UTL_FILE.fseek(file, 0) 而不是 (2) 和 (3)。

      分享和享受。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-20
        • 2014-02-02
        • 2013-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-09
        • 2012-11-29
        相关资源
        最近更新 更多