PL/SQL 游标的使用详解

一:通过游标,PL/SQL 指向语句被分析以后的活动集

二:对于不同的SQL语句,游标的使用情况不同:
1:非查询语句--隐式的
2:结果是单行的查询语句--隐式的或显式的
3:结果是多行的查询语句--显式的

三:游标属性
1:%FOUND
2:%NOTFOUND
3:%ISOPEN
4:%ROWCOUNT

三:显式游标的用法
四个步骤
(1)定义一个游标名,以及与其相对应的SELECT 语句。语法:CURSOR cursor_name IS select_statement
(2)打开游标。语法:OPEN cursor_name
(3)提取游标。语法:FETCH cursor_name INTO {variable_list | record_variable }。
如:FETCH c_cursor INTO v_ename, v_sal
(4)关闭游标。语法:CLOSE cursor_name
例:
DECLARE
v_ename emp.ename%TYPE;
v_sal emp.sal%TYPE;
CURSOR c_cursor IS SELECT ename, sal FROM emp WHERE rownum<11;--声明的最后部分定义游标
BEGIN
OPEN c_cursor;--执行部分的开始打开游标
FETCH c_cursor INTO v_ename, v_sal;--打开后提取一次游标
WHILE c_cursor %FOUND LOOP
DBMS_OUTPUT.PUT_LINE(v_ename||'---'||to_char(v_sal) );
FETCH c_cursor INTO v_ename, v_sal;--循环最后提取游标
END LOOP;
CLOSE c_cursor;--游标提取结束后关闭游标
END;

四:参数化游标
定义游标名的后面加(变量名 类型)。变量用来和SQL的条件语句做比较
例:
DECLARE
v_ename emp.ename%TYPE;
v_sal emp.sal%TYPE;
CURSOR c_cursor(P_sal emp.sal%type)
IS SELECT ename, sal FROM emp WHERE sal >= P_sal;
BEGIN
OPEN c_cursor(1000);
FETCH c_cursor INTO v_ename, v_sal;
WHILE c_cursor %FOUND LOOP
DBMS_OUTPUT.PUT_LINE(v_ename||’---‘||to_char(v_sal) );
FETCH c_cursor INTO v_ename, v_sal;
END LOOP;
CLOSE c_cursor;
END;


五:隐式游标
显式游标主要是用于对查询语句的处理,尤其是查询结果为多条记录;
而对于非查询语句,则由系统自动设置游标,
称为隐式游标,隐式游标的名字为SQL,是由系统定义的。
对于隐式游标的操作,如定义、打开、取值及关闭操作,都由系统自动完成,无需用户进行处理。
用户只能通过隐式游标的相关属性,来完成相应的操作。
1:隐式游标属性
(1)%FOUND
(2)%NOTFOUND
(3)%ISOPEN
(4)%ROWCOUNT
例:
DECLARE
V_deptno emp.deptno%TYPE :=&p_deptno;
BEGIN
DELETE FROM emp WHERE deptno=v_deptno;
IF SQL%NOTFOUND THEN
DELETE FROM dept WHERE deptno= 20;
END IF;
END;


六:游标检索循环
例:
DECLARE
v_empno emp.empno%TYPE;
v_sal emp.sal%TYPE;
CURSOR c_cursor IS SELECT empno, sal FROM emp;
BEGIN
OPEN c_cursor;
LOOP
FETCH c_cursor INTO v_empno, v_sal;
EXIT WHEN c_cursor %NOTFOUND;
IF v_sal<=1200 THEN
UPDATE emp SET sal=sal+50 WHERE empno=v_empno;
DBMS_OUTPUT.PUT_LINE('编码为'||v_empno||'工资已更新!');
END IF;
DBMS_OUTPUT.PUT_LINE('记录数:'|| c_cursor %ROWCOUNT);
END LOOP;
CLOSE c_cursor;
END;

七:游标的FOR循环
游标FOR循环语句,自动执行游标的OPEN、FETCH、CLOSE语句和循环语句的功能;
当进入循环,自动打开游标,并提取第一行游标数据。
当处理完当前所提取的数据而进入下一次循环时,自动提取下一行数据。
当提取完结果集中的所有数据后结束循环,并自动关闭游标。

1:语法:
FOR 索引变量名 IN 游标名 LOOP
-- 游标数据处理代码
END LOOP;

例:
DECLARE
CURSOR c_sal IS SELECT empno, ename, sal FROM emp ;
BEGIN
--隐含打开游标
FOR v_sal IN c_sal LOOP
--隐含执行一个FETCH语句。 通过索引变量提取游标数据
DBMS_OUTPUT.PUT_LINE( to_char(v_sal.empno)||'---'||v_sal.ename||'---'||to_char(v_sal.sal)) ;
--隐含监测c_sal%NOTFOUND
END LOOP;
--隐含关闭游标
END;


例:
DECLARE
CURSOR c_cursor(dept_no NUMBER DEFAULT 10) IS --参数化游标
SELECT dname, loc FROM dept WHERE deptno <= dept_no;
BEGIN
DBMS_OUTPUT.PUT_LINE(‘dept_no参数值为30:’);
FOR c1_rec IN c_cursor (30) LOOP--for循环从索引变量到游标活动集
DBMS_OUTPUT.PUT_LINE(c1_rec.dname||'---'||c1_rec.loc);--循环体根据索引提取游标数据
END LOOP;
DBMS_OUTPUT.PUT_LINE(CHR(10)||'使用默认的dept_no参数值10:');
FOR c1_rec IN c_cursor LOOP
DBMS_OUTPUT.PUT_LINE(c1_rec.dname||'---'||c1_rec.loc);
END LOOP;
END;


八:游标变量

游标变量是动态的,而游标是静态的。游标只能与指定的查询相连,
即固定指向一个查询的内存处理区域,而游标变量可与不同的查询语句相连,
可以指向不同查询语句的内存处理区域,只要这些查询语句的返回类型兼容即可。

原文地址:https://www.cnblogs.com/maqiang123/p/7270157.html