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

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

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

    JAVA—咖啡館

    ——歡迎訪問rogerfan的博客,常來《JAVA——咖啡館》坐坐,喝杯濃香的咖啡,彼此探討一下JAVA技術,交流工作經驗,分享JAVA帶來的快樂!本網站部分轉載文章,如果有版權問題請與我聯系。

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      447 Posts :: 145 Stories :: 368 Comments :: 0 Trackbacks

    環境區域是用來處理SQL語句的一個oracle存儲區域。游標是指向它的指針或句柄。通過游標,PL/SQL程序可以控制這個環境區域中被處理的語句。

    Oracle中的游標有兩種:顯式游標、隱式游標。

    顯示游標是用cursor...is命令定義的游標,它可以對查詢語句(select)返回的多條記錄進行處理,而隱式游標是在執行插入(insert)、刪除(delete)、修改(update)和返回單條記錄的查詢(select)語句時由PL/SQL自動定義的。

    1、顯式游標操作

    顯式游標在塊定義部分、包或子程序中聲明。當聲明了顯式游標后,可以通過以下三條命令控制顯式游標的操作:打開游標、推進游標、關閉游標。

    (1)聲明顯式游標

    --例1


    declare   
    v_auths auths%rowtype;   
    v_code auths.author_code%type;   
    cursor c_auths is    
        select * from auths where author_code=v_code;

    上例是將PL/SQL變量綁定在WHERE子句中,下面將游標參數綁定在游標的WHERE子句中:

    --例2


    delcare   
    cursor c_auths(p_code auths.author_code%type) is   
        select * from auths where author_code=p_code;  

     

    (2)打開顯式游標

    游標操作的第一步是打開游標。

    例1,下面的語句是打開上節例1中聲明的顯式游標c_auths;


    begin   
    --在打開游標前為綁定變量賦值。   
    v_code:='A00001';   
    --打開游標。   
    open c_auths;  


    例2,如果對于一個帶參數的游標


    begin   
    --打開游標時將參數傳入。   
    open c_auths('A00001');  


    打開一個已打開的游標也是合法的。當第二次打開游標時,PL/SQL先自動關閉游標,然后再打開。一次打開多個游標也是PL/SQL所允許的。

    (3)推進顯式游標

    當打開顯式游標后,就可以使用FETCH語句來推進游標,返回查詢結果集中的一行。每執行完一條FETCH語句后,顯式游標會自動指向查詢結果集的下一行。

    (4)關閉顯式游標

    當整個結果集都檢索完以后,應當關閉游標。關閉游標用來通知PL/SQL游標操作已經結束,并且釋放游標所占用的資源(結果集所使用的資源空間)。

    2、游標的屬性

    游標有四個屬性:%found、%notfound、%isopen和%rowcount。要注意這些屬性只能使用在過程性語句中,而不能使用在SQL語句中。

    表tableattribute,表中有兩列column1(number類型)和column2(varchar2類型),現在向表中插入兩條記錄:

    insert into tableattribute values(10,'first');

    insert into tableattribute values(20,'second');

    ...

    3、顯式游標的推進循環


    delcare   
    --聲明一個變量,這個變量用來接收游標返回的結果集。   
    v_salary auths.salary%type;   
    v_code auths.author_code%type;   
    /*聲明游標,該游標的查詢結果集是作家代碼為"A00001"到"A00006"的工資值。*/  
    cursor c_salary is select salary,author_code from auths where author_code<='A00006';   
    begin   
    --打開游標,并初始化結果集   
    open c_salary;   
    loop   
        --推進游標,將游標的查詢結果集中的一行存到變量v_salary中。   
        fetch c_salary into v_salary,v_code;   
        --當結果集中沒有行時退出循環。   
        exit when c_salary%notfound;   
        --如果查詢到的作家工資小于或等于200,則增加該作家的工資值。   
        if v_salary<=200 then   
          update auths set salary=salary+50 where author_code=v_code;   
        end if;   
    end loop;   
    --關閉游標,釋放游標占用資源。   
    close c_salary;   
    --提交所做的修改。   
    commit;   
    end;  


    PL/SQL還提供了一種簡單類型的循環,可以自動控制游標的打開、推進和關閉,叫做游標的FOR循環。


    delcare   
    cursor c_salary is   
        select salary form auths where author_code<='A00006';   
    begin   
    --開始游標FOR循環,隱含地打開c_salary游標。   
    for v_salary in c_salary loop   
        --一個隱含的fetch語句在這里被執行。   
      if v_salary.salary<=200 then   
          update auths set salary=salary+50 where salary=v_salary.salary;   
        end if;   
        --在循環繼續前,一個隱含的c_auths%notfound被檢測。   
     end loop;   
    --現在循環已經結束,c_auths游標的一個隱含的close操作被執行。   
    commit;   
    end;  


    使用current of cursor子句作為條件


    delcare   
    --聲明游標時在select語句中必須加for update of子句。   
    cursor c_salary is   
        select salary form auths where author_code<'A00006' for update of salary;   
    begin   
    for v_salary in c_salary loop   
        if v_salary.salary<=200 then   
          --下面的update語句中的current of子句用來表明結果集的當前行。
        update auths set salary=salary+50 where current of c_salary;  
        end if;   
    end loop;   
    commit;   
    end;  

     

    如果在游標的FOR循環中使用子查詢,則不用在塊定義部分聲明顯式游標,在FOR循環中子查詢隱含聲明了一個顯式游標。


    begin   
    --在下面的FOR循環中隱含地聲明了一個游標c_salary。   
     for c_salary in   
    (select salary form auths where author_code<='A00006') loop   
        if c_salary.salary<=200 then   
          update auths set salary=salary+50 where salary=c_salary.salary;   
        end if;   
    end loop;   
    commit;   
    end;  


    4、隱式游標處理

    PL/SQL隱式地打開SQL游標,并在它內部處理SQL語句,然后關閉它。SQL游標用來處理insert、update、delete以及返回一行的select...into語句。

    一個SQL游標不管是打開還是關閉,open、fetch和close命令都不能操作它。SQL游標與顯式游標類似,也有四個一樣的屬性。當打開SQL游標之前,SQL游標的屬性都為NULL。


    begin   
    update auths set entry_date_time=sysdate where author_code='A00017';   
    --如果update語句中修改的行不存在(SQL%notfound返回值為true),則向auths表中插入一行。   
    if sql%nofound then   
        insert into auths(author_code,name,sex,birthdate,salary,entry_date_time)   
          values('A000017','qiuys',1,'30-apr-40',88.5,sysdate);   
    end if;   
    end;  


    --如果update語句中修改的行不存在(sql%rowcount=0)


    declare   
    v_birthdate date;   
    begin   
    select birthdate into v_birthdate from auths where name='qiuys';   
    --如果查詢到一條記錄,則刪除該記錄。   
    if sql%found then   
        delete from auths where name='qiuys';   
    end if;   
    exception   
    when no_data_found then   
        dbms_output.put_line('該記錄不存在');   
    when too_many_rows then   
        dbms_output_line('存在同名的作家');   
    end;  


    5、游標變量

    到目前為止前面所有顯式游標的例子都是靜態游標-即游標與一個SQL語句關聯,并且該SQL語句在編譯時已經確定。

    而游標變量是一個引用類型(REF)的變量。

    (1)游標變量的聲明


    declare   
    --使用%rowtype定義一個游標變量類型。   
    type t_authsref is ref cursor return auths%rowtype;   
    --定義一個記錄類型。   
    type t_coderecord is record(   
        author_code article.author_code%type,   
        article_code article.article_code%type);   
    --聲明一個記錄類型的變量。   
    v_code t_coderecord;   
    --使用t_coderecord作為一個游標變量類型的結果集類型。   
    type t_coderef is ref cursor return t_codeRecord;   
    --使用v_code作為一個游標變量類型的結果集類型。   
    type t_coderef2 is ref cursor return v_code%type;   
    --使用上面的類型聲明的兩個游標變量。   
    v_authcv t_authsref;   
    v_codecv t_coderef;  


    PL/SQL2.8以上版本中,可以使用一個沒有指定結果集類型的游標變量(沒有RETURN)來指定多個不同類型的查詢。

    type t_authsref if ref cursor;

    v_cursorvar t_authsref;--聲明一個該類型的變量。

    (2)打開游標變量

    為了將一個游標變更與一個具體的select語句聯系起來,open的語法中增加了一個select語句。


    open cursor_variable for select_statement;   
    declare   
    type t_authorsref is ref cursor return auths%rowtype;   
    v_authscv t_authorsref;   
    --然后打開   
    open v_authscv for select * from auths;  


    3)推進游標變更

    (4)關閉游標變更

    該操作用來釋放查詢所占用的資源。但沒有釋放游標變量占用的存儲空間。當變量超出作用域時,它所占用的空間才被釋放掉。

    下面的塊中定義了一個沒有指定結果集的游標變量,這樣我們就可以使用這個游標變量指向不同的查詢,并能夠返回不同的記錄類型:


    set serveroutput on size 100000 --設置存儲緩沖區大小。   
    declare   
    /*定義游標變更類型t_curref,該游標變量類型沒有指定結果集類型,所以該游標變量類型的變量可以返回不同的PL/SQL記錄類型。*/  
    type t_curref is ref cursor;   
    --聲明一個游標變量類型的變量   
    c_cursorref t_curref;   
    --定義PL/SQL記錄類型t_authorrec,該類型的變量用來接收游標變量的返回值。   
    type t_authorrec is record(   
        authorcode auths.author_code%type,   
        name auths.name%type);   
    --定義PL/SQL記錄類型t_articlerec,該類型的變量也用來接收游標變量的返回值。   
    type t_articlerec is record(   
        authorcode article.author_code%type,   
        title artitle.title%type);   
    --聲明兩個記錄類型變量。   
    v_author t_authorrec;   
    v_article t_articlerec;   
    begin   
    --打開游標變量c_cursorref,返回t_authorrec類型的記錄。   
    open c_cursorref for    
        select author_code,name from auths where author_code in('A00001','A00002','A00003','A00004','A00005');   
    --推進游標變量   
    fetch c_cursorref into v_author;   
    --游標變量的推進循環。   
    while c_cursorref%found loop   
        --將作家代碼和相應的作家名字輸出到屏幕上。   
        dbms_output.put(v_author.authorcode||':'||v_author.name||' ');   
        fetch c_cursorref into v_author;   
    end loop;   
    dbms_output.new_line;--向屏幕上輸出一個回車行。   
    --關閉游標變量,僅僅將游標變量指定的資源釋放掉,游標變量本身的存儲空間沒有釋放掉。   
    close c_cursorref;   
    --再次打開游標變量,返回t_articlerec類型的記錄。   
    open c_cursorref for    
        select author_code,title from article   
        where author_code in('A00001','A00002','A00003','A00004','A00005');   
    fetch c_cursorref into v_article;   
    while c_cursorref%found loop   
        ...   
    end loop;   
    close c_cursorref;   
    end;  


    注意,在上例中,第一次關閉游標變量是可省略的,因為在第二次打開游標變量時,就將第一次的查詢丟失掉了。而且游標變量也有游標屬性,通常在推進游標變量時使用這些游標屬性,例如上例使用了%found屬性。

    posted on 2009-06-02 16:01 rogerfan 閱讀(3486) 評論(0)  編輯  收藏 所屬分類: 【數據庫】
    主站蜘蛛池模板: 国产vA免费精品高清在线观看| 最近新韩国日本免费观看| 亚洲成av人影院| 国产精品免费观看| 老司机午夜免费视频| 亚洲精品线在线观看| 午夜一区二区免费视频| gogo免费在线观看| 亚洲乱码一区av春药高潮| 亚洲国产精品成人一区| aⅴ免费在线观看| 精品在线视频免费| 久久亚洲精品无码aⅴ大香| 日韩视频在线免费| 免费观看91视频| 国产精品亚洲天堂| 亚洲国产视频一区| 国产亚洲情侣一区二区无码AV| 午夜福利不卡片在线播放免费| 一进一出60分钟免费视频| 亚洲an日韩专区在线| 亚洲精品国产精品乱码视色 | 亚洲AV无码国产精品色午友在线| 免费大片黄在线观看yw| 国产免费福利体检区久久| 亚洲一区二区观看播放| 亚洲人成影院在线| 国产午夜亚洲精品国产成人小说| 在线观看免费人成视频色| 全免费a级毛片免费看| 色妞www精品视频免费看| 亚洲无mate20pro麻豆| 亚洲av激情无码专区在线播放| 一级毛片直播亚洲| 日韩免费a级毛片无码a∨| 香蕉免费一区二区三区| WWW国产成人免费观看视频| 亚洲成a∧人片在线观看无码| 亚洲宅男天堂a在线| 亚洲一区二区三区夜色| 亚洲日韩精品一区二区三区无码 |