前情提要:
在通过select语句查询是,返回的结果通常是多行记录组成的集合。为此SQL提供 了游标机制。游标可以充当指针的作用,使应用程序设计语言一次只能处理查询记过中的一行。在Oracle中,可以使用隐式和显示两种游标。在pl/sql 中程序所有发出的DML和select语句,Oracle都会自动声明“隐式游标”。为了处理由select语句返回的一组记录,需要在pl/sql程序中申明和处理“显示游标”。
游标的主要属性如下:
%found 布尔型属性,如果SQL语句至少影响一行,则为true,否则为false
%notfound 布尔型属性,与%found相反
%isopen 布尔型属性,当游标已打开时返回true,游标关闭为false
%rowcount 数字型属性,返回受sql语句影响的行数
如果执行了一个select语句则可以通过SQL%ROWCONT来检查受影响的行数,还可以通过SQL%FOUND属性值是否为true,以检查SQL语句是否影响到了任何行。
程序演示:
DECLARE
BEGIN
UPDATE emp SET sal=1500 WHERE deptno=20;
IF SQL%FOUND THEN
dbms_output.put_line('更新了'||sql%ROWCOUNT||'行');
ELSE
dbms_output.put_line('没有更新');
END IF;
END;
BEGIN
UPDATE emp SET sal=1500 WHERE deptno=20;
IF SQL%FOUND THEN
dbms_output.put_line('更新了'||sql%ROWCOUNT||'行');
ELSE
dbms_output.put_line('没有更新');
END IF;
END;
显示游标:
显示游标是在pl/sql程序中使用包含select语句来声明的游标。如果需要处理从数据库中检索的一组记录,则可以使用显示游标。使用显示游标处理数据需要4个PL/SQL步骤
声明游标,打开游标,检索数据和关闭游标
CURSOR 游标名[(参数1 数据类型[参数2 数据类型...])]
IS SELECT语句;
打开和关闭游标:
打开游标就是执行声明游标所指定的查询语句。游标必须声明后才能打开,打开游标也就是调用游标中的select语句。打开游标的过程非常简单,只需要使用关键字OPEN并指定打开的游标名及传递的参数值
open
游标名[(参数1 数据类型[参数2 数据类型...])];
例如,要打开上面声明的游标emp_cursor,可以使用如下代码:
open
emp_cursor;
如果执行该语句,其输入的参数就是默认值,将会把SMITH的信息查询出来,如果要查KING
的信息
open
emp_cursor('KING
');
关闭游标使得用户不能再从查询结果中检索数据。使用完游标后应该马上关闭游标,释放select查询结果。如果关闭上面定义的游标emp_cursor,可以使用如下语句:
close
emp_cursor;
检索数据:
检索数据就是从检索到的结果集中获取数据保存到变量中,以遍在程序中进行处理。这4个操作步骤在程序中是依次进行的,即只有先声明游标才能打开,一旦打开游标就能从获取数据,当不需要数据时就关闭游标
游标声明中的select语句返回一组数据,open语句执行了select语句,close语句释放select语句的查询结果。而这一切工作都是为了从检索数据
检索数据使用fetch语句找出结果集中的单行,并从中提取单个值传给主变量语法如下:
fetch cursor_name into {variable_list|recod_variable};
程序演示:
DECLARE
CURSOR my_cursor(in_no IN PLS_INTEGER) IS SELECT * FROM emp WHERE deptno=in_no;
cuesor_result emp%ROWTYPE;
BEGIN
OPEN my_cursor(20);
LOOP
FETCH my_cursor INTO cuesor_result;
EXIT WHEN my_cursor%NOTFOUND;
dbms_output.put_line(cuesor_result.ename);
END LOOP;
END;
游标for循环:
在pl/sql中还有一种更加方便的使用显示游标的方法,那就是游标for循环,游标for循环是显示游标的一种快捷方式,它使用for循环依次读取结果集 中的行数据,当for循环开始时游标自动打开(不需要使用open方法)每循环依次,系统自动读取游标当前行的数据(不需要使用FETCH),当退出 for循环时,游标自动关闭(不需要使用close)
程序演示:
DECLARE
CURSOR my_cursor(in_no IN PLS_INTEGER) IS SELECT * FROM emp WHERE deptno=in_no;
BEGIN
FOR r IN my_cursor(20) LOOP
dbms_output.put_line(r.ename);
END LOOP;
END;
CURSOR my_cursor(in_no IN PLS_INTEGER) IS SELECT * FROM emp WHERE deptno=in_no;
BEGIN
FOR r IN my_cursor(20) LOOP
dbms_output.put_line(r.ename);
END LOOP;
END;