有谁知道如何将以下查询生成的所有行作为脚本单独运行?
select 'DROP TABLE '||table_name||' CASCADE CONSTRAINTS;' from user_tables;
我基本上想做的是删除我的数据库(这是oracle)上的所有用户表和约束。我得到的输出是正确的,但我想知道如何在不复制/粘贴的情况下运行所有行。
此外,是否有更有效的方法来删除所有表(包括约束)?
begin
for i in (select table_name from user_tables)
loop
execute immediate ('drop table ' || i.table_name || ' cascade constraints');
end loop;
end;
/
Justin Cave 提出了一个很好的观点——假设所有外键都引用主键,而不是唯一约束,下面将从依赖层次结构的最外层分支开始删除用户模式中的表。没有主键的表将最后被删除。
begin
for i in (select parent_table, max(tree_depth) as tree_depth
from (select parent.table_name as parent_table,
child.constraint_name as foreign_key,
child.table_name as child_table,
LEVEL AS TREE_DEPTH
from (select table_name, constraint_name
from USER_constraints
where constraint_type = 'P'
) parent
LEFT JOIN
(SELECT TABLE_NAME, CONSTRAINT_NAME,
r_constraint_name
FROM USER_CONSTRAINTS
WHERE CONSTRAINT_TYPE = 'R') child
on parent.constraint_name =
child.r_constraint_name
CONNECT BY NOCYCLE
(PRIOR CHILD.TABLE_NAME = PARENT.TABLE_NAME)
UNION
select DT.table_name as parent_table,
NULL AS FOREIGN_KEY, NULL AS CHILD_TABLE,
0 AS TREE_DEPTH
FROM USER_TABLES DT
WHERE TABLE_NAME NOT IN
(SELECT TABLE_NAME
FROM USER_CONSTRAINTS
WHERE CONSTRAINT_TYPE = 'P')
)
group by parent_table
order by 2 desc
)
loop
execute immediate ('drop table ' || i.parent_table ||
' cascade constraints');
end loop;
end;
/
快速而肮脏的解决方案是做类似的事情
FOR x IN (SELECT * FROM user_tables)
LOOP
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE ' || x.table_name ||
' CASCADE CONSTRAINTS';
EXCEPTION
WHEN others THEN
dbms_output.put_line( 'Failed to drop ' || x.table_name );
END;
END LOOP;
并运行多次,直到所有表都被删除。这将需要多次传递,因为您不能删除父表,而仍然存在具有引用父表的外键的子表。
更简洁的选择是针对数据字典编写分层查询以获取子表、这些孩子的父母、祖父母等,并遍历树以删除适当的对象。这应该可以避免错误,但需要更多的工作来编写代码。
execute immediate
- 传入生成的字符串
删除表以使用truncate语句时通常更有效。
您可以使用 execute immediate 命令执行动态脚本