PLSQL遊標詳解

  一、在PL/SQL程序中定義的遊標稱做顯示遊標。顯示遊標處理需四個PL/SQL步驟:

   1)cursor 遊標名稱 is 查詢語句;

   2)open 遊標名稱

   3)Fectch 遊標名稱 into 變量列表;

   4)close 遊標名稱


   例:學習使用遊標,順便使用%type


   --使用while循環

   declare 

       employee emp.ename %type;

         salary emp.sal %type;

         cursor cursor_test is   select ename,sal from emp;

   begin

         open cursor_test;

         fetch cursor_test into employee,salary;

         while cursor_test %found loop

           dbms_output.put_line(employee||':'||to_char(salary));

           fetch cursor_test into employee,salary;

         end loop;

         close cursor_test;

     end;



     --使用loop循環實現

     declare

       V_ename emp.ename %type;

       V_sal emp.sal %type;

       cursor c1 is select ename,sal from emp;

     begin

       open c1;

       loop

           fetch c1 into V_ename,V_sal;

           dbms_output.put_line(V_ename||to_char(V_sal));

           exit when c1 % notfound;

         end loop;

       close c1;

     end;

二、帶參數的遊標

1)eg:


declare

-- 遊標的參數,只能接受傳遞的值,而不能返回值,參數只定義數據類型,沒有大小。能夠給參數賦一個缺省值。

cursor c1(p_deptno varchar2) is select ename,sal from emp where 


emp.deptno=p_deptno; 

v_deptno varchar2(3);

v_ename emp.ename %type;

v_sal emp.sal %type;

begin

v_deptno := '06';

dbms_output.put_line(v_deptno||':');

open c1(v_deptno);   --在打開遊標時對參數賦值

loop

fetch c1 into v_ename,v_sal;

dbms_output.put_line(v_ename||to_char(v_sal));

exit when c1%notfound;

end loop;

close c1;

end;


2)

eg:給遊標加入缺省值,同時練習使用%rowtype


declare

--給參數設定默認值時,能夠使用: 參數名 參數類型 DEfault 缺省值 或者是參數           名 參數類型 := 缺省值

cursor c1(p_deptno varchar2 DEFAULT '05') is select * from emp where 


emp.deptno=p_deptno;   

v_emp emp%rowtype; /*練習使用%rowtype,能夠經過"變量.字段名"來引用數據庫中的內容 */

v_deptno varchar2(2);

begin

v_deptno := '06';

open c1(v_deptno);

loop

fetch c1 into v_emp;

dbms_output.put_line(v_emp.ename||to_char(v_emp.sal));

exit when c1%notfound;

end loop;

close c1;

end;

三、隱式遊標

咱們能夠使用for循環來對遊標進行隱式處理。For循環中變量v_test不須要在聲明部分聲明,它由PLSQL編譯器進行隱式的聲明。而且for循環開始的時候,遊標也就隱式地打開了。

declare

   cursor thy_test_cursor is

     select empno, ename, job, mgr, hiredate, sal + comm salary, dname

       from emp, dept

     where emp.deptno = dept.deptno;


begin

           --遊標的當前記錄已被隱式地提取給變量 v_test

   for v_test in thy_test_cursor loop 

     dbms_output.put_line(v_test.ename || ' ' || v_test.dname || ' ' ||to_char(v_test.salary));

   end loop;

end;

三、遊標修改和刪除操做

遊標修改和刪除操做是指在遊標定位下,修改或刪除表中指定的數據行。這時,要求遊標查詢語句中必須使用for update選項。

爲了對正在處理(查詢)的行不被另外的用戶改動,oracle提供一個for update子句來對全部選擇的行進行鎖定,該需求迫使oracle鎖定遊標結果集合的行,能夠防止其餘事務處理更新或刪除相同的行,直到您的事務處理提交或回退爲止。

語法:

Select…from..for update [of column[,column]…][nowait]

如 果另外一個會話已對活動集中行加了鎖,那麼select for update操做一直等待到其它的會話釋放這些鎖後才繼續本身的操做,對於這種狀況,當加上nowait子句時,若是這些行真的被另外一個會話鎖定,則 open當即返回並給出:ora-0054:resource busy and acquire with nowait specified。若是使用for update聲明遊標,則可在delete和update語句中使用where current of cursor_name 子句,修改或刪除遊標結果集合當前行對應的數據表中數據行。

         declare

         cursor c_thy2 is

           select * from emp for update of sal;

begin

           for v_record in c_thy2 loop

             if v_record.sal < 1000 then

                 update emp set sal = 1000, comm = 200 where current of c_thy2;

             end if;

           end loop;

           commit;

             end;

-------------------------------------------------------------------------------------------------------------------------------
我本身寫的程序

declare 
   mycrdbalance biactcardacctb.crdbalance %type;
   mycrdpaccno biactcardacctb.crdpaccno %type;
   cursor my_cursor is   select crdpaccno,crdbalance from biactcardacctb where crdrealbal='0' and crdbalance!='0';
begin
   open my_cursor;
   fetch my_cursor into mycrdpaccno,mycrdbalance;
   while my_cursor %found loop
         update biactcardacctb set crdrealbal=mycrdbalance where crdpaccno=mycrdpaccno;
         fetch my_cursor into mycrdpaccno,mycrdbalance;
   end loop;
   close my_cursor;
end;數據庫

相關文章
相關標籤/搜索