【发布时间】:2018-02-12 18:29:12
【问题描述】:
我使用oracle DB维护了30多张表,如何删除所有表中的所有数据?我只想删除数据而不删除表。
【问题讨论】:
-
这个问题似乎是题外话,因为它属于 dba.stackexchange.com
我使用oracle DB维护了30多张表,如何删除所有表中的所有数据?我只想删除数据而不删除表。
【问题讨论】:
没有命令'ALTER TABLE XXX DISABLE ALL CONSTRAINTS'
我提出这个建议;
BEGIN
FOR c IN (SELECT table_name, constraint_name FROM user_constraints WHERE constraint_type = 'R')
LOOP
EXECUTE IMMEDIATE ('alter table ' || c.table_name || ' disable constraint ' || c.constraint_name);
END LOOP;
FOR c IN (SELECT table_name FROM user_tables)
LOOP
EXECUTE IMMEDIATE ('truncate table ' || c.table_name);
END LOOP;
FOR c IN (SELECT table_name, constraint_name FROM user_constraints WHERE constraint_type = 'R')
LOOP
EXECUTE IMMEDIATE ('alter table ' || c.table_name || ' enable constraint ' || c.constraint_name);
END LOOP;
END;
【讨论】:
生成一个脚本来截断(= 删除所有行)所有表:
select 'truncate table ' || table_name || ';' from user_tables
然后执行脚本。
【讨论】:
truncate 是非事务性的,即不能回滚。
为了解决约束问题,这样的事情应该可以工作:
BEGIN
FOR T in (SELECT table_name FROM user_tables) LOOP
EXECUTE IMMEDIATE 'ALTER TABLE '||T.table_name||' DISABLE ALL CONSTRAINTS';
END LOOP;
FOR T in (SELECT table_name FROM user_tables) LOOP
EXECUTE IMMEDIATE 'TRUNCATE TABLE '||T.table_name;
END LOOP;
FOR T in (SELECT table_name FROM user_tables) LOOP
EXECUTE IMMEDIATE 'ALTER TABLE '||T.table_name||' ENABLE ALL CONSTRAINTS';
END LOOP;
END;
【讨论】:
alter table ... disable all constraints 会抛出 ORA-01735: invalid ALTER TABLE option,这将导致脚本无法截断 每个 表(如果至少有一个)没有约束的表。您可能希望将 execute immediate 放在 begin .. exception 块中。
截断的潜在缺点是它可能会在参照完整性约束上失败。因此,您首先要禁用外键约束,然后进行截断,然后重新启用约束。 克隆模式(exp 和 imp)的“加号”是你也可以删除并重新创建表空间(如果你想回收一些物理磁盘空间作为删除所有数据的结果,你可能想要这样做)。
【讨论】:
克隆架构然后删除旧表?
【讨论】:
我使用上面提到的答案创建了这个存储过程。 这可以完美运行,没有任何错误或异常。
create or replace PROCEDURE DELETE_ALL_DATA
AS
cursor r1 is select * from user_constraints;
cursor r2 is select * from user_tables;
cursor r3 is select * from user_constraints;
cursor r4 is select * from user_tables;
BEGIN
FOR c1 IN r1
loop
for c2 in r2
loop
begin
if c1.table_name = c2.table_name and c1.status = 'ENABLED' THEN
dbms_utility.exec_ddl_statement('alter table ' || c1.owner || '.' || c1.table_name || ' disable constraint ' || c1.constraint_name);
end if;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
continue;
WHEN OTHERS
THEN
continue;
end;
end loop;
END LOOP;
FOR T in (SELECT table_name FROM user_tables) LOOP
begin
EXECUTE IMMEDIATE 'TRUNCATE TABLE '||T.table_name;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
continue;
WHEN OTHERS
THEN
continue;
end;
END LOOP;
FOR c1 IN r3
loop
for c2 in r4
loop
begin
if c1.table_name = c2.table_name and c1.status = 'DISABLED' THEN
dbms_utility.exec_ddl_statement('alter table ' || c1.owner || '.' || c1.table_name || ' enable constraint ' || c1.constraint_name);
end if;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
continue;
WHEN OTHERS
THEN
continue;
end;
end loop;
END LOOP;
commit;
END DELETE_ALL_DATA;
【讨论】:
Andomar 的答案略有不同,即截断特定用户的所有表,而不是仅截断当前用户的表:
SELECT 'TRUNCATE TABLE ' || owner || '.' || table_name || ';' FROM all_tables WHERE owner = 'user/schema'
将上面的user/schema 位替换为您感兴趣的用户/模式的名称(在引号之间)。
【讨论】:
删除oracle中所有表的所有数据
声明
str VARCHAR2(100);
开始
为我输入
(从 user_objects 中选择 object_name,其中 object_type='TABLE'
)
环形
str := '截断表'|| i.object_name;
立即执行 str;
DBMS_OUTPUT.PUT_LINE('表数据已删除:' || i.object_name);
结束循环;
结束;
欲了解更多信息:http://www.oracleinformation.com/2014/10/delete-all-the-data-from-all-tables.html
【讨论】:
这两行脚本最好
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
GO
EXEC sp_MSForEachTable 'DELETE FROM ?'
GO
【讨论】: