プロシージャ(パラメータなし)を使用して、プロシージャが起動されたスキーマ内にあるユーザー作成のデータベースオブジェクトをすべて削除しようとしていますが、これを実行する方法がよくわかりません。これが私がこれまでに持っているものですが、私はこれについて間違った方法で行っていると思います。
create or replace procedure CLEAN_SCHEMA is
cursor schema_cur is
select 'drop '||object_type||' '|| object_name|| DECODE(OBJECT_TYPE,'TABLE',' CASCADE CONSTRAINTS;',';')
from user_objects;
schema_rec schema_cur%rowtype;
begin
select 'drop '||object_type||' '|| object_name|| DECODE(OBJECT_TYPE,'TABLE',' CASCADE CONSTRAINTS;',';')
into schema_rec
from user_objects;
end;
/
create or replace
FUNCTION DROP_ALL_SCHEMA_OBJECTS RETURN NUMBER AS
PRAGMA AUTONOMOUS_TRANSACTION;
cursor c_get_objects is
select object_type,'"'||object_name||'"'||decode(object_type,'TABLE' ,' cascade constraints',null) obj_name
from user_objects
where object_type in ('TABLE','VIEW','PACKAGE','SEQUENCE','SYNONYM', 'MATERIALIZED VIEW')
order by object_type;
cursor c_get_objects_type is
select object_type, '"'||object_name||'"' obj_name
from user_objects
where object_type in ('TYPE');
BEGIN
begin
for object_rec in c_get_objects loop
execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name);
end loop;
for object_rec in c_get_objects_type loop
begin
execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name);
end;
end loop;
end;
RETURN 0;
END DROP_ALL_SCHEMA_OBJECTS;
上記の関数を作成し(自律型であるため、関数を介してDDLを呼び出すことができます)、次のことができます。
select DROP_ALL_SCHEMA_OBJECTS from dual;
すべてのオブジェクトを削除したい場合は、実行中のprocを削除しようとしないでください(procを気にしないので、object_typeリストにprocまたは関数がありません)
すべてを削除したい場合は、匿名ブロックが必要です
しかし、ansi sql(plsqlではない)のみを許可するツール、つまりストアドプロシージャからこれを実行できる必要がありました。
楽しい。
declare
cursor ix is
select *
from user_objects
where object_type in ('TABLE', 'VIEW', 'FUNCTION', 'SEQUENCE');
begin
for x in ix loop
execute immediate('drop '||x.object_type||' '||x.object_name);
end loop;
end;
ユーザーが権限を再適用するのが難しい場合を除いて、ユーザーを削除して再作成する方がおそらく簡単です。
Martin Brambleyに感謝します、
私たちはあなたの答えを次のように単純化できると思います。
CREATE OR REPLACE
procedure DROP_ALL_SCHEMA_OBJECTS AS
PRAGMA AUTONOMOUS_TRANSACTION;
cursor c_get_objects is
select object_type,'"'||object_name||'"'||decode(object_type,'TABLE' ,' cascade constraints',null) obj_name
FROM USER_OBJECTS
where object_type in ('TABLE','VIEW','PACKAGE','SEQUENCE','SYNONYM', 'MATERIALIZED VIEW', 'TYPE')
order by object_type;
BEGIN
begin
for object_rec in c_get_objects loop
execute immediate ('drop '||object_rec.object_type||' ' ||object_rec.obj_name);
end loop;
end;
END DROP_ALL_SCHEMA_OBJECTS;
/
execute DROP_ALL_SCHEMA_OBJECTS;
ありがとうMartin BrambleyそしてVijayan Srinivasan!
ただし、Vijayan Srinivasanのバージョンは正しくありません。これは、タイプ 'TYPE'の依存オブジェクトが、ドロップ中にエラーを生成することがあるためです。
ORA-02303:型を削除したり、型または表に依存するものに置き換えることはできません
私のバージョンでは、スキーマからすべてのオブジェクトが削除されます。
CREATE OR REPLACE procedure DROP_ALL_SCHEMA_OBJECTS AS PRAGMA AUTONOMOUS_TRANSACTION; cursor c_get_objects is selectuo.object。 object_type_2、 '"' || uo.object_name || '"' || decode(uo.object_type、 'TABLE'、 'カスケード制約'、null)obj_name2 FROM USER_OBJECTS uo where uo .object_type in( 'TABLE'、 'VIEW'、 'PACKAGE'、 'SEQUENCE'、 'SYNONYM'、 'MATERIALIZED VIEW'、 'FUNCTION'、 'PROCEDURE') and not(uo.object_type = ' TABLE 'および存在(user_nested_tables untから1を選択、uo.object_name = unt.table_name)) および存在しない(uo.object_type =' PROCEDURE 'およびuo.object_name =' DROP_ALL_SCHEMA_OBJECTS ') 順序by uo.object_type; cursor c_get_objects_type is select object_type、 '"' || object_name || '"' obj_name from user_objects where object_type in( ' TYPE '); cursor c_get_dblinks is select' "'|| db_link ||'" 'obj_name from user_db_links; cursor c_get_jobs is select '"' || object_name || '"' obj_name from user_objects where object_type = 'JOB'; cursor c_get_dbms_jobs is select job obj_number_id from user_jobs where schema_user!= 'SYSMAN'; BEGIN begin for object_rec in c_get_objects loop 即時実行( 'drop' || object_rec.object_type_2 || '' || object_rec.obj_name2); end loop; for object_rec in c_get_objects_type loop begin 即時実行( 'drop' || object_rec.object_type || '' || object_rec.obj_name); end; end loop; for object_rec in c_get_dblinks loop 即時実行( 'drop database link' || object_rec.obj_name); end loop; for object_rec in c_get_jobs loop DBMS_SCHEDULER.DROP_JOB(job_name => object_rec.obj_name); end loop; commit; for object_rec in c_get_dbms_ jobs loop dbms_job.remove(object_rec.obj_number_id); end loop; commit; end; END DROP_ALL_SCHEMA_OBJECTS; / DROP_ALL_SCHEMA_OBJECTS; ドロッププロシージャDROP_ALL_SCHEMA_OBJECTS; exit; [.____を実行します。 ]
あなたは近くにいます-他の誰かがあなたが声明のために「EXECUTEIMMEDIATE」を必要としていると指摘したように。次のことを考慮する必要があります。
これを行うためのプロシージャを作成する代わりに、これを匿名のPL/SQLブロックとして実行して、実行中のプロシージャを削除しようとする問題が発生しないようにします。
TABLEのオブジェクトタイプのテストを追加し、その場合は、dropステートメントを変更して、外部キー制約を介して他のテーブルの「親」であるテーブルを処理するカスケードオプションを含めます。ドロップをブロックする依存関係を考慮しない順序でカーソルリストを生成する可能性があることに注意してください。
また、依存関係については、最初にテーブルを削除するのがおそらく最善です(このオブジェクトタイプに低い数値を割り当てるDECODEをカーソルに追加し、この値でカーソルを選択するように順序付けます)。テーブル定義で列タイプとして使用されるタイプTYPEのOracleオブジェクトがある場合は、最初にテーブルを削除する必要があります。
Oracle Advanced Queuingを使用する場合、これに関連するオブジェクトは、AQパッケージAPI呼び出しで削除する必要があります。通常のDROPTABLEを使用してキューサポート用にOracleで生成されたテーブルを削除することはできますが、関連するキューを削除したり、追加し直したりできないというキャッチ22の位置にいることに気付くでしょう。少なくともバージョン10gまでは、この状況が存在する場合、データベースを特別なモードにしないと、含まれているスキーマを削除することさえできませんでした。
あなたが持っているものは良いスタートです。
残りは次のとおりです。
最後に、これは明らかに非常に危険な方法であるため、ストアドプロシージャではなくスクリプトに配置して、誰もが実行できるようにデータベースに残さないようにすることを検討してください。