<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Decode360's Blog

    業(yè)精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
      397 隨筆 :: 33 文章 :: 29 評論 :: 0 Trackbacks
    關(guān)于DBMS_SQL的使用
    http://www.itpub.net/thread-9530-1-1.html

    ??? 在PL/SQL程序設(shè)計過程中,會遇到很多必須使用動態(tài)sql的地方,oracle系統(tǒng)所提供的DMBS_SQL包可以幫助你解決問題。
    ?
    ?
    (一)介紹

    ??? DBMS_SQL系統(tǒng)包提供了很多函數(shù)及過程,現(xiàn)在簡要闡述其中使用頻率較高的幾種:

    ??? function open_cursor:打開一個動態(tài)游標(biāo),并返回一個整型;

    ??? procedure close_cursor(c in out integer)
    :關(guān)閉一個動態(tài)游標(biāo),參數(shù)為open_cursor所打開的游標(biāo);

    ??? procedure parse(c in integer, statement in varchar2, language_flag in integer):對動態(tài)游標(biāo)所提供的sql語句進行解析,參數(shù)C表示游標(biāo),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]):定義動態(tài)游標(biāo)所能得到的對應(yīng)值,其中c為動態(tài)游標(biāo),positon為對應(yīng)動態(tài)sql中的位置(從1開始),column為該值所對應(yīng)的變量,可以為任何類型,column_size只有在column為定義長度的類型中使用如VARCHAR2,CHAR等(該過程有很多種情況,此處只對一般使用到的類型進行表述);

    ??? function execute(c in integer):執(zhí)行游標(biāo),并返回處理一個整型,代表處理結(jié)果(對insert,delete,update才有意義,而對select語句而言可以忽略);

    ??? function fetch_rows(c in integer):對游標(biāo)進行循環(huán)取數(shù)據(jù),并返回一個整數(shù),為0時表示已經(jīng)取到游標(biāo)末端;

    ??? procedure column_value(c in integer, position in integer, value):將所取得的游標(biāo)數(shù)據(jù)賦值到相應(yīng)的變量,c為游標(biāo),position為位置,value則為對應(yīng)的變量;

    ??? procedure bind_variable(c in integer, name in varchar2, value):定義動態(tài)sql語句(DML)中所對應(yīng)字段的值,c為游標(biāo),name為字段名稱,value為字段的值;

    ??? 以上是在程序中經(jīng)常使用到的幾個函數(shù)及過程,其他函數(shù)及過程請參照oracle所提供定義語句dbmssql.sql
    ?

    (二)一般過程

    ??? 對于一般的select操作,如果使用動態(tài)的sql語句則需要進行以下幾個步驟:
    ??? open cursor--->parse--->define column--->excute--->fetch rows--->close cursor;
    ??? 而對于dml操作(insert,update)則需要進行以下幾個步驟:
    ??? open cursor--->parse--->bind variable--->execute--->close cursor;
    ??? 對于delete操作只需要進行以下幾個步驟:
    ??? open cursor--->parse--->execute--->close cursor;
    ?

    (三)具體案例

    ??? 下面就本人所開發(fā)系統(tǒng)中某一程序做分析
    ??? 該過程為一股票技術(shù)曲線計算程序,將數(shù)據(jù)從即時數(shù)據(jù)表中取出,并按照計算曲線的公式,對這些數(shù)據(jù)進行計算,并將結(jié)果保存到技術(shù)曲線表中.
    ?
    --**********************************
    --procedure name:R_Ma_Main
    --入口參數(shù):PID股票代碼,PEND時間,pinterval時間間隔,totab目標(biāo)數(shù)據(jù)表
    --調(diào)用函數(shù):R_GetSql1,R_GetSql2
    --功能:具體計算單支股票ma技術(shù)曲線
    --時間:2001-06-20
    --**********************************
    create or replace procedure R_Ma_Main
    ? (
    ?? pid varchar2,
    ?? pend varchar2,
    ?? pinterval varchar2,
    ?? totab varchar2
    ? ) is?????????????????????
    ?
    --定義數(shù)組
    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;--時間數(shù)組
    TempIndex Index_Type;--股票收盤價數(shù)組
    TempMa Index_Type;--ma技術(shù)曲線數(shù)據(jù)

    cursor1 integer;--游標(biāo)
    cursor2 integer;--游標(biāo)
    rows_processed integer;--執(zhí)行游標(biāo)返回

    TempInter integer;--參與計算數(shù)值個數(shù)
    TempVal integer;--計算時間類型
    TempSql varchar2(500);--動態(tài)sql語句
    MyTime varchar2(12);--時間
    MyIndex number;--數(shù)值
    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);--得到選擇數(shù)據(jù)的sql語句

    ? --得到當(dāng)天的即時數(shù)據(jù),并依次保存到數(shù)組中
    ? cursor1 := dbms_sql.open_cursor;? --創(chuàng)建游標(biāo)
    ? dbms_sql.parse(cursor1, TempSql, dbms_sql.native);? --解析動態(tài)sql語句,取兩個字段,時間及價格,其中時間以14位的varchar2表示
    ? dbms_sql.define_column(cursor1, 1, MyTime, 12);? --分別定義sql語句中各字段所對應(yīng)變量
    ? 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;--按倒序的方法填入數(shù)組
    ????? end;
    ??? else
    ????? exit;
    ??? end if;
    ? end loop;
    ? dbms_sql.close_cursor(cursor1);
    ?
    ? --如果取得的數(shù)據(jù)量不夠計算個數(shù),則跳出程序
    ? 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;

    ? --依次對當(dāng)天數(shù)據(jù)計算ma值,并保存到ma數(shù)組中
    ? 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技術(shù)曲線
    ??? 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);--插入數(shù)據(jù)
    ??? end loop;
    ??? end;
    ? end if;
    ? commit;
    ? dbms_sql.close_cursor(cursor2);
    ? --數(shù)據(jù)量不足跳出
    ? <<JumpLess>>
    ? null;
    ?
    ? --exception處理,無關(guān)本話題
    end;
    /
    ?

    (四)個人觀點

    ??? 在使用dbms_sql系統(tǒng)包的過程中,其方法簡單而又不失靈活,但還是需要注意一些問題:
    ?
    ??? 1、在整個程序的設(shè)計過程中,對游標(biāo)的操作切不可有省略的部分,一旦省略其中某一步驟,則會程序編譯過程既告失敗,如在程序結(jié)尾處未對改游標(biāo)進行關(guān)閉操作,則在再次調(diào)用過程時會出現(xiàn)錯誤.
    ??? 2、dbms_sql除了可以做一般的select,insert,update,delete等靜態(tài)的sql做能在過程中所做工作外,還能執(zhí)行create等DDL操作,不過在執(zhí)行該類操作時應(yīng)首先顯式賦予執(zhí)行用戶相應(yīng)的系統(tǒng)權(quán)限,比如create table等.該類操作只需open cursor--->prase--->close cursor即能完成.

    ??? 以上為本人在工作中對dbms_sql的一點點看法,不到之處,請予指正.
    ??? 對于想更深了解dbms_sql的朋友,請閱讀dbmssql.sql文件.
    ?
    ?
    附個Oracle自帶的流程說明(強大啊):
    ?
    ? --? The flow of procedure calls will typically look like this:
    ? --
    ? --????????????????????? -----------
    ? --??????????????????? | 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 |
    ? --????????????????????? ------------
    ? --
    ? ---------------
    ?
    ?
    posted on 2009-01-24 22:13 decode360 閱讀(142) 評論(0)  編輯  收藏 所屬分類: 06.PLSQL
    主站蜘蛛池模板: 中文字幕乱码免费看电影| 亚洲精品乱码久久久久久中文字幕| 免费av一区二区三区| 337p日本欧洲亚洲大胆人人 | 黄色毛片免费在线观看| 亚洲人成在线精品| 亚洲AV无码一区二区乱孑伦AS| 免费人成激情视频| 免费鲁丝片一级观看| 69av免费观看| 免费成人在线电影| 你懂的网址免费国产| 一个人看的www视频免费在线观看 一个人看的免费观看日本视频www | aⅴ免费在线观看| 国产精品免费观看调教网| 一级看片免费视频囗交| 粉色视频成年免费人15次| 亚洲精品无播放器在线播放| 国产亚洲玖玖玖在线观看| 亚洲一区二区三区久久| 亚洲无砖砖区免费| 亚洲成人黄色网址| 亚洲欧洲日产国码www| 91亚洲va在线天线va天堂va国产| 亚洲欧洲第一a在线观看| 亚洲精品国产字幕久久不卡| 亚洲欧洲∨国产一区二区三区| 亚洲一区精品伊人久久伊人| 亚洲免费在线观看| 久久精品亚洲男人的天堂| 中文字幕专区在线亚洲| 自拍偷自拍亚洲精品第1页| 亚洲中文久久精品无码| 亚洲精品制服丝袜四区| 国产V亚洲V天堂无码久久久| 亚洲不卡中文字幕无码| 亚洲av网址在线观看| 亚洲黄色免费观看| 亚洲国产最大av| 亚洲成a人片在线观看天堂无码| 亚洲国产精品无码观看久久|