cursor之for loop、for update of

原文地址:http://blog.csdn.net/csdn1234/article/details/4000924

一.游标式for循环

不用显式open和close游标

SQL> DECLARE
  2     CURSOR c_orders IS SELECT * FROM orders;
  3     v_order orders%ROWTYPE;
  4  BEGIN
  5     OPEN c_orders;
  6     FOR v_order IN c_orders LOOP
  7        DBMS_OUTPUT.PUT_LINE(v_order.orderid||':'||v_order.positioncode);
  8     END LOOP;
  9     CLOSE c_orders;
 10  END;
 11  /

结果:

DECLARE
*
第 1 行出现错误:
ORA-06511: PL/SQL: 游标已经打开
ORA-06512: 在 line 2
ORA-06512: 在 line 6

为什么会出现错误呢?因为游标式for循环已经隐式地进行了游标的open、fetch、close处理.

SQL> DECLARE
  2     CURSOR c_orders IS SELECT * FROM orders;
  3     v_order orders%ROWTYPE;
  4  BEGIN
  5     --这里会隐式地打开游标
  6     FOR v_order IN c_orders LOOP
  7       --隐式fetch记录
  9       --进行c_orders%NOTFOUND判断
  8       DBMS_OUTPUT.PUT_LINE(v_order.orderid||':'||v_order.positioncode);
 10     END LOOP;
 11  END;
 12  /

 

二.FOR UPDATE与FOR UPDATE OF

 

1.用来给游标基表加行锁.

 

2.FOR UPDATE OF COLUMN1[,COLUMN2,..]

是指示后面的操作将更新哪些列,会给这些列所在的基表加行锁.并不是约束只能更新这些列,更新其它列也可以.

 

3.WHERE CURRENT OF

FOR UPDATE和FOR UPDATE OF只能指向一个表,不能指向多个表.

DECLARE
  CURSOR c_orders IS select a.orderid id1,b.orderid id2,a.positioncode,b.showcount from
  orders a,order2 b where a.orderid=b.orderid FOR UPDATE OF positioncode,showcount;
  v_order c_orders%ROWTYPE;
BEGIN
  OPEN c_orders;
  
  LOOP
    FETCH c_orders  INTO v_order;
    EXIT WHEN c_orders%NOTFOUND;
    dbms_output.put_line(v_order.id1||','||v_order.id2||','||v_order.positioncode||','||v_order.showcount);
    UPDATE order2 SET showcount=8 WHERE CURRENT OF c_orders;
    IF SQL%NOTFOUND THEN
      DBMS_OUTPUT.PUT_LINE('NOT FOUND');
    END IF;
  END LOOP;
  COMMIT;
  CLOSE c_orders;
END;

执行的结果是:

1,1,C,9
NOT FOUND
2,2,C,9
NOT FOUND
3,3,C,9
NOT FOUND
4,4,C,9
NOT FOUND
5,5,C,9
NOT FOUND

将FOR UPDATE OF positioncode,showcount换成FOR UPDATE也是同样的结果.

换成FOR UPDATE OF showcount,只指向一个表.

DECLARE
  CURSOR c_orders IS select a.orderid id1,b.orderid id2,a.positioncode,b.showcount from
  orders a,order2 b where a.orderid=b.orderid FOR UPDATE OF showcount;
  v_order c_orders%ROWTYPE;
BEGIN
  OPEN c_orders;
  
  LOOP
    FETCH c_orders  INTO v_order;
    EXIT WHEN c_orders%NOTFOUND;
    dbms_output.put_line(v_order.id1||','||v_order.id2||','||v_order.positioncode||','||v_order.showcount);
    UPDATE order2 SET showcount=8 WHERE CURRENT OF c_orders;
    IF SQL%NOTFOUND THEN
      DBMS_OUTPUT.PUT_LINE('NOT FOUND');
    END IF;
  END LOOP;
  COMMIT;
  CLOSE c_orders;
END;

则成功执行:

1,1,C,9
2,2,C,9
3,3,C,9
4,4,C,9
5,5,C,9

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值