ORACLE 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) := 'D?i';   
   begin   
   execute immediate 'insert into dept vals   (: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; 

對於處理動態語句,EXECUTE IMMEDIATE 比以前可能用到的更容易並且更高效.
當意圖執行動態語句時,適當地處理異常更加重要.應該關注於捕獲所有可能的異常.15:40 | 添加評論 | 固定鏈接 | 寫入日志 | SQLoracle中insert into select的用法

INSERT INTO t_work  
            (f_recid, f_jobid, f_ruleid, f_jobtype, f_operid, f_opername,  
             f_btime, f_assigntime, f_downtime, f_worktimes, f_finishtime)  
   SELECT SYS_GUID () AS f_recid, f_jobid, f_ruleid, f_jobtype, f_operid,  
          f_opername, f_btime, f_assigntime,f_downtime,  
          DECODE (f_downtime, null,1, f_downtime + 1) as f_worktimes,  
          TO_CHAR (SYSDATE, 'yyyy-MM-dd hh:mm:ss') AS finishtime  
     FROM t_bfer  
    WHERE f_jobid = '21'  

說明將t_bfer中的一條記錄添加到t_work表中。
其中b_bfer中沒有的列有f_recid和t_finishtime;
f_worktimes需要加1。
SYS_GUID()的意思是生成一個32位的永不重復的字符串。
DECODE(f_downtime, null,1, f_downtime + 1)的意思是如果f_downtime為空(null)得到的值為1,否則為f_downtime+1。
TO_CHAR(SYSDATE, 'yyyy-MM-dd hh:mm:ss')為格式化時間格式;在表t_work中f_finishtime的數據類型為varchar2.
15:22 | 添加評論 | 固定鏈接 | 寫入日志 | SQLPL/SQL開發中動態SQL的使用方法
原文來自:http://blog.chinaunix.net/u/19673/showart_272022.html

一般的PL/SQL程序設計中,在DML和事務控制的語句中可以直接使用SQL,但是DDL語句及系統控制語句卻不能在PL/SQL中直接使用,要想實現在PL/SQL中使用DDL語句及系統控制語句,可以通過使用動態SQL來實現。
  首先我們應該了解什么是動態SQL,在Oracle數據庫開發PL/SQL塊中我們使用的SQL分為:靜態SQL語句和動態SQL語句。所謂靜態SQL 指在PL/SQL塊中使用的SQL語句在編譯時是明確的,執行的是確定對象。而動態SQL是指在PL/SQL塊編譯時SQL語句是不確定的,如根據用戶輸入的參數的不同而執行不同的操作。編譯程序對動態語句部分不進行處理,只是在程序運行時動態地創建語句、對語句進行語法分析並執行該語句。

一、本地動態SQL
  本地動態SQL是使用EXECUTE IMMEDIATE語句來實現的。
  1、本地動態SQL執行DDL語句:
  需求:根據用戶輸入的表名及字段名等參數動態建表。

create or replace procedure proc_test  
(  
table_name in varchar2, --表名  
field1 in varchar2, --字段名  
datatype1 in varchar2, --字段類型  
field2 in varchar2, --字段名  
datatype2 in varchar2 --字段類型  
) as  
str_sql varchar2(500);  
begin  
str_sql:=create table||table_name||’(’||field1||’ ’||datatype1||’,’||field2||’ ’||datatype2||’)’;  
execute immediate str_sql; --動態執行DDL語句  
exception  
when others then  
null;  
end ;  

以上是編譯通過的存儲過程代碼。下面執行存儲過程動態建表。

    SQL> execute proc_test(’dinya_test’,’id’,’number(8) not null’,’name’,’varchar2(100)’);  
    PL/SQL procedure s?ssfully completed  
    SQL> desc dinya_test;  
    Name Type Nullable Default Comments   
    ---- ------------- -------- ------- --------   
    ID NUMBER(8)  
    NAME VARCHAR2(100) Y  
    SQL>  

到這里,就實現了我們的需求,使用本地動態SQL根據用戶輸入的表名及字段名、字段類型等參數來實現動態執行DDL語句。
  2、本地動態SQL執行DML語句。
  需求:將用戶輸入的值插入到上例中建好的dinya_test表中。

create or replace procedure proc_insert  
(  
id in number, --輸入序號  
name in varchar2 --輸入姓名  
) as  
str_sql varchar2(500);  
begin  
str_sql:=insert into dinya_test vals(:1,:2)’;  
execute immediate str_sql using id,name; --動態執行插入操作  
exception  
when others then  
null;  
end ;  

執行存儲過程,插入數據到測試表中。

SQL> execute proc_insert(1,’dinya’);  
PL/SQL procedure s?ssfully completed  
SQL> select * from dinya_test; 

在上例中,本地動態SQL執行DML語句時使用了using子句,按順序將輸入的值綁定到變量,如果需要輸出參數,可以在執行動態SQL的時候,使用RETURNING INTO 子句,如:

declare  
p_id number:=1;  
v_count number;  
begin  
v_string:=select count(*) from table_name a where a.id=:id’;  
execute immediate v_string into v_count using p_id;   
end ; 

更多的關於動態SQL中關於返回值及為輸出輸入綁定變量執行參數模式的問題,請讀者自行做測試。
  二、使用DBMS_SQL包
  使用DBMS_SQL包實現動態SQL的步驟如下:A、先將要執行的SQL語句或一個語句塊放到一個字符串變量中。B、使用DBMS_SQL包的 parse過程來分析該字符串。C、使用DBMS_SQL包的bind_variable過程來綁定變量。D、使用DBMS_SQL包的execute函數來執行語句。
  1、使用DBMS_SQL包執行DDL語句
  需求:使用DBMS_SQL包根據用戶輸入的表名、字段名及字段類型建表。

create or replace procedure proc_dbms_sql  
(  
table_name in varchar2, --表名  
field_name1 in varchar2, --字段名  
datatype1 in varchar2, --字段類型  
field_name2 in varchar2, --字段名  
datatype2 in varchar2 --字段類型  
)as  
v_cursor number; --定義光標  
v_string varchar2(200); --定義字符串變量  
v_row number; --行數  
begin  
v_cursor:=dbms_sql.open_cursor; --為處理打開光標  
v_string:=create table||table_name||’(’||field_name1||’ ’||datatype1||’,’||field_name2||’ ’||datatype2||’)’;  
dbms_sql.parse(v_cursor,v_string,dbms_sql.native); --分析語句  
v_row:=dbms_sql.execute(v_cursor); --執行語句  
dbms_sql.close_cursor(v_cursor); --關閉光標  
exception  
when others then  
dbms_sql.close_cursor(v_cursor); --關閉光標  
raise;  
end; 

以上過程編譯通過后,執行過程創建表結構:

SQL> execute proc_dbms_sql(’dinya_test2’,’id’,’number(8) not null’,’name’,’varchar2(100)’);  
PL/SQL procedure s?ssfully completed  
SQL> desc dinya_test2;  
Name Type Nullable Default Comments   
---- ------------- -------- ------- --------   
ID NUMBER(8)   
NAME VARCHAR2(100) Y   
SQL>  

2、使用DBMS_SQL包執行DML語句
  需求:使用DBMS_SQL包根據用戶輸入的值更新表中相對應的記錄。
  查看表中已有記錄:

SQL> select * from dinya_test2;
ID NAME
1 Oracle
2 CSDN
3 ERP
SQL>

  建存儲過程,並編譯通過:

    create or replace procedure proc_dbms_sql_update  
    (  
    id number,  
    name varchar2  
    )as  
    v_cursor number; --定義光標  
    v_string varchar2(200); --字符串變量  
    v_row number; --行數  
    begin  
    v_cursor:=dbms_sql.open_cursor; --為處理打開光標  
    v_string:=update dinya_test2 a set a.name=:p_name where a.id=:p_id’;  
    dbms_sql.parse(v_cursor,v_string,dbms_sql.native); --分析語句  
    dbms_sql.bind_variable(v_cursor,’:p_name’,name); --綁定變量  
    dbms_sql.bind_variable(v_cursor,’:p_id’,id); --綁定變量  
    v_row:=dbms_sql.execute(v_cursor);           --執行動態SQL  
    dbms_sql.close_cursor(v_cursor); --關閉光標  
    exception  
    when others then  
    dbms_sql.close_cursor(v_cursor); --關閉光標  
    raise;  
end;

執行過程,根據用戶輸入的參數更新表中的數據:

SQL> execute proc_dbms_sql_update(2,’csdn_dinya’);  
PL/SQL procedure s?ssfully completed  
SQL> select * from dinya_test2;  
ID NAME  
1 Oracle  
2 csdn_dinya  
3 ERP  
SQL>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM