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

时间:2016-02-19 20:46:01

标签: oracle plsql parallel-processing query-optimization

我正在使用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 个答案:

答案 0 :(得分:0)

请注意确定为什么要get_rowid_chunk, set_chunk_status等。我会by_row => TRUE使用create_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;
/