PL/SQL中的游标
1、逐行处理查询结果,以编程的方式访问数据
2、游标的类型:隐式游标、显示游标、REF游标(REF 游标用于处理运行时才能确定的动态 SQL 查询的结果)
常用的几个属性:
- %FOUND : SQL 语句影响了一行或多行时为 TRUE
- %NOTFOUND : SQL 语句没有影响任何行时为TRUE
- %ROWCOUNT : SQL 语句影响的行数
- %ISOPEN : 游标是否打开
隐式游标
SQL%ISOPEN : 隐式游标中,当执行sql语句时,游标自动打开。执行完毕之后自动关闭,所以每次查看的时候都是false的
BEGIN
UPDATE emp SET comm = 200 WHERE empno = 7369;
IF SQL%NOTFOUND THEN
DBMS_OUTPUT.put_line('更新失败');
ELSE
DBMS_OUTPUT.put_line('已经更新');
END IF;
END;
BEGIN
UPDATE emp SET comm = 200;
IF SQL%ROWCOUNT!= 0 THEN
DBMS_OUTPUT.put_line('更新了' || SQL%ROWCOUNT || '行');
ELSE
DBMS_OUTPUT.put_line('未更新');
END IF;
IF SQL%ISOPEN THEN
DBMS_OUTPUT.put_line('打开');
ELSE
DBMS_OUTPUT.put_line('关闭');
END IF;
END;
显示游标
显示游标的操作过程:
数据库------->打开游标------------>执行sql---------->结果到变量中去--------------->关闭游标
使用的步骤
- 定义游标: cursor 游标名称 is select语句
- 开启游标: open 游标名称
- 使用游标:fetch 游标名称 into 变量列表
- 关闭游标: close 游标名称
/*不带参数的显示游标*/
DECLARE
emp_empno emp.empno%TYPE;
emp_ename emp.ename%TYPE;
CURSOR emp_cur IS --定义游标
SELECT empno,ename FROM emp;
BEGIN
OPEN emp_cur; --开启游标
LOOP
FETCH emp_cur INTO emp_empno,emp_ename; --使用游标
EXIT WHEN emp_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(emp_cur%ROWCOUNT || ':姓名:'||emp_ename || ',编号:'||emp_empno);
END LOOP;
CLOSE emp_cur;--关闭游标
END;
/*带参数的显示游标*/
DECLARE
emp_name emp.ename%TYPE;
emp_sal emp.sal%TYPE;
emp_deptParam emp.deptno%TYPE;
CURSOR emp_cur(emp_deptno NUMBER) IS
SELECT ename,sal FROM emp WHERE deptno=emp_deptno;
BEGIN
emp_deptParam:=&部门编号;
OPEN emp_cur(emp_deptParam);
LOOP
FETCH emp_cur INTO emp_name,emp_sal;
EXIT WHEN emp_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(emp_name||' '||emp_sal);
END LOOP;
END;
/*使用显示游标更新数据*/
DECLARE
src_sal NUMBER;---存之前的工资
CURSOR emp_cur IS--声明游标
SELECT sal FROM emp WHERE sal < 3000 FOR UPDATE OF sal;--给对应要操作的行加上行级锁
BEGIN
OPEN emp_cur;
LOOP
FETCH emp_cur INTO src_sal;--给src_sal赋值
EXIT WHEN emp_cur%NOTFOUND;
UPDATE emp SET sal=1.1*src_sal WHERE CURRENT OF emp_cur;--当前遍历到的游标
END LOOP;
CLOSE emp_cur;
COMMIT;
END;
/*
使用FOR循环来遍历显示游标【循环游标】
在for循环的时候,游标自动打开,当for循环结束时,游标自动关闭;
类似java中增强for循环
*/
DECLARE
dept_no emp.deptno%TYPE;
CURSOR emp_cur(deptparam NUMBER) IS
SELECT ename FROM emp WHERE emp.deptno=deptparam ;
BEGIN
dept_no := &部门编号;
FOR myEmp IN emp_cur(dept_no)--类似于java中的增强for循环,
LOOP
DBMS_OUTPUT.put_line(myEmp.ename);
END LOOP;
IF emp_cur%ISOPEN THEN --用来判断游标是否开启
DBMS_OUTPUT.put_line('打开');
ELSE
DBMS_OUTPUT.put_line('关闭');
END IF;
END;
显示游标类似jdbc中prepareStatement执行之后得到ResultSet,通过rs的rs.next()一行一行的变量。fetch类型于pojo.setXXX(rs.getXXX(“xxx”));
显示游标需要手动开启关闭游标。隐式游标自动开启关闭游标,使用SQl%ISOPEN查看的时候永远都是false的。