【问题标题】:Dropping all user tables/sequences in Oracle删除 Oracle 中的所有用户表/序列
【发布时间】:2011-02-02 17:32:50
【问题描述】:

作为我们构建过程和不断发展的数据库的一部分,我正在尝试创建一个脚本,该脚本将删除用户的所有表和序列。我不想重新创建用户,因为这将需要比允许更多的权限。

我的脚本创建一个过程来删除表/序列,执行该过程,然后删除该过程。我正在从 sqlplus 执行文件:

drop.sql:


create or replace procedure drop_all_cdi_tables
is
cur integer;
begin
cur:= dbms_sql.OPEN_CURSOR();
for t in (select table_name from user_tables) loop
execute immediate 'drop table ' ||t.table_name|| ' cascade constraints';
end loop;
dbms_sql.close_cursor(cur);

cur:= dbms_sql.OPEN_CURSOR();
for t in (select sequence_name from user_sequences) loop
execute immediate 'drop sequence ' ||t.sequence_name;
end loop;
dbms_sql.close_cursor(cur);
end;
/
execute drop_all_cdi_tables;
/
drop procedure drop_all_cdi_tables;
/

不幸的是,删除该程序会导致问题。似乎会导致竞争条件,并且该过程在执行之前被丢弃。
例如:

SQL*Plus:发布 11.1.0.7.0 - 2010 年 3 月 30 日星期二 18:45:42 生产 版权所有 (c) 1982、2008,甲骨文。版权所有。 连接到: Oracle Database 11g 企业版 11.1.0.7.0 - 64 位生产 具有分区、OLAP、数据挖掘和实际应用程序测试选项 程序已创建。 PL/SQL 过程成功完成。 程序已创建。 程序下降。 删除过程 drop_all_user_tables * 第 1 行的错误: ORA-04043: 对象 DROP_ALL_USER_TABLES 不存在 SQL> 与 Oracle Database 11g 企业版 11.1.0.7.0 - 64 版断开连接 具有分区、OLAP、数据挖掘和实际应用程序测试选项

关于如何让它发挥作用的任何想法?

【问题讨论】:

    标签: sql oracle plsql build-process oracle11g


    【解决方案1】:

    只需运行这两条语句,然后运行所有结果:

    select 'drop table ' || table_name || ';' from user_tables;
    select 'drop sequence ' || sequence_name || ';' from user_sequences;
    

    【讨论】:

      【解决方案2】:

      由于某种原因,OMG Ponies 解决方案在 PLSQL 上给出了错误“SQL 命令未正确结束”。如果其他人遇到同样的问题,我可以通过以下方式删除当前架构中的所有表。

      DECLARE
        table_name VARCHAR2(30);
        CURSOR usertables IS SELECT * FROM user_tables WHERE table_name NOT LIKE 'BIN$%';
      BEGIN
        FOR i IN usertables
        LOOP
        EXECUTE IMMEDIATE 'drop table ' || i.table_name || ' cascade constraints';
        END LOOP;
      END;
      /
      

      致谢:Snippler

      【讨论】:

        【解决方案3】:

        除了 OMG Ponies 提出的解决方案,如果你有带空格的序列,你需要稍微增强一下 PLSQL:

        BEGIN
          FOR i IN (SELECT sequence_name FROM user_sequences)
            Loop
              EXECUTE IMMEDIATE('"DROP SEQUENCE ' || user || '"."' || i.sequence_name || '"');
            End Loop;
        End;
        /
        

        【讨论】:

          【解决方案4】:

          对于 SQL 语句,末尾的分号将执行该语句。 / 将执行前面的语句。 因此,你结束行

          drop procedure drop_all_cdi_tables;
          /
          

          将删除该过程,然后尝试再次删除它。

          如果您查看输出,您会看到“PROCEDURE CREATED”,然后执行,然后在重新执行最后一条语句时再次看到“PROCEDURE CREATED”(EXECUTE 是 SQL*Plus 命令,而不是语句,因此不是't buffered)然后“PROCEDURE DROPPED”,然后它尝试(但失败)第二次删除它。

          PS。我同意 Dougman 对奇怪的 DBMS_SQL 调用的看法。

          【讨论】:

            【解决方案5】:

            看起来您的示例错误消息在drop_all_user_tables 上出现错误,但您给出的示例是针对drop_all_cdi_tablesdrop_all_user_tables 代码看起来不同吗?

            您还调用了dbms_sql,但似乎没有使用它进行任何解析。

            【讨论】:

            • drop_all_cdi_tables 是相同的代码。 dbms_sql 是从另一个示例中借用的 - 我是 P/L SQL 新手 :)
            【解决方案6】:

            如果您不打算保留存储过程,我会使用anonymous PLSQL block

            BEGIN
            
              --Bye Sequences!
              FOR i IN (SELECT us.sequence_name
                          FROM USER_SEQUENCES us) LOOP
                EXECUTE IMMEDIATE 'drop sequence '|| i.sequence_name ||'';
              END LOOP;
            
              --Bye Tables!
              FOR i IN (SELECT ut.table_name
                          FROM USER_TABLES ut) LOOP
                EXECUTE IMMEDIATE 'drop table '|| i.table_name ||' CASCADE CONSTRAINTS ';
              END LOOP;
            
            END;
            

            【讨论】:

            • 这可以解决问题。奇怪的是,我不得不在脚本末尾添加一个尾随 / 来实际执行匿名 PLSQL 块。如果我们稍后创建一个自定义 MSBUILD 任务来执行脚本中的语句 - / 会导致问题吗?
            • / 告诉 sqlplus 您的 PLSQL 块已完成,并将其提交给数据库进行处理。因此,如果您的 MSBUILD 使用 sqlplus,它将需要 /.
            • @OMGPonies 我正在尝试从 Oracle SQL Developer 执行相同的命令,但我收到错误消息:ORA-00701: object necessary for warmstarting database cannot be altered 以及其他错误。有什么提示吗?
            猜你喜欢
            • 2022-01-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-12-14
            • 1970-01-01
            • 2018-04-15
            • 1970-01-01
            相关资源
            最近更新 更多