我在java程序中使用以下函数将列从临时表复制到主表。
FUNCTION TEST(TBL_NAME VARCHAR2, TMP_TBL_NAME VARCHAR2, ID_COL VARCHAR2, REQ_COL VARCHAR2, BATCH_SIZE NUMBER) RETURN NUMBER AS
BEGIN
EXECUTE IMMEDIATE 'SELECT COUNT(1) FROM ' || TMP_TBL_NAME INTO TOTAL_RECORDS;
OFFSET := 0;
WHILE OFFSET < TOTAL_RECORDS
LOOP
MAX_RESULTS := OFFSET + BATCH_SIZE;
EXECUTE IMMEDIATE 'SELECT ' || ID_COL || ', ' || REQ_COL || ' FROM ' || TMP_TBL_NAME || ' WHERE SEQ_NBR BETWEEN :OFFSET AND :MAX_RESULTS' BULK COLLECT INTO SEQ_IDS, REQ_COL_VALUESS USING OFFSET, MAX_RESULTS;
FORALL IND IN SEQ_IDS.FIRST .. SEQ_IDS.LAST
EXECUTE IMMEDIATE 'UPDATE ' || TBL_NAME || ' SET ' || REQ_COL || ' = :REQ_COL_VAL WHERE ' || ID_COL || ' = :ID_COL_VAL' USING REQ_COL_VALUESS(IND), SEQ_IDS(IND);
OFFSET := MAX_RESULTS;
COMMIT;
END LOOP;
RETURN 0;
EXCEPTION
WHEN OTHERS THEN
RAISE CUST_EXCEPTION;
END;
预期的结果是当我运行batch_size为100000时,对于每次提交,必须更新100000条记录,因为上面使用的id_col是主键。在运行java程序之后,当我在主表中检查更新时,我可以看到正在更新的批次6469或80148的记录。
临时表中有大约1000万条记录。如果我删除了forall update语句,我将以适当的批量大小迭代数据。
可以澄清一下为什么会发生这种情况
答案 0 :(得分:0)
1)您的临时表中有多少条记录?
2)为什么你不使用sys_refcursor和bulk collect with limit?
declare
v_cursor sys_refcursor;
res1 sys.DBMS_DEBUG_VC2COLL; -- - predefined collection in oracle
res2 sys.DBMS_DEBUG_VC2COLL;
v_batch_size pls_integer := 50;
begin
open v_cursor for 'Select 1,2 from dual connect by level < 10000';
loop
fetch v_cursor bulk collect into res1,res2 limit v_batch_size;
exit when res1.count =0;
dbms_output.put_line(res1.count);
-- forall ind in res1.first .. res1.last loop e.g
-- commit;
end loop;
close v_cursor;
end;
答案 1 :(得分:0)
-- first iteration offset= 0 , max_result = 10
-- v_batch_size = 10
-- offset := 0
-- MAX_RESULTS := 10
select seg from ( Select level seg from dual connect by level < 1000) where seg between 0 and 10;
-- secound iteration
-- v_batch_size = 10
-- offset := 10
-- MAX_RESULTS := 20
select seg from ( Select level seg from dual connect by level < 1000) where seg between 10 and 20;