1樓:匿名使用者
一般的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 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;
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過程來分析該字串。
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 --欄位型別
)asv_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>
傳字的詞語,關於傳字的成語
傳,有兩個讀音。傳宗接代。傳播。傳承。傳遞。傳媒。傳票。另乙個讀音。傳記。傳略。樹碑立傳。別傳。自傳。水滸傳。關於傳字的成語 代代相傳 名不虛傳 樹碑立傳 十世單傳 傳誦一時 言歸正傳 言傳身教 傳宗接代 以訛傳訛 一傳十,十傳百 異聞傳說 藏諸名山,傳之其人 一人傳虛,萬人傳實 傳道受業 克傳弓冶...
趙姓男孩傳字輩怎麼起名字趙姓男孩傳字輩四字怎麼起名字
今年的主題是夢想,建議起名時加個 夢 字 名字會很和諧 又富有正能量。我的回答若對您有所幫助,別忘記點個採納哦。軒睿怎麼樣呢 先恭喜恭喜。恭喜你們公升級為爸爸媽媽 個人看法 以我多年和孩子們打交道的角度來分析 你可以大聲連續快速的念孩子的名字 只要念的過程中不跑音 念著很上口就行 這樣做的目的是避免...
傳有幾種讀音,傳字的兩個讀音怎麼讀
傳說 chu n 傳記 zhu n 我知道這2種 傳字的兩個讀音怎麼讀?傳 字讀chu n和 zhu n 簡體部首 亻 部外筆畫 4 總筆畫 6釋義 轉 zhu n 授,遞 遞。輸。戒。統。言 身教。推廣,散布 宣 流 名。奇 解說經義的文字 經 左 記載某人一生事蹟的文字 小 自 紀 記。略。樹碑...