【问题标题】:Dropping all objects of a schema删除模式的所有对象
【发布时间】:2017-02-11 09:33:41
【问题描述】:

下面的查询将返回一个语句,该语句可用于删除当前用户 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 视图中存在哪些对象?它会删除数据库中所有模式的所有表,还是查询会抛出错误?意图是仅删除 Schema 'A' 的对象。

【问题讨论】:

  • 准确地说:查询不会丢弃任何东西。它返回将删除某些内容的语句。语句会删除视图、包和其他一些对象,但不会删除表。

标签: oracle plsql oracle11g


【解决方案1】:

user_objects 视图包含当前用户的对象,因此如果以 SYS 身份运行,它将尝试删除 SYS 的对象 - 非常糟糕的消息,因为它会破坏您的数据库。您可以阅读有关 tthat 视图的三个版本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';

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


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

【讨论】:

    【解决方案2】:

    仅供参考,下面的查询只生成所有的 sql,然后您需要运行生成的 sql 才能真正完成工作。

    代码片段(包括表格):

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

    【讨论】:

      【解决方案3】:

      不,当以 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;
      

      【讨论】:

        【解决方案4】:
        CREATE OR REPLACE PROCEDURE PROC_ABHISEK_CLEAR_DB_SCHEMA AS
        /******************************************************************************
           NAME:      PROC_ABHISEK_CLEAR_DB_SCHEMA
           PURPOSE:   Clears Database Schema by dropping vital Oracle Objects
           AUTHOR:    ABHISEK
           DATE:      28-Jan-2021
        ******************************************************************************/
        TYPE list_string is table of varchar2(300);
        query_list list_string;
        delete_gen_query varchar2(500);
        PROGRAM_NAME varchar2(50);
        begin
            PROGRAM_NAME := 'DB CLEARING PROCESS';
            dbms_output.put_line(PROGRAM_NAME||' Started...');
            delete_gen_query := q'$select 'drop ' || object_type || ' ' || 
                                   DECODE(object_type, 'TABLE', object_name || ' CASCADE CONSTRAINTS',
                                     object_name) 
                                   from user_objects 
                                   where object_type in ('TABLE','VIEW','SEQUENCE') order by object_name$';
            execute immediate delete_gen_query bulk collect into query_list;
            dbms_output.put_line('Total Objects to be deleted: ' || query_list.count );
            
            for cnt in 1..query_list.count
            loop
                execute immediate query_list(cnt);
            end loop;
        end PROC_ABHISEK_CLEAR_DB_SCHEMA;
        /
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-11-25
          • 1970-01-01
          • 2020-05-03
          • 2018-12-27
          • 2013-01-06
          • 2012-11-04
          • 1970-01-01
          相关资源
          最近更新 更多