Oracle資料庫的BULK COLLECT用法之批量增刪改的相關知識是本文我們主要要介紹的內容,FORALL語句的一個關鍵性改進,它可以大大簡化代碼,並且對於那些要在PL/SQL程式中更新很多行資料的程式來說,它可顯著提高其效能。
用FORALL來增強DML的處理能力
Oracle為Oracle8i中的PL/SQL引入了兩個新的資料操縱語言(DML)語句:BULK COLLECT和FORALL。這兩個語句在PL/SQL內部進行一種數組處理;BULK COLLECT提供對資料的高速檢索,FORALL可大大改進INSERT、UPDATE和DELETE操作的效能。Oracle資料庫使用這些語句大大減少了。
PL/SQL與SQL語句執行引擎的環境切換次數,從而使其效能有了顯著提高。使用BULK COLLECT,你可以將多個行引入一個或多個集合中,而不是單獨變數或記錄中。下面這個BULK COLLECT的執行個體是將標題中包含有"PL/SQL"的所有書籍檢索出來共置於記錄的一個關聯陣列中,它們都位於通向該資料庫的單一通道中。
類似地,FORALL將資料從一個PL/SQL集合傳送給指定的使用集合的表。
BULK COLLECT和FORALL都非常有用,它們不僅提高了效能,而且還簡化了為PL/SQL中的SQL操作所編寫的代碼。
create or replace function f_test_bluk_collection return number is /* --test bluk collection limit TYPE prod_tab IS TABLE OF products%ROWTYPE; products_tab prod_tab := prod_tab(); start_time number; end_time number; CURSOR products_data IS SELECT * FROM products; BEGIN Start_time := DBMS_UTILITY.get_time; OPEN products_data; LOOP FETCH products_data BULK COLLECT INTO products_tab LIMIT 10000; EXIT WHEN products_data%NOTFOUND; DBMS_OUTPUT.PUT_LINE('Processed ' || to_char(products_tab.count) || ' rows'); END LOOP; CLOSE products_data; end_time := DBMS_UTILITY.get_time; DBMS_OUTPUT.PUT_LINE('Bulk Collect: ' || to_char(end_time - start_time)); */ --test forall TYPE prod_tab IS TABLE OF products%ROWTYPE; products_tab prod_tab := prod_tab(); start_time number; end_time number;BEGIN -- Populate a collection - 100000 rows SELECT * BULK COLLECT INTO products_tab FROM products; EXECUTE IMMEDIATE 'TRUNCATE TABLE products'; Start_time := DBMS_UTILITY.get_time; FOR i in products_tab.first .. products_tab.last LOOP INSERT INTO products (product_id, product_name, effective_date) VALUES (products_tab(i).product_id, products_tab(i).product_name, products_tab(i).effective_date); END LOOP; end_time := DBMS_UTILITY.get_time; DBMS_OUTPUT.PUT_LINE('Conventional Insert:' || to_char(end_time - start_time)); EXECUTE IMMEDIATE 'TRUNCATE TABLE products'; Start_time := DBMS_UTILITY.get_time; FORALL i in products_tab.first .. products_tab.last INSERT INTO products VALUES products_tab (i); end_time := DBMS_UTILITY.get_time; DBMS_OUTPUT.PUT_LINE('Bulk Insert :' || to_char(end_time - start_time)); commit; return 0;end f_test_bluk_collection;