<!-- /* 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
(2)FOR 循环中直接使用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