PL/SQL開發中動態SQL的使用方法
內容摘要:在PL/SQL開發過程中,使用SQL,PL/SQL可以實現大部份的需求,但是在某些特殊的情況下,在PL/SQL中使用標準的SQL語句或DML語句不能實現自己的需求,比如需要動態建表或某個不確定的操作需要動態執行。這就需要使用動態SQL來實現。本過幾個例項來詳細的講解動態SQL的使用。
本文適宜讀者範圍:初級,中級
系統環境:
OS:windows 2000 Professional (英文版)
Oracle:8.1.7.1.0
正文:
一般的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語句是不確定的,如根據使用者輸入的引數的不同而執行不同的操作。編譯程式對動態語句部分不進行處理,只是在程式執行時動態地建立語句、對語句進行語法分析並執行該語句。
Oracle中動態SQL可以透過本地動態SQL來執行,也可以透過DBMS_SQL包來執行。下面就這兩種情況分別進行說明:
一、本地動態SQL
本地動態SQL是使用EXECUTE IMMEDIATE語句來實現的。
1、本地動態SQL執行DDL語句:
需求:根據使用者輸入的表名及欄位名等引數動態建表。
以上是編譯透過的儲存過程程式碼。下面執行儲存過程動態建表。
到這裡,就實現了我們的需求,使用本地動態SQL根據使用者輸入的表名及欄位名、欄位型別等引數來實現動態執行DDL語句。
2、本地動態SQL執行DML語句。
需求:將使用者輸入的值插入到上例中建好的dinya_test表中。
執行儲存過程,插入資料到表中。
在上例中,本地動態SQL執行DML語句時使用了using子句,按順序將輸入的值繫結到變數,如果需要輸出引數,可以在執行動態SQL的時候,使用RETURNING INTO 子句,如:
更多的關於動態SQL中關於返回值及為輸出輸入繫結變數執行引數模式的問題,請讀者自行做測試。
二、使用DBMS_SQL包
使用DBMS_SQL包實現動態SQL的步驟如下:A、先將要執行的SQL語句或一個語句塊放到一個字串變數中。B、使用DBMS_SQL包的parse過程來分析該字串。、使用DBMS_SQL包的bind_variable過程來繫結變數。D、使用DBMS_SQL包的execute函式來執行語句。
1、使用DBMS_SQL包執行DDL語句
需求:使用DBMS_SQL包根據使用者輸入的表名、欄位名及欄位型別建表。
以上過程編譯透過後,執行過程建立表結構:
2、使用DBMS_SQL包執行DML語句
需求:使用DBMS_SQL包根據使用者輸入的值更新表中相對應的記錄。
檢視錶中已有記錄:
建儲存過程,並編譯透過:
執行過程,根據使用者輸入的引數更新表中的資料:
執行過程後將第二條的name欄位的資料更新為新值csdn_dinya。這樣就完成了使用dbms_sql包來執行DML語句的功能。
使用DBMS_SQL中,如果要執行的動態語句不是查詢語句,使用DBMS_SQL.Execute或DBMS_SQL.Variable_Value來執行,如果要執行動態語句是查詢語句,則要使用DBMS_SQL.define_column定義輸出變數,然後使用DBMS_SQL.Execute, DBMS_SQL.Fetch_Rows, DBMS_SQL.Column_Value及DBMS_SQL.Variable_Value來執行查詢並得到結果。
總結說明:
在Oracle開發過程中,我們可以使用動態SQL來執行DDL語句、DML語句、事務控制語句及系統控制語句。但是需要注意的是,PL/SQL塊中使用動態SQL執行DDL語句的時候與別的不同,在DDL中使用繫結變數是非法的(bind_variable(v_cursor,’:p_name’,name)),分析後不需要執行DBMS_SQL.Bind_Variable,直接將輸入的變數加到字串中即可。另外,DDL是在呼叫DBMS_SQL.PARSE時執行的,所以DBMS_SQL.EXECUTE也可以不用,即在上例中的v_row:=dbms_sql.execute(v_cursor)部分可以不要。
本文適宜讀者範圍:初級,中級
系統環境:
OS:windows 2000 Professional (英文版)
Oracle:8.1.7.1.0
正文:
一般的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語句是不確定的,如根據使用者輸入的引數的不同而執行不同的操作。編譯程式對動態語句部分不進行處理,只是在程式執行時動態地建立語句、對語句進行語法分析並執行該語句。
Oracle中動態SQL可以透過本地動態SQL來執行,也可以透過DBMS_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 successfully 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 values(:1,:2)’; execute immediate str_sql using id,name; --動態執行插入操作 exception when others then null; end ; |
執行儲存過程,插入資料到表中。
SQL> execute proc_insert(1,’dinya’); PL/SQL procedure successfully completed SQL> select * from dinya_test; ID NAME 1 dinya |
在上例中,本地動態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過程來分析該字串。、使用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 successfully 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 successfully completed SQL> select * from dinya_test2; ID NAME 1 Oracle 2 csdn_dinya 3 ERP SQL> |
執行過程後將第二條的name欄位的資料更新為新值csdn_dinya。這樣就完成了使用dbms_sql包來執行DML語句的功能。
使用DBMS_SQL中,如果要執行的動態語句不是查詢語句,使用DBMS_SQL.Execute或DBMS_SQL.Variable_Value來執行,如果要執行動態語句是查詢語句,則要使用DBMS_SQL.define_column定義輸出變數,然後使用DBMS_SQL.Execute, DBMS_SQL.Fetch_Rows, DBMS_SQL.Column_Value及DBMS_SQL.Variable_Value來執行查詢並得到結果。
總結說明:
在Oracle開發過程中,我們可以使用動態SQL來執行DDL語句、DML語句、事務控制語句及系統控制語句。但是需要注意的是,PL/SQL塊中使用動態SQL執行DDL語句的時候與別的不同,在DDL中使用繫結變數是非法的(bind_variable(v_cursor,’:p_name’,name)),分析後不需要執行DBMS_SQL.Bind_Variable,直接將輸入的變數加到字串中即可。另外,DDL是在呼叫DBMS_SQL.PARSE時執行的,所以DBMS_SQL.EXECUTE也可以不用,即在上例中的v_row:=dbms_sql.execute(v_cursor)部分可以不要。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/196700/viewspace-1087022/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PL/SQL執行動態SQLSQL
- PL/SQL 動態sql語句例SQL
- pl/sql--動態SQL常用方法SQL
- PLSQL Language Referenc-PL/SQL動態SQL-何時需要動態SQLSQL
- PLSQL Language Referenc-PL/SQL動態SQL-練習:在動態SQL塊中呼叫子程式。SQL
- PLSQL Language Referenc-PL/SQL動態SQL-動態SQL中重複的佔位符名名稱SQL
- PL/SQL中動態掉用儲存過程SQL儲存過程
- PLSQL Language Referenc-PL/SQL動態SQL-本地動態SQL(EXECUTE IMMEDIATE語句)SQL
- PL/SQL開發記錄SQL
- 【PL/SQL開發】-----詭異啊SQL
- WEB PL/SQL Report 的開發方法WebSQL
- SqlServer中的動態SqlSQLServer
- shell動態指令碼和pl/sql動態指令碼的比較指令碼SQL
- pl/sql中的row物件SQL物件
- PLSQL Language Referenc-PL/SQL靜態SQL-靜態SQL的描述-偽列SQL
- PLSQL Language Referenc-PL/SQL靜態SQL-靜態SQL的描述-語句SQL
- APEX 通過PL/SQL動態展示區域中動態內容SQL
- pl/sql中的引數模式SQL模式
- oracle PL/SQL中的過載OracleSQL
- pl/sql中bulk collect的用法SQL
- (轉)pl/sql開發異常處理SQL
- 利用pl/sql執行本地的sql檔案中的sql語句SQL
- 【PL/SQL】向表中插入連續數字之PL/SQL方法SQL
- 使用CASE表示式替代SQL Server中的動態SQLSQLServer
- Oracle PL/SQL中EXCEPTION用法OracleSQLException
- PL/SQLSQL
- sql中limit使用方法SQLMIT
- PL/SQL中command window與SQL window的區別SQL
- 繫結變數在靜態sql和動態sql中變數SQL
- SQL&PL/SQL (轉)SQL
- PLSQL Language Reference-PL/SQL語言基礎-表示式-PL/SQL表示式中的SQL函式SQL函式
- PLSQL Language Referenc-PL/SQL靜態SQL-靜態SQL的描述-游標-開啟和關閉顯式游標SQL
- PLSQL Language Referenc-PL/SQL靜態SQL-靜態SQL的描述-游標-顯式游標SQL
- 【PL/SQL】在PL/SQL中執行重新整理Shared Pool命令SQL
- oracle動態sql執行table表中儲存的sqlOracleSQL
- PL/SQL Developer中輸入SQL語句時如何自動提示欄位SQLDeveloper
- 動態SQLSQL
- 動態SQL intoSQL