嗨朋友们正在编写一个存储过程,选择并将数据从一个表插入到同一数据库中的另一个表但是不同的用户,以加快插入尝试使用批量收集和forall但问题是我正在使用动态SQL在选择表名的过程中,它是相应的主键名和来自另一个状态表的日期验证列
例如:考虑以下查询
Select empid from emp_tab where trunc(insert_time)=trunc(sysdate)
此处 PRIMARY KEY - empid
, TABLENAME - emp_tab
,日期验证列 - {{1在过程的运行时从另一个状态表中过程将动态选择过程但是我无法将insert_time
和bulk collect
合并到动态SQL中forall
正在获取
不一致的数据类型
错误,bulk collect
正在
虚拟列
错误
forall
和bulk
是否支持动态sql ????
如果没有,那么还有其他方法可以加快像forall
欢迎任何建议 提前致谢
答案 0 :(得分:0)
是的,他们这样做。尽管BULK COLLECT
是一个强大的工具,但它的所有限制可能会很棘手。以下是使用REF CURSOR
的示例,但您可以根据需要构建TYPES
。
-- create source data
CREATE TABLE temp_table_source AS
(SELECT ROWNUM id,
dbms_random.String('U', 10) name,
Round(dbms_random.Value(1, 7000)) salary
FROM dual
CONNECT BY LEVEL <= 5000 -- number of rows for the test
);
-- create destination table (empty)
CREATE TABLE temp_table_dest AS
SELECT * FROM temp_table_source WHERE 1 = 2;
-- Dynamic bulk anonymous block
DECLARE
v_stmt VARCHAR2(100);
v_insert VARCHAR2(100);
TYPE rec_source IS RECORD ( -- a type to represent your data
id temp_table_source.id%TYPE,
name temp_table_source.name%TYPE,
salary temp_table_source.salary%TYPE
);
TYPE t_source IS TABLE OF rec_source;
m_source t_source;
TYPE l_cursor_type IS REF CURSOR;
l_cursor l_cursor_type;
BEGIN
v_stmt := 'SELECT * FROM temp_table_source where 1 = :x';
v_insert := 'INSERT INTO temp_table_dest (id, name, salary) VALUES (:a, :b, :c)';
OPEN l_cursor FOR v_stmt USING 1; -- example of filtering
LOOP -- use limits to test performance, but the LOOP is optional
FETCH l_cursor BULK COLLECT INTO m_source LIMIT 1000;
--
FORALL i IN 1 .. m_source.COUNT
EXECUTE IMMEDIATE v_insert
USING m_source(i).id, m_source(i).name, m_source(i).salary;
--
COMMIT;
EXIT WHEN m_source.COUNT = 0;
END LOOP;
END;
/
-- See the result
Select count(1) from temp_table_dest;
如果您还需要动态TYPE
,则需要创建它并在程序结束时删除,而不是在包中声明它。