oracle 批量刪除表數據的4種方式


1.情景展示

  情景一:

  刪除PRIMARY_INDEX_TEST表中,MINDEX_ID字段為空的數據

  情景二:

  刪除VIRTUAL_CARD_TEST表中的臟數據

2.解決方案

  情景一的解決方案: 

DELETE FROM PRIMARY_INDEX_TEST WHERE MINDEX_ID IS NULL

  情景二的解決方案:

  最簡單的方法,見文末 2019/10/17

  2018/12/10

  方案1:使用快速游標法(刪除一次提交一次);

 1 --快速游標法
 2 BEGIN
 3   FOR TEMP_CURSOR IN (SELECT ID
 4                         FROM VIRTUAL_CARD3
 5                        WHERE INSTR(NAME, '*') > 0
 6                       UNION
 7                       SELECT ID
 8                         FROM VIRTUAL_CARD3
 9                        WHERE INSTR(NAME, '#') > 0
10                       UNION
11                       SELECT ID
12                         FROM VIRTUAL_CARD3
13                        WHERE INSTR(NAME, '/') > 0
14                       UNION
15                       SELECT ID
16                         FROM VIRTUAL_CARD3
17                        WHERE INSTR(NAME, '+') > 0
18                       UNION
19                       SELECT ID
20                         FROM VIRTUAL_CARD3
21                        WHERE INSTR(NAME, '!') > 0
22                       UNION
23                       SELECT ID
24                         FROM VIRTUAL_CARD3
25                        WHERE INSTR(NAME, '.') > 0) LOOP
26     /* LOOP循環的是TEMP_CURSOR(逐條讀取TEMP_CURSOR) */
27     DELETE FROM VIRTUAL_CARD3 WHERE VIRTUAL_CARD3.ID = TEMP_CURSOR.ID;
28     COMMIT; --提交
29   END LOOP;
30 END;

  執行時間:

  方案2:更多游標使用方法,見文末推薦;

  方案3:使用存儲過程按id進行逐條刪除。

 1 CREATE OR REPLACE PROCEDURE DELETE_TABLE_BATCH(V_ROWS IN NUMBER /*刪除多少條數據后進行提交*/) IS
 2   /**
 3   * 內容:
 4   * 日期:2018/12/05
 5   * 作者:Marydon
 6   * 版本:1.0
 7   */
 8   I NUMBER(10); --聲明變量,用於記錄次數
 9 BEGIN
10   FOR TEMP_TABLE IN (SELECT ID
11                        FROM VIRTUAL_CARD_TEST
12                       WHERE INSTR(NAME, '*') > 0
13                      UNION
14                      SELECT ID
15                        FROM VIRTUAL_CARD_TEST
16                       WHERE INSTR(NAME, '#') > 0
17                      UNION
18                      SELECT ID
19                        FROM VIRTUAL_CARD_TEST
20                       WHERE INSTR(NAME, '/') > 0
21                      UNION
22                      SELECT ID
23                        FROM VIRTUAL_CARD_TEST
24                       WHERE INSTR(NAME, '+') > 0
25                      UNION
26                      SELECT ID
27                        FROM VIRTUAL_CARD_TEST
28                       WHERE INSTR(NAME, '!') > 0
29                      UNION
30                      SELECT ID
31                        FROM VIRTUAL_CARD_TEST
32                       WHERE INSTR(NAME, '.') > 0) LOOP
33     /* LOOP循環的是TEMP_TABLE(逐條讀取TEMP_TABLE) */
34     DELETE VIRTUAL_CARD_TEST WHERE VIRTUAL_CARD_TEST.ID = TEMP_TABLE.ID;
35     I := I + 1; --刪除一次,+1
36     IF I >= V_ROWS THEN
37       COMMIT; --提交
38       I := 0; --重置
39     END IF;
40   END LOOP;
41 EXCEPTION
42   /* 輸出異常信息 */
43   WHEN OTHERS THEN
44     DBMS_OUTPUT.PUT_LINE('異常編號:' || SQLCODE);
45     DBMS_OUTPUT.PUT_LINE('異常信息:' || SQLERRM);
46     ROLLBACK; --回滾
47 END DELETE_TABLE_BATCH;

  創建並運行該存儲過程

  刪除16522條數據,用了6分21秒,比方式一慢太多了。 

  方案4:

  將要保留的數據插入到新表

 1 --將要保留的數據插入到新表
 2 CREATE TABLE VIRTUAL_CARD_TEMP2 AS(
 3 SELECT *
 4   FROM VIRTUAL_CARD2
 5  WHERE INSTR(NAME, '*') = 0
 6    AND INSTR(NAME, '#') = 0
 7    AND INSTR(NAME, '/') = 0
 8    AND INSTR(NAME, '+') = 0
 9    AND INSTR(NAME, '!') = 0
10    AND INSTR(NAME, '.') = 0)

  刪除原來的表

--刪除原表
drop table VIRTUAL_CARD2

  將新建的表進行重命名成刪除表的名稱。

  說明:原來的表有過存在外鍵約束等關系時,並沒有進行測試,因為該表沒有索引之類東西,自己測試的時候一定要慎重!!!

  方案5:使用in函數

DELETE FROM VIRTUAL_CARD_TEMP
 WHERE ID_CARD IN (SELECT T1.ID_CARD
                     FROM VIRTUAL_CARD_TEMP T1
                    WHERE INSTR(T1.NAME, '*') > 0
                   UNION
                   SELECT T1.ID_CARD
                     FROM VIRTUAL_CARD_TEMP T1
                    WHERE INSTR(T1.NAME, '#') > 0
                   UNION
                   SELECT T1.ID_CARD
                     FROM VIRTUAL_CARD_TEMP T1
                    WHERE INSTR(T1.NAME, '/') > 0
                   UNION
                   SELECT T1.ID_CARD
                     FROM VIRTUAL_CARD_TEMP T1
                    WHERE INSTR(T1.NAME, '+') > 0
                   UNION
                   SELECT T1.ID_CARD
                     FROM VIRTUAL_CARD_TEMP T1
                    WHERE INSTR(T1.NAME, '!') > 0
                   UNION
                   SELECT T1.ID_CARD
                     FROM VIRTUAL_CARD_TEMP T1
                    WHERE INSTR(T1.NAME, '.') > 0)

  說明:ID_CARD字段必須具有唯一性。 

 

寫在最后

  哪位大佬如若發現文章存在紕漏之處或需要補充更多內容,歡迎留言!!!

 相關推薦:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM