遊標For..Loop與Open..Close的比較

最近,在項目開發過程中,通過在存儲過程、函數、包的使用過程,對遊標有了一定的認識,所以,總結下來。
首先,舉一個簡單的例子,來比較一些通過For..Loop讀取遊標和Open..Close的區別。
-- declare
   -- this cursor is get table employee's info
cursor   cur_employee   is
       select  *   from   employee;

         -- this curso is get table dept's info
cursor   cur_dept   is
       select  *   from   dept;

         -- this cursor is get table employee & dept  info
cursor  cur_info  is
       select  e.*,   d.dept_name
    from  employee e ,  dept d
    where  e.dept_no  =  d.dept_no(+);


        -- to save cursor record's value

v_employee_row employee%rowtype;
v_dept_row dept%rowtype;

 

-- for .. loop
for v_row in cur_employee loop
   -- TODO-A
end loop;
   -- TODO-B

 

-- open ..close
open cur_employee
    fetch cur_employee into v_employee_row;
close cur_table_test;

 

     1.使用For..Loop的方式讀取cursor,open、fetch、close都是隱式打開的。所以,不用擔心忘記關閉遊標而造成性能上的問題。
     2.使用For..Loop的代碼,代碼更加乾淨、簡潔,而且,效率更高。
     3.使用For..Loop讀取遊標後,存儲記錄的變量不需要定義,而且,可以自動匹配類型。假如讀取多個表的記錄,顯然用Open的fetch..into就顯得相當困難了。
     fetch cur_info into X (這裏的就相當麻煩,而且,隨着涉及的表、字段的增加更加困難)    
     4.For..Loop在使用遊標的屬性也有麻煩的地方。因爲記錄是在循環內隱含定義的,所以,不能在循環之外查看遊標屬性。
         假如要做這樣的處理:當遊標爲空時,拋出異常。把下面的讀取遊標屬性的代碼:
if   cur_employee%notfound  then
   -- can not found record form cursor
    RAISE_APPLICATION_ERROR(error_code, error_content);
end if;

放在<< TODO-B >>的位置,雖然編譯可以通過,但在運行時,就會報錯:ORA-01001:invalid cursor
放在<< TODO-A>>的位置,讀取遊標的notfound屬性。顯然,也是不行的。因爲,如果遊標爲空的話,就會直接跳出循環,根本不會執行循環體內的代碼。但是,也並不是說,就不能使用For..Loop來處理了。可以通過設置標誌字段處理。
定義變量:v_not_contain_data bollean default true;
For..Loop循環內增加一行代碼:v_not_contain_data := false;
這樣,在循環體外可以通過標誌位來判斷:
         If v_not_contain_data then
     RAISE_APPLICATION_ERROR(error_code, error_content);
end if;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章