1.情景展示
情景一:
删除primary_index_test表中,mindex_id字段为空的数据
情景二:
删除virtual_card_test表中的脏数据
2.解决方案
情景一的解决方案:
1
|
delete from primary_index_test where mindex_id is null |
情景二的解决方案:
方案1:使用快速游标法(删除一次提交一次);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
--快速游标法 begin for temp_cursor in ( select id from virtual_card3 where instr( name , '*' ) > 0 union select id from virtual_card3 where instr( name , '#' ) > 0 union select id from virtual_card3 where instr( name , '/' ) > 0 union select id from virtual_card3 where instr( name , '+' ) > 0 union select id from virtual_card3 where instr( name , '!' ) > 0 union select id from virtual_card3 where instr( name , '.' ) > 0) loop /* loop循环的是temp_cursor(逐条读取temp_cursor) */ delete from virtual_card3 where virtual_card3.id = temp_cursor.id; commit ; --提交 end loop; end ; |
执行时间:
方案2:更多游标使用方法,见这里
方案3:使用存储过程按id进行逐条删除。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
create or replace procedure delete_table_batch(v_rows in number /*删除多少条数据后进行提交*/) is /** * 内容: * 日期:2018/12/05 * 作者:marydon * 版本:1.0 */ i number(10); --声明变量,用于记录次数 begin for temp_table in ( select id from virtual_card_test where instr( name , '*' ) > 0 union select id from virtual_card_test where instr( name , '#' ) > 0 union select id from virtual_card_test where instr( name , '/' ) > 0 union select id from virtual_card_test where instr( name , '+' ) > 0 union select id from virtual_card_test where instr( name , '!' ) > 0 union select id from virtual_card_test where instr( name , '.' ) > 0) loop /* loop循环的是temp_table(逐条读取temp_table) */ delete virtual_card_test where virtual_card_test.id = temp_table.id; i := i + 1; --删除一次,+1 if i >= v_rows then commit ; --提交 i := 0; --重置 end if; end loop; exception /* 输出异常信息 */ when others then dbms_output.put_line( '异常编号:' || sqlcode); dbms_output.put_line( '异常信息:' || sqlerrm); rollback ; --回滚 end delete_table_batch; |
创建并运行该存储过程
删除16522条数据,用了6分21秒,比方式一慢太多了。
方案4:
将要保留的数据插入到新表
1
2
3
4
5
6
7
8
9
10
|
--将要保留的数据插入到新表 create table virtual_card_temp2 as ( select * from virtual_card2 where instr( name , '*' ) = 0 and instr( name , '#' ) = 0 and instr( name , '/' ) = 0 and instr( name , '+' ) = 0 and instr( name , '!' ) = 0 and instr( name , '.' ) = 0) |
删除原来的表
1
2
|
--删除原表 drop table virtual_card2 |
将新建的表进行重命名成删除表的名称。
说明:原来的表有过存在外键约束等关系时,并没有进行测试,因为该表没有索引之类东西,自己测试的时候一定要慎重!!!
方案5:使用in函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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字段必须具有唯一性。
以上就是oracle 批量删除表数据的几种方法的详细内容,更多关于oracle 批量删除表数据的资料请关注服务器之家其它相关文章!
原文链接:https://www.cnblogs.com/Marydon20170307/p/10072539.html