內容摘要在PL/SQL開發過程中
使用SQL
PL/SQL可以實現大部份的需求
但是在某些特殊的情況下
在PL/SQL中使用標准的SQL語句或DML語句不能實現自己的需求
比如需要動態建表或某個不確定的操作需要動態執行
這就需要使用動態SQL來實現
本文通過幾個實例來詳細的講解動態SQL的使用
本文適宜讀者范圍
Oracle初級
中級
系統環境 OS
windows
Professional (英文版)
Oracle
正文 一般的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語句來實現的
本地動態SQL執行DDL語句 需求
根據用戶輸入的表名及字段名等參數動態建表
create or replace procedure proc_test
(
table_name in varchar
表名
field
in varchar
字段名
datatype
in varchar
字段類型
field
in varchar
字段名
datatype
in varchar
字段類型
) as
str_sql varchar
(
);
begin
str_sql:=
create table
||table_name||
(
||field
||
||datatype
||
||field
||
||datatype
||
)
;
execute immediate str_sql;
動態執行DDL語句
exception
when others then
null;
end ;
以上是編譯通過的存儲過程代碼
下面執行存儲過程動態建表
SQL> execute proc_test(
dinya_test
id
number(
) not null
name
varchar
(
)
);
PL/SQL procedure successfully completed
SQL> desc dinya_test;
Name Type Nullable Default Comments
ID NUMBER(
)
NAME VARCHAR
(
) Y
SQL>
到這裡
就實現了我們的需求
使用本地動態SQL根據用戶輸入的表名及字段名
字段類型等參數來實現動態執行DDL語句
本地動態SQL執行DML語句 需求
將用戶輸入的值插入到上例中建好的dinya_test表中
create or replace procedure proc_insert
(
id in number
輸入序號
name in varchar
輸入姓名
) as
str_sql varchar
(
);
begin
str_sql:=
insert into dinya_test values(:
:
)
;
execute immediate str_sql using id
name;
動態執行插入操作
exception
when others then
null;
end ;
執行存儲過程
插入數據到測試表中
SQL> execute proc_insert(
dinya
);
PL/SQL procedure successfully completed
SQL> select * from dinya_test;
ID NAME
dinya
在上例中
本地動態SQL執行DML語句時使用了using子句
按順序將輸入的值綁定到變量
如果需要輸出參數
可以在執行動態SQL的時候
使用RETURNING INTO 子句
如
declare
p_id number:=
;
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函數來執行語句
使用DBMS_SQL包執行DDL語句 需求
使用DBMS_SQL包根據用戶輸入的表名
字段名及字段類型建表
create or replace procedure proc_dbms_sql
(
table_name in varchar
表名
field_name
in varchar
字段名
datatype
in varchar
字段類型
field_name
in varchar
字段名
datatype
in varchar
字段類型
)as
v_cursor number;
定義光標
v_string varchar
(
);
定義字符串變量
v_row number;
行數
begin
v_cursor:=dbms_sql
open_cursor;
為處理打開光標
v_string:=
create table
||table_name||
(
||field_name
||
||datatype
||
||field_name
||
||datatype
||
)
;
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_test
id
number(
) not null
name
varchar
(
)
);
PL/SQL procedure successfully completed
SQL> desc dinya_test
;
Name Type Nullable Default Comments
ID NUMBER(
)
NAME VARCHAR
(
) Y
SQL>
使用DBMS_SQL包執行DML語句 需求
使用DBMS_SQL包根據用戶輸入的值更新表中相對應的記錄
查看表中已有記錄
SQL> select * from dinya_test
;
ID NAME
Oracle
CSDN
ERP
SQL>
建存儲過程
並編譯通過
create or replace procedure proc_dbms_sql_update
(
id number
name varchar
)as
v_cursor number;
定義光標
v_string varchar
(
);
字符串變量
v_row number;
行數
begin
v_cursor:=dbms_sql
open_cursor;
為處理打開光標
v_string:=
update dinya_test
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(
csdn_dinya
);
PL/SQL procedure successfully completed
SQL> select * from dinya_test
;
ID NAME
Oracle
csdn_dinya
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
From:http://tw.wingwit.com/Article/program/SQLServer/201311/22089.html