ORA-29494: DBMS_PARALLEL_EXECUTE 运行任务错误的无效状态

Posted

技术标签:

【中文标题】ORA-29494: DBMS_PARALLEL_EXECUTE 运行任务错误的无效状态【英文标题】:ORA-29494: invalid state for run task error with DBMS_PARALLEL_EXECUTE 【发布时间】:2016-02-19 20:46:01 【问题描述】:

我正在使用 DBMS_PARALLEL_EXECUTE 运行 PL/SQL 过程。我遇到了 ORA-29494:运行任务错误的无效状态。我的代码如下:

以下是 DBMS_OUTPUT 语句的示例输出:

加工 5743 加工 5744

当我使用来自 user_parallel_execute_chunks 的输入 rowid 单独运行创建任务、块任务和运行任务时,它适用于单个块。同样没有循环,任务对所有块运行,并以错误提示 chunk_not_found 结束。为了处理这个问题,我使用了循环,但我无法让它工作

CREATE OR REPLACE PROCEDURE code_parse_wrapper AS
l_sql_stmt VARCHAR2(32767);
l_chunk_id NUMBER;
l_start_rowid ROWID;
l_end_rowid ROWID;
l_any_rows BOOLEAN;
l_try NUMBER;
l_status NUMBER;
l_stmt CLOB;
V_CHUNK_ID NUMBER;
V_STATUS VARCHAR2(30);
BEGIN
BEGIN

dbms_parallel_execute.drop_task(task_name => 'parallel_processing');
DBMS_OUTPUT.PUT_LINE('TASK DROPPED');
END;    
BEGIN
dbms_parallel_execute.create_task(task_name => 'parallel_processing');
DBMS_OUTPUT.PUT_LINE('TASK CREATED');
END;


-- Create Chunks

BEGIN
dbms_parallel_execute.create_chunks_by_rowid
(
    'parallel_processing',
    'SchemaName',
    'ORDER_DETAIL',
    FALSE,
    50000
); 
END;

BEGIN   
LOOP
    dbms_parallel_execute.get_rowid_chunk
    (
        task_name => 'parallel_processing',
        chunk_id => l_chunk_id,
        start_rowid => l_start_rowid,
        end_rowid => l_end_rowid,
        any_rows => l_any_rows
    );
  select STATUS INTO V_STATUS from user_parallel_execute_tasks where task_name =  'parallel_processing';
    DBMS_OUTPUT.PUT_LINE(V_STATUS);

    l_sql_stmt := ' begin CODE_PARSE6_AK( :start_id, :end_id ); end;';
    DBMS_OUTPUT.PUT_LINE(l_chunk_id);
--    DBMS_OUTPUT.PUT_LINE(l_sql_stmt);
 IF (l_any_rows = false) THEN 
 EXIT;
  END IF;   

BEGIN
    -- Get next unassigned chunk.
    --  EXECUTE IMMEDIATE 'l_sql_stmt USING l_start_rowid, l_end_rowid'; 

        dbms_parallel_execute.run_task('parallel_processing',
                                                     l_sql_stmt,
                                                     DBMS_SQL.NATIVE,
                                                    parallel_level => 10
                                                  );

                                                  l_try := 0;
 l_status := dbms_parallel_execute.task_status('parallel_processing');

 WHILE(l_try < 2 and l_status != dbms_parallel_execute.finished)     LOOP
             l_try := l_try + 1;
             dbms_parallel_execute.resume_task('parallel_processing');
             l_status :=    dbms_parallel_execute.task_status('parallel_processing'); 


    dbms_parallel_execute.set_chunk_status
        (
            task_name => 'parallel_processing',
            chunk_id => l_chunk_id,
            status => dbms_parallel_execute.processed
        ); 

        END LOOP;

    EXCEPTION

        WHEN OTHERS THEN
            -- Record chunk error.
            dbms_parallel_execute.set_chunk_status
            (
                task_name => 'parallel_processing',
                chunk_id => l_chunk_id,
                status => dbms_parallel_execute.processed_with_error,
                err_num => SQLCODE,
                err_msg => SQLERRM
            );
            END;

 COMMIT;

END LOOP;
END;


END;

【问题讨论】:

【参考方案1】:

请注意为什么要使用get_rowid_chunk, set_chunk_status 等。我会使用by_row =&gt; TRUEcreate_chunks_by_rowid

我认为,您可以在这里使用更简单、更简洁的代码......我已经使用它多年,没有任何问题。可以通过更改 l_sql_stmt 中的 DML 来重用它。

DECLARE
  l_task     VARCHAR2(30) := 'parallel_processing';
  l_sql_stmt VARCHAR2(32767);
  l_try      NUMBER;
  l_status   NUMBER;
BEGIN
  DBMS_PARALLEL_EXECUTE.create_task (task_name => l_task);

  DBMS_PARALLEL_EXECUTE.create_chunks_by_rowid(task_name   => l_task,
                                               table_owner => 'SCHEMANAME',
                                               table_name  => 'ORDER_DETAIL',
                                               by_row      => TRUE,
                                               chunk_size  => 10000);

  l_sql_stmt := 'begin CODE_PARSE6_AK( :start_id, :end_id ); end;';

  DBMS_PARALLEL_EXECUTE.run_task(task_name      => l_task,
                                 sql_stmt       => l_sql_stmt,
                                 language_flag  => DBMS_SQL.NATIVE,
                                 parallel_level => 10);

  -- If there is error, RESUME it for at most 2 times.
  l_try := 0;
  l_status := DBMS_PARALLEL_EXECUTE.task_status(l_task);
  WHILE(l_try < 2 and l_status != DBMS_PARALLEL_EXECUTE.FINISHED) 
  Loop
    l_try := l_try + 1;
    DBMS_PARALLEL_EXECUTE.resume_task(l_task);
    l_status := DBMS_PARALLEL_EXECUTE.task_status(l_task);
  END LOOP;

  DBMS_PARALLEL_EXECUTE.drop_task(l_task);
END;
/

【讨论】:

以上是关于ORA-29494: DBMS_PARALLEL_EXECUTE 运行任务错误的无效状态的主要内容,如果未能解决你的问题,请参考以下文章

简易先进先出队列-自用

函数参数

多重背包

合租房合同模板

启动代码分析 02

ACM数论 求幂乘