1. 程式人生 > >Oracle遊標的概念和簡單應用

Oracle遊標的概念和簡單應用

概念: 

    遊標用於處理select語句的查詢結果(結果集 ResultSet) , 

    有些人也認為 遊標就是查詢結果 

使用步驟與語法格式(非滾動遊標)

    1.  宣告遊標

            申明區: 
                cursor 遊標名稱  is select語句;
    2.  開啟遊標

            open 遊標名稱;

    3.  提取一行資料(遊標向下移動)

            fetch 遊標名稱 into 變數;--將遊標中的某一行賦值給一個變數!

    4.  關閉遊標
            close  遊標名稱;

            1.  資源為什麼要關閉: 
                    控制代碼數量 1024

            2.  已關閉的資源可以重複關閉嗎? 

                遊標的開啟與關閉  不可重複執行, 否則報錯
例子: 定義一個遊標 , 用來存放s_emp表中的 id, last_name,salary ,然後提取遊標的前五條資料, 並列印 , 最後關閉遊標!


set serveroutput on;
declare
    /*宣告遊標*/
    cursor s_emp_c is select id,last_name,salary from s_emp;
    /*宣告一個型別, 匹配結果集中一行的資料型別*/
    type myemp is record(
        id s_emp.id%type,
        last_name s_emp.last_name%type,
        salary s_emp.salary%type
    );
    /*宣告一個變數,用來承接遊標取出的資料*/
    var_me myemp;
begin
    /*開啟遊標*/
    open s_emp_c;
    /*遊標向下移動一行, 並取出資料*/
    for i in 1..5 loop
        fetch s_emp_c into var_me;
        dbms_output.put_line('這個員工的編號為:'||var_me.id||',名稱為:'||var_me.last_name||',他的月薪為:'||var_me.salary);
    end loop;
    close s_emp_c;
end;
使用 遊標名稱%rowtype
定義一個遊標 , 用來存放s_emp表中的 id, last_name,salary ,然後提取遊標的前五條資料, 並列印 , 最後關閉遊標!


set serveroutput on;
declare
    /*宣告遊標*/
    cursor s_emp_c is select id,last_name,salary from s_emp;

    /*宣告一個變數, 通過遊標名稱%rowtype 獲取一個匹配當前遊標中資料型別訂單record變數
    */
    var_me  s_emp_c%rowtype;
begin
    /*開啟遊標*/
    open s_emp_c;
    /*遊標向下移動一行, 並取出資料*/
    for i in 1..5 loop
        fetch s_emp_c into var_me;
        dbms_output.put_line('這個員工的編號為:'||var_me.id||',名稱為:'||var_me.last_name||',他的月薪為:'||var_me.salary);
    end loop;
    close s_emp_c;
end;
/

通過遊標 獲取 多個表中的資料

查詢s_dept 中的name欄位 和 s_region中的name欄位 ,通過遊標進行操作

set serveroutput on;

declare
    cursor dr_c is select d.name dn,r.name rn from s_dept d,s_region r where d.region_id=r.id;

    var_dr dr_c%rowtype;
begin
    open dr_c;

    fetch dr_c into var_dr;

    dbms_output.put_line('部門名稱:'||var_dr.dn||',地區名稱:'||var_dr.rn);

    close dr_c;
end;
/

遊標屬性

使用一些屬性, 進行迴圈遍歷遊標操作

1.  遊標名稱%found  

    如果遊標提取到了新資料 , 則返回true , 否則返回false .

2.  遊標名稱%notfound

    如果遊標提取不到新資料 , 則返回true , 提取到了資料返回false

-------------------------------------------

上面的兩個屬性, 想要使用, 必須滿足兩個前提條件: 

    1.  遊標 必須 是開啟狀態 ! 否則出現非法遊標操作

    2.  遊標 必須 執行過 fetch (遊標在結果集中任意一行) , 否則返回null
   通過遊標獲取s_emp表格中的(id,last_name,salary), 獲取所有行

declare
    cursor myemp is select id,last_name,salary from s_emp;
    var_me myemp%rowtype;
begin
    open myemp;
    loop
        fetch myemp into var_me;
        exit when myemp%notfound;
        dbms_output.put_line('員工編號:'||var_me.id||',姓名:'||var_me.last_name||',員工月薪:'||var_me.salary);
    end loop;
    close myemp;
end;

智慧迴圈遍歷遊標

for迴圈 , 在進行遊標的迭代時 , 

    會自動定義變數, 
    自動開啟遊標, 
    自動提取資料, 
    自動關閉遊標 .


使用for迴圈 獲取s_emp表格中的id,last_name,salary

declare
    cursor myemp is select id,last_name name,salary from s_emp;
begin
    for var_me in myemp loop
            /*
                在這個迴圈中 , var_me就是每次迴圈迭代時的 每一行的資料
            */
        dbms_output.put_line('id='||var_me.id||', name='||var_me.name||', 月薪='||var_me.salary);
    end loop;
end;
/

帶引數的遊標

一個遊標在定義時 , 
可以設計,在開啟時需要傳遞引數 , 這個引數是 可以在select語句中使用的

格式:

cursor 遊標名稱(引數列表) is select語句
1.  引數的型別不能使用長度修飾 , 可以通過%type傳遞型別

2.  引數傳遞的時機:
    在開啟遊標時 傳入 ,
    例如:
    open 遊標名稱(引數);


根據使用者輸入的id , 查詢一個員工的資訊(id,last_name_salary)
set serveroutput on;
declare
    cursor myemp(var_id number) is select id,last_name name,salary from s_emp where id=var_id;

    var_me myemp%rowtype;
    var_input number;
begin
    var_input :=&請輸入您要查詢的員工的id;
    open myemp(var_input);
    fetch myemp into var_me;
    dbms_output.put_line(var_me.name);
    close myemp;
end;
/
使用智慧迴圈時 ,如何傳遞引數
根據使用者輸入的id , 查詢員工編號大於使用者輸入的員工編號的員工的資訊(id,last_name_salary)
set serveroutput on;
declare
    cursor myemp(var_id number) is select id,last_name name,salary from s_emp where id>var_id;

    var_input number;
begin
    var_input :=&請輸入員工的id;

    for  var_me in myemp(var_input) loop

        dbms_output.put_line('id='||var_me.id); 

    end loop;

end;
/

參考遊標 ref cursor

概念: 

    遊標對應的select語句, 不必在申明區就指定, 可以在開啟遊標時 指定SQL語句

語法格式:

    1.  申明區定義一個參考遊標的型別

        type 參考遊標型別名稱 is ref cursor;

    2.  定義一個變數

        變數名稱 參考遊標型別;

    3.  開啟遊標, 並關聯SELECT語句

        open 遊標變數名稱 for 'SELECT語句';

例子:
根據使用者輸入的id , 查詢員工編號大於使用者輸入的員工編號的員工的資訊

之前進行遊標的遍歷時 ,我們通過遊標的名稱%rowtype獲取型別

在參考遊標中 時無法這樣去做的, 因為在申明區, 遊標還不知道自己的行型別
set serveroutput on;
declare
    type mc is ref cursor;
    var_mc mc;
    -- 這個字串 , 就是用來做SQL查詢語句的
    var_select varchar2(3000);
    var_input number;

    type myemp is record(
        id  s_emp.id%type,
        salary s_emp.salary%type
    );
    var_me myemp;
begin
    var_input:=&請輸入員工id;
    var_select:='select id,salary from s_emp where id>'||var_input;
    open var_mc for var_select;

    loop
        fetch var_mc into var_me;
        exit when var_mc%notfound;
        dbms_output.put_line('員工的id:'||var_me.id||',員工的薪資:'||var_me.salary);
    end loop;
end;
/