游标

来源:互联网 发布:c 低级编程 编辑:程序博客网 时间:2024/06/04 20:45

参考: http://www.cnblogs.com/sc-xx/archive/2011/12/03/2275084.html

PL/SQL中游标分为两类:

显式游标:由用户定义、操作,用于返回多行数据的select查询。

隐式游标:由系统自动进行操作,用于处理DML语句和返回单行数据的select查询。

 

   显式游标有下列四个属性。

    (1)%ISOPEN

    (2)%FOUND

    (3)%NOTFOUND

    (4)%ROWCOUNT

1. 游标声明

CURSOR cursor_name IS select_statement

2. 显式游标检索

    2.1  简单循环检索游标  exit ... when  cursor_name%NOTFOUND

-- fetch...into...   exit when cursor_name%notfound  declare   cursor c_user  is  select cust_no,cust_nm,cust_type  from zct_customer  where rownum<10;  c_row c_user%rowtype; begin  open c_user;       loop         fetch c_user into c_row;         exit when c_user%notfound;         dbms_output.put_line(c_row.cust_nm||'-'||c_row.cust_no);        end loop;   close c_user; end;

    2.2 while循环检索游标   while cursor_name%FOUND LOOP

-- while   declare   cursor c_user  is  select cust_no,cust_nm,cust_type  from zct_customer  where rownum<10;  c_row c_user%rowtype; begin  open c_user;         fetch c_user into c_row;         while c_user%found loop         dbms_output.put_line(c_row.cust_nm||'-'||c_row.cust_no||'-'||c_row.cust_type);         fetch c_user into c_row;        end loop;   close c_user; end;

    2.3 for循环检索游标       for loop_variable in cursor_name LOOP

-- for ... in   declare   cursor c_user  is  select cust_no,cust_nm,cust_type  from zct_customer  where rownum<10;  c_row c_user%rowtype; begin         for c_row in c_user loop         dbms_output.put_line(c_row.cust_nm||'-'||c_row.cust_no);        end loop; end;

3. 游标更新或删除数据

如果要利用游标更新或删除数据,需要在游标定义中使用 for update子句,对要修改或删除的数据加锁。语法:

    cursor cursor_name is

     select select_list_item from table for update;

  若定义游标使用 for update子句,则在执行时,可以在update语句或delete语句中使用 where current of 子句,以修改或删除由表中当前行所对应的数据库中的数据,

  语法为:

    where current of cursor_name;

注意:如果游标定义时没有使用 for update子句,则不能用游标修改或者删除数据库中的数据。

declare      cursor      c_emp     is      select * from emp where ENAME LIKE 'A%' OR ENAME LIKE 'S%' for update;      v_increment number;      v_emp c_emp%rowtype;begin      for v_emp in c_emp loop          dbms_output.put_line(r_AddSal.ENAME||'原来的工资:'||r_AddSal.SAL);          case v_emp.deptno             when 10 then v_increment := 100;             when 20 then v_increment := 200;             when 30 then v_increment := 300;             else v_increment := 80;          end case;          UPDATE emp SET SAL=v_increment WHERE CURRENT OF c_emp;      end loop;end;

注意:由于commit 语句会释放会话拥有的任和锁,因此如果在检索游标的循环内使用 commit 语句会释放定义游标时对数据加的锁,导致利用游标修改或删除数据的操作失败。

4.隐式游标

       显式游标用于处理返回多行数据的 select 查询,但所有的SQL语句都有一个执行的缓冲区,隐式游标就是执行该缓冲区的指针,由系统隐含的打开、处理和关闭。隐式游标又称为SQL游标。

      隐式游标主要用于处理  INSERT、UPDATE、DELETE 以及单行的 select ... into 语句,没有 OPEN、 FETCH、 CLOSE等操作命令。

     与显式游标类似,隐式游标也有下列四个属性。

    (1)SQL%ISOPEN

    (2)SQL%FOUND

    (3)SQL%NOTFOUND

    (4)SQL%ROWCOUNT

BEGINUPDATE emp SET sal = sal+100 WHERE empno=1000;     IF SQL%NOTFOUND THEN        INSERT INTO emp(empno,sal) VALUES(1000,1500);     END IF;END;

begin         update emp set ENAME='ALEARK' WHERE EMPNO=7469;         if sql%isopen then           dbms_output.put_line('Openging');           else             dbms_output.put_line('closing');             end if;          if sql%found then            dbms_output.put_line('游标指向了有效行');--判断游标是否指向有效行            else              dbms_output.put_line('Sorry');              end if;              if sql%notfound then                dbms_output.put_line('Also Sorry');                else                  dbms_output.put_line('Haha');                  end if;                   dbms_output.put_line(sql%rowcount);                   exception                      when no_data_found then                       dbms_output.put_line('Sorry No data');                       when too_many_rows then                         dbms_output.put_line('Too Many rows');                         end;







0 0
原创粉丝点击