i want to insert the data from 7 views (defintely multiple views, less or more, depends...) into one table with DBMS_PARALLEL_EXECUTE, table structure and view structures are the same.
i am quite new how to handle this package and always facing the same error: variable not in select list, i tried different solutions and ending up with creating a wrapping procuedure dynamically but i do not getting my code to run:
PROCEDURE load_data_as_task (
strLoadTable varchar2,
arrLoadViews arrv
)
AS
strLoadTask varchar2(80);
strLoadView varchar2(80);
stmtWrapperProc clob;
BEGIN
for lv in arrLoadViews.first..arrLoadViews.last loop
-- set task name
strLoadTask := arrLoadViews(lv)||'_task';
-- creating wrapper procedure
stmtWrapperProc := q'[
CREATE OR REPLACE PROCEDURE insert_from_view(p_id number) AS
BEGIN
EXECUTE IMMEDIATE 'INSERT INTO ]'||strLoadTable||q'[ SELECT * FROM ]'||arrLoadViews(lv)||q'[';
END;
]';
execute immediate stmtWrapperProc;
-- create Task
DBMS_PARALLEL_EXECUTE.CREATE_TASK(strLoadTask);
-- create one chunk per load view
DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_SQL(
task_name => strLoadTask,
sql_stmt => 'SELECT ' || to_char(lv) || ' AS view_id FROM dual',
by_rowid => false
);
DBMS_PARALLEL_EXECUTE.RUN_TASK(
task_name => strLoadTask,
sql_stmt => 'BEGIN insert_from_view(:start_id); END;',
--sql_stmt => 'DECLARE dummy NUMBER; BEGIN dummy := :start_id; EXECUTE IMMEDIATE ''INSERT INTO '||strLoadTable||' SELECT * FROM '||arrLoadViews(lv)||'''; END;',
language_flag => DBMS_SQL.NATIVE,
parallel_level => 1
);
end loop;
END;
the procedure is insinde a package, load views and target table already created.
it would be great if anyone can help me to achieve this or maybe know a simpler way to load data from different views in one table parallel (at the same time)
thanks in advance!
for anyone that is facing the same problem, i figured out a solution
if using DBMS_PARALLEL_EXECUTE to insert from a view it is necessary to use the bind variables :start_id and :end_id to create chunks and use it in the insert statement, even for the whole view.
here is a solution to create dummy chunks for each view and run as tasks:
for lv in arrLoadViews.first..arrLoadViews.last loop
-- create Task
DBMS_PARALLEL_EXECUTE.CREATE_TASK(strLoadTask);
-- create one dummy chunk per load view, start_id and end_id must be set
DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_SQL(
task_name => strLoadTask,
sql_stmt => 'SELECT 1 AS start_id, 1 as end_id FROM DUAL',
by_rowid => false
);
-- create insert statement, start_id and end_id must be set as bind variable from dummy chunk
stmtInsert := '
INSERT INTO '||strLoadTable||'
SELECT * FROM '||arrLoadViews(lv)||'
WHERE :start_id = 1 AND :end_id = 1';
DBMS_PARALLEL_EXECUTE.RUN_TASK(
task_name => strLoadTask,
sql_stmt => stmtInsert,
language_flag => DBMS_SQL.NATIVE,
parallel_level => 1
);
end loop;