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>