高分求教一个概念和用法
游标在好多的书上看到,可是就是一说,讲得不清楚,或者是我比较笨,那位能给个解释,告诉我游标用来干什么,最好有例子!谢谢 问题点数:100、回复次数:8Top
1 楼bzszp(SongZip)回复于 2005-07-28 11:08:27 得分 50
例如:
SQL> select * from t;
AAA BBB
---------- ----------
1 2
3 4
5 6
1 1
已用时间: 00: 00: 00.70
SQL> set serveroutput on
SQL> declare
2 cursor c is select * from t;
3 v_t t%rowtype;
4 begin
5 open c;
6 fetch c into v_t;
7 while c%found loop
8 dbms_output.put_line(v_t.aaa||';'||v_t.bbb);
9 fetch c into v_t;
10 end loop;
11 close c;
12 end;
13 /
1;2
3;4
5;6
1;1
PL/SQL 过程已成功完成。
已用时间: 00: 00: 00.70
SQL>Top
2 楼bzszp(SongZip)回复于 2005-07-28 11:11:06 得分 0
用于对某个结果集 的每条数据进行处理
上面的例子 是 显示游标的用法,下面是隐式游标的用法
SQL> declare
2 cursor c is select * from t;
3 begin
4 for v_t in c loop
5 dbms_output.put_line(v_t.aaa||';'||v_t.bbb);
6 end loop;
7 end;
8 /
1;2
3;4
5;6
1;1
PL/SQL 过程已成功完成。
已用时间: 00: 00: 00.40
SQL>Top
3 楼njhart2003()回复于 2005-07-28 11:22:35 得分 0
游标是一个查询的记录集。
1.隐式游标
for x in (select * from t) loop
:a:=x.f1; -- x是隐式游标
....
end loop;
2.显示游标
cursor cur1 is select f1 from t;
open cur1;
fetch cur1 into a; -- cur1是显式游标
....
close cur1;
显示游标注意结构要完整,有打开游标,就一定要有关闭游标的语句。
3.带参数的游标
cursor cur1(p1 in t.id%type) is select f1 from t where id=p1;
....
Top
4 楼UandM(NULL)回复于 2005-07-28 12:04:51 得分 0
游标管理
游标:
用来查询数据库,获取记录集合(结果集)的指针,可以让开发者一次访问一行结果集,在每条结果集上作操作。
分类:
静态游标:
分为显式游标和隐式游标。
REF游标:一种引用类型,类似于指针。
显式游标:
CURSOR 游标名 ( 参数 ) [返回值类型] IS
Select 语句
生命周期:
1. 打开游标(OPEN):
解析,绑定。。。不会从数据库检索数据
2. 从游标中获取记录(FETCH INTO):
执行查询,返回结果集。通常定义局域变量作为从游标获取数据的缓冲区。
3. 关闭游标(CLOSE)
完成游标处理,用户不能从游标中获取行。还可以重新打开。
选项:参数和返回类型
set serveroutput on
declare
cursor emp_cur ( p_deptid in number) is
select * from employees where department_id = p_deptid;
l_emp employees%rowtype;
begin
dbms_output.put_line(‘Getting employees from department 30’);
open emp_cur(30);
loop
fetch emp_cur into l_emp;
exit when emp_cur%notfound;
dbms_output.put_line(‘Employee id ‘|| l_emp.employee_id || ‘ is ‘);
dbms_output.put_line(l_emp.first_name || ‘ ‘ || l_emp.last_name);
end loop;
close emp_cur;
dbms_output.put_line(‘Getting employees from department 90’);
open emp_cur(90);
loop
fetch emp_cur into l_emp;
exit when emp_cur%notfound;
dbms_output.put_line(‘Employee id ‘|| l_emp.employee_id || ‘ is ‘);
dbms_output.put_line(l_emp.first_name || ‘ ‘ || l_emp.last_name);
end loop;
close emp_cur;
end;
/
Top
5 楼camel2165(camel)回复于 2005-07-28 12:07:43 得分 50
游标概述
为了处理SQL语句,ORACLE将在内存中分配一个区域-上下文区,它包含了完成处理过程的必要信息,其中包括已经处理完的行数、指向被分析语句的指针和在查询情况下的活动集,它是查询语句返回的数据行集。游标就是指向上下文区的句柄或指针。
游标的处理
游标的处理共分四个部分:声明、打开、取值和关闭。
1) 声明游标
声明游标的语法结构如下:
CURSOR cursor_name IS select_statement;
游标声明的时候也可以引用PL/SQL变量,但是这些变量必须在游标说明之前说明,如下:
DECLARE
V_Department classes.department%TYPE;
V_Course classes.course%TYPE;
CURSOR c_classes IS
SELECT * from classes WHERE department=V_Department
AND course=V_Course;
BEGIN
…
END;
如果上述两个变量说明放在游标说明的后边,则是非法的。
2) 打开游标
打开游标的语法结构如下:
OPEN cursor_name;
打开游标时,发生下列事情:
检验绑定变量的值
基于绑定变量的值和查询语句,返回数据集
指针指向第一行
3) 使用游标检索
使用游标检索数据的语法结构如下:
FETCH cursor_name INTO variable;
其中,变量可以是单独的变量、变量列表或记录等,不过要与SELECT列表相对应。
在每一个FETCH执行之后,数据集指针开始指向下一个数据行,最后一个FETCH不再给输出变量分配值,这些输出变量的值仍是原来的。
4) 关闭游标
关闭游标的语法结构如下:
CLOSE cursor_name;
游标的属性
在PL/SQL中,游标一共有四个属性:
%FOUND
检测当前的FETCH语句是否有数据行返回。游标打开后,它的值为NULL,因为还没有任何数据检索的动作。当游标指向最后一条记录,再执行一个FETCH语句后,它的值为FALSE。
%NOTFOUND
检测当前的FETCH语句是否有数据行返回。游标打开后,它的值为NULL,因为还没有任何数据检索的动作。当游标指向最后一条记录,再执行一个FETCH语句后,它的值为TRUE。
%ISOPEN
检测光标是否打开。
%ROWCOUNT
返回当前FETCH语句已经从数据集中检索数据行的个数。当游标刚打开后,它的值为0,随着FETCH语句的使用,它的值依次累加。
参数化游标
前面我们已经看到,游标定义的时候,可以带有绑定变量,然后在打开游标前,给绑定变量赋值就可以了。我们现在还有一种定义方式,就是使用带有参数的游标,即参数化游标,在打开游标的时候,赋予相应的参数就可以了,如下:
DECLARE
CURSOR c_classess(p_department classes.department%TYPE,p_course classes.course%TYPE) IS
SELECT * FROM classess WHERE department=p_department AND course=p_course;
BEGIN
OPEN c_classes(‘HIS’,101);
…
END;
处理隐式游标
对于所有的SQL语句,都是在一个上下文区执行的。因此需要一个游标指向该上下文区,这个游标就是SQL游标。与显式游标不同的是,SQL游标不是由程序打开或者关闭的,PL/SQL隐含的打开SQL游标,处理完SQL语句后,自动关闭。
隐式游标被用于处理INSERT、UPDATE、DELETE和SELECT INTO语句。在隐式游标的四个属性中,SQL%ISOPEN属性永远都是FALSE。
隐式游标举例如下:
update …;
if SQL%NOTFOUND then…
update …;
if SQL%ROWCOUNT=0 then…
在SELECT INTO语句中,使用SQL%NOTFOUND是无效的,因为如果没有检索到数据时,将会产生一个异常,语句控制权被转移到异常处理模块,在NO_DATA_FOUND异常中处理,而不会执行接下来的SQL%NOTFOUND。
游标检索循环
对游标来说,检索数据集中的所有数据是通过循环来实现的。这个循环有多种形式。
简单循环
简单循环是指使用简单的循环(LOOP…END LOOP)来进行游标处理,游标的属性被用来控制循环执行的次数。
LOOP
FETCH…
…
EXIT WHEN cursor_name%NOTFOUND;
…
END LOOP
WHILE循环
FETCH…
WHILE cursor_name%FOUND LOOP
…
FETCH…
END LOOP;
游标FOR循环
前面描述的两种循环都需要使用OPEN、FETCH和CLOSE语句来显式的处理游标。PL/SQL提供了更加简单的循环类型,可以隐式的处理游标,这就是游标FOR循环。
DECLARE
CURSOR c_HistoryStudents IS
SELECT id, first_name, last_name
FROM students
WHERE major = 'History';
BEGIN
FOR v_StudentData IN c_HistoryStudents LOOP
INSERT INTO registered_students (student_id, department, course)
VALUES (v_StudentData.ID, 'HIS', 301);
INSERT INTO temp_table (num_col, char_col)
VALUES (v_StudentData.ID,
v_StudentData.first_name || ' ' || v_StudentData.last_name);
END LOOP;
END;
上例有两个需要说明的地方:
1)记录v_StudentData不需要在说明部分说明,它是有PL/SQL隐式说明的,类型是c_HistoryStudents%ROWTYPE,它的作用域只有FOR循环本身,并且不能给其赋值。
2)c_HistoryStudents被循环隐式打开、检索和关闭。在每一次循环之前,%FOUND属性被检查以确保数据集中是否还有数据。
游标FOR循环还可以更简短一些,就是将游标本身的声明也变成隐含的,如下:
FOR v_StudentData IN (SELECT id, first_name, last_name
FROM students
WHERE major = 'History') LOOP
INSERT INTO registered_students (student_id, department, course)
VALUES (v_StudentData.ID, 'HIS', 301);
INSERT INTO temp_table (num_col, char_col)
VALUES (v_StudentData.ID,
v_StudentData.first_name || ' ' || v_StudentData.last_name);
END LOOP;
上例中,游标的声明取消了,放在了FOR语句自身的括号内,同时也没有了游标名称。
NO_DATA_FOUND与%NOTFOUND
NO_DATA_FOUND是异常,只有在SELECT INTO语句的WHERE子句没有匹配的数据时出现,而游标的WHERE子句或UPDATE、DELETE语句的WHERE子句没有匹配的数据时,不会产生该异常,所以我们可以使用SQL%NOTFOUND。
SELECT FOR UPDATE游标
(涉及数据加锁问题,暂时忽略,可以参见《Oracle9i PL/SQL程序设计》173页)
游标变量
到目前为止,我们看到的显式游标变量都是静态游标,即游标与某SQL语句相关联。我们现在可以通过游标变量在运行时与不同的查询语句建立关联。
使用游标变量的步骤如下:
声明游标变量
TYPE type_name IS REF CURSOR;
Cursor_name type_name;
或
TYPE type_name IS REF CURSOR RETURN student%ROWTYPE;
Cursor_name type_name;
游标变量的声明分为两个步骤,首先声明一个游标变量类型,这个类型可以是约束的,也可以是无约束的,约束类型必须返回一个记录类型的返回值,同时当匹配查询语句的时候,查询列表也要与返回的记录类型相一致,无约束类型就没有这个问题。声明完毕游标变量类型以后,就可以声明游标变量了。
打开游标变量
OPEN cursor_name FOR select_statement;
若游标变量是约束类型的,则查询语句要与之匹配。
注意:OPEN FOR中的查询语句必须在程序中硬编码,不能包含在变量中,这个限制可以在动态SQL中解决。
打开游标变量之后,就可以正常的使用和关闭了。
游标变量使用举例:
CREATE OR REPLACE PROCEDURE ShowCursorVariable (p_Table IN VARCHAR2) AS
TYPE t_ClassesRooms IS REF CURSOR;
v_CursorVar t_ClassesRooms;
v_Department classes.department%TYPE;
v_Course classes.course%TYPE;
v_RoomID rooms.room_id%TYPE;
v_Description rooms.description%TYPE;
BEGIN
IF p_Table = 'classes' THEN
OPEN v_CursorVar FOR SELECT department, course FROM classes;
ELSIF p_table = 'rooms' THEN
OPEN v_CursorVar FOR SELECT room_id, description FROM rooms;
ELSE
RAISE_APPLICATION_ERROR(-20000,'Input must be ''classes'' or ''rooms''');
END IF;
LOOP
IF p_Table = 'classes' THEN
FETCH v_CursorVar INTO v_Department, v_Course;
EXIT WHEN v_CursorVar%NOTFOUND;
INSERT INTO temp_table (num_col, char_col) VALUES (v_Course, v_Department);
ELSE
FETCH v_CursorVar INTO v_RoomID, v_Description;
EXIT WHEN v_CursorVAR%NOTFOUND;
INSERT INTO temp_table (num_col, char_col) VALUES (v_RoomID, SUBSTR(v_Description, 1, 60));
END IF;
END LOOP;
CLOSE v_CursorVar;
COMMIT;
END ShowCursorVariable;
Top
6 楼skyinfo(tiger)回复于 2005-07-28 14:28:04 得分 0
我是來虛心學習的Top
7 楼waterfirer(水清)回复于 2005-07-28 17:00:45 得分 0
markTop
8 楼nowait(独行天涯路)回复于 2005-07-28 22:23:23 得分 0
我建议楼主看看oracle的联机文档。我反正是把这一系列文档当字典翻^_^Top




