execute immediate

首先在這裏發發牢騷,指責下那些刻板的書寫方式,不考慮讀者理不理解,感受就是給專業人員用來複習用的同樣,沒有前戲,直接就高潮,實在受不了!沒基礎或基礎差的徹底不知道發生了什麼,一臉懵逼的看着,一星差評!!!sql

execute immediateoracle

如下引用介紹比較好的例子說明框架

create or replace procedure proc_test( --參數區域
) is 
--變量區域
    --sql腳本
    v_sql varchar2(2000) :=''; --記錄學生數量
    v_num number; begin
--執行區域

    -- execute immediate用法1:馬上執行sql語句
    v_sql := 'create or replace view myview as select id,name from student'; execute immediate v_sql; --- execute immediate用法2:馬上執行sql語句,並賦值給某個變量
    v_sql := 'select count(1) from student'; execute immediate v_sql into v_num; -- execute immediate用法3:帶參數的sql
    v_sql:='select * from student t where t.name=:1 and t.age=:2'; execute immediate v_sql using 'ZhangSan',23; end proc_test; /

看了上面的代碼,是否以爲理解?NO,NO,NO性能

對execute immediate  的解釋以下spa

簡單來講 就是你一個存儲過程中 建立了一個表 table_a 而後要用insert into將其餘的數據插入到這個table_a當中,可是由於你在建立過程的時候 table_a還不存在,過程就會顯示有編譯錯誤,由於table_a不存在必然致使過程沒法執行,因此沒法編譯成功,而把insert into語句加如到 execute immediate以後 則oracle不會再去理會這個對象是否存在,所以能夠成功編譯和執行。code

看完了,估計還會有小朋友舉手問,跟動態有什麼關係,爲什麼扯上動態,哪裏動態了,能不能講明白,等等。。。對象

敲黑板,人家說的動態,是說execute immediate後面跟的SQL代碼不固定,你想寫就寫啥,動態的!blog

而後又有小朋友,站起來了,你呀的,胡我啊,說最後代碼,隨便寫,我都想笑,這個跟直接寫SQL代碼,不要前面的execute immediate有什麼區別?不都執行那條語句麼?字符串

哈哈,小朋友你坐下別激動,你問到點上了,execute immediate後邊SQL代碼要用一對單引號的(即' '),而直接寫SQL沒有的對吧,告訴你動態的祕訣就在於execute immediate後邊SQL代碼能夠去拼接,這就實現了所謂動態,會根據不一樣狀況,拼接不一樣的代碼。get

簡單舉例

直接寫的   select * from dual;

用execute immediate寫    v_sql:='select * from dual';
                                          EXECUTE IMMEDIATE v_sql; 
通常來講直接寫SQL的性能是高於拼字符串的,由於若是執行拼字符串的須要內部自動調動oracle機制,先解析字符串映射成SQL語句而後再執行。
可是拼SQL的方式有好處。即SQL語句是一個字符串能夠動態拼接,根據不一樣的條件來改變SQL語句,這是直接寫SQL所不能達到的。
拼SQL還有個好處就是    v_sql:='select * from tables t where t.c_date=:1 and t.name=:2';  
                                         EXECUTE IMMEDIATE v_sql USING '20130304','xiaoming';
能夠動態的對參數傳遞值,這是最大的優點。 
語法結構:
EXECUTE IMMEDIATE dynamic_string [INTO {define_variable[,define_variable]| record}] [USING [IN | OUT | IN OUT] bind_argument[,[IN | OUT \ IN OUT] bind_argumnet]…] [{RETURNING | RETURN} INTO bind_argument[,bind_argument]…];

本地動態SQL語句一個優勢是能夠在代碼中是使用綁定變量。

先說說綁定變量 ":"稱綁定變量指示符,解釋以下:

它是用戶放入查詢中的佔位符,它會告訴Oracle" 如今生成一個方案框架,實際執行語句的時候,會提供應該使用的實際值"。

例子以下:
select * from emp where dep='sale' ;                   //不使用綁定變量
select * from emp where dep=:sale                    //使用綁定變量

用法
    處理DDL操做(CREATE,ALTER,DROP)
    CREATE OR REPLACE PROCEDURE drop_table(table_name VARCHAR2)
    IS
     Sql_statemet VARCHAR2(100);
    BEGIN 
     Sql_statement:=’DROP TABLE’ || table_name;
     EXECUTE IMMEDIATE sql_statement;
    END;
    /
    創建過程drop_table後,調用以下:
    SQL> exec drop_table(‘worker’)
    處理DCL操做(GRANT REVOKE)
    SQL> conn system/manager
    CREATE OR REPLACE PROCEDURE grant_sys_priv(priv VARCHAR2,username VARCHAR2)
    IS
     Sql_stat VARCHAR2(100);
    BEGIN
     Sql_stat:=’GRANT 「 || priv|| ’ TO ’|| username;
    EXECUTE IMMEDIATE sql_stat;
    END;
    /
    調用
    SQL> exec grant_sys_priv(‘CREATE SESSION’,’SCOTT’)
    處理DML操做(INSERT UPDATE DELETE)
    若是DML語句帶有佔位符,那麼在E I語句中則要帶USING子句
    若是DML語句帶有RETURNING子句,那麼E I語句中要帶有RETURNINGINTO子句
    例子,處理單行查詢:
    DECLARE
     sql_stat VARCHAR2(100);
     emp_record tbl%ROWTYPE;
    BEGIN
     sql-stat:='SELECT * FROM tbl WHERE tblno=:no';
     EXECUTE IMMEDIATE sql_stat INTO emp_record USING &1;
     dbms_output.put_line(emp_record.ename||emp_record.sal);
    END;

EXECUTE IMMEDIATE -- 用法例子


1. 在PL/SQL運行DDL語句


begin
   execute immediate 'set role all';
end;


2. 給動態語句傳值(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. 從動態語句檢索值(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. 動態調用例程.例程中用到的綁定變量參數必須指定參數類型.
黓認爲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語句填充臨時表,
用臨時表進行進一步的處理,也能夠用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;

相關文章
相關標籤/搜索