动态SQL和PL/SQL的EXECUTE选项分析
EXECUTE IMMEDIATE代替了以前Oracle8i中DBMS_SQL package包.它解析并馬上執行動態的SQL語句或非運行時創建的PL/SQL塊.動態創建和執行SQL語句性能超前,EXECUTE IMMEDIATE的目標在于減小企業費用并獲得較高的性能,較之以前它相當容易編碼.盡管DBMS_SQL仍然可用,但是推薦使用EXECUTE IMMEDIATE,因為它獲的收益在包之上。?
使用技巧?
1. EXECUTE IMMEDIATE將不會提交一個DML事務執行,應該顯式提交。 如果通過EXECUTE IMMEDIATE處理DML命令,那么在完成以前需要顯式提交或者作為EXECUTE IMMEDIATE自己的一部分. 如果通過EXECUTE IMMEDIATE處理DDL命令,它提交所有以前改變的數據。?
2. 不支持返回多行的查詢,這種交互將用臨時表來存儲記錄(參照例子如下)或者用REF cursors.?
3. 當執行SQL語句時,不要用分號,當執行PL/SQL塊時,在其尾部用分號。?
4. 在Oracle手冊中,未詳細覆蓋這些功能。下面的例子展示了所有用到Execute immediate的可能方面.希望能給你帶來方便。?
5. 對于Forms開發者,當在PL/SQL 8.0.6.3.版本中,Forms 6i不能使用此功能。 EXECUTE IMMEDIATE用法例子 1. 在PL/SQL運行DDL語句 ?
?? ?EXECUTE IMMEDIATE 'set role all';
END;
2. 給動態語句傳值(USING 子句) ?
?? ?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. 從動態語句檢索值(INTO子句) ?
?? ?l_cnt VARCHAR2(20);
BEGIN
?? ?EXECUTE IMMEDIATE 'select count(1) from emp' into l_cnt;
?? ?dbms_output.put_line(l_cnt);
END;
4. 動態調用例程.例程中用到的綁定變量參數必須指定參數類型.黓認為IN類型,其它類型必須顯式指定。
?? ?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變量。 ?
?? ?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子句前。 ?
?? ?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語句填充臨時表,用臨時表進行進一步的處理,也可以用REF cursors糾正此缺憾。 ?
?? ?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;
對于處理動態語句,EXECUTE IMMEDIATE比以前可能用到的更容易并且更高效.當意圖執行動態語句時,適當地處理異常更加重要.應該關注于捕獲所有可能的異常。
總結
以上是生活随笔為你收集整理的动态SQL和PL/SQL的EXECUTE选项分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用MySQL的存储过程
- 下一篇: Powershell访问数组