我正在阅读有关BULK COLLECT和dbms_sql用法的更多内容,并尝试将其应用于我的一个程序 在我的存储过程中,核心逻辑是从另一个表的值
进入表的INSERTCREATE OR replace PROCEDURE My_procedure (pi_date IN DATE,
po_error OUT VARCHAR2,
po_error_desc OUT nocopy VARCHAR2)
AS
curr_date DATE;
BEGIN
CURR_DATE := PI_DATE;
INSERT INTO t1
(col1,
col2,
col3,
col4,
col5)
SELECT t2.col1,
t2.col2,
t2.col3,
t2.col4,
CURR_DATE
EXCEPTION
WHEN OTHERS THEN
PO_ERROR := -1;
PO_ERROR_DESC := 'proc nam : '
|| 'my_procedure'
|| ', err_num :'
|| SQLCODE
|| ' | , err_msg :'
|| SQLERRM;
ROLLBACK;
DBMS_SESSION.free_unused_user_memory;
END;
但是,由于将要插入另一个表的数据很大,我的第二个修改过程
我使用了BULK COLLECT和dbms_sql,如下所示
CREATE OR replace PROCEDURE My_procedure (pi_date DATE,
po_error OUT VARCHAR2,
po_error_desc OUT nocopy VARCHAR2)
AS
v_curr_date DATE;
l_col1 dbms_sql.Varchar2_Table;
l_col2 dbms_sql.Varchar2_Table;
l_col3 dbms_sql.Number_Table;
l_col4 dbms_sql.Number_Table;
CURSOR c1 IS
SELECT *
FROM t2;
BEGIN
V_CURR_DATE := PI_DATE;
PO_ERROR := 0;
OPEN c1;
LOOP
FETCH c1 bulk collect INTO l_col1, l_col2, l_col3, l_col4 limit 1000;
forall indx IN 1..l_col1.COUNT
INSERT INTO t2
(col1,
col2,
col3,
col4,
col5)
VALUES (L_col1(indx),
L_col2(indx),
L_col3(indx),
L_col4(indx),
V_CURR_DATE);
EXCEPTION
WHEN OTHERS THEN
PO_ERROR := -1;
PO_ERROR_DESC := 'proc nam : '
|| 'my_procedure'
|| ', err_num :'
|| SQLCODE
|| ' | , err_msg :'
|| SQLERRM;
ROLLBACK;
DBMS_SESSION.free_unused_user_memory;
END;
所以这是我的第二个例子,我根据文档使用了BULK collect
有人可以指出dbms_sql.Varchar2_Table
的确切用法吗?
如上所示,如果col1的实际长度为VARCHAR2(40),但dbms_sql.Varchar2_Table
使用VARCHAR2(2000)
TYPE varchar2_table IS TABLE OF VARCHAR2(2000) INDEX BY BINARY_INTEGER;
答案 0 :(得分:0)
当你使用LIMIT
子句时,你的批量收集循环需要是一个完整的循环:
-- Open the cursor
OPEN cursor_name;
-- Loop through cursor records
LOOP
-- Fetch the cursor results into a collection limited to a set figure
FETCH cursor_name BULK COLLECT INTO table
LIMIT 1000;
-- For every record in the collection
FORALL x IN INDICES OF table
INSERT INTO target_table
(col)
VALUES
table(x);
-- Set up the limit loop exit criteria
EXIT WHEN table.COUNT < 1000; -- Less that the limit you set
-- End the loop
END LOOP;
-- Close the cursor
CLOSE cursor_name;
此伪代码段应该让您开始使用正确的路径来使批量代码正常工作。您当前对DBMS_SQL
表的声明看起来很好。
希望它有所帮助...