web-dev-qa-db-ja.com

Oracleのスキーマのすべてのコンテンツを削除する

Oracleのスキームのすべてのコンテンツを削除することは可能ですか?私はこのスクリプトを見つけました:

Begin
for c in (select table_name from user_tables) loop
execute immediate ('drop table '||c.table_name||' cascade constraints);
end loop;
End;

しかし、スキーマ、インデックス、テーブル、制約のすべてを削除するものがあるかどうかを知りたいのですが、スキーマは削除しません(ユーザーの削除...)。

ありがとう。

23
zerosssa

通常、ユーザーをドロップして追加するのが最も簡単です。データベースへのシステムまたはsysdbaアクセスがある場合、これが推奨される方法です。

システムレベルのアクセス権がなく、スキーマをスクラブする場合、次のsqlは一連のドロップステートメントを生成し、実行できます。

select 'drop '||object_type||' '|| object_name|| DECODE(OBJECT_TYPE,'TABLE',' CASCADE CONSTRAINTS','') || ';'  from user_objects

次に、通常はごみ箱をパージして、本当にきれいにします。正直に言うと、Oracleのごみ箱はあまり使用されていないので、無効にしたいのですが、とにかく:

purge recyclebin;

これにより、ドロップステートメントのリストが生成されます。すべてが実行されるわけではありません-カスケードでドロップすると、PK_ *インデックスのドロップは失敗します。しかし、最終的にはかなりきれいなスキーマになります。確認する:

select * from user_objects

また、追加するだけで、質問のPl/sqlブロックはテーブルのみを削除し、他のすべてのオブジェクトは削除しません。

シモンズ:いくつかのウェブサイトからコピーされ、私にとって有用でした。テストされ、魅力のように動作します。

37
venki

はい、できます。ユーザーを削除して、スキーマオブジェクトを削除できます。 DROP USERステートメントは、Oracleデータベースからユーザーを削除し、そのユーザーが所有するすべてのオブジェクトを削除するために使用されます。

DROP USER TestDB;

このステートメントは適切に実行され、TestDBがスキーマ内のオブジェクトを所有していない場合にのみ、TestDBというユーザーを削除します。センステーブルやビューなどのオブジェクト。オブジェクトが含まれている場合、DROP USERステートメントを実行すると、次のエラーメッセージが表示されます。

Error starting at line : 1 in command -
DROP USER TestDB
Error report -
SQL Error: ORA-01922: CASCADE must be specified to drop 'TESTDB'
01922. 00000 -  "CASCADE must be specified to drop '%s'"
*Cause:    Cascade is required to remove this user from the system.  The
           user own's object which will need to be dropped.
*Action:   Specify cascade.

TestDBがスキーマ内でオブジェクトを所有している場合、代わりに次のDROP USERステートメントを実行する必要があります。

DROP USER TestDB CASCADE;

このステートメントは、TestDBが所有するすべてのオブジェクトを削除し、TestDBオブジェクトのすべての参照整合性制約も削除されます。

2
Bacteria

次のSQLplusスクリプトは、目的のユーザーからすべてのスキーマオブジェクトを削除するために必要なSQLステートメントを生成します。

set heading off
set pagesize 0
set feedback off

-- wipe out all scheduler jobs
select 'exec dbms_scheduler.drop_job(job_name => '''||j.job_creator||'.'||j.job_name||''');'
from user_scheduler_jobs j
/

-- wipe out all XML schemas
select 'exec dbms_xmlschema.deleteSchema(schemaURL => '''||s.qual_schema_url||''',delete_option => dbms_xmlschema.DELETE_CASCADE_FORCE);'
from user_xml_schemas s
/

-- wipe out all remaining objects
select 'drop '
       ||o.object_type
       ||' '||object_name
       ||case o.object_type when 'TABLE' then ' cascade constraints' when 'TYPE' then ' force' else '' end
       ||';'
from user_objects o
where o.object_type not in ('JOB','LOB','PACKAGE BODY','INDEX','TRIGGER')
and not exists (select 1
                from user_objects r
                where r.object_name = o.object_name 
                and   r.object_type = 'MATERIALIZED VIEW'
                and   o.object_type != 'MATERIALIZED VIEW'
               )
/

-- empty the recycle bin
select 'purge recyclebin;' from dual
/

スクリプトは私にとってはそのまま100%動作しますが、何らかの理由で完全ではない場合、次のように仮想マシン(VM)を使用して簡単に拡張できます。

  1. [空にするスキーマユーザー]としてログオンします
  2. VMのスナップショットを撮る
  3. 上記のスクリプトを実行して削除ステートメントを作成します
  4. 削除ステートメントを実行します(一部のオブジェクトはスクリプト削除ステートメントの前に自動的に削除されるため、「オブジェクトが存在しない」エラーは無視できます。これは所有オブジェクトが削除される結果として発生します)
  5. ログオフ
  6. sYSとしてログオンし、「ユーザーの削除[空のスキーマユーザー];」を実行します。 -カスケードオプションなし

手順6が失敗した場合、ユーザーが削除されないようにする残りのオブジェクトを特定し、上記のスクリプトに追加する必要があります。ユーザーがドロップするまで(つまり、スクリプトが包括的なものになるまで)繰り返し、スクリプトを保存します。

VM=をスナップショットにロールバックし、更新されたスクリプトを使用してステップ3と4を繰り返します。これで、100%空のスキーマになります。

1
Pancho

すぐに使用できるgithubで次のスクリプトを見つけました(SQL * Plus:Release 12.2.0.1.0 Production):

https://Gist.github.com/rafaeleyng/33eaef673fc4ee98a6de4f70c8ce3657

著者のRafael Eyngに感謝します。

オブジェクトを削除するスキーマにログインするだけです。

BEGIN
   FOR cur_rec IN (SELECT object_name, object_type
                     FROM user_objects
                    WHERE object_type IN
                             ('TABLE',
                              'VIEW',
                              'PACKAGE',
                              'PROCEDURE',
                              'FUNCTION',
                              'SEQUENCE',
                              'SYNONYM'
                             ))
   LOOP
      BEGIN
         IF cur_rec.object_type = 'TABLE'
         THEN
            EXECUTE IMMEDIATE    'DROP '
                              || cur_rec.object_type
                              || ' "'
                              || cur_rec.object_name
                              || '" CASCADE CONSTRAINTS';
         ELSE
            EXECUTE IMMEDIATE    'DROP '
                              || cur_rec.object_type
                              || ' "'
                              || cur_rec.object_name
                              || '"';
         END IF;
      EXCEPTION
         WHEN OTHERS
         THEN
            DBMS_OUTPUT.put_line (   'FAILED: DROP '
                                  || cur_rec.object_type
                                  || ' "'
                                  || cur_rec.object_name
                                  || '"'
                                 );
      END;
   END LOOP;
END;
/
0
Heri

これは私が使用したものです:

set echo off feedback off serverout on

spool drop_all_objects.sql

declare  l_object varchar2(32000);

begin

  for i in (select object_name, object_type from dba_objects where owner='<owner>') loop

    if i.object_type='JOB' then

          l_object := 'begin dbms_scheduler.drop_job (job_name => ''<owner>'||i.object_name||'''); end;';

elsif i.object_type='PROGRAM' then

      l_object := 'begin dbms_scheduler.drop_program (program_name => ''<owner>'||i.object_name||'''); end;';

elsif i.object_type='RULE' then

      l_object := 'begin dbms_rule_adm.drop_rule (rule_name => ''<owner>'||i.object_name||''', force => TRUE); end;';

elsif i.object_type='RULE SET' then

      l_object := 'begin dbms_rule_adm.drop_rule_set (rule_set_name => ''<owner>'||i.object_name||''', delete_rules => TRUE); end;';

elsif i.object_type='CHAIN' then

      l_object := 'begin dbms_scheduler.drop_chain (chain_name => ''<owner>'||i.object_name||''', force => TRUE); end;';

elsif i.object_type='RULE' then

      l_object := 'begin dbms_rule_adm.drop_evaluation_context (evaluation_context_name => ''<owner>'||i.object_name||''', force => TRUE); end;';

else

          l_object := 'drop '||i.object_type||'<owner>'||i.object_name||';';

end if;

dbms_output.put_line(i_object);

dbms_output.put_line('/');

end loop;

end;

/

@drop_all_objects
0
John Taylor

ただ行く:

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