简体   繁体   English

Oracle Datapump导出错误“无效的参数值”

[英]Oracle datapump export error “invalid argument value”

I have a datapump export script which I'd like to get running. 我有一个想要运行的datapump导出脚本。 The DB is Oracle 11g. 该数据库是Oracle 11g。 To try it out, I've been executing it in SQLDeveloper. 要尝试,我一直在SQLDeveloper中执行它。 The script looks like this: 该脚本如下所示:

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;

The trouble is that I get an error which I cannot explain and I have no idea how to track it down. 问题是我遇到了我无法解释的错误,也不知道如何找到它。 The error message is: 错误消息是:

Error report: 错误报告:

ORA-39001: invalid argument value ORA-39001:无效的参数值

ORA-06512: at "SYS.DBMS_SYS_ERROR", line 79 ORA-06512:位于“ SYS.DBMS_SYS_ERROR”行79

ORA-06512: at "SYS.DBMS_DATAPUMP", line 3507 ORA-06512:位于“ SYS.DBMS_DATAPUMP”行3507

ORA-06512: at "SYS.DBMS_DATAPUMP", line 3756 ORA-06512:位于“ SYS.DBMS_DATAPUMP”行3756

ORA-06512: at line 18 ORA-06512:在第18行

  1. 00000 - "invalid argument value" 00000-“无效的参数值”

*Cause: The user specified API parameters were of the wrong type or *原因:用户指定的API参数类型错误或

value range. 值范围。 Subsequent messages supplied by 由以下人员提供的后续消息

DBMS_DATAPUMP.GET_STATUS will further describe the error. DBMS_DATAPUMP.GET_STATUS将进一步描述该错误。

*Action: Correct the bad argument and retry the API. *操作:更正错误的参数并重试API。

The important part here is the "ORA-06512: at line 18". 这里的重要部分是“ ORA-06512:第18行”。 This points to the first ADD_FILE statement. 这指向第一个ADD_FILE语句。 After scouring the Internet Oracle documentation regarding the datapump, I am at a loss as to what is supposed to be wrong. 在搜索有关数据泵的Internet Oracle文档之后,我对应该出错的地方一无所知。 I also can't figure out how to use DBMS_DATAPUMP.GET_STATUS when the job doesn't even get defined, let alone run. 当作业甚至没有定义时,我也想不出如何使用DBMS_DATAPUMP.GET_STATUS ,更不用说运行了。

I've tried not using the reusefile parameter and I've tried replacing DBMS_DATAPUMP.KU$_FILE_TYPE_DUMP_FILE with the actual integer value it represents, which is 1. 我尝试不使用复用reusefile参数,并尝试将DBMS_DATAPUMP.KU$_FILE_TYPE_DUMP_FILE替换DBMS_DATAPUMP.KU$_FILE_TYPE_DUMP_FILE表示的实际整数值,即1。

Running this in SQLDeveloper leaves an entry floating around in dba_datapump_jobs, which isn't all that simple to get rid of. 在SQLDeveloper中运行它会在dba_datapump_jobs中留下一个浮动的条目,要摆脱它并不是那么简单。 The state of the job is "DEFINING". 作业的状态为“定义”。 This prevents me running the script a second time. 这样可以防止我第二次运行脚本。 After searching for around an hour I found out that it could be removed with DROP TABLE "TMF"."TST TMF.ACHIMSTEST11" PURGE , though why that works is a mystery. 搜索了大约一个小时后,我发现可以使用DROP TABLE "TMF"."TST TMF.ACHIMSTEST11" PURGE删除它,但是为什么这样做仍然是个谜。

I guess I should point out that I did not write this script, it was generated from a FreeMarker template in a Java program. 我想我应该指出,我没有编写此脚本,它是从Java程序中的FreeMarker模板生成的。 In the Java program the generated script is run as an OracleCallableStatement and for 11g databases that works. 在Java程序中,生成的脚本作为OracleCallableStatement运行,并适用于11g数据库。 The only reason I'm fiddling with it in SQLDeveloper is to try to get it to work for a 12c database. 我在SQLDeveloper中摆弄它的唯一原因是试图使它适用于12c数据库。 Needless to say the script doesn't work for 12c in SQLDeveoper either. 不用说该脚本对于SQLDeveoper中的12c也不起作用。 I'd kind of hoped it would work for 11g. 我有点希望它能适用于11g。

Incidentally, the error I get when running the Java with a 12c database is the same one as shown above. 顺便说一句,运行带有12c数据库的Java时遇到的错误与上面显示的相同。

If anyone can see anything that is actually wrong or even just looks suspect, I'd be very grateful for the advice. 如果有人看到任何错误或什至只是可疑的东西,我将不胜感激。

I also can't figure out how to use DBMS_DATAPUMP.GET_STATUS when the job doesn't even get defined, let alone run. 当作业甚至没有定义时,我也想不出如何使用DBMS_DATAPUMP.GET_STATUS,更不用说运行了。

The job is defined, you have a handle by the time you call add_file . 作业已定义,在调用add_file时便有了一个句柄。 SO you can add an exception handler to call get_status and output the results (after doing set serveroutput on of course): 因此,您可以添加一个异常处理程序来调用get_status并输出结果(当然set serveroutput onset serveroutput on进行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;
/

(Yes, I know when others is bad, even when re-raising, but this is a temporary thing...) (是的,我知道when others不好的时候,甚至是重新筹款的时候,但这只是暂时的事情...)

Given what you've shown and the call that's erroring, I expect that will show something like: 鉴于您所显示的内容以及发生错误的呼叫,我希望它将显示如下内容:

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

Presumably when this is run as a callable statement it uses a different path for the directory object. 大概当它作为可调用语句运行时,它将为目录对象使用不同的路径。 Or doesn't include the create/drop at all, which you wouldn't normally do at run-time. 或者根本不包含创建/删除操作,通常您在运行时不会这样做。 The 12c version either doesn't have the directory defined, or if it's on a different server the path being used isn't valid there. 12c版本没有定义目录,或者如果它在其他服务器上,则所使用的路径在那里无效。 Or, perhaps, is RAC and is only valid on one node, which might make the error intermittent. 或者,也许是RAC,并且仅在一个节点上有效,这可能会使错误断断续续。

In what you've shown though, the /home/achim part looks suspect. 在您所显示的内容中, /home/achim部分看起来很可疑。 The Oracle process owner - usually oracle - has to be able to read and write files in the operating system directory, and unless you've opened your home directory up for whole world to see, you're probably getting a failure because oracle cannot create the dump file where you asked it to. Oracle进程的所有者(通常是oracle必须能够在操作系统目录中读写文件,除非您打开主目录以供全世界查看,否则您可能会失败,因为oracle无法创建您要求的转储文件。

If that is the case then change the directory path to point to somewhere you are sure oracle does have the necessary permissions; 如果是这种情况,则将目录路径更改为指向某个位置,以确保oracle确实具有必要的权限; if you have access to that account, try to create a file manually from the command line to verify. 如果您有权访问该帐户,请尝试从命令行手动创建文件以进行验证。 If not you you'll just need to check the permissions on the operating system directory and its hierarchy carefully. 如果不是,则只需要仔细检查操作系统目录及其层次结构上的权限即可。

You might see a different error of course, but it looks like it has to be something related to the directory or file, not the other arguments. 当然,您可能会看到一个不同的错误,但是看起来它必须与目录或文件相关,而不是其他参数。

Also, for removing orphan jobs, see My Oracle Support document 336014.1. 另外,有关删除孤立作业的信息,请参见My Oracle Support文档336014.1。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM