web-dev-qa-db-ja.com

PL / SQL-BeginEndブロック内にユーザーをドロップ

SQL Serverの使用経験はありますが、現在PL SQLの使用を開始しており、2つのテクノロジーの違いにより、いくつかの問題に直面しています。

データベースを削除するスクリプトがいくつかあり、ユーザーを削除する必要がある場合は、次のようにします。

DEFINE OWNER = MYUSER

ALTER SESSION SET DDL_LOCK_TIMEOUT = 3600;

BEGIN
  FOR r IN (select sid,serial# from v$session where username=&OWNER)
  LOOP
      EXECUTE IMMEDIATE 'alter system kill session ''' || r.sid  || ',' || r.serial# || '''';
  END LOOP;

  DROP USER &OWNER CASCADE;
END;
/

ただし、次のエラーが発生します。

詳細:ORA-06550:6行目、3列目:PLS-00103:次のいずれかが予期されているときに、記号\ "DROP \"が発生しました:

(開始ケース宣言宣言gotoの終了例外出口ifループmod nullプラグマレイズリターン選択更新ながら<<続行現在の削除フェッチロック挿入オープンロールバックセーブポイントセットSQL実行コミットフォーオールマージパイプパージjson_exists json_value json_query json_object json_array(DBDエラー:

'BEGIN FOR r IN(select sid、serial#from v $ session where username = MYUSER)'のchar 189の<*>インジケーターの近くにエラーがある可能性がありますLOOP EXECUTE IMMEDIATE 'alter system kill session' '' || r.sid || '、' || r.serial#|| '' '';ループ終了; <*>DROP USER MYUSER CASCADE;終わり; ')

私はすでに8行目にスラッシュを追加しようとしました:

  END LOOP;
  /
  DROP USER &OWNER CASCADE;
END;
/

エラーはまだ表示されており、DROP USER &OWNER CASCADE;をスクリプトの最後に移動しようとしましたが、まだエラーが発生します。

私は何が間違っているのか理解できず、私はすでにこれについてこれを含む多くのリンクを読みました:

何が問題ですか? Begin End空行を許可しませんか? DROP USER &OWNER CASCADE;は別のBegin End内にある必要がありますか?

1
Ninita

コードには2つの問題がありました。

  1. @BalazsPappのように、DROP USERコマンドはスクリプトの最後またはexecute immediate内にある必要があると述べました
  2. v$sessionの選択に引用符がありません。 DROP USERコマンドをスクリプトの最後に移動すると、「R」の無効な使用が原因で他のエラーが表示されます。しかし、このエラーは欠落している引用に対して発生しました。

コードを修正すると、次のコードが機能するようになります。

DEFINE OWNER = MYUSER

ALTER SESSION SET DDL_LOCK_TIMEOUT = 3600;

BEGIN
  FOR r IN (select sid,serial# from v$session where username='&OWNER')
  LOOP
      EXECUTE IMMEDIATE 'alter system kill session ''' || r.sid  || ',' || r.serial# || '''';
  END LOOP;
END;
/
DROP USER &OWNER CASCADE;
1
Ninita

データ定義言語(DDL)ステートメント

DDLステートメントは次のとおりです。

... DROP ...(DROPで始まるすべてのステートメント)...

PL/SQLは静的SQLとしてDDLをサポートしていません。

PL/SQL静的SQL

PL/SQLでDDLステートメントを実行するには、動的SQLを使用します。

PL/SQL動的SQL

例:

begin
  ...
  execute immediate 'DROP USER &OWNER CASCADE';
  ...
end;
/

または単に使用:

BEGIN
  FOR r IN (select sid,serial# from v$session where username=&OWNER)
  LOOP
      EXECUTE IMMEDIATE 'alter system kill session ''' || r.sid  || ',' || r.serial# || '''';
  END LOOP;
END;
/

DROP USER &OWNER CASCADE;
3
Balazs Papp