2011-04-11 19 views
1

是否有人知道如何将下列查询生成的所有行作为脚本自行运行?如何运行一个脚本,这是从Oracle DB下的另一个脚本生成的?

select 'DROP TABLE '||table_name||' CASCADE CONSTRAINTS;' from user_tables; 

什么基本上,我试图做的,是删除所有对我的数据库用户表和约束(这是甲骨文)。我得到的输出是正确的,但我想知道如何在没有复制/粘贴的情况下运行所有​​行。

此外,是否有更有效的方式来删除所有表(包括约束)?

回答

4
begin 
    for i in (select table_name from user_tables) 
    loop 
    execute immediate ('drop table ' || i.table_name || ' cascade constraints'); 
    end loop; 
end; 
/

贾斯汀洞提出了一个良好的出发点 - 以下将下降开始依赖层次结构的最外面的分支机构用户的方案中的表,假设所有外键引用主键,而不是唯一的约束。没有主键的表最后将被丢弃。

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; 
/
+0

这是正确的!谢谢...你错过了第4行的括号。 – 2011-04-11 21:32:36

+0

更正了 - 没有测试,natch。 – 2011-04-12 00:33:26

1

execute immediate - 通过生成的字符串

+0

'执行inmediate select'DROP TABLE'|| table_name ||'来自user_tables'的CASCADE CONSTRAINTS'? 我收到以下错误: **错误在第1行:ORA-06550:第1行,第17列:PLS-00103:遇到以下符号之一时出现符号“SELECT”::=。 (@%;符号“;”代替“SELECT”继续。** – 2011-04-11 21:11:40

+0

谢谢!这是一个答案,但我需要更多的解释。 – 2011-04-11 21:43:44

1

它删除表使用truncate语句时通常更有效英寸

可以使用执行立即命令执行动态脚本

+0

谢谢!我将如何处理约束,而使用truncate语句? – 2011-04-11 21:16:08

+1

首先想到的是使用select * from all_constraints where table_name ='mytable'来检查约束,并使用execute immediate将它们放入循环中,与您对表格执行的操作相同,但可能会有 – 2011-04-11 21:19:05

+0

谢谢Mac!我会稍后再试。 – 2011-04-11 21:42:45

3

的快速和肮脏的解决办法是做类似

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; 

和运行多次,直到所有的表都被丢弃。这将需要多次传递,因为当仍有子表引用父项的外键时,您不能删除父表。

清理程序选项是为数据字典编写分层查询以获取子表,这些子项的父母,祖父母等,并遍历树来删除相应的对象。这应该避免错误,但它需要更多的工作来编写代码。

+0

我更新了我的答案用你的优秀建议。 – 2011-04-13 17:55:25

相关问题