ビルドプロセスと進化するデータベースの一部として、ユーザーのすべてのテーブルとシーケンスを削除するスクリプトを作成しようとしています。許可されているよりも多くのアクセス許可が必要になるため、ユーザーを再作成したくありません。
私のスクリプトは、テーブル/シーケンスを削除するプロシージャを作成し、プロシージャを実行してから、プロシージャを削除します。私は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に本番運用[2010年..____。] Copyright(c)1982、2008、Oracle。 接続先: Oracle Database 11g Enterprise Editionリリース11.1.0.7.0-64ビット実動 パーティション化により、 OLAP、データマイニング、およびReal Application Testingオプション プロシージャが作成されました。 PL/SQLプロシージャが正常に完了しました。 プロシージャが作成されました。 プロシージャがドロップされました。 ドロッププロシージャdrop_all_user_tables * 1行目のエラー: ORA-04043:オブジェクトDROP_ALL_USER_TABLESは存在しません SQL> Oracle Database 11gから切断Enterprise Editionリリース11.1.0.7.0-64 パーティショニング、OLAP、データマイニング、およびReal Application Testingオプション
これを機能させる方法についてのアイデアはありますか?
ストアドプロシージャを保持するつもりがない場合は、 匿名PLSQLブロック を使用します。
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;
SQLステートメントの場合、末尾のセミコロンがステートメントを実行します。 /は前のステートメントを実行します。そのため、次の行を終了します
drop procedure drop_all_cdi_tables;
/
プロシージャをドロップしてから、もう一度ドロップしてみます。
出力を見ると、「PROCEDURE CREATED」が表示され、実行され、最後のステートメントが再実行されるため「PROCEDURE CREATED」が再び表示されます(EXECUTEはステートメントではなくSQL * Plusコマンドであり、バッファリングされません) )、次に「PROCEDURE DROPPED」を選択し、2回目にドロップしようとします(そして失敗します)。
PS。奇妙なDBMS_SQL呼び出しについてはDougmanに同意します。
例のエラーメッセージはdrop_all_user_tables
でエラーを受け取っているようですが、指定した例はdrop_all_cdi_tables
のものです。 drop_all_user_tables
コードは異なって見えますか?
また、dbms_sql
への呼び出しがありますが、それを使用して解析を行っていないようです。
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;
/
何らかの理由で、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
これらの2つのステートメントを実行してから、すべての結果を実行します。
select 'drop table ' || table_name || ';' from user_tables;
select 'drop sequence ' || sequence_name || ';' from user_sequences;