以下的文章主要是介绍Oracle 10g来批量绑定forall bulk collect的具体方法,我们大家都知道批量绑定一般的情况下是通过减少在PL/SQL与SQL引擎之间的上下文切换(context switches )以此提高性能,批量绑定(Bulk binds)主要包括:
(1) Input collections, use the FORALL statement,用来改善DML(INSERT、UPDATE和DELETE) 操作的性能。
(2) Output collections, use BULK COLLECT clause,用来提高查询(SELECT)的性能。
Oracle 10g开始forall语句可以使用三种方式:
in low..up
in indices of collection 取得集合元素下标的值。
in values of collection 取得集合元素的值。
forall语句还可以使用部分集合元素。
sql%bulk_rowcount(i)表示forall语句第i元素所作用的行数。
--droptableblktest; --CREATETABLEblktest(numNUMBER(20),namevarchar2(50)); --CREATEORREPLACEPROCEDUREp_bulktest IS DECLARE TYPEtype_numISTABLEOFNUMBERINDEXBYBINARY_INTEGER; TYPEtype_nameISTABLEOFVARCHAR2(50)INDEXBYBINARY_INTEGER; tab_numtype_num; tab_nametype_name; t1NUMBER; t2NUMBER; t3NUMBER; BEGIN FORiIN1..500000LOOP tab_num(i):=i; tab_name(i):='name:'||to_char(i); ENDLOOP; SELECTdbms_utility.get_time INTOt1 FROMdual; FORiIN1..500000LOOP INSERTINTOblktest VALUES (tab_num(i),tab_name(i)); ENDLOOP; SELECTdbms_utility.get_time INTOt2 FROMdual; FORALLiIN1..500000 INSERTINTOblktest VALUES (tab_num(i),tab_name(i)); SELECTdbms_utility.get_time INTOt3 FROMdual; dbms_output.put_line('ExecutionTime(S)'); dbms_output.put_line('-------------------'); dbms_output.put_line('FORloop:' ||to_char((t2-t1)/100)); dbms_output.put_line('FORALL: ' ||to_char((t3-t2)/100)); END; /* ExecutionTime(S) FORloop:32.78 FORALL: 2.64 */ /*
bulk collect 语句
用于取得批量数据,只适用于select into ,fetch into 及DML语句的返回子句
DECLARE TYPEtype_empISTABLEOF scott.emp%ROWTYPEINDEXBYBINARY_INTEGER; tab_emptype_emp; TYPEtype_enameISTABLEOF scott.emp.ename%TYPEINDEXBYBINARY_INTEGER; tab_enametype_ename; CURSORcIS SELECT* FROMscott.emp; BEGIN SELECT*BULKCOLLECT INTOtab_emp FROMscott.emp; FORiIN1..tab_emp.COUNTLOOP dbms_output.put_line(tab_emp(i).ename); ENDLOOP; dbms_output.new_line; DELETEscott.empRETURNING enameBULKCOLLECTINTOtab_ename; FORiIN1..tab_emp.COUNTLOOP dbms_output.put_line(tab_emp(i).ename); ENDLOOP; ROLLBACK; OPENc; FETCHcBULKCOLLECT INTOtab_emp; dbms_output.new_line; FORiIN1..tab_emp.COUNTLOOP dbms_output.put_line(tab_emp(i).sal); ENDLOOP; END; */
批量输入FORALL+批量输出BULK
DECLARE,批量输入FORALL+批量输出BULK
TYPEtype_numISTABLEOFNUMBER; tab_1type_num; tab_2type_num; BEGIN tab_1:=type_num(1,2,3); FORALLiIN1..tab_1.COUNT --EXECUTEIMMEDIATE'updatet2setidid2=id*2 whereid=:1returningid2into:2' --USINGtab_1(i)RETURNINGBULKCOLLECTINTOtab_2; updatet2setidid2=id*2whereid=tab_1(i) returningid2bulkcollectintotab_2; FORiIN1..tab_2.COUNTLOOP dbms_output.put_line(tab_2(i)); ENDLOOP; END;