我想從一個表中獲取大約6百萬行並將其插入到另一個表中。 我如何使用批量收集和提交?如何使用批量收集並插入到Pl/SQl
回答
CREATE OR REPLACE PROCEDURE fast_way IS
TYPE PartNum IS TABLE OF parent.part_num%TYPE
INDEX BY BINARY_INTEGER;
pnum_t PartNum;
TYPE PartName IS TABLE OF parent.part_name%TYPE
INDEX BY BINARY_INTEGER;
pnam_t PartName;
BEGIN
SELECT part_num, part_name
BULK COLLECT INTO pnum_t, pnam_t
FROM parent;
FOR i IN pnum_t.FIRST .. pnum_t.LAST
LOOP
pnum_t(i) := pnum_t(i) * 10;
END LOOP;
FORALL i IN pnum_t.FIRST .. pnum_t.LAST
INSERT INTO child
(part_num, part_name)
VALUES
(pnum_t(i), pnam_t(i));
COMMIT;
END
批量收集大記錄數量和沒有限制設置可以導致內存不足問題 – Sathya
declare
-- define array type of the new table
TYPE new_table_array_type IS TABLE OF NEW_TABLE%ROWTYPE INDEX BY BINARY_INTEGER;
-- define array object of new table
new_table_array_object new_table_array_type;
-- fetch size on bulk operation, scale the value to tweak
-- performance optimization over IO and memory usage
fetch_size NUMBER := 5000;
-- define select statment of old table
-- select desiered columns of OLD_TABLE to be filled in NEW_TABLE
CURSOR old_table_cursor IS
select * from OLD_TABLE;
BEGIN
OPEN old_table_cursor;
loop
-- bulk fetch(read) operation
FETCH old_table_cursor BULK COLLECT
INTO new_table_array_object LIMIT fetch_size;
EXIT WHEN old_table_cursor%NOTFOUND;
-- do your business logic here (if any)
-- FOR i IN 1 .. new_table_array_object.COUNT LOOP
-- new_table_array_object(i).some_column := 'HELLO PLSQL';
-- END LOOP;
-- bulk Insert operation
FORALL i IN INDICES OF new_table_array_object SAVE EXCEPTIONS
INSERT INTO NEW_TABLE VALUES new_table_array_object(i);
COMMIT;
END LOOP;
CLOSE old_table_cursor;
End;
希望這有助於。
不錯。 'COMMIT'的批量大小爲'fetch_size'。另外,你可以把'EXIT WHEN',立即移到'FETCH'嗎? –
是的,EXIT WHEN可能在FETCH後立即(當前的語法只是我的習慣:),我在FORALL之後設置了COMMITE以防止創建一個大的redolog。感謝您的評論。 –
請注意,您應該'退出時,new_table_array_object.COUNT = 0'而不是'退出時,old_table_cursor%NOTFOUND',所以你不會錯過任何行(見http://www.oracle.com/technetwork/issue-archive/2008 /08-mar/o28plsql-095155.html) – LPrc
SQL引擎解析並執行SQL語句,但在某些情況下會將數據返回到PL/SQL引擎。
在執行PL/SQL語句期間,每個SQL語句都會在兩個引擎之間導致上下文切換。當PL/SQL引擎找到SQL語句時,它停止並將控制權交給SQL引擎。 SQL引擎執行該語句並返回到PL/SQL引擎中的數據。這種控制轉移是調用上下文切換。通常PL/SQL引擎之間的切換非常快,但是上下文切換執行時間很大,從而影響性能。 SQL引擎檢索所有行並將它們加載到集合中並切換回PL/SQL引擎。使用批量收集多行可以通過單個上下文切換獲取。
舉例:1
DECLARE
Type stcode_Tab IS TABLE OF demo_bulk_collect.storycode%TYPE;
Type category_Tab IS TABLE OF demo_bulk_collect.category%TYPE;
s_code stcode_Tab;
cat_tab category_Tab;
Start_Time NUMBER;
End_Time NUMBER;
CURSOR c1 IS
select storycode,category from DEMO_BULK_COLLECT;
BEGIN
Start_Time:= DBMS_UTILITY.GET_TIME;
FOR rec in c1
LOOP
NULL;
--insert into bulk_collect_a values(rec.storycode,rec.category);
END LOOP;
End_Time:= DBMS_UTILITY.GET_TIME;
DBMS_OUTPUT.PUT_LINE('Time for Standard Fetch :-' ||(End_Time-Start_Time) ||' Sec');
Start_Time:= DBMS_UTILITY.GET_TIME;
Open c1;
FETCH c1 BULK COLLECT INTO s_code,cat_tab;
Close c1;
FOR x in s_code.FIRST..s_code.LAST
LOOP
null;
END LOOP;
End_Time:= DBMS_UTILITY.GET_TIME;
DBMS_OUTPUT.PUT_LINE('Using Bulk collect fetch time :-' ||(End_Time-Start_Time) ||' Sec');
END;
- 1. 使用批量收集的PLSQL集合
- 2. PLSQL - 批量收集的最大限制?
- 3. PLSQL通過1-N表的連接批量收集到UDT中?
- 4. 如何使用遊標插入到嵌套表集合plsql
- 5. PLSQL變量插入
- 6. 如何在具有動態值的mysql中使用PLSQL插入批量數據
- 7. 如何使用Redis批量插入?
- 8. 如何批量插入使用SubSonic?
- 9. 關於PLSQL批量收集和嵌套表
- 10. sqlite併發批量插入
- 11. 使用Neo4j批量插入
- 12. 使用SQlite批量插入
- 13. 批量插入/使用Hibernate
- 14. 使用EF4.2批量插入
- 15. 批量插入使用SQL
- 16. 使用SQLAlchemy批量插入
- 17. 批量插入使用ContinueOnError
- 18. 使用PHP批量插入
- 19. 如何批量插入?
- 20. 使用「for update」進行批量收集
- 21. 甲骨文批量收集腳本插入數據
- 22. 使用批量收集將數據追加到表變量
- 23. 批量/批量插入R
- 24. 如何使用node.js將數據批量插入到SQL Server中
- 25. 如何使用Python將批量數據插入到Neo4j中
- 26. 如何使用C批量插入到MySQL#
- 27. 批量插入到mysql
- 28. PHPexcel批量插入到mysql
- 29. 批量插入到表
- 30. 在PLSQL中批量插入而不是循環?
我建議不要在所有使用遊標。性能上簡單的'insert ... into ... select ... from'會更高效。而且你還應該發佈一些代碼,展示你的嘗試以及你面臨的具體問題。 –
簡單 - 'CREATE TABLE new_tbl_with_6m_rec AS SELECT * FROM old_tbl_with_6m_rec WHERE whatever_conditions;' – Rachcha