Oracle 数据泵导出错误 "invalid argument value"

Oracle datapump export error "invalid argument value"

我有一个数据泵导出脚本,我想要 运行ning。数据库是 Oracle 11g。为了尝试一下,我一直在 SQLDeveloper 中执行它。脚本如下所示:

DECLARE  
     JOBHANDLE   NUMBER;
     STATUS      VARCHAR2(20);
     LOGFILE     UTL_FILE.FILE_TYPE; 
     LINE        VARCHAR2(200); 
     ROW         NUMBER := 1; 
 
     TYPE OUTPUT_TYPE IS TABLE OF VARCHAR2(128) INDEX BY PLS_INTEGER;
     OUTPUT      OUTPUT_TYPE;
 BEGIN
     EXECUTE IMMEDIATE 'CREATE OR REPLACE DIRECTORY "TESTDIR11" AS ''/home/achim/temp/0003759/T0987654321/'' ';
 
     JOBHANDLE := DBMS_DATAPUMP.OPEN(
         operation => 'EXPORT',
         job_mode  => 'TABLE',
         job_name  => 'TST TMF.ACHIMSTEST11');
  
     DBMS_DATAPUMP.ADD_FILE(
         HANDLE    => JOBHANDLE,
         filename  => 'Q01DED3D.dmp',
         directory => 'TESTDIR11',
         filetype  => DBMS_DATAPUMP.KU$_FILE_TYPE_DUMP_FILE
         ,reusefile => 1
         );
  
     DBMS_DATAPUMP.ADD_FILE(
         HANDLE    => JOBHANDLE,
         filename  => 'Q01DED3D.log',
         directory => 'TESTDIR11',
         filetype  => DBMS_DATAPUMP.KU$_FILE_TYPE_LOG_FILE
         ,reusefile => 1
         );
 
     BEGIN
         DBMS_DATAPUMP.SET_PARAMETER(
                 handle => JOBHANDLE,
                 name   => 'INCLUDE_METADATA',
                 value  => 0);
 
         DBMS_DATAPUMP.METADATA_FILTER(
                 HANDLE      => JOBHANDLE, 
                 name        => 'NAME_LIST', 
                 value       => '''ACHIMSTEST11''',
                 object_path => 'TABLE');
 
         DBMS_DATAPUMP.METADATA_FILTER(
                 HANDLE  => JOBHANDLE, 
                 name    => 'SCHEMA_LIST', 
                 value   => '''TMF''');
 
         DBMS_DATAPUMP.START_JOB(JOBHANDLE);
         DBMS_DATAPUMP.WAIT_FOR_JOB(JOBHANDLE, STATUS);
     EXCEPTION
         WHEN OTHERS 
         THEN
             status := 'ERROR'; 
     END;
 
     DBMS_DATAPUMP.DETACH(JOBHANDLE); 
 
     LOGFILE := UTL_FILE.FOPEN('TESTDIR', 'Q01DED3D.log', 'R'); 
     Loop BEGIN
         UTL_FILE.GET_LINE(LOGFILE, LINE);
         OUTPUT(ROW) := LINE; 
         ROW := ROW + 1;
     EXCEPTION 
         WHEN No_Data_Found 
         THEN 
             EXIT; 
         END;
     END Loop; 
 
     EXECUTE IMMEDIATE 'DROP DIRECTORY "TESTDIR"';
 
 END;

问题是我遇到了一个无法解释的错误,而且我也不知道如何找到它。错误信息是:

Error report:

ORA-39001: invalid argument value

ORA-06512: at "SYS.DBMS_SYS_ERROR", line 79

ORA-06512: at "SYS.DBMS_DATAPUMP", line 3507

ORA-06512: at "SYS.DBMS_DATAPUMP", line 3756

ORA-06512: at line 18

  1. 00000 - "invalid argument value"

*Cause: The user specified API parameters were of the wrong type or

value range. Subsequent messages supplied by

DBMS_DATAPUMP.GET_STATUS will further describe the error.

*Action: Correct the bad argument and retry the API.

这里的重要部分是“ORA-06512:第 18 行”。这指向第一个 ADD_FILE 语句。在搜索了有关数据泵的 Internet Oracle 文档之后,我不知道哪里出了问题。我也不知道如何使用 DBMS_DATAPUMP.GET_STATUS 当工作甚至没有被定义时,更不用说 运行.

我试过不使用 reusefile 参数,我试过将 DBMS_DATAPUMP.KU$_FILE_TYPE_DUMP_FILE 替换为它代表的实际整数值,即 1。

运行 SQLDeveloper 中的这个在 dba_datapump_jobs 中留下了一个浮动的条目,要删除它并不是那么简单。作业的状态是“DEFINING”。这使我无法 运行 第二次使用脚本。搜索了大约一个小时后,我发现可以使用 DROP TABLE "TMF"."TST TMF.ACHIMSTEST11" PURGE 将其删除,但为什么会这样仍然是个谜。

我想我应该指出这个脚本不是我写的,它是从 Java 程序中的 FreeMarker 模板生成的。在 Java 程序中,生成的脚本是 运行 作为 OracleCallableStatement 并且适用于 11g 数据库。我在 SQLDeveloper 中摆弄它的唯一原因是试图让它为 12c 数据库工作。不用说,该脚本也不适用于 SQLDeveoper 中的 12c。我有点希望它适用于 11g。

顺便说一句,当 运行 使用 12c 数据库连接 Java 时,我得到的错误与上面显示的相同。

如果有人能看出任何实际错误或看起来可疑的地方,我将非常感谢您的建议。

I also can't figure out how to use DBMS_DATAPUMP.GET_STATUS when the job doesn't even get defined, let alone run.

作业已定义,调用时您已获得句柄 add_file。所以你可以添加一个异常处理程序来调用 get_status 并输出结果(当然是在 set serveroutput on 之后):

...
EXCEPTION
  WHEN OTHERS THEN
    DECLARE
      job_state varchar2(4000);
      status ku$_Status;
    BEGIN
      DBMS_DATAPUMP.GET_STATUS(
        handle    => jobhandle,
        mask      => dbms_datapump.KU$_STATUS_JOB_ERROR,
        timeout   => null,
        job_state => job_state,
        status    => status);

    FOR I IN 1..status.error.COUNT LOOP
      DBMS_OUTPUT.PUT_LINE(status.error(I).errornumber || ': ' || status.error(I).logtext);
    END LOOP;
  END;

  RAISE;
END;
/

(是的,我知道 when others 不好,即使在重新加注时也是如此,但这是暂时的...)

鉴于您所展示的内容和出错的调用,我希望它会显示如下内容:

ORA-39001: invalid argument value
ORA-39000: bad dump file specification
ORA-31641: unable to create dump file "/home/achim/temp/0003759/T0987654321/Q01DED3D.dmp"
ORA-27040: file create error, unable to create file
Linux-x86_64 Error: 2: No such file or directory
Additional information: 1
ORA-27037: unable to obtain file status
Linux-x86_64 Error: 2: No such file or directory
Additional information: 3

大概当这是 运行 作为可调用语句时,它使用目录对象的不同路径。或者根本不包括 create/drop,而您通常不会在 运行 时这样做。 12c 版本没有定义目录,或者如果它在不同的服务器上,则使用的路径在那里无效。或者,也许是 RAC,并且仅在一个节点上有效,这可能会使错误间歇性发生。

不过,在您展示的内容中,/home/achim 部分看起来很可疑。 Oracle 进程所有者 - 通常 oracle - 必须能够在操作系统目录中读取和写入文件,除非你已经打开你的主目录让全世界都看到,否则你可能会失败因为 oracle 无法在您要求的位置创建转储文件。

如果是这种情况,请将目录路径更改为指向您确定 oracle 确实具有必要权限的某个地方;如果您有权访问该帐户,请尝试从命令行手动创建一个文件以进行验证。如果不是,您只需要仔细检查操作系统目录及其层次结构的权限。

您当然可能会看到不同的错误,但看起来它必须与目录或文件相关,而不是其他参数。

此外,要删除孤立作业,请参阅 My Oracle Support 文档 336014.1。