游标:是一个指向上下文区(处理SQL所分配的一片内存区域)的句柄或指针。
显示游标
处理包括四个步骤:
1声明游标 CURSOR cursor_name IS SELECT_statement;
2打开游标 open cursor_name
3将结果提取到PL/SQL变量中。FETCH cursor_name INTO List_of_variables or PL/SQL_record;
4关闭游标。close cursor_name
显示游标用来处理返回多于一行的SELECT语句,隐式游标用于处理INSERT,UPDATE,DELETE和单行的SELECT。。。INTO语句。
SQL游标,PL/SQL隐含地条打开SQL游标,处理其中的SQL语句,然后关闭游标。所以,OPEN、FETCH和CLOSE命令是无关的。游标属性可以用于SQL游标。
游标循环提取
1 简单循环:loop ...end loop 2 while循环 while...loop
Declare
V_StudentID students.id%TYPE;
V_FirstName students.first_name%TYPE;
V_LastName students.last_name%TYPE;
CURSOR c_HistoryStudents IS
select id,first_name,second_name from students where major='history';
begin
open c_HistoryStudents;
loop
fetch c_HistoryStudents into V_STudentID,V_FirstName,V_LastName;
1 Exit when c_HistoryStudents%notfound; 2:while C_HistoryStudents%found loop
insert into registered_students(student_id,department,course) values(V_StudnetID,'his',301);
End loop
2fetch c_HistoryStudents into //出现两次fetch,一次在循环前面,一次在循环后面,必要的,这样循环条件(c_History%found)将对每一次循环叠代都进行求值。
close c_HistoryStudents;
commit;
end;
3 FOR循环
Declare
CURSOR c_HistoryStudents IS
select id,first_name,second_name from students where major='history';
begin
--begin the loop .An implicit OPEN of c_HistoryStudents is done here.
For v_StudentData IN c_HistoryStudents loop
--An implicit FETCH is done here.
--Process the fetched rows,in this case sign up each
--student for History 301 by insert them into the registered_students table.
insert into registered_students(student_id,department,course) values(V_StudnetID,'his',301);
--Before the loop will continue,an implicit check of c_HistoryStudents%NOTFOUND is done here.
end loop
--Now that the loop is finished,an implicit CLOSE of c_HistoryStudents is done.
--Commit our work.
commit ;
end;
4 select for update循环
这种方法包含两个部分-在游标声明部分的for update 子句和在update或delete语句中where current of子句。
(1) for update
是SELECT语句的一部分。它是作为该语句的最后一个子句,在order by 子句(如果存在的话)的后边。其语法是
select ...from...for update[of column_reference] [nowait] column_reference是执行该查询的表列。
(2)where current of
语法为:where current of cursor 这里的cursor是使用for update子句声明的游标的名字。where couuent of 子句会求值算出刚刚被游标检索出的行。
update 语句仅仅更新在游标声明的for update子句处列出的列。如果没有列出任何列,那么所有的列都可以都更新。
Declare
v_NumCredits classes.num_credits%TYPE;
currsor c_RegisteredStudnets is
select * from students where id in (select student_id from registered_students where department='HIS' AND course=101)
for update of current_credits;
begin
--set up the cursor fetch loop.
for v_Student in c_RegisteredStudents LOOP
select num_credits into v_NumCredits where department='HIS' and course=101;
--update the row we just retrieved from the cursor.
update students
set current_credits=current_credit+v+NumCredits
where current of c_RegisteredStudents;
END LOOP;
COMMIT;
END;