35

ビルドプロセスと進化するデータベースの一部として、ユーザーのすべてのテーブルとシーケンスを削除するスクリプトを作成しようとしています。許可されているよりも多くの権限が必要になるため、ユーザーを再作成したくありません。

私のスクリプトは、テーブル/シーケンスを削除するプロシージャを作成し、プロシージャを実行してから、プロシージャを削除します。私は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に本番環境

 Copyright(c)1982、2008、Oracle。全著作権所有。


 に接続されています:
 Oracle Database 11gEnterpriseEditionリリース11.1.0.7.0-64ビット本番
 パーティショニング、OLAP、データマイニング、および実際のアプリケーションテストオプションを使用


 プロシージャが作成されました。


 PL/SQLプロシージャが正常に完了しました。


 プロシージャが作成されました。


 手順が削除されました。

 ドロッププロシージャdrop_all_user_tables
 *
 1行目のエラー。
 ORA-04043:オブジェクトDROP_ALL_USER_TABLESは存在しません


 SQL> Oracle Database 11gEnterpriseEditionリリース11.1.0.7.0から切断-64
 パーティショニング、OLAP、データマイニング、および実際のアプリケーションテストオプションを使用

これを機能させる方法について何かアイデアはありますか?

4

6 に答える 6

83

ストアドプロシージャを保持するつもりがない場合は、匿名の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;
于 2010-03-31T01:21:39.300 に答える
6

SQLステートメントの場合、最後のセミコロンがステートメントを実行します。/は前のステートメントを実行します。このように、あなたはの行を終了します

drop procedure drop_all_cdi_tables;
/

プロシージャを削除してから、もう一度削除してみます。

出力を見ると、「PROCEDURE CREATED」が表示されてから実行され、最後のステートメントが再実行されるときに「PROCEDURECREATED」が再度表示されます(EXECUTEはSQL * Plusコマンドであり、ステートメントではないため、バッファリングされません) )次に「PROCEDUREDROPPED」を実行すると、2回目のドロップが試行されます(失敗します)。

PS。奇妙なDBMS_SQL呼び出しについてDougmanに同意します。

于 2010-03-31T01:36:36.420 に答える
4

これらの2つのステートメントを実行してから、すべての結果を実行します。

select 'drop table ' || table_name || ';' from user_tables;
select 'drop sequence ' || sequence_name || ';' from user_sequences;
于 2018-02-10T09:25:22.377 に答える
2

エラーメッセージの例でエラーが発生してdrop_all_user_tablesいるようですが、表示した例はですdrop_all_cdi_tablesdrop_all_user_tablesコードは異なって見えますか?

また、への呼び出しがありますdbms_sqlが、それを使用していないようです。

于 2010-03-31T01:23:45.603 に答える
1

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;
/
于 2015-06-01T08:47:17.860 に答える
0

何らかの理由で、OMGPoniesソリューションは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

于 2016-10-24T18:41:21.593 に答える