1. 程式人生 > >遊標的概念、作用、屬性、查詢操作、可更新的遊標

遊標的概念、作用、屬性、查詢操作、可更新的遊標

       一、遊標的主要針對操作物件是從資料庫返回的結果集,廣義上可以理解為是從結果集中一行一行讀取資料的方法,一種機制,狹義上也可以將遊標理解為所要操作的結果集,因為在操作的最開始就需要給遊標指定一個要操作的結果集(corsor c is select ....),也可以將遊標理解為操作的每一行的而形成的臨時檔案,裡面存放的是讀取出來的該行的副本,這個臨時檔案提供了向前遍歷和向後遍歷以及處理資料的能力。

        二、遊標最常用的作用,就是查詢資料,大多的語言都支援使用遊標來檢索SQL資料庫中的資料,並儲存查詢的結果以供之後使用,比如我們在日常過程中需要重複處理容易個結果集,我們就可以選擇只加載一次結果集,建立一個遊標並反覆使用,這樣就比多次建立結果集效率要高的多。

        三、遊標的四個屬性(一下預設curcor_name都為c)

1、%notfound  最近一次fetch後是否取到結果,布林型別,如果有結果就返回true

    舉個栗子:

                open c;

                    loop

                        fetch c into v_name;

                        exit when(c%notfound);

                        dbms_output.put_line(v_name.vname);

                   end loop;

                close c;

2、%found  最近一次fetch後是否取到結果,布林型別,如果沒有,則為false

     舉個例子:

                   open c;

                        while c%found loop

                            ....

                            fetch c into v_name;

                        end loop;

                    close c;

3、%rowcount  返回的是遊標取到的行數 為number型別

    舉個栗子:

                      open c;

                            loop

                                fetch c into v_name;

                                exit when c%rowcount>5;

                                ....

                            end loop;

                      close c;

4、%isopen 表示的是此刻否開啟遊標,是布林型別,當開啟時為true,一般用的比較少;

    舉個栗子:如果想判斷遊標是否開啟,如果沒有開啟就執行開啟的操作

                 if not(c%isopen) then

                        open c;

                 end if;

                 fetch c into....;


        四、用遊標進行簡單的查詢操作

        注意:如果想讓cmd打印出來我們要求的結果,需要提前加上一條語句:set serveroutput on

                declare 

                        cursor c is  (宣告一個遊標並指向如下查詢語句的結果集)

                                  select * from emp;

                        v_emp c%rowtype;  (生命一個變數,遊標指向的是返回結果集的行)

                begin

                        open c;  (開啟遊標後才會執行查詢語句)

                                fetch c into v_emp;   (捕捉到一行結果放到變數v_emp中)

                                dbms_output.put_line(v_emp.ename);  (列印得到的結果中的ename欄位)

                        close c;

                   end; 

                    /

        五、使用loop迴圈的方式遍歷結果集

                declare 

                        cursor c is

                                select * from emp;

                        v_emp c%rowtype;

                begin

                        open c;

                            loop

                                    fetch c into v_emp;

                                    exit when(c%notfound);

                                    dbms_output.put_line(v_emp.ename);

                            end loop;

                        close c;

                end; 

                /

        (注:如果此處將列印語句與判斷何時退出的語句交換位置,會出現將最後一個查到的資料重新列印一遍的情況)

        六、使用while迴圈遍歷得到資料

                declare

                        cursor c is

                                select * from emp;

                        v_emp c%rowtype;  //使用while遍歷,仍然需要對v_emp進行宣告

                begin

                        open c;

                                fetch c into v_emp;

                                while(c%found) loop   (噹噹前最近的一次遊標發現了一行的時候執行如下語句)

                                        dbms_output.put_line(v_emp.ename);

                                        fetch c into v_emp;

                        end loop;

                        close c;

                end;

                /

    七、使用for迴圈遍歷資料

                declare

                        corsor c is 

                                select * from emp;

                begin

                        for v_emp in c loop

                                dbms_output.put_line(v_emp.ename);

                        end loop;

                end;

    八、帶引數的遊標

                declare

                        cursor c(v_deptno emp.deptno%type,v_job emp.job%type)

                        is

                                select ename,sal from emp where deptno = v_deptno and job = v_job;

                    begin

                            for v_temp in c(30,'CLERK') loop

                                    dbms_output.put_line(v_temp.ename);

                            end loop;

                    end;

                    /

    九、可更新的遊標

            declare

                    cursor c is

                            select * from emp for update;

             begin

                        for v_temp in c loop;

                                if(v_temp.sal < 2000) then

                                        update emp set sal = sal*2 where current of c(指當前遊標);

                                 elsif (v_temp.sal = 5000) then

                                        delete from emp where current of c;

                                  end if;

                         end loop;

                         commit;

                end;