隨筆-314  評論-209  文章-0  trackbacks-0

          這段代碼同樣是執(zhí)行了1000條insert語句,但是每一條語句都是不同的,因此ORACLE會把每條語句硬解析一次,其效率就比前面那段就低得多了。如果要提高效率,不妨使用綁定變量將循環(huán)中的語句改為

                sqlstr:='insert into 測試表 (:i,:i+1,:i*1,:i*2,:i-1) ';

                execute immediate sqlstr using i,i,i,i,i;

          這樣執(zhí)行的效率就高得多了。

          我曾試著使用綁定變量來代替表名、過程名、字段名等,結(jié)果是語句錯誤,結(jié)論就是綁定變量不能當(dāng)作嵌入的字符串來使用,只能當(dāng)作語句中的變量來用。

          從效率來看,由于oracle10G放棄了RBO,全面引入CBO,因此,在10G中使用綁定變量效率的提升比9i中更為明顯。

          最后,前面說到綁定變量是在通常情況下能提升效率,那哪些是不通常的情況呢?

          答案是:在字段(包括字段集)建有索引,且字段(集)的集的勢非常大(也就是有個值在字段中出現(xiàn)的比例特別的大)的情況下,使用綁定變量可能會導(dǎo)致查詢計劃錯誤,因而會使查詢效率非常低。這種情況最好不要使用綁定變量。

           

           

           

           

           

           

           

          EXECUTE IMMEDIATE代替了以前Oracle8i中DBMS_SQL package包.它解析并馬上執(zhí)行動態(tài)的SQL語句或非運(yùn)行時創(chuàng)建的PL/SQL塊.動態(tài)創(chuàng)建和執(zhí)行SQL語句性能超前,EXECUTE IMMEDIATE的目標(biāo)在于減小企業(yè)費(fèi)用并獲得較高的性能,較之以前它相當(dāng)容易編碼.盡管DBMS_SQL仍然可用,但是推薦使用EXECUTE IMMEDIATE,因為它獲的收益在包之上。

          使用技巧

           

          1. EXECUTE IMMEDIATE將不會提交一個DML事務(wù)執(zhí)行,應(yīng)該顯式提交
          如果通過EXECUTE IMMEDIATE處理DML命令,那么在完成以前需要顯式提交或者作為EXECUTE IMMEDIATE自己的一部分. 如果通過EXECUTE IMMEDIATE處理DDL命令,它提交所有以前改變的數(shù)據(jù)

           

          2. 不支持返回多行的查詢,這種交互將用臨時表來存儲記錄(參照例子如下)或者用REF cursors.

           

          3. 當(dāng)執(zhí)行SQL語句時,不要用分號,當(dāng)執(zhí)行PL/SQL塊時,在其尾部用分號.

           

          4. 在Oracle手冊中,未詳細(xì)覆蓋這些功能。下面的例子展示了所有用到Execute immediate的可能方面.希望能給你帶來方便.

           

          5. 對于Forms開發(fā)者,當(dāng)在PL/SQL 8.0.6.3.版本中,F(xiàn)orms 6i不能使用此功能.

           

          EXECUTE IMMEDIATE用法例子

           

          1. 在PL/SQL運(yùn)行DDL語句


          begin
          execute immediate 'set role all';
          end;

           

          2. 給動態(tài)語句傳值(USING 子句)


          declare
          l_depnam varchar2(20) := 'testing';
          l_loc    varchar2(10) := 'Dubai';
          begin
          execute immediate 'insert into dept values (:1, :2, :3)'
              using 50, l_depnam, l_loc;
          commit;
          end;

           

          3. 從動態(tài)語句檢索值(INTO子句)


          declare
          l_cnt    varchar2(20);
          begin
          execute immediate 'select count(1) from emp'
              into l_cnt;
          dbms_output.put_line(l_cnt);
          end;

           

          4. 動態(tài)調(diào)用例程.例程中用到的綁定變量參數(shù)必須指定參數(shù)類型.黓認(rèn)為IN類型,其它類型必須顯式指定

           

          declare
          l_routin   varchar2(100) := 'gen2161.get_rowcnt';
          l_tblnam   varchar2(20) := 'emp';
          l_cnt      number;
          l_status   varchar2(200);
          begin
          execute immediate 'begin ' || l_routin || '(:2, :3, :4); end;'
              using in l_tblnam, out l_cnt, in out l_status;

          if l_status != 'OK' then
               dbms_output.put_line('error');
          end if;
          end;

           

          5. 將返回值傳遞到PL/SQL記錄類型;同樣也可用%rowtype變量


          declare
          type empdtlrec is record (empno number(4),
                                     ename varchar2(20),
                                     deptno number(2));
          empdtl empdtlrec;
          begin
          execute immediate 'select empno, ename, deptno ' ||
                             'from emp where empno = 7934'
              into empdtl;
          end;

           

          6. 傳遞并檢索值.INTO子句用在USING子句前

           

          declare
          l_dept    pls_integer := 20;
          l_nam     varchar2(20);
          l_loc     varchar2(20);
          begin
          execute immediate 'select dname, loc from dept where deptno = :1'
              into l_nam, l_loc
              using l_dept ;
          end;

           

          7. 多行查詢選項.對此選項用insert語句填充臨時表,用臨時表進(jìn)行進(jìn)一步的處理,也可以用REF cursors糾正此缺憾.

          declare
          l_sal   pls_integer := 2000;
          begin
          execute immediate 'insert into temp(empno, ename) ' ||
                             '          select empno, ename from emp ' ||
                             '          where sal > :1'
              using l_sal;
          commit;
          end;

           

                 對于處理動態(tài)語句,EXECUTE IMMEDIATE比以前可能用到的更容易并且更高效.當(dāng)意圖執(zhí)行動態(tài)語句時,適當(dāng)?shù)靥幚懋惓8又匾?應(yīng)該關(guān)注于捕獲所有可能的異常.

          posted on 2010-11-01 14:42 xzc 閱讀(963) 評論(0)  編輯  收藏 所屬分類: Oracle
          主站蜘蛛池模板: 汾阳市| 大名县| 黑龙江省| 泸定县| 鹤壁市| 嵩明县| 云浮市| 和平县| 迁西县| 湾仔区| 定陶县| 金昌市| 崇明县| 上栗县| 昌江| 崇仁县| 秭归县| 桂平市| 贞丰县| 竹北市| 大兴区| 格尔木市| 东山县| 贵溪市| 铜山县| 和硕县| 汉源县| 黄浦区| 阜平县| 栖霞市| 龙井市| 红河县| 交口县| 周口市| 青岛市| 新泰市| 门头沟区| 济南市| 景德镇市| 弥渡县| 梁河县|