Oracle 過程中執行動態 SQL 或 DDL 語句
如果你用的是 Oracle 8i 及以上的版本,那簡單,在過程中用 execute immediate sql_str 就行, sql_str 是一個拼湊的 SQL 語句,但這個動態語句中帶引數,或 Select 的結果要 into 到變數中時就要稍加留心一下了。而在 8i 以前的版本(誰還用這麼古老的玩藝,總有些不得已的地方,老系統考慮升級成本遺留下來的,應用軟體所伴隨著的等),都沒法用 execute immediate,就得使用 DBMS_SQL 包來實現了
何謂動態 SQL 和 DDL 語句呢?通常在過程中要操作的表名、欄位名都必須是明確的,否則編譯過程時就要報錯,但如果這兩者也用變數名來表示就是動態的。DDL 就是資料庫物件定義的操作,如 CREATE TABLE/VIEW/INDEX/SYN/CLUSTER....,及這些物件的刪除、修改操作等等。
比如在 Oracle 中有執行下面過程塊的意圖時,就要使用到 execute immediate 或是 DBMS_SQL 包了。當然下面的語句塊是通不過的。
1 2 3 4 5 6 7 8 |
declare
col_name
varchar2(30) := 'name' ;
--假定表user存在name欄位
col_val
varchar2(30);
begin
select
col_name into
col_val --按照慣常思維,可能就會這麼寫
from
user
where
age between
18 and
25; --編譯時會提示列名不存在的
drop
table
t2; --不能直接執行
DDL 語句,後面查詢 t2 編譯器就無能為力了
end ;
|
現在我們提出對上面問題的解,針對第一個 Select 語句來說明,並假設查詢中還帶有引數。塊中的 DDL 也是類似的解法。例子因力圖涵蓋更多內容,所以稍顯複雜,如果不需要 into (如 update/delete 語句),或者不帶引數,會簡單多了,應不難簡化。有兩種處理方法,以 8i 為分水嶺。
1. Oracle 8i 及以上版本的過程中處理動態 SQL 語句的辦法
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 |
declare
v_col_name
varchar2(30) := 'name' ;
--欄位名
name 用變數來表示
v_user_name
varchar2(30); --使用者名稱稱
v_user_age
integer ;
--使用者年齡
v_sql_str
varchar2(500); --動態
SQL 語句
begin
v_sql_str
:= 'select
' ||v_col_name|| ',age
from users --欄位名後面不能緊隨 into 到變量了
where
age between :start_age and :end_age and rownum=1' ;
--兩個命名引數
--用
execute immediate 動態執行 SQL 語句
--注意其後的
into 欄位值到變數的寫法,還有 using 來代入引數
execute
|