web-dev-qa-db-ja.com

ExceptionステートメントでSQLファイルを実行する

こんにちはスプールファイルを実行しているときに、例外ステートメントでSQLファイルを実行しようとしています。

私はこのようなものを持っています:

column dt new_value _dt 
select to_char(sysdate,'yyyymmdd_hh24mi') dt from dual; 
set line 10000;
set pagesize 50000;
set serveroutput on;

spool .\backup\backup.sql

select dbms_metadata.get_ddl(object_type, object_name)
from user_objects
where object_type in ('FUNCTION')
and object_name = 'TEST_TABLE';

Spool Off

spool .\!Run_&_dt..txt

BEGIN
    raise_application_error( -20001, 'This is a custom error' );
EXCEPTION 
    WHEN OTHERS THEN
        Prompt ./backup/backup.sql
        @ ./backup/backup.sql
END;

Spool Off

そして、私は次のエラーを受け取ります:

>> BEGIN
     raise_application_error( -20001, 'This is a custom error' );
EXCEPTION 
    WHEN OTHERS THEN
        Prompt ./backup/backup.sql
        @ ./backup/backup.sql
END;


Spool Off
Error at line 18
ORA-06550: line 6, column 11:
PLS-00103: Encountered the symbol "/" when expecting one of the following:

    <an identifier> <a double-quoted delimited-identifier>
    current delete exists prior
ORA-06550: line 6, column 49:
PLS-00103: Encountered the symbol "SQL" when expecting one of the following:

    <an identifier> <a double-quoted delimited-identifier>
    current delete exists prior

前もって感謝します。

宜しくお願いします。

2
csuazo

そのため、少し混乱します。SQL* Plusスクリプトを記述していて、SQL * Plusコマンドと、SQLコマンドおよびPL/SQLブロックの両方を受け入れます。

SQL * Plusコマンド はクライアントマシン上でローカルに実行されるため、ローカルファイルシステム上の他のスクリプトにアクセスできます。

BEGIN..ENDブロック内はすべてPL/SQLコードであり、言語が異なるため、スクリプトの他の部分とは動作が異なります。コードのブロック全体がサーバーに送信され、そこで実行されますが、データベースはPrompt@などのsqlplusコマンドを解釈する方法を認識していません。

PL/SQLブロックにデータベースサーバーでスクリプトを実行させる方法があります- この回答を参照 詳細については-=とは思いません本当にあなたが欲しいもの。

あなたの例から何が欲しいかを伝えるのは難しいですが、私は調べることをお勧めします シェルスクリプトを使用したsqlplusエラーの処理 -これを2つのsqlplusスクリプトに分割し、最初のスクリプトを実行して、戻りコードを確認します、およびエラーが発生した場合は、2番目のスクリプトを実行します。 Sqlplus自体には、組み込みの例外処理の方法はあまりありません。

5
kfinity

投稿された質問への回答

kfinityの答えはかなり良いです。合格/不合格に基づいてスクリプトを実行する場合は、シェルレベルで例外をキャッチし、それに応じて次のスクリプトを実行する必要があります。

「あなたがやろうとしていること」に基づいた答え

コメントを読んでいると、次のことをしようとしているように感じます

  1. 新しいオブジェクトをインストールする
  2. それが失敗した場合は、古いオブジェクトを再インストールしてください。

「古いオブジェクトをバックアップ」する必要はありません。新しいオブジェクトをデータベースの現在のEDITIONに含まれないようにインストールする必要があるだけです。

Edition-Based Redefinition は、Oracle 11gR2以降の機能です。特定のデータベースオブジェクトを「インストールするが、デフォルトでは使用しない」ことができます。

あなたのスクリプトプロセスはこのようになります

  1. 新規作成EDITION
  2. セッションを新しいEDITIONに設定
  3. 新しいEDITIONにオブジェクトをインストールする
  4. すべてが合格したら、EDITIONを現在のエディションにします
  5. 何かがうまくいかない場合。ドロップEDITION
    • 古いオブジェクトは変更されません。
    • DDLのバックアップは不要になりました。

使用例もここにあります: https://Oracle-base.com/articles/11g/edition-based-redefinition-11gr2

3
Michael Kutz