首页 文章

删除架构的所有对象

提问于
浏览
4

下面的查询将删除当前用户A的架构中存在的所有表(正常场景) .

select 'drop '||object_type||' '|| object_name || ';' 
from user_objects 
where object_type in ('VIEW','PACKAGE','SEQUENCE', 'PROCEDURE', 'FUNCTION', 'INDEX');

但是,如果此查询由DBA以SYS或SYSDBA登录运行,该怎么办?使用sys / sysdba用户登录时user_objects视图中存在哪些对象?它会丢弃数据库中所有模式的所有表,还是查询会抛出错误?意图是仅删除模式“A”的对象 .

2 回答

  • 3

    user_objects 视图包含当前用户's objects, so if run as SYS it would try to drop SYS'的对象 - 非常糟糕的消息,因为它会破坏您的数据库 . 您可以阅读有关视图in the documentation的三个版本 .

    要让SYS查看其他用户的对象,您应该查看 dba_objects 视图,过滤您感兴趣的用户;并在drop语句中包含目标模式(所有者):

    select 'drop ' || object_type || ' "' || owner || '"."' || object_name || '";'
    from dba_objects
    where object_type in ('VIEW','PACKAGE','SEQUENCE', 'PROCEDURE', 'FUNCTION', 'INDEX')
    and owner = 'A';
    

    我还包括用双引号包装对象名称(不太有用的是所有者),以防有任何使用带引号的标识符创建的对象 .


    如果您在查询中包含表并尝试运行输出,则可能会因尝试以错误的顺序删除相关对象而导致错误,即在其子项之前删除父表 . 也存在对象类型,但如果您最终想要删除所有内容,则删除并重新创建用户可能更简单 - 捕获并重新创建其权限 .

  • 1

    否则作为SYS执行时会破坏您的数据库 . 试试this . 它会提示3次清除模式名称 .

    如果你的模式中有好奇的对象类型(比如SCHEDULER CHAIN - 例如),请注意这个脚本可能会陷入无限循环

    set serveroutput on size unlimited
    declare
      v_ItemCount integer;
    begin
      SELECT count(*)
        INTO v_ItemCount
        FROM ALL_OBJECTS AO
       WHERE AO.OWNER = '&USER'
         AND AO.OBJECT_TYPE NOT IN ('INDEX', 'LOB')
         AND AO.OBJECT_NAME NOT LIKE 'BIN$%';
      while (v_ItemCount > 0) loop
        for v_Cmd in (SELECT 'drop ' || AO.OBJECT_TYPE || ' ' || '"'||AO.OWNER||'"'|| '.' || '"'||AO.OBJECT_NAME||'"' ||
                             DECODE(AO.OBJECT_TYPE,
                                    'TABLE',
                                    ' CASCADE CONSTRAINTS',
                                    '') as DROPCMD,
                                    AO.OWNER,
                                    AO.OBJECT_TYPE,
                                    AO.OBJECT_NAME
                        FROM ALL_OBJECTS AO
                       WHERE AO.OWNER = '&USER'
                         AND AO.OBJECT_TYPE NOT IN ('INDEX', 'LOB')
                         AND AO.OBJECT_NAME NOT LIKE 'BIN$%') 
        loop
          begin
            if v_Cmd.OBJECT_TYPE = 'SCHEDULE' then
              DBMS_SCHEDULER.DROP_SCHEDULE('"'||v_Cmd.OWNER||'"'||'.'||'"'||v_Cmd.OBJECT_NAME||'"', true);
            ELSIF v_Cmd.OBJECT_TYPE = 'JOB' then
              DBMS_SCHEDULER.DROP_JOB('"'||v_Cmd.OWNER||'"'||'.'||'"'||v_Cmd.OBJECT_NAME||'"', true);
            ELSIF v_Cmd.OBJECT_TYPE = 'PROGRAM' then
              DBMS_SCHEDULER.DROP_PROGRAM('"'||v_Cmd.OWNER||'"'||'.'||'"'||v_Cmd.OBJECT_NAME||'"', true);                              
            else
              execute immediate v_Cmd.dropcmd;
            end if;  
            dbms_output.put_line(v_Cmd.dropcmd);        
          exception
            when others then
              null; -- ignore errors
          end;
        end loop;
        SELECT count(*)
          INTO v_ItemCount
          FROM ALL_OBJECTS AO
         WHERE AO.OWNER = '&USER'     
           AND AO.OBJECT_TYPE NOT IN ('INDEX','LOB')
           AND AO.OBJECT_NAME NOT LIKE 'BIN$%';
      end loop;
      execute immediate 'purge dba_recyclebin';
    end;
    

相关问题