第九章使用游标

<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:15.6pt;} div.Section1 {page:Section1;} /* List Definitions */ @list l0 {mso-list-id:964121647; mso-list-type:hybrid; mso-list-template-ids:470482610 1576956404 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l0:level1 {mso-level-text:(%1); mso-level-tab-stop:36.0pt; mso-level-number-position:left; text-indent:-36.0pt;} ol {margin-bottom:0cm;} ul {margin-bottom:0cm;} -->

一:显示游标1.定义游标,2.打开游标,3.提取数据,4.关闭游标

DECLARE

  CURSOR emp_cursor IS

  SELECT ename,sal FROM emp WHERE deptno=10;

  v_ename emp.ename%TYPE;

  v_sal emp.sal%TYPE;

BEGIN

  OPEN emp_cursor;

   LOOP

    FETCH emp_cursor INTO v_ename,v_sal;

    EXIT WHEN emp_cursor%NOTFOUND;

     dbms_output.put_line(v_ename||': '||v_sal);

   END LOOP;

    CLOSE emp_cursor;

END;

二:游标属性:%ISOPEN%FOUND%NOTFOUND%ROWCOUNT

DECLARE

TYPE name_array_type IS VARRAY(5) OF VARCHAR2(10);

name_array name_array_type;

CURSOR emp_cursor IS SELECT ename FROM emp;

rows INT:=5;

v_count INT:=0;

BEGIN

OPEN emp_cursor;

LOOP

FETCH emp_cursor BULK COLLECT INTO name_array

LIMIT rows;

dbms_output.put('雇员名:');

FOR i IN 1..(emp_cursor%ROWCOUNT-v_count) LOOP

dbms_output.put(name_array(i)||' ');

END LOOP;

dbms_output.new_line;

v_count:=emp_cursor%ROWCOUNT;

dbms_output.put_line('Count'||v_count);

EXIT WHEN emp_cursor%NOTFOUND;

   END LOOP;

 CLOSE emp_cursor;

 END;

雇员名:SMITH ALLEN WARD JONES MARTIN

Count5

雇员名:BLAKE CLARK KING TURNER JAMES

Count10

雇员名:FORD MILLER MARY

Count13

三:基于游标定义记录变量

DECLARE

 CURSOR emp_cursor IS SELECT ename,sal FROM emp;

 emp_record emp_cursor%ROWTYPE;

BEGIN

 OPEN emp_cursor;

 LOOP

  FETCH emp_cursor INTO emp_record;

  EXIT WHEN emp_cursor%NOTFOUND;

  dbms_output.put_line('雇员名:'||emp_record.ename||',雇员工资'||emp_record.sal);

 END LOOP;

CLOSE emp_cursor;

END;

雇员名:SMITH,雇员工资3600

雇员名:ALLEN,雇员工资2342.56

雇员名:WARD,雇员工资1830.13

雇员名:JONES,雇员工资3272.5

雇员名:MARTIN,雇员工资1830.13

雇员名:BLAKE,雇员工资4172.69

雇员名:CLARK,雇员工资2450

四:参数游标

DECLARE

CURSOR emp_cursor(no NUMBER) IS

SELECT ename FROM emp WHERE deptno=no;

v_ename emp.ename%TYPE;

BEGIN

OPEN emp_cursor(10);

LOOP

FETCH emp_cursor INTO v_ename;

EXIT WHEN emp_cursor%NOTFOUND;

dbms_output.put_line(v_ename);

END LOOP;

CLOSE emp_cursor;

END;

五:使用游标删除,更新数据

SELECT语句引用到多表时,可以使用OF确定哪些表要加锁,如果没有OF则所有表会加锁。当更新当前游标行数据,必须使用WHERE CURRENT OF

DECLARE

 CURSOR emp_cursor IS

  SELECT ename,sal,dname,emp.deptno FROM emp,dept

  WHERE emp.deptno=dept.deptno

  FOR UPDATE OF emp.deptno;

 emp_record emp_cursor%ROWTYPE;

BEGIN

 OPEN emp_cursor;

 LOOP

   FETCH emp_cursor INTO emp_record;

   EXIT WHEN emp_cursor%NOTFOUND;

   IF emp_record.deptno=30 THEN

    UPDATE emp SET sal=sal+100 WHERE CURRENT OF emp_cursor;

   END IF;

   dbms_output.put_line('雇员名:'||emp_record.ename||',工资:'emp_record.sal||',部门名:'||emp_record.dname);

 END LOOP;

 CLOSE emp_cursor;

END;

六:使用游标更新数据

DECLARE

CURSOR emp_cursor IS

SELECT ename,sal FROM emp FOR UPDATE;

v_ename emp.ename%TYPE;

v_oldsal emp.sal%TYPE;

BEGIN

 OPEN emp_cursor;

 LOOP

  FETCH emp_cursor INTO v_ename,v_oldsal;

 EXIT WHEN emp_cursor%NOTFOUND;

  IF v_oldsal<2000 THEN

   UPDATE emp SET sal=sal+100 WHERE CURRENT OF emp_cursor;

  END IF;

 END LOOP;

CLOSE emp_cursor;

END;

七:游标FOR循环

1

DECLARE

 cursor emp_cursor IS SELECT ename,sal FROM emp;

BEGIN

  FOR emp_record IN emp_cursor LOOP

   dbms_output.put_line(''||emp_cursor%ROWCOUNT||'个雇员:'||emp_record.ename);

  END LOOP;

END;

1个雇员:SMITH

2个雇员:ALLEN

3个雇员:WARD

4个雇员:JONES

5个雇员:MARTIN

6个雇员:BLAKE

7个雇员:CLARK

2FOR 循环中直接使用SELECT

BEGIN

  FOR emp_record IN

  (SELECT ename,sal FROM emp) LOOP

    dbms_output.put_line(emp_record.ename);

  END LOOP;

END;

八:使用游标变量:使用游标变量可以在打开游标时指定SELECT语句。

(1)       不指定return子句即打开游标可以使用任何SELECT语句

DECLARE

TYPE emp_cursor_type IS REF CURSOR;

emp_cursor emp_cursor_type;

emp_record emp%ROWTYPE;

BEGIN

OPEN emp_cursor FOR SELECT * FROM emp WHERE deptno=10;

LOOP

FETCH emp_cursor INTO emp_record;

EXIT WHEN emp_cursor%NOTFOUND;

dbms_output.put_line(''||emp_cursor%ROWCOUNT||'个雇员:'||emp_record.ename);

END LOOP;

CLOSE emp_cursor;

END;

(2)       指定return子句即游标SELECT返回结果必须与返回值相匹配。

DECLARE

TYPE emp_record_type IS RECORD(

name VARCHAR2(10),salary NUMBER(6,2));

TYPE emp_cursor_type IS REF CURSOR

RETURN emp_record_type;

emp_cursor emp_cursor_type;

emp_record emp_record_type;

BEGIN

OPEN emp_cursor FOR SELECT ename,sal FROM emp

WHERE deptno=20;

LOOP

FETCH emp_cursor INTO emp_record;

EXIT WHEN emp_cursor%NOTFOUND;

dbms_output.put_line(''||emp_cursor%ROWCOUNT||'个雇员:'||emp_record.name);

END LOOP;

CLOSE emp_cursor;

END;

 

九:CURSOR表达式:使结果集可以包含嵌套游标的数据,用于处理复杂的多表关联数据

DECLARE

TYPE refcursor IS REF CURSOR;

CURSOR dept_cursor(no NUMBER) IS

SELECT a.dname,CURSOR(SELECT ename,sal FROM emp

WHERE deptno=a.deptno)

FROM dept a WHERE a.deptno=no;

empcur refcursor;

v_dname dept.dname%TYPE;

v_ename emp.ename%TYPE;

v_sal emp.sal%TYPE;

BEGIN

OPEN dept_cursor(&no);

LOOP

FETCH dept_cursor INTO v_dname,empcur;

EXIT WHEN dept_cursor%NOTFOUND;

dbms_output.put_line('部门名:'||v_dname);

LOOP

FETCH empcur INTO v_ename,v_sal;

EXIT WHEN empcur%NOTFOUND;

dbms_output.put_line('雇员名:'||v_ename||',工资'||v_sal);

END LOOP;

END LOOP;

CLOSE dept_cursor;

END;

部门名:ACCOUNTING

雇员名:CLARK,工资2450

雇员名:KING,工资5000

雇员名:MILLER,工资1400

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值