質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.55%

DBMS_DATAPUMPにて、「ORA-39001 引数値が無効です」が発生

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 13K+

yamaha

score 9

お世話になります。

スキーマ内の全テーブルをバックアップする処理を作成しているのですが、
題意の通り、ORA-39001 引数値が無効です のエラーを解決することができません。

①どこでエラーが発生しているのか。
②エラー解決のために、どの部分を変えればよいのか。

上記2点について、解答をよろしくお願いします。

なお、バッチからSQLファイルを呼び出して実行しております。
以下、ソース(SQLファイル)です。

CREATE OR REPLACE DIRECTORY BK_DIR AS '&1';

    DECLARE
        HANDLE NUMBER;
        RET_STR VARCHAR2(20);
        INFO CHAR;
        T_NAME VARCHAR2(100);

    BEGIN
        FOR INFO IN (select TABLE_NAME from USER_TABLES order by 1 desc) LOOP
        DBMS_OUTPUT.PUT_LINE('開始');

            HANDLE:=DBMS_DATAPUMP.OPEN(
                                       'EXPORT'
                                      ,'TABLE'
                                      );
            DBMS_DATAPUMP.ADD_FILE(
                                   HANDLE
                                  ,INFO.TABLE_NAME||'.dmp'
                                  ,'BK_DIR'
                                  ,NULL
                                  ,DBMS_DATAPUMP.KU$_FILE_TYPE_DUMP_FILE
                                  ,1);

            T_NAME := ''''||INFO.TABLE_NAME||'''';
            DBMS_DATAPUMP.METADATA_FILTER(
                                          HANDLE
                                         ,'NAME_EXPR'
                                         ,'IN('||T_NAME||')'
                                         );

            DBMS_DATAPUMP.START_JOB(
                                    HANDLE
                                   ,0
                                   );

            DBMS_DATAPUMP.WAIT_FOR_JOB(
                                       HANDLE
                                      ,RET_STR
                                      );            
        END LOOP;
    /
 END;

DROP DIRECTORY BK_DIR;
EXIT;
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

スクリプトが正常に動作するために修正が必要な点がいくつかあります。

(1)DBMS_DATAPUMP.ADD_FILE内
誤) ,'||INFO.TABLE_NAME||'.dmp'
正) ,INFO.TABLE_NAME||'.dmp'

(2)DBMS_DATAPUMP.ADD_FILEの後
誤) TABLE_NAME := ''''||INFO.TABLE_NAME||'''';
正) T_NAME  := ''''||INFO.TABLE_NAME||'''';

(3)DBMS_DATAPUMP.METADATA_FILTER内
誤) ,'IN('||TABLE_NAME||')'
正) ,'IN('||T_NAME||')'

(4)END LOOP;の後
誤) 
正) END;

本題ですが、

ORA-39001 引数値が無効です

おそらく次の修正で改善されます。
1行目
誤) CREATE OR REPLACE DIRECTORY BACKUP_DIR AS '&1';
正) CREATE OR REPLACE DIRECTORY BK_DIR AS '&1';

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/23 07:15 編集

    > <ディレクトリの存在有無>
    > エクスプローラからアクセスできることを確認しております。
    ディレクトリのアクセス確認はDBサーバーから実施していますか?
    クライアントから実施していませんか?
    DBサーバーがディレクトリオブジェクトで指定されたパスに読み書きをするので、
    DBサーバーで読み書きできないといけません。

    キャンセル

  • 2016/02/23 18:01

    回答ありがとうございます。
    原因が特定できました。nabe3がおっしゃるとおり、DBサーバーからの読み書きが
    できないため、出ていたエラーでした。一時的にローカルに環境を作成していたため、
    この事象がおきていたのだと思います。

    大変お世話になりました。

    キャンセル

  • 2016/02/24 12:14

    無事解決できたようでよかったです。

    キャンセル

0

例外処理でSQLCODEとSQLERRMを使用してエラーメッセージを拾ってみてはいかがでしょうか?

DECLARE
    vMsg    VARCHAR2(2048);

BEGIN

EXCEPTION
    WHEN OTHERS THEN
        vMsg := SQLERRM(SQLCODE);
        DBMS_OUTPUT.PUT_LINE(vMsg);

END
/


こんな感じで。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/19 13:43

    回答ありがとうございます。
    例外処理を実装し、ログを確認しましたが、同じく、
    「ORA-39001 引数値が無効です」
    のエラーを確認しました。

    キャンセル

0

処理ステップを格納する変数を定義し、各プロシージャを呼び出す前に
その変数に一意の値を設定しておき、EXCEPTIONでその変数を出力するように
すればどこでエラーが発生しているのかが明確になります。

ただ、私の環境(Oracle Linux 5、Oracle Database 11.2.0.2)で試して
みてもエラーにはなりません。

以下は実験の結果

systemユーザで実施
SQL> grant create any directory to scott;
SQL> grant drop any directory to scott;

事前にoracleユーザで実施
$ mkdir /home/oracle/bk_dir

問題のSQLを test.sql として作成
ただし、最後のほうの
        END LOOP;
    /
 END;

        END LOOP;
    END;
    /
に修正

$ sqlplus scott/tiger
SQL> @test
1に値を入力してください: /home/oracle/bk_dir
旧   1: CREATE OR REPLACE DIRECTORY BK_DIR AS '&1'
新   1: CREATE OR REPLACE DIRECTORY BK_DIR AS '/home/oracle/bk_dir'

ディレクトリが作成されました。

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

ディレクトリが削除されました。

※1に値を入力してください: に対して、存在しないディレクトリを
指定するとエラー(ORA-39001)になります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/22 11:33 編集

    回答ありがとうございます。
    ユーザー情報をわすれてしまったため、新ユーザーでコメントさせていただきます。
    (yamaha本人です。)

    ログの出力について、解答の通りに書き換え調べたところ、ADD_FILEの処理で
    エラーが発生しているようです。

    デイレクトリの存在確認は、テーブルに存在することと、アクセスが可能であることでよろしいでしょうか?

    nabe3へのコメントの通り、確認しています。
    何か情報が不足していましたら、追記いたします。よろしく願いします。

    キャンセル

  • 2016/02/22 16:03

    ディレクトリの存在確認は、私の実験の結果においてでは、/home/oracle/bk_dir
    が存在していて、oracleユーザで読み込み/書き込みができるようになっているか
    どうかを確認して下さい。

    Linux環境ならば、以下のように確認できます。

    $ ls -l /home/oracle | grep bk_dir
    drwxr-xr-x 2 oracle oinstall 4096 2月 21 22:25 bk_dir


    あと、スクリプトを実行するユーザ(私の実験の結果においてでは scott)
    にcreate any directoryとdrop any directoryシステム権限が付与されて
    いるかどうかも確認して下さい。
    スクリプトを実行するユーザでSQL*Plusで接続後以下のSQLで確認できます。

    $ sqlplus scott/tiger
    SQL> select privilege from user_sys_privs;

    キャンセル

  • 2016/02/22 16:33 編集

    以下をためしてもらえませんか。

    $ sqlplus scott/tiger
    ※SQL*Plusにログインするユーザはscottでなくてもかまいません。

    SQL> CREATE OR REPLACE DIRECTORY BK_DIR AS '/home/oracle/bk_dir';
    ※エラーが発生しないか
    (そちらはWindows環境のようなので、/home/oracle/bk_dirの部分は
     適当に書き換えて下さい。)

    SQL> SELECT GRANTEE,PRIVILEGE FROM USER_TAB_PRIVS WHERE TABLE_NAME='BK_DIR';
    ※以下のような結果になるか
    GRANTEE PRIVILEGE
    ------------------------------ ----------------------------------------
    SCOTT EXECUTE
    SCOTT READ
    SCOTT WRITE


    SET SERVEROUTPUT ON
    DECLARE
    HANDLE NUMBER;
    STEP VARCHAR2(100);
    BEGIN
    STEP := 'OPEN';
    HANDLE:=DBMS_DATAPUMP.OPEN('EXPORT','TABLE');
    STEP := 'ADD_FILE';
    DBMS_DATAPUMP.ADD_FILE(HANDLE,'DEPT.dmp','BK_DIR',NULL,DBMS_DATAPUMP.KU$_FILE_TYPE_DUMP_FILE,1);
    EXCEPTION
    WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE(STEP);
    DBMS_OUTPUT.PUT_LINE(SQLERRM);
    END;
    /
    ※上記スクリプトの実行でエラーにならないか


    SQL> DROP DIRECTORY BK_DIR;

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.55%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる