Oracle 批量收集和dbms_sql的使用
我阅读了更多关于dbms_sql的批量收集和使用的内容,并尝试将其应用于我的一个过程 在我的存储过程中,核心逻辑是从另一个表的值插入到一个表中Oracle 批量收集和dbms_sql的使用,oracle,oracle11g,Oracle,Oracle11g,我阅读了更多关于dbms_sql的批量收集和使用的内容,并尝试将其应用于我的一个过程 在我的存储过程中,核心逻辑是从另一个表的值插入到一个表中 CREATE OR replace PROCEDURE My_procedure (pi_date IN DATE, po_error OUT VARCHAR2, p
CREATE 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;
然而,由于要插入到另一个表中的数据是巨大的,在我的第二个修改过程中
我使用了批量收集和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;
所以这里是我的第二个例子,我已经按照文档使用了批量收集
有人能指出dbms\u sql.Varchar2\u Table
的确切用法吗
如上所示,如果col1的实际长度是VARCHAR2(40),但是dbms\u sql。VARCHAR2\u表使用VARCHAR2(2000)
当您使用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;
——打开光标
打开游标名称;
--循环浏览游标记录
环
--将光标结果提取到限制在设定图形范围内的集合中
将游标\u名称批量收集到表中
限1000;
--对于集合中的每个记录
表的索引中的所有x
插入到目标_表中
(col)
价值观
表(x);
--设置限制循环退出条件
当table.COUNT<1000时退出;--低于你设定的限制
--结束循环
端环;
--关闭光标
关闭光标和名称;
这个伪代码片段应该可以帮助您找到正确的路径,让批量代码正常工作。您当前对DBMS\u SQL
表的声明看起来不错
希望能有帮助……你的确切问题是什么?您提供的代码充满语法错误。您应该提供您正在使用的确切来源,并提及您遇到的问题。我的问题是,我在第二个示例中使用的方法,即使用批量收集并使用dbms_sql插入到另一个表中,是否正确。希望这是好的。谢谢我关于dbms_sql的问题如上所示,如果col1的实际长度是VARCHAR2(40),但是dbms_sql.VARCHAR2_表使用VARCHAR2(2000),并且根据oracle文档,VARCHAR2_表是类型VARCHAR2_表是VARCHAR2(2000)的表,通过二进制_整数进行索引;那么,当实际长度为40时,为什么要使用2000空格呢?它是一个方便的构造函数,可以快速有效地使用包含VARCHAR2
值的表。如果您真的担心VARCHAR2(2000)数组使用的额外字节,请创建自己的集合,最大长度为40TYPE array_40_chartype是由二进制_整数组成的VARCHAR2(40)索引表
然后使用以下类型声明一个表:array\u 40\u char array\u 40\u chartype代码>瞧。感谢Ollie在您的示例中将游标\u名称批量收集到表中,这里的表是一种收集类型,对吗?是的。这是一个收藏。我通常使用关联数组进行批量收集。
-- 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;