定义
游标是数据的集合,游标也是数据集合的指针,可以从游标中获取集合中的值
分类
自定义游标:静态的和动态的
系统游标(隐式的)
游标的操作:打开,遍历,关闭
静态游标
显示打开,显示关闭
declare
-- Local variables here
-- 定义静态游标
CURSOR c_emp IS SELECT * FROM emp WHERE deptno=10;
-- 定义变量,存储数据
v_emp emp%ROWTYPE;
begin
-- Test statements here
-- 打开游标
OPEN c_emp;
LOOP
FETCH c_emp INTO v_emp;-- 取游标中的记录,此时游标指针移动
dbms_output.put_line(v_emp.empno||'-'||v_emp.ename);
EXIT WHEN c_emp%NOTFOUND;-- %notfound没有数据
END LOOP;
-- 为了避免遗忘,先写关闭游标
IF c_emp%ISOPEN THEN -- %isopen打开状态属性
CLOSE c_emp;
END IF;
EXCEPTION
when OTHERS THEN
dbms_output.put_line(SQLCODE||'-'||SQLERRM);
end;
?
-- 优化后的代码
-- Created on 2021/1/26 by 96093
declare
-- Local variables here
-- 定义静态游标
CURSOR c_emp IS SELECT * FROM emp WHERE deptno=10;
-- 定义变量,存储数据
v_emp emp%ROWTYPE;
begin
-- Test statements here
-- 打开游标
OPEN c_emp;
LOOP
FETCH c_emp INTO v_emp;-- 取游标中的记录,此时游标指针移动
IF c_emp%NOTFOUND THEN-- %notfound没有数据
EXIT;
ELSE
dbms_output.put_line(v_emp.empno||'-'||v_emp.ename);
END IF;
END LOOP;
-- 为了避免遗忘,先写关闭游标
IF c_emp%ISOPEN THEN -- %isopen打开状态属性
CLOSE c_emp;
END IF;
EXCEPTION
when OTHERS THEN
dbms_output.put_line(SQLCODE||'-'||SQLERRM);
end;
自动打开和关闭
-- Created on 2021/1/26 by 96093
declare
-- Local variables here
i integer;
CURSOR c_emp IS SELECT * FROM emp WHERE deptno=10;
v_emp emp%ROWTYPE;
begin
-- Test statements here
-- 简单操作
FOR v_emp IN c_emp LOOP
dbms_output.put_line(v_emp.empno||'-'||v_emp.ename);
END LOOP;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(SQLCODE||'-'||SQLERRM);
end;
动态游标
-- Created on 2021/1/26 by 96093
declare
-- Local variables here
v_deptno emp.deptno%TYPE;
TYPE dync IS REF CURSOR;-- 定义动态游标类型
c_emp dync;
v_emp emp%ROWTYPE;
v_flag NUMBER :=0; -- 是否有数据,0为无,1为有
begin
-- Test statements here
SELECT deptno INTO v_deptno FROM emp WHERE empno=7788;
OPEN c_emp FOR SELECT * FROM emp WHERE deptno=v_deptno;
LOOP
FETCH c_emp INTO v_emp;
IF c_emp%NOTFOUND THEN
IF v_flag=0 THEN
dbms_output.put_line('no data');
END IF;
EXIT;
ELSE
dbms_output.put_line(v_emp.empno||'-'||v_emp.ename);
v_flag:=1;
END IF;
END LOOP;
IF c_emp%ISOPEN THEN
CLOSE c_emp;
END IF;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(SQLCODE||'-'||SQLERRM);
end;
动态游标和静态游标在定义和打开有区别
隐式游标:sql%rowcount
declare
-- Local variables here
i integer;
begin
-- Test statements here
UPDATE emp SET sal=sal+0;
dbms_output.put_line('影响的行数'||SQL%ROWCOUNT);
IF SQL%ROWCOUNT>0 THEN
dbms_output.put_line('update success');
ELSE
dbms_output.put_line('update failure');
END IF;
end;
定义一个带参数的游标
declare
-- Local variables here
v_row emp%ROWTYPE;
CURSOR c_emp2(dno emp.deptno%TYPE) IS SELECT * FROM emp WHERE deptno=dno;
begin
-- Test statements here
OPEN c_emp2(10);
LOOP
FETCH c_emp2 INTO v_row;
EXIT WHEN c_emp2%NOTFOUND;
dbms_output.put_line(v_row.empno);
END LOOP;
IF c_emp2%ISOPEN THEN
CLOSE c_emp2;
END IF;
end;
?
-- 简单操作
declare
-- Local variables here
v_row emp%ROWTYPE;
CURSOR c_emp2(dno emp.deptno%TYPE) IS SELECT * FROM emp WHERE deptno=dno;
begin
-- Test statements here
FOR v_row IN c_emp2(10) LOOP
dbms_output.put_line(v_row.empno);
END LOOP;
end;
%isopen,%notfound,%rowcount