關於DBMS_SQL的使用
在PL/SQL程式設計過程中,會遇到很多必須使用動態sql的地方,oracle系統所提供的DMBS_SQL包可以幫助你解決問題。
DBMS_SQL系統包提供了很多函式及過程,現在簡要闡述其中使用頻率較高的幾種:
function open_cursor:開啟一個動態遊標,並返回一個整型;
procedure close_cursor(c in out integer)
:關閉一個動態遊標,引數為open_cursor所開啟的遊標;procedure parse(c in integer, statement in varchar2, language_flag in integer):對動態遊標所提供的sql語句進行解析,引數C表示遊標,statement為sql語句,language-flag為解析sql語句所用oracle版本,一般有V6,V7跟native(在不明白所連database版本時,使用native);
procedure define_column(c in integer, position in integer, column any datatype, [column_size in integer]):定義動態遊標所能得到的對應值,其中c為動態遊標,positon為對應動態sql中的位置(從1開始),column為該值所對應的變數,可以為任何型別,column_size只有在column為定義長度的型別中使用如VARCHAR2,CHAR等(該過程有很多種情況,此處只對一般使用到的型別進行表述);
function execute(c in integer):執行遊標,並返回處理一個整型,代表處理結果(對insert,delete,update才有意義,而對select語句而言可以忽略);
function fetch_rows(c in integer):對遊標進行迴圈取資料,並返回一個整數,為0時表示已經取到遊標末端;
procedure column_value(c in integer, position in integer, value):將所取得的遊標資料賦值到相應的變數,c為遊標,position為位置,value則為對應的變數;
procedure bind_variable(c in integer, name in varchar2, value):定義動態sql語句(DML)中所對應欄位的值,c為遊標,name為欄位名稱,value為欄位的值;
以上是在程式中經常使用到的幾個函式及過程,其他函式及過程請參照oracle所提供定義語句dbmssql.sql
(二)一般過程
對於一般的select操作,如果使用動態的sql語句則需要進行以下幾個步驟:
open cursor—>parse—>define column—>excute—>fetch rows—>close cursor;
open cursor—>parse—>bind variable—>execute—>close cursor;
open cursor—>parse—>execute—>close cursor;
(三)具體案例
下面就本人所開發系統中某一程式做分析
該過程為一股票技術曲線計算程式,將資料從即時資料表中取出,並按照計算曲線的公式,對這些資料進行計算,並將結果儲存到技術曲線表中.
–procedure name:R_Ma_Main
–入口引數:PID股票程式碼,PEND時間,pinterval時間間隔,totab目標資料表
–呼叫函式:R_GetSql1,R_GetSql2
–功能:具體計算單支股票ma技術曲線
–時間:2001-06-20
–**********************************
create or replace procedure R_Ma_Main
(
pid varchar2,
pend varchar2,
pinterval varchar2,
totab varchar2
) is
–定義陣列
type Date_type is table of varchar2(12) index by binary_integer;
type Index_type is table of number index by binary_integer;
TempDate Date_Type;–時間陣列
TempIndex Index_Type;–股票收盤價陣列
TempMa Index_Type;–ma技術曲線資料
cursor1 integer;–遊標
cursor2 integer;–遊標
rows_processed integer;–執行遊標返回
TempInter integer;–參與計算數值個數
TempVal integer;–計算時間型別
TempSql varchar2(500);–動態sql語句
MyTime varchar2(12);–時間
MyIndex number;–數值
MidIndex number;–中間變數
i integer := 999;
j integer;
begin
TempInter := to_number(substr(pinterval,1,4));
TempVal := to_number(substr(pinterval,5,2));
TempSql := R_GetSql1(pid, pend, TempVal);–得到選擇資料的sql語句
–得到當天的即時資料,並依次儲存到陣列中
cursor1 := dbms_sql.open_cursor; –建立遊標
dbms_sql.parse(cursor1, TempSql, dbms_sql.native); –解析動態sql語句,取兩個欄位,時間及價格,其中時間以14位的varchar2表示
dbms_sql.define_column(cursor1, 1, MyTime, 12); –分別定義sql語句中各欄位所對應變數
dbms_sql.define_column(cursor1, 2, MyIndex);
rows_processed := dbms_sql.execute(cursor1);
loop
if dbms_sql.fetch_rows(cursor1) > 0 then
begin
dbms_sql.column_value(cursor1, 1, MyTime);
dbms_sql.column_value(cursor1, 2, MyIndex);
TempDate(i) := MyTime;
TempIndex(i) := MyIndex;
i := i – 1;–按倒序的方法填入陣列
end;
else
exit;
end if;
end loop;
dbms_sql.close_cursor(cursor1);
–如果取得的資料量不夠計算個數,則跳出程式
if i > 999-TempInter then
goto JumpLess;
end if;
–初始化中間變數
MidIndex := 0;
TempIndex(i) := 0;
for j in i..i+TempInter-1 loop
MidIndex := MidIndex + TempIndex(j);
end loop;
–依次對當天資料計算ma值,並儲存到ma陣列中
for j in i+TempInter..999 loop
MidIndex := MidIndex – TempIndex(j-TempInter) + TempIndex(j);
TempMa(j) := MidIndex/TempInter;
end loop;
if TempVal < 6 then–如果計算的是分鐘跟天的ma技術曲線
begin
cursor2 := dbms_sql.open_cursor;
TempSql := `insert into ` || totab || ` values(:r_no, :i_interval, :i_time, :i_index)`;
dbms_sql.parse(cursor2, TempSql, dbms_sql.native);
for j in i+TempInter..999 loop
dbms_sql.bind_variable(cursor2, `r_no`, pid);
dbms_sql.bind_variable(cursor2, `i_interval`, pinterval);
dbms_sql.bind_variable(cursor2, `i_time`, TempDate(j));
dbms_sql.bind_variable(cursor2, `i_index`, TempMa(j));
rows_processed := dbms_sql.execute(cursor2);–插入資料
end loop;
end;
end if;
commit;
dbms_sql.close_cursor(cursor2);
–資料量不足跳出
<<JumpLess>>
null;
–exception處理,無關本話題
end;
/
(四)個人觀點
在使用dbms_sql系統包的過程中,其方法簡單而又不失靈活,但還是需要注意一些問題:
2、dbms_sql除了可以做一般的select,insert,update,delete等靜態的sql做能在過程中所做工作外,還能執行create等DDL操作,不過在執行該類操作時應首先顯式賦予執行使用者相應的系統許可權,比如create table等.該類操作只需open cursor—>prase—>close
cursor即能完成.
以上為本人在工作中對dbms_sql的一點點看法,不到之處,請予指正.
對於想更深瞭解dbms_sql的朋友,請閱讀dbmssql.sql檔案.
—
— ———–
— | open_cursor |
— ———–
— |
— |
— v
— —–
— ————>| parse |
— | —–
— | |
— | |———
— | v |
— | ————– |
— |——–>| bind_variable | |
— | ^ ————- |
— | | | |
— | ———–| |
— | |<——–
— | v
— | query?———- yes ———
— | | |
— | no |
— | | |
— | v v
— | ——- ————-
— |———–>| execute | ->| define_column |
— | ——- | ————-
— | |———— | |
— | | | ———-|
— | v | v
— | ————– | ——-
— | ->| variable_value | | ——>| execute |
— | | ————– | | ——-
— | | | | | |
— | ———-| | | |
— | | | | v
— | | | | ———-
— | |<———– |—–>| fetch_rows |
— | | | ———-
— | | | |
— | | | v
— | | | ——————–
— | | | | column_value |
— | | | | variable_value |
— | | | ———————
— | | | |
— | |<————————–
— | |
— —————–|
— |
— v
— ————
— | close_cursor |
— ————
—
—————
相關文章
- DBMS_SQLSQL
- DBMS_SQL例子SQL
- 關於Remix的使用REM
- 關於split的使用
- java 關於fileinputstream的使用Java
- 關於索引的使用模式索引模式
- Android關於Typedarray的使用Android
- 關於MySQL使用的時長MySql
- Masonry 關於ScrollView的使用View
- 關於InputMethodManager的使用方法
- Windows 關於Robocopy的使用詳解Windows
- QT5.9關於QMenuBar的使用QT
- 關於Gson解析的使用匯總
- @html.DropDownList關於它的使用HTML
- 關於微信小程式webview的使用微信小程式WebView
- 關於excelize庫的使用問題Excelize
- 關於Oracle OCI驅動的使用Oracle
- 關於Struts的學習和使用
- Oracle中關於函式的使用Oracle函式
- 關於DOCTYPE的使用和說明
- 關於繫結變數的使用變數
- 關於WPF進度條的使用
- 關於虛擬機器的使用虛擬機
- 關於JSON的簡單使用JSON
- 關於OScache,swarmcache使用Swarm
- mybatis關於list的foreach的使用MyBatis
- 關於GJSON包的簡單使用JSON
- (轉)git中關於fetch的使用Git
- vue 前端關於token的使用(基礎)Vue前端
- 關於iOS開發中copy的使用iOS
- 關於一些變數的使用變數
- 關於Apache Tika的學習和使用Apache
- Android 關於WebView的使用技巧小解AndroidWebView
- 關於oracle內建函式的使用Oracle函式
- 關於solairs10的find命令使用AI
- 軟體中關於使用IP的限制
- 關於使用多表做update的語法
- 關於soapUi工具的安裝使用教程UI